refactor(page): refactor dashboard --> info

This commit is contained in:
qianmoQ 2024-11-17 15:01:12 +08:00
parent df7f58926b
commit fd044a072a
7 changed files with 193 additions and 128 deletions

View File

@ -5,14 +5,12 @@
</ShadcnButton>
</div>
<div v-if="result.blobURL || pic" class="pt-2 grid place-items-center">
<div>
<img class="max-h-[180px]" :src="result.blobURL ? result.blobURL : pic" alt=""/>
</div>
<div v-if="result.blobURL || pic" class="mt-2.5 flex justify-center">
<ShadcnAvatar square :src="result.blobURL ? result.blobURL : pic" style="width: 200px; height: 200px"/>
</div>
<ShadcnModal v-if="isShowModal"
:is-visible="isShowModal"
v-model="isShowModal"
:title="$t('common.cropper')"
@close="isShowModal = $event">
<div class="p-0">
@ -27,12 +25,15 @@
<ShadcnButton size="small" @click="isShowModal = false">
{{ $t('common.cancel') }}
</ShadcnButton>
<ShadcnButton size="small" type="error" @click="clear">
{{ $t('common.clear') }}
</ShadcnButton>
<ShadcnButton size="small" type="error" @click="reset">
{{ $t('common.reset') }}
</ShadcnButton>
<ShadcnButton size="small" @click="getResult">
{{ $t('common.cropper') }}
</ShadcnButton>

View File

@ -2,7 +2,7 @@
<ShadcnCard>
<template #title>
<ShadcnSpace>
<ShadcnButton size="small">
<ShadcnButton>
<RouterLink :to="`/admin/dataset/info/source/${configure.code}`" target="_blank">
<span class="flex items-center">
<ShadcnIcon icon="Plus" size="15"/>
@ -11,17 +11,17 @@
</RouterLink>
</ShadcnButton>
<ShadcnButton size="small" type="default" @click="visualVisible = true">
<ShadcnButton type="default" @click="visualVisible = true">
<ShadcnIcon icon="BarChart" :size="15"/>
<span>{{ $t('dataset.common.visual') }}</span>
</ShadcnButton>
<ShadcnTooltip :content="$t('query.tip.pageShow')">
<ShadcnTooltip class="mt-1" :content="$t('query.tip.pageShow')">
<ShadcnSwitch v-model="isPage" @on-change="onChange"/>
</ShadcnTooltip>
<ShadcnTooltip :content="$t('query.tip.smallTips')">
<ShadcnButton circle size="small" type="default">
<ShadcnButton circle type="default">
<ShadcnIcon icon="CircleHelp" :size="15"/>
</ShadcnButton>
</ShadcnTooltip>

View File

@ -1,13 +1,11 @@
<template>
<div>
<ShadcnSelect v-model="applySource" :placeholder="$t('source.tip.selectSource')" @on-change="onChange">
<template #options>
<ShadcnSelectOption v-for="item in items"
:label="item.name"
:value="`${item.id}:${item.type}:${item.code}`"
:disabled="!item.available">
</ShadcnSelectOption>
</template>
<ShadcnSelect v-model="applySource"
v-model:options="options"
lazy
:placeholder="$t('source.tip.selectSource')"
:load-data="loadMoreData"
@on-change="onChange">
</ShadcnSelect>
</div>
</template>
@ -36,23 +34,29 @@ export default defineComponent({
data()
{
return {
items: [] as SourceModel[],
options: [] as SourceModel[],
loading: false,
applySource: undefined
applySource: undefined,
pageIndex: 1,
pageTotal: 10,
dataCount: 0
}
},
created()
{
this.handlerInitialize()
this.handleInitialize()
},
methods: {
handlerInitialize()
handleInitialize()
{
this.loading = true
SourceService.getAll(this.filter)
.then((response) => {
if (response.status) {
this.items = response.data.content
this.options = response.data.content.map((item: any) => ({ ...item, label: item.name, value: `${ item.id }:${ item.type }:${ item.code }` }))
this.dataCount = response.data.total
this.pageTotal = response.data.totalPage
this.pageIndex = response.data.page
if (this.value) {
this.applySource = this.value as any
}
@ -60,6 +64,22 @@ export default defineComponent({
})
.finally(() => this.loading = false)
},
async loadMoreData(callback: (children: any[]) => void)
{
if (this.pageIndex < this.pageTotal) {
this.filter.page = this.pageIndex + 1
const response = await SourceService.getAll(this.filter)
if (response.status) {
const options = response.data.content.map((item: any) => ({ ...item, label: item.name, value: `${ item.id }:${ item.type }:${ item.code }` }))
this.dataCount = response.data.total
this.pageTotal = response.data.totalPage
this.pageIndex = response.data.page
console.log(options)
callback(options)
}
}
},
onChange()
{
this.$emit('on-change', this.applySource)

View File

@ -1,6 +1,6 @@
<template>
<div class="relative h-full w-full">
<ShadcnSpin v-model="loading" fixed style="margin-top: 100px;"/>
<div class="relative h-full w-full" :style="{ width: width, height: height }">
<ShadcnSpin v-model="loading" fixed/>
<div v-if="localConfiguration && !loading">
<div v-if="localConfiguration.message" class="p-4">

View File

@ -11,7 +11,7 @@
</template>
<template #content>
<div class="mb-3">
<div class="mb-3 min-h-screen">
<Loader2 v-if="loading" class="w-full justify-center animate-spin"/>
<div v-else class="hidden flex-col md:flex">
<div class="flex-1 space-y-4 pt-6">

View File

@ -6,53 +6,58 @@
@on-close="onCancel">
<div class="relative w-full h-full">
<ShadcnSpin v-model="loading"/>
<ShadcnSpin v-model="loading" fixed/>
<div v-if="!loading" class="p-2">
<FormField type="radio" name="theme">
<FormItem class="space-y-1">
<FormMessage/>
<RadioGroup v-model="report" class="grid w-full grid-cols-4 gap-8 pt-2">
<FormItem v-for="item of data" :key="item.id">
<FormLabel class="[&:has([data-state=checked])>div]:border-primary">
<FormControl>
<RadioGroupItem :value="item.id as unknown as string" class="sr-only"/>
</FormControl>
<div class="items-center rounded-md border-4 border-muted p-1 hover:border-accent cursor-pointer text-center">
<VisualView width="200px" height="100px" :code="item.dataset?.code as string" :configuration="JSON.parse(item.configure as string)"
:type="item.type" :query="item.type === 'DATASET' ? JSON.parse(item.query as string) : item.query" :original="item?.source?.id"/>
</div>
<span class="block w-full p-2 text-center font-normal">{{ item.name }}</span>
</FormLabel>
</FormItem>
</RadioGroup>
</FormItem>
</FormField>
<ShadcnToggleGroup v-model="report">
<ShadcnRow gutter="8">
<ShadcnCol v-for="item of data" span="4">
<ShadcnToggle :key="item.id" class="px-1 py-1" :value="item.id">
<ShadcnCard :title="item.name">
<template #extra>
<ShadcnTooltip v-if="item.description" :content="item.description">
<ShadcnIcon icon="Info" size="20"/>
</ShadcnTooltip>
</template>
<VisualView width="300px" height="250px"
:code="item.dataset?.code as string"
:configuration="JSON.parse(item.configure as string)"
:type="item.type"
:query="item.type === 'DATASET' ? JSON.parse(item.query as string) : item.query"
:original="item?.source?.id"/>
</ShadcnCard>
</ShadcnToggle>
</ShadcnCol>
</ShadcnRow>
</ShadcnToggleGroup>
<div v-if="data.length === 0" class="flex w-full items-center">
{{ $t('common.noData') }}
</div>
</div>
<ShadcnPagination v-if="data.length > 0"
v-model="pageIndex"
class="py-2 mt-2"
show-total
show-sizer
:page-size="pageSize"
:total="dataCount"
:sizerOptions="[12, 24, 36]"
@on-change="onPageChange"
@on-prev="onPrevChange"
@on-next="onNextChange"
@on-change-size="onSizeChange"/>
</div>
<ShadcnPagination v-if="data.length > 0"
v-model="pageIndex"
class="py-2"
show-total
show-sizer
:page-size="pageSize"
:total="dataCount"
:sizerOptions="[10, 20, 50]"
@on-change="onPageChange"
@on-prev="onPrevChange"
@on-next="onNextChange"
@on-change-size="onSizeChange"/>
<template #footer>
<ShadcnSpace>
<ShadcnButton type="default" @click="onCancel">
{{ $t('common.cancel') }}
</ShadcnButton>
<ShadcnButton @click="onSubmit()">
<ShadcnButton :disabled="!report" @click="onSubmit()">
{{ $t('common.save') }}
</ShadcnButton>
</ShadcnSpace>
@ -152,8 +157,9 @@ export default defineComponent({
},
onSubmit()
{
const node = this.data.find(item => item.id === toNumber(this.report))
const node = this.data.find(item => item.id === toNumber(this.report[0]))
this.$emit('change', node)
this.onCancel()
},
onCancel()

View File

@ -12,64 +12,88 @@
</ShadcnSpace>
</template>
<!-- <div id="content">-->
<!-- <GridLayout ref="refLayout" :layout="layouts" :responsive="true" :col-num="12" :row-height="30" :is-draggable="true" :is-resizable="true" :vertical-compact="true"-->
<!-- :use-css-transforms="true">-->
<!-- <GridItem v-for="item in layouts" :ref="el => set$Children(el)" :key="item.i" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i" :min-h="3" :min-w="3"-->
<!-- @resized="onResize">-->
<!-- <DataCapCard :style="{width: item.width, height: item.height}">-->
<!-- <template #title>{{ item.title ? item.title : $t('dataset.common.notSpecifiedTitle') }}</template>-->
<!-- <template #extra>-->
<!-- <Button size="icon" class="w-6 h-6 rounded-full bg-color-error" @click="onRemove(item.i)">-->
<!-- <Trash :size="15"/>-->
<!-- </Button>-->
<!-- </template>-->
<!-- <VisualView v-if="item.original" class="-ml-3" :width="item.width.replace('px', '') - 20 + 'px'" :height="item.height.replace('px', '') - 48 + 'px'"-->
<!-- :code="item.node.code" :configuration="JSON.parse(item.node.configure)" :type="item.original?.type"-->
<!-- :query="item.original.type === 'DATASET' ? JSON.parse(item.original.query as string) : item.original.query" :original="item?.original?.source?.id"/>-->
<!-- <VisualView v-else class="-ml-3" :width="item.width.replace('px', '') - 20 + 'px'" :height="item.height.replace('px', '') - 48 + 'px'"-->
<!-- :code="item.node.code" :configuration="JSON.parse(item.node.configure)" :query="JSON.parse(item.node.query)"/>-->
<!-- </DataCapCard>-->
<!-- </GridItem>-->
<!-- </GridLayout>-->
<!-- </div>-->
<div class="min-h-screen">
<GridLayout ref="refLayout"
:layout="layouts"
:responsive="true"
:col-num="12"
:row-height="60"
:is-draggable="true"
:is-resizable="true"
:vertical-compact="true"
:use-css-transforms="true">
<GridItem v-for="item in layouts"
:ref="el => set$Children(el)"
:key="item.i"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:min-h="3"
:min-w="3"
@resized="onResize">
<ShadcnCard class="h-full w-full">
<template #title>{{ item.title ? item.title : $t('dataset.common.notSpecifiedTitle') }}</template>
<template #extra>
<ShadcnButton circle size="small" type="error" @click="onRemove(item.i)">
<ShadcnIcon icon="Trash" size="15"/>
</ShadcnButton>
</template>
<VisualView v-if="item.original"
:width="calculateWidth(item)"
:height="calculateHeight(item)"
:code="item.node.code"
:configuration="JSON.parse(item.node.configure)"
:type="item.original?.type"
:query="item.original.type === 'DATASET' ? JSON.parse(item.original.query as string) : item.original.query"
:original="item?.original?.source?.id"/>
<VisualView v-else
:width="calculateWidth(item)"
:height="calculateHeight(item)"
:code="item.node.code"
:configuration="JSON.parse(item.node.configure)"
:query="JSON.parse(item.node.query)"/>
</ShadcnCard>
</GridItem>
</GridLayout>
</div>
</ShadcnCard>
<!-- <Dialog :is-visible="configureVisible" :title="$t('common.configure')">-->
<!-- <div v-if="formState" class="pl-3 pr-4">-->
<!-- <FormField name="name">-->
<!-- <FormItem class="space-y-2">-->
<!-- <FormLabel>{{ $t('common.name') }}</FormLabel>-->
<!-- <FormMessage/>-->
<!-- <Input v-model="formState.name"/>-->
<!-- </FormItem>-->
<!-- </FormField>-->
<!-- <FormField name="description">-->
<!-- <FormItem class="space-y-2">-->
<!-- <FormLabel>{{ $t('common.description') }}</FormLabel>-->
<!-- <FormMessage/>-->
<!-- <Textarea v-model="formState.description"/>-->
<!-- </FormItem>-->
<!-- </FormField>-->
<!-- <FormField name="avatar">-->
<!-- <FormItem class="space-y-2">-->
<!-- <FormLabel>{{ $t('common.avatar') }}</FormLabel>-->
<!-- <FormMessage/>-->
<!-- <CropperHome :pic="formState?.avatar?.path" @update:value="handlerCropper"/>-->
<!-- </FormItem>-->
<!-- </FormField>-->
<!-- </div>-->
<!-- <template #footer>-->
<!-- <div class="space-x-5">-->
<!-- <Button variant="outline" size="sm" @click="configureVisible = false">-->
<!-- {{ $t('common.cancel') }}-->
<!-- </Button>-->
<!-- <Button :loading="loading" :disabled="loading" size="sm" @click="handlerSave">-->
<!-- {{ $t('common.save') }}-->
<!-- </Button>-->
<!-- </div>-->
<!-- </template>-->
<!-- </Dialog>-->
<ShadcnModal v-model="configureVisible" :title="$t('common.configure')">
<ShadcnForm v-if="configureVisible && formState"
v-model="formState"
@on-submit="onSubmit">
<ShadcnFormItem name="name"
:label="$t('common.name')"
:rules="[{ required: true, message: $t('common.name') }]">
<ShadcnInput v-model="formState.name" name="name"/>
</ShadcnFormItem>
<ShadcnFormItem name="description" :label="$t('common.description')">
<ShadcnInput v-model="formState.description" type="textarea" name="description"/>
</ShadcnFormItem>
<ShadcnFormItem name="avatar" :label="$t('common.avatar')">
<CropperHome :pic="formState?.avatar?.path" @update:value="onCropper"/>
</ShadcnFormItem>
<div class="flex justify-end">
<ShadcnSpace>
<ShadcnButton type="default" @click="configureVisible = false">
{{ $t('common.cancel') }}
</ShadcnButton>
<ShadcnButton submit :loading="loading" :disabled="loading">
{{ $t('common.save') }}
</ShadcnButton>
</ShadcnSpace>
</div>
</ShadcnForm>
</ShadcnModal>
<ChartContainer v-if="dataReportVisible"
:is-visible="dataReportVisible"
@ -91,7 +115,8 @@ import ChartContainer from '@/views/pages/admin/dashboard/components/ChartContai
export default defineComponent({
name: 'DashboardEditor',
components: { ChartContainer, CropperHome, VisualView, GridItem, GridLayout },
components: { ChartContainer, CropperHome, VisualView, GridItem, GridLayout
},
props: {
info: {
type: Object as () => DashboardModel | null
@ -108,7 +133,8 @@ export default defineComponent({
loading: false,
configureVisible: false,
formState: null as DashboardModel | null,
dataReportVisible: false
dataReportVisible: false,
rowHeight: 60
}
},
created()
@ -130,18 +156,32 @@ export default defineComponent({
}
}, 300)
},
onResize(i: string | number, w: number, h: number, x: number, y: number)
// Modified resize handler
onResize(i: string | number, w: number, h: number)
{
console.debug(w, h)
const node = this.layouts.find((obj: { i: string; }) => obj.i === i)
node.width = `${ y }px`
node.height = `${ x }px`
if (node) {
node.w = w
node.h = h
}
},
onRemove(i: string | number)
{
this.layouts = this.layouts.filter((obj: { i: string; }) => obj.i !== i)
},
handlerCropper(value: any)
// The method of calculating the width
calculateWidth(item: any): string
{
const widthPercentage = (item.w * (100 / this.columnNumber))
return `calc(${ widthPercentage }% - rem)` // Subtract margins
},
// How to calculate the height
calculateHeight(item: any): string
{
const totalHeight = item.h * this.rowHeight
return `${ totalHeight - 48 }px` // Subtract the height of the card head
},
onCropper(value: any)
{
const configure = {
code: this.formState?.code,
@ -154,7 +194,6 @@ export default defineComponent({
if (this.formState) {
this.formState.avatar = response.data
}
this.$Message.success({
content: this.$t('common.successfully'),
showIcon: true
@ -175,8 +214,6 @@ export default defineComponent({
y: 0,
w: 3,
h: 4,
width: '350px',
height: '150px',
i: 'new-' + Date.now(),
title: node.name,
node: {
@ -193,16 +230,17 @@ export default defineComponent({
{
if (this.formState) {
this.formState.configure = JSON.stringify(this.layouts)
this.layouts.forEach((item: { node: { id: any; }; }) => this.formState?.reports?.push({ id: item.node.id }))
this.layouts.forEach((item: { node: { id: any; }; }) => {
this.formState?.reports?.push({ id: item.node.id })
})
this.loading = true
DashboardService.saveOrUpdate(this.formState)
.then(response => {
if (response.status) {
this.$Message.success({
content: this.$t('dashboard.tip.publishSuccess').replace('$VALUE', this.formState?.name),
content: this.$t('dashboard.tip.publishSuccess').replace('$VALUE', String(this.formState?.name)),
showIcon: true
})
if (response.data) {
this.$router.push(`/admin/dashboard/preview/${ response.data?.code }`)
}