70 lines
1.9 KiB
Vue
70 lines
1.9 KiB
Vue
<template>
|
|
<div class="widget-shell">
|
|
<div class="widget-handle" :class="{ 'is-edit': editing }">
|
|
<v-icon :icon="icon" size="small" class="mr-2" />
|
|
<span class="widget-title">{{ title }}</span>
|
|
<v-spacer />
|
|
<div class="widget-actions">
|
|
<v-progress-circular v-if="loading" indeterminate size="14" width="2" class="mr-1" />
|
|
<v-btn icon="mdi-refresh" size="x-small" variant="text" title="Refresh" @click="$emit('refresh')" />
|
|
<v-btn v-if="editing" icon="mdi-close" size="x-small" variant="text" color="error" title="Remove" @click="$emit('remove')" />
|
|
</div>
|
|
</div>
|
|
<div class="widget-body">
|
|
<slot />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
// Common chrome for every dashboard widget: a draggable title bar (.widget-handle) with refresh/remove
|
|
// actions (.widget-actions are excluded from the drag), and a scrollable body slot.
|
|
export default {
|
|
props: {
|
|
title: { type: String, required: true },
|
|
icon: { type: String, default: 'mdi-view-dashboard-outline' },
|
|
editing: { type: Boolean, default: false },
|
|
loading: { type: Boolean, default: false }
|
|
},
|
|
emits: ['refresh', 'remove']
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.widget-shell {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: rgb(var(--v-theme-surface));
|
|
border: 1px solid rgba(128, 128, 128, 0.22);
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
}
|
|
.widget-handle {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
padding: 6px 8px 6px 12px;
|
|
border-bottom: 1px solid rgba(128, 128, 128, 0.18);
|
|
background: rgba(128, 128, 128, 0.06);
|
|
min-height: 38px;
|
|
}
|
|
.widget-handle.is-edit {
|
|
cursor: move;
|
|
background: rgba(var(--v-theme-primary), 0.08);
|
|
}
|
|
.widget-title {
|
|
font-weight: 600;
|
|
font-size: 0.9rem;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
.widget-body {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow: auto;
|
|
padding: 12px;
|
|
}
|
|
</style>
|