feat: edit tab item name, add widgets in tab

This commit is contained in:
Qiuxia Fan 2022-01-09 16:58:11 +08:00
parent 7cdd57325a
commit 92b03a006e
5 changed files with 105 additions and 18 deletions

View File

@ -24,7 +24,7 @@ import { useAppStoreWithOut } from "@/store/modules/app";
interface DashboardState {
showConfig: boolean;
layout: LayoutConfig[];
selectedGrid: Nullable<LayoutConfig>;
selectedGrid: Nullable<LayoutConfig>; // edit widgets
entity: string;
layerId: string;
activedGridItem: string;
@ -61,13 +61,14 @@ export const dashboardStore = defineStore({
return d;
});
this.layout.push(newWidget);
this.activedGridItem = newWidget.i;
},
addTab() {
const newWidget: LayoutConfig = {
x: 0,
y: 0,
w: 24,
h: 12,
h: 20,
i: String(this.layout.length),
type: "Tab",
children: [
@ -89,6 +90,7 @@ export const dashboardStore = defineStore({
return d;
});
this.layout.push(newWidget);
this.activedGridItem = newWidget.i;
},
addTabItem(item: LayoutConfig) {
const idx = this.layout.findIndex((d: LayoutConfig) => d.i === item.i);
@ -102,6 +104,25 @@ export const dashboardStore = defineStore({
};
this.layout[idx].children?.push(i);
},
addTabWidget(tabIndex: number) {
const idx = this.layout.findIndex(
(d: LayoutConfig) => d.i === this.activedGridItem
);
const newWidget = {
x: 0,
y: 0,
w: 24,
h: 12,
i: String(this.layout[idx].children[tabIndex].children.length),
type: "Widget",
widget: {},
graph: {},
standard: {},
};
if (this.layout[idx].children) {
this.layout[idx].children[tabIndex].children.push(newWidget);
}
},
activeGridItem(index: string) {
this.activedGridItem = index;
},

View File

@ -36,4 +36,5 @@ export const ConfigData = {
sortOrder: "DEC",
unit: "s",
},
children: [],
};

View File

@ -26,7 +26,7 @@ export interface LayoutConfig {
metrics?: string[];
type?: string;
queryMetricType?: string;
children?: any[];
children?: any;
}
export interface WidgetConfig {

View File

@ -16,22 +16,33 @@ limitations under the License. -->
<div class="flex-h tab-header">
<div class="tabs">
<span
v-for="(item, idx) in data.children || []"
v-for="(child, idx) in data.children || []"
:key="idx"
:class="{ active: state.activeTab === idx }"
:class="{ active: activeTabIndex === idx }"
@click="clickTabs(idx)"
>
{{ item.name }}
<input
@click="editTabName(idx)"
v-model="child.name"
placeholder="Please input"
class="tab-name"
:readonly="isNaN(editTabIndex)"
:class="{ view: isNaN(editTabIndex) }"
/>
<Icon
v-show="state.activeTab === idx"
v-show="activeTabIndex === idx"
size="sm"
iconName="cancel"
@click="deleteTabItem(idx)"
/>
</span>
<span class="add-Item" @click="addTabItem">
<Icon size="middle" iconName="add" />
<span class="tab-icons">
<i @click="addTabItem">
<Icon size="middle" iconName="add" />
</i>
<i @click="addTabWidget">
<Icon size="middle" iconName="playlist_add" />
</i>
</span>
</div>
<div class="operations">
@ -55,12 +66,15 @@ limitations under the License. -->
:i="item.i"
:key="item.i"
>
<Widget :item="item" />
<Widget
:data="item"
:active="dashboardStore.activedGridItem === item.i"
/>
</grid-item>
</grid-layout>
</template>
<script lang="ts" setup>
import { defineProps, reactive } from "vue";
import { defineProps, reactive, ref } from "vue";
import type { PropType } from "vue";
import Widget from "./Widget.vue";
import { LayoutConfig } from "@/types/dashboard";
@ -68,21 +82,25 @@ import { useDashboardStore } from "@/store/modules/dashboard";
const props = defineProps({
data: {
type: Object as PropType<{ type: string; children: any[] }>,
type: Object as PropType<{ type: string; children: any[]; i: string }>,
default: () => ({ children: [] }),
},
active: { type: Boolean, default: false },
});
const dashboardStore = useDashboardStore();
const state = reactive<{ layout: any[]; activeTab: number }>({
layout: [],
activeTab: 0,
const activeTabIndex = ref<number>(0);
const editTabIndex = ref<number>(NaN); // edit tab item name
const state = reactive<{
layout: LayoutConfig[];
}>({
layout:
dashboardStore.layout[props.data.i].children[activeTabIndex.value].children,
});
function layoutUpdatedEvent(newLayout: LayoutConfig[]) {
state.layout = newLayout;
}
function clickTabs(idx: number) {
state.activeTab = idx;
activeTabIndex.value = idx;
}
function removeTab() {
dashboardStore.removeControls(props.data);
@ -93,14 +111,27 @@ function deleteTabItem(idx: number) {
function addTabItem() {
dashboardStore.addTabItem(props.data);
}
function editTabName(index: number) {
editTabIndex.value = index;
}
function handleClick(el: any) {
if (el.target.className === "tab-name") {
return;
}
editTabIndex.value = NaN;
}
function addTabWidget() {
dashboardStore.addTabWidget(activeTabIndex.value);
}
document.body.addEventListener("click", handleClick, false);
</script>
<style lang="scss" scoped>
.tabs {
height: 40px;
color: #ccc;
span {
display: inline-block;
width: auto;
padding: 0 10px;
margin: 0 10px;
height: 40px;
@ -108,12 +139,42 @@ function addTabItem() {
cursor: pointer;
}
.tab-name {
max-width: 80px;
height: 25px;
line-height: 25px;
outline: none;
color: #333;
font-style: normal;
margin-right: 5px;
}
.tab-icons {
color: #333;
i {
margin-right: 3px;
}
}
.view {
cursor: pointer;
}
input.tab-name {
border: 0;
}
span.active {
border-bottom: 1px solid #409eff;
color: #409eff;
}
}
.el-input__inner {
border: none !important;
}
.operations {
color: #aaa;
cursor: pointer;

View File

@ -157,6 +157,10 @@ function clickIcons(t: { id: string; content: string; name: string }) {
color: #666;
}
.item {
font-size: 12px;
}
.selectors {
min-width: 180px;
}