feat: add and remove tabs, create and remove tab items

This commit is contained in:
Qiuxia Fan
2022-01-07 17:20:03 +08:00
parent 59ea77d65c
commit a94c5ff4cb
7 changed files with 178 additions and 35 deletions

View File

@@ -13,65 +13,118 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<div v-if="data.children.length">
<div class="flex-h tab-header">
<div class="tabs">
<span v-for="(item, idx) in data.children || []" :key="idx">{{
item.name
}}</span>
</div>
<grid-layout
v-model:layout="state.layout"
:col-num="24"
:row-height="10"
:is-draggable="true"
:is-resizable="true"
@layout-updated="layoutUpdatedEvent"
>
<grid-item
v-for="item in state.layout"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
<span
v-for="(item, idx) in data.children || []"
:key="idx"
:class="{ active: state.activeTab === idx }"
@click="clickTabs(idx)"
>
<Widget :item="item" />
</grid-item>
</grid-layout>
{{ item.name }}
<Icon
v-show="state.activeTab === idx"
size="sm"
iconName="cancel"
@click="deleteTabItem(idx)"
/>
</span>
<span class="add-Item" @click="addTabItem">
<Icon size="sm" iconName="add" />
</span>
</div>
<div class="operations">
<Icon size="sm" iconName="clearclose" @click="removeTab" />
</div>
</div>
<div class="tabs" v-else>Please add Widgets</div>
<grid-layout
v-model:layout="state.layout"
:col-num="24"
:row-height="10"
:is-draggable="true"
:is-resizable="true"
@layout-updated="layoutUpdatedEvent"
>
<grid-item
v-for="item in state.layout"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
>
<Widget :item="item" />
</grid-item>
</grid-layout>
</template>
<script lang="ts" setup>
import { defineProps, reactive } from "vue";
import type { PropType } from "vue";
import Widget from "./Widget.vue";
import { LayoutConfig } from "@/types/dashboard";
import { useDashboardStore } from "@/store/modules/dashboard";
defineProps({
const props = defineProps({
data: {
type: Object as PropType<{ type: string; children: any[] }>,
default: () => ({ children: [] }),
},
});
const state = reactive<{ layout: any }>({
const dashboardStore = useDashboardStore();
const state = reactive<{ layout: any[]; activeTab: number }>({
layout: [],
activeTab: 0,
});
function layoutUpdatedEvent(newLayout: LayoutConfig) {
function layoutUpdatedEvent(newLayout: LayoutConfig[]) {
state.layout = newLayout;
}
function clickTabs(idx: number) {
state.activeTab = idx;
}
function removeTab() {
dashboardStore.removeControls(props.data);
}
function deleteTabItem(idx: number) {
dashboardStore.removeTabItem(props.data, idx);
}
function addTabItem() {
dashboardStore.addTabItem(props.data);
}
</script>
<style lang="scss" scoped>
.tabs {
height: 30px;
border-bottom: 1px solid #eee;
height: 40px;
span {
display: inline-block;
width: auto;
padding: 5px 10px;
border-right: 1px solid #ccc;
padding: 0 10px;
margin: 0 10px;
height: 40px;
line-height: 40px;
cursor: pointer;
}
span.active {
border-bottom: 1px solid #409eff;
color: #409eff;
}
}
.operations {
color: #aaa;
cursor: pointer;
height: 40px;
line-height: 40px;
padding-right: 10px;
}
.tab-header {
justify-content: space-between;
width: 100%;
border-bottom: 1px solid #eee;
}
.vue-grid-layout {

View File

@@ -69,7 +69,6 @@ export default defineComponent({
async function queryMetrics() {
const loadingInstance = loading({
text: t("loading"),
fullscreen: false,
});
const json = await dashboardStore.fetchMetricValue(props.data);
@@ -91,7 +90,7 @@ export default defineComponent({
}
function removeWidget() {
dashboardStore.removeWidget(data);
dashboardStore.removeControls(data);
}
function setConfig() {
dashboardStore.setConfigPanel(true);