diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataSourcePopover.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataSourcePopover.vue index 629eca906f..445cfc3958 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataSourcePopover.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataSourcePopover.vue @@ -3,8 +3,9 @@ import { computed, reactive, watch, } from 'vue'; import type { TranslateResult } from 'vue-i18n'; +import { useRoute } from 'vue-router/composables'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import { PButton, PPopover, PSelectCard, PI, PDivider, @@ -32,7 +33,8 @@ import WidgetFormAssetSecurityDataSourcePopper import WidgetFormCostDataSourcePopper from '@/common/modules/widgets/_components/WidgetFormCostDataSourcePopper.vue'; import WidgetFormUnifiedCostDataSourcePopper from '@/common/modules/widgets/_components/WidgetFormUnifiedCostDataSourcePopper.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; +import { useWidgetQuery } from '@/common/modules/widgets/_composables/use-widget-query'; import { DATA_SOURCE_DOMAIN, DATA_TABLE_OPERATOR, @@ -45,34 +47,44 @@ import type { DataTableDataType, DataTableSourceType, DataTableOperator, DataTableAddOptions, DataTableTransformOptions, } from '@/common/modules/widgets/types/widget-model'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; -import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; +import { useDashboardWidgetListQuery } from '@/services/dashboards/composables/use-dashboard-widget-list-query'; const widgetGenerateStore = useWidgetGenerateStore(); const widgetGenerateState = widgetGenerateStore.state; const allReferenceStore = useAllReferenceStore(); -const dashboardDetailStore = useDashboardDetailInfoStore(); -const dashboardDetailState = dashboardDetailStore.state; const userStore = useUserStore(); +const route = useRoute(); +const dashboardId = computed(() => route.params.dashboardId); const emit = defineEmits<{(e: 'scroll'): void;}>(); const { visibleContents } = useContentsAccessibility(MENU_ID.ASSET_INVENTORY); /* Query */ +const { + api: widgetApi, +} = useWidgetQuery({ + widgetId: computed(() => widgetGenerateState.widgetId), +}); const { dataTableList, - api, - keys: widgetQueryKeys, - queryClient, -} = useWidgetFormQuery({ + keys: dataTableKeys, + api: dataTableApi, +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); +const queryClient = useQueryClient(); + const { dashboard, - keys, -} = useDashboardDetailQuery({ - dashboardId: computed(() => dashboardDetailState.dashboardId), +} = useDashboardGetQuery({ + dashboardId, +}); +const { + keys: widgetKeys, +} = useDashboardWidgetListQuery({ + dashboardId, }); @@ -193,16 +205,16 @@ const state = reactive({ /* Api */ const widgetCreateFn = (params: WidgetCreateParams): Promise => { - if (dashboardDetailState.dashboardId?.startsWith('private')) { - return api.privateWidgetAPI.create(params); + if (dashboardId.value?.startsWith('private')) { + return widgetApi.privateWidgetAPI.create(params); } - return api.publicWidgetAPI.create(params); + return widgetApi.publicWidgetAPI.create(params); }; const { mutateAsync: createWidget, isPending: widgetCreateLoading } = useMutation({ mutationFn: widgetCreateFn, onSuccess: (data) => { - const _isPrivate = dashboardDetailState.dashboardId?.startsWith('private'); - const widgetListQueryKey = _isPrivate ? keys.privateWidgetListQueryKey : keys.publicWidgetListQueryKey; + const _isPrivate = dashboardId.value?.startsWith('private'); + const widgetListQueryKey = _isPrivate ? widgetKeys.privateWidgetListQueryKey : widgetKeys.publicWidgetListQueryKey; queryClient.setQueryData(widgetListQueryKey.value, (oldData: ListResponse) => (oldData.results?.length ? { ...oldData, results: [...oldData.results, data], } : { @@ -215,16 +227,16 @@ const { mutateAsync: createWidget, isPending: widgetCreateLoading } = useMutatio }, }); const dataTableAddFn = (params: DataTableAddParameters): Promise => { - if (dashboardDetailState.dashboardId?.startsWith('private')) { - return api.privateDataTableAPI.add(params); + if (dashboardId.value?.startsWith('private')) { + return dataTableApi.privateDataTableAPI.add(params); } - return api.publicDataTableAPI.add(params); + return dataTableApi.publicDataTableAPI.add(params); }; const { mutateAsync: addDataTable, isPending: dataTableAddLoading } = useMutation({ mutationFn: dataTableAddFn, onSuccess: (data) => { const _isPrivate = widgetGenerateState.widgetId?.startsWith('private'); - const dataTableListQueryKey = _isPrivate ? widgetQueryKeys.privateDataTableListQueryKey : widgetQueryKeys.publicDataTableListQueryKey; + const dataTableListQueryKey = _isPrivate ? dataTableKeys.privateDataTableListQueryKey : dataTableKeys.publicDataTableListQueryKey; queryClient.setQueryData(dataTableListQueryKey.value, (oldData: ListResponse) => (oldData.results?.length ? { ...oldData, results: [...oldData.results, data], } : { @@ -269,7 +281,7 @@ const handleCreateUnsavedTransform = async (operator: DataTableOperator) => { } as Partial; const _isPrivate = widgetGenerateState.widgetId?.startsWith('private'); - const dataTableListQueryKey = _isPrivate ? widgetQueryKeys.privateDataTableListQueryKey : widgetQueryKeys.publicDataTableListQueryKey; + const dataTableListQueryKey = _isPrivate ? dataTableKeys.privateDataTableListQueryKey : dataTableKeys.publicDataTableListQueryKey; await queryClient.setQueryData(dataTableListQueryKey.value, (oldData: ListResponse) => (oldData.results?.length ? { ...oldData, results: [...oldData.results, unsavedTransformData], } : { @@ -288,7 +300,7 @@ const handleConfirmDataSource = async () => { // create widget if (widgetGenerateState.overlayType === 'ADD' && !widgetGenerateState.widgetId) { await createWidget({ - dashboard_id: dashboardDetailState.dashboardId as string, + dashboard_id: dashboardId.value as string, tags: { created_by: userStore.state.userId }, widget_type: 'table', }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardAddContents.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardAddContents.vue index 8c86344cc9..9a4269820e 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardAddContents.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardAddContents.vue @@ -3,7 +3,7 @@ import { computed, defineExpose, onMounted, reactive, watch, } from 'vue'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import { cloneDeep, isArray, isEqual, uniq, } from 'lodash'; @@ -17,6 +17,7 @@ import type { PrivateDataTableModel } from '@/api-clients/dashboard/private-data import type { DataTableDeleteParameters } from '@/api-clients/dashboard/public-data-table/schema/api-verbs/delete'; import type { DataTableUpdateParameters } from '@/api-clients/dashboard/public-data-table/schema/api-verbs/update'; import type { PublicDataTableModel } from '@/api-clients/dashboard/public-data-table/schema/model'; +import { useServiceQueryKey } from '@/query/query-key/use-service-query-key'; import { i18n } from '@/translations'; import { useAllReferenceStore } from '@/store/reference/all-reference-store'; @@ -38,7 +39,8 @@ import WidgetFormDataTableCardSourceForm import { useDataTableCascadeUpdate, } from '@/common/modules/widgets/_composables/use-data-table-cascade-update'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; +import { useWidgetQuery } from '@/common/modules/widgets/_composables/use-widget-query'; import { DATA_SOURCE_DOMAIN, DATA_TABLE_OPERATOR, @@ -53,7 +55,6 @@ import type { } from '@/common/modules/widgets/types/widget-model'; import { GROUP_BY } from '@/services/cost-explorer/constants/cost-explorer-constant'; -import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; interface Props { selected: boolean; @@ -68,20 +69,24 @@ const props = defineProps(); const widgetGenerateStore = useWidgetGenerateStore(); const widgetGenerateState = widgetGenerateStore.state; const allReferenceStore = useAllReferenceStore(); -const dashboardDetailStore = useDashboardDetailInfoStore(); -const dashboardDetailState = dashboardDetailStore.state; /* Query */ const { widget, + keys: widgetKeys, + fetcher: widgetFetcher, +} = useWidgetQuery({ + widgetId: computed(() => widgetGenerateState.widgetId), +}); +const { dataTableList, - keys, - api, - fetcher, - queryClient, -} = useWidgetFormQuery({ + keys: dataTableKeys, + api: dataTableApi, + fetcher: dataTableFetcher, +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); +const queryClient = useQueryClient(); const { cascadeUpdateDataTable, } = useDataTableCascadeUpdate({ @@ -230,33 +235,37 @@ const modalState = reactive({ referenceDataTableName: '', }); +/* Query Keys */ +const { withSuffix: privateDataTableGetQueryKey } = useServiceQueryKey('dashboard', 'private-data-table', 'get'); +const { withSuffix: publicDataTableGetQueryKey } = useServiceQueryKey('dashboard', 'public-data-table', 'get'); +const { withSuffix: privateDataTableLoadQueryKey } = useServiceQueryKey('dashboard', 'private-data-table', 'load'); +const { withSuffix: publicDataTableLoadQueryKey } = useServiceQueryKey('dashboard', 'public-data-table', 'load'); +const { withSuffix: privateWidgetLoadQueryKey } = useServiceQueryKey('dashboard', 'private-widget', 'load'); +const { withSuffix: publicWidgetLoadQueryKey } = useServiceQueryKey('dashboard', 'public-widget', 'load'); +const { withSuffix: privateWidgetLoadSumQueryKey } = useServiceQueryKey('dashboard', 'private-widget', 'load-sum'); +const { withSuffix: publicWidgetLoadSumQueryKey } = useServiceQueryKey('dashboard', 'public-widget', 'load-sum'); + /* APIs */ const invalidateLoadQueries = async (data: DataTableModel) => { - await queryClient.invalidateQueries({ - queryKey: [ - ...(state.isPrivate ? keys.privateDataTableLoadQueryKey.value : keys.publicDataTableLoadQueryKey.value), - data.data_table_id, - ], - }); - await queryClient.invalidateQueries({ - queryKey: [ - ...(state.isPrivate ? keys.privateWidgetLoadQueryKey.value : keys.publicWidgetLoadQueryKey.value), - dashboardDetailState.dashboardId, - widgetGenerateState.widgetId, - ], - }); - await queryClient.invalidateQueries({ - queryKey: [ - ...(state.isPrivate ? keys.privateWidgetLoadSumQueryKey.value : keys.publicWidgetLoadSumQueryKey.value), - dashboardDetailState.dashboardId, - widgetGenerateState.widgetId, - ], - }); + if (!widgetGenerateState.widgetId) return; + if (data.data_table_id.startsWith('private')) { + await Promise.all([ + queryClient.invalidateQueries({ queryKey: privateDataTableLoadQueryKey(state.dataTableId) }), + queryClient.invalidateQueries({ queryKey: privateWidgetLoadQueryKey(widgetGenerateState.widgetId) }), + queryClient.invalidateQueries({ queryKey: privateWidgetLoadSumQueryKey(widgetGenerateState.widgetId) }), + ]); + } else { + await Promise.all([ + queryClient.invalidateQueries({ queryKey: publicDataTableLoadQueryKey(state.dataTableId) }), + queryClient.invalidateQueries({ queryKey: publicWidgetLoadQueryKey(widgetGenerateState.widgetId) }), + queryClient.invalidateQueries({ queryKey: publicWidgetLoadSumQueryKey(widgetGenerateState.widgetId) }), + ]); + } }; const { mutateAsync: updateDataTableMutation } = useMutation({ - mutationFn: fetcher.updateDataTableFn, + mutationFn: dataTableFetcher.updateDataTableFn, onSuccess: async (data) => { - const dataTableListQueryKey = state.isPrivate ? keys.privateDataTableListQueryKey : keys.publicDataTableListQueryKey; + const dataTableListQueryKey = state.isPrivate ? dataTableKeys.privateDataTableListQueryKey : dataTableKeys.publicDataTableListQueryKey; await queryClient.setQueryData(dataTableListQueryKey.value, (oldData: ListResponse) => { if (oldData.results) { return { @@ -271,6 +280,7 @@ const { mutateAsync: updateDataTableMutation } = useMutation({ } return oldData; }); + await queryClient.invalidateQueries({ queryKey: state.isPrivate ? privateDataTableGetQueryKey(state.dataTableId) : publicDataTableGetQueryKey(state.dataTableId) }); await invalidateLoadQueries(data); setInitialDataTableForm(); @@ -284,11 +294,11 @@ const { mutateAsync: updateDataTableMutation } = useMutation({ }, }); const { mutateAsync: updateWidget } = useMutation({ - mutationFn: fetcher.updateWidgetFn, + mutationFn: widgetFetcher.updateWidgetFn, onSuccess: (data) => { const widgetQueryKey = widgetGenerateState.widgetId?.startsWith('private') - ? keys.privateWidgetGetQueryKey - : keys.publicWidgetGetQueryKey; + ? widgetKeys.privateWidgetGetQueryKey + : widgetKeys.publicWidgetGetQueryKey; queryClient.setQueryData(widgetQueryKey.value, () => data); }, onError: (e) => { @@ -363,8 +373,8 @@ const updateDataTable = async (): Promise => { }; const deleteDataTableFn = (params: DataTableDeleteParameters): Promise => { if (params.data_table_id.startsWith('private')) { - return api.privateDataTableAPI.delete(params); - } return api.publicDataTableAPI.delete(params); + return dataTableApi.privateDataTableAPI.delete(params); + } return dataTableApi.publicDataTableAPI.delete(params); }; const { mutateAsync: deleteDataTable } = useMutation({ mutationFn: deleteDataTableFn, @@ -376,7 +386,7 @@ const { mutateAsync: deleteDataTable } = useMutation({ widgetGenerateStore.setAllDataTableInvalidMap(_allDataTableInvalidMap); const _isPrivate = widgetGenerateState.widgetId?.startsWith('private'); - const dataTableListQueryKey = _isPrivate ? keys.privateDataTableListQueryKey : keys.publicDataTableListQueryKey; + const dataTableListQueryKey = _isPrivate ? dataTableKeys.privateDataTableListQueryKey : dataTableKeys.publicDataTableListQueryKey; await queryClient.setQueryData(dataTableListQueryKey.value, (oldData: ListResponse) => { if (oldData.results) { return { @@ -441,6 +451,9 @@ const handleCancelModal = () => { modalState.visible = false; }; const handleUpdateDataTable = async () => { + if (!widgetGenerateState.widgetId) { + throw new Error('Widget ID is required'); + } state.loading = true; const result = await updateDataTable(); if (result) { diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFilters.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFilters.vue index e5cd5a3d9f..1b95dc5731 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFilters.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFilters.vue @@ -40,7 +40,7 @@ import ErrorHandler from '@/common/composables/error/errorHandler'; import { useProxyValue } from '@/common/composables/proxy-state'; import WidgetFormDataTableCardFiltersItem from '@/common/modules/widgets/_components/WidgetFormDataTableCardFiltersItem.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; import { DATA_SOURCE_DOMAIN, DATA_TABLE_QUERY_OPERATOR, @@ -89,7 +89,7 @@ const appContextStore = useAppContextStore(); /* Query */ const { dataTableList, -} = useWidgetFormQuery({ +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFiltersItem.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFiltersItem.vue index a1548c2c11..d95158238b 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFiltersItem.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardFiltersItem.vue @@ -4,6 +4,7 @@ import { onClickOutside } from '@vueuse/core/index'; import { computed, onMounted, reactive, ref, } from 'vue'; +import { useRoute } from 'vue-router/composables'; import { isArray } from 'lodash'; @@ -25,9 +26,8 @@ import type { DataTableQueryFilterForDropdown } from '@/common/modules/widgets/t import { blue, gray } from '@/styles/colors'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; import { getOrderedGlobalVariables } from '@/services/dashboards/helpers/dashboard-global-variables-helper'; -import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; interface Props { @@ -39,16 +39,15 @@ interface Props { } const props = defineProps(); - +const route = useRoute(); +const dashboardId = computed(() => route.params.dashboardId); const emit = defineEmits<{(e: 'delete'): void; (e: 'update:selected-filter', filter: DataTableQueryFilterForDropdown): void; }>(); const operatorButtonRef = ref(null); -const dashboardDetailStore = useDashboardDetailInfoStore(); -const dashboardDetailState = dashboardDetailStore.state; -const { dashboard } = useDashboardDetailQuery({ - dashboardId: computed(() => dashboardDetailState.dashboardId), +const { dashboard } = useDashboardGetQuery({ + dashboardId, }); const state = reactive({ visibleMenu: false, diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardHeaderTitle.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardHeaderTitle.vue index 5fae855e2d..50e17a7d08 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardHeaderTitle.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardHeaderTitle.vue @@ -2,7 +2,7 @@ import { computed, reactive } from 'vue'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import { cloneDeep } from 'lodash'; import { @@ -17,7 +17,8 @@ import { showErrorMessage, showSuccessMessage } from '@/lib/helper/notice-alert- import ErrorHandler from '@/common/composables/error/errorHandler'; import { useProxyValue } from '@/common/composables/proxy-state'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; +import { useWidgetQuery } from '@/common/modules/widgets/_composables/use-widget-query'; import { DATA_TABLE_TYPE, } from '@/common/modules/widgets/_constants/data-table-constant'; @@ -47,13 +48,20 @@ const widgetGenerateState = widgetGenerateStore.state; /* Query */ const { widget, + fetcher: widgetFetcher, + keys: widgetKeys, +} = useWidgetQuery({ + widgetId: computed(() => widgetGenerateState.widgetId), +}); +const { dataTableList, - fetcher, - keys, - queryClient, -} = useWidgetFormQuery({ + keys: dataTableKeys, + fetcher: dataTableFetcher, +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); +const queryClient = useQueryClient(); + const storeState = reactive({ currentDataTable: computed(() => dataTableList.value.find((dataTable) => dataTable.data_table_id === props.dataTableId)), @@ -79,7 +87,7 @@ const handleSelectDataTable = async (dataTableId: string) => { const _widgetOptions = cloneDeep(widget.value?.options); const sanitizedOptions = sanitizeWidgetOptions(_widgetOptions, widget.value?.widget_type, storeState.currentDataTable); await updateWidget({ - widget_id: widgetGenerateState.widgetId, + widget_id: widgetGenerateState.widgetId as string, state: 'INACTIVE', options: sanitizedOptions, }); @@ -121,11 +129,11 @@ const handleClickNameConfirm = async () => { /* Api */ const { mutateAsync: updateWidget } = useMutation({ - mutationFn: fetcher.updateWidgetFn, + mutationFn: widgetFetcher.updateWidgetFn, onSuccess: (data) => { const widgetQueryKey = widgetGenerateState.widgetId?.startsWith('private') - ? keys.privateWidgetQueryKey - : keys.publicWidgetQueryKey; + ? widgetKeys.privateWidgetGetQueryKey + : widgetKeys.publicWidgetGetQueryKey; queryClient.setQueryData(widgetQueryKey.value, () => data); }, onError: (e) => { @@ -134,7 +142,7 @@ const { mutateAsync: updateWidget } = useMutation({ }, }); const { mutate: updateDataTable } = useMutation({ - mutationFn: fetcher.updateDataTableFn, + mutationFn: dataTableFetcher.updateDataTableFn, onSuccess: async (data) => { await syncDataTableList(data); showSuccessMessage(i18n.t('COMMON.WIDGETS.DATA_TABLE.FORM.DATA_TABLE_NAME_SUCCESS'), ''); @@ -147,7 +155,7 @@ const { mutate: updateDataTable } = useMutation({ }); const syncDataTableList = async (data: DataTableModel) => { const _isPrivate = widgetGenerateState.widgetId?.startsWith('private'); - const dataTableListQueryKey = _isPrivate ? keys.privateDataTableListQueryKey : keys.publicDataTableListQueryKey; + const dataTableListQueryKey = _isPrivate ? dataTableKeys.privateDataTableListQueryKey : dataTableKeys.publicDataTableListQueryKey; await queryClient.setQueryData(dataTableListQueryKey.value, (oldData: ListResponse) => { if (oldData.results) { return { diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAddLabels.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAddLabels.vue index 103f17b60a..1251b6c7da 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAddLabels.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAddLabels.vue @@ -11,24 +11,17 @@ import { PIconButton, PFieldGroup, PTextInput, PButton, PFieldTitle, } from '@cloudforet/mirinae'; -import type { PrivateDataTableModel } from '@/api-clients/dashboard/private-data-table/schema/model'; -import type { PublicDataTableModel } from '@/api-clients/dashboard/public-data-table/schema/model'; import { i18n } from '@/translations'; import { useProxyValue } from '@/common/composables/proxy-state'; import WidgetFormDataTableCardTransformFormWrapper from '@/common/modules/widgets/_components/WidgetFormDataTableCardTransformFormWrapper.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-query'; import { DATA_TABLE_OPERATOR } from '@/common/modules/widgets/_constants/data-table-constant'; import { isFieldNameValid } from '@/common/modules/widgets/_helpers/widget-data-table-helper'; -import { useWidgetGenerateStore } from '@/common/modules/widgets/_store/widget-generate-store'; import type { TransformDataTableProps, TransformDataTableInfo } from '@/common/modules/widgets/types/widget-data-table-type'; import type { AddLabelsOptions } from '@/common/modules/widgets/types/widget-model'; - - - -type DataTableModel = PublicDataTableModel|PrivateDataTableModel; interface AdditionalLabel { name: string; value: string; @@ -41,18 +34,9 @@ const emit = defineEmits<{(e: 'update:operator-options', value: AddLabelsOptions (e: 'update:invalid', value: boolean): void; }>(); -const widgetGenerateStore = useWidgetGenerateStore(); -const widgetGenerateState = widgetGenerateStore.state; /* Query */ -const { - dataTableList, -} = useWidgetFormQuery({ - widgetId: computed(() => widgetGenerateState.widgetId), -}); +const currentDataTable = useWidgetDataTableQuery(computed(() => props.originData?.data_table_id)); -const storeState = reactive({ - currentDataTable: computed|undefined>(() => dataTableList.value.find((d) => d.data_table_id === dataTableInfo.value.dataTableId)), -}); const dataTableInfo = ref({ dataTableId: props.originData?.data_table_id, @@ -68,7 +52,7 @@ const state = reactive({ const fieldNames = state.refinedLabels.map((label) => label.name); if (fieldNames.includes(DATE_FIELD)) return true; if (fieldNames.length !== new Set(fieldNames).size) return true; - if (state.refinedLabels.some((d) => !isFieldNameValid(d.name, storeState.currentDataTable))) return true; + if (state.refinedLabels.some((d) => !isFieldNameValid(d.name, currentDataTable.data.value))) return true; return false; }), }); @@ -85,7 +69,7 @@ const getInvalidText = (idx: number): TranslateResult|undefined => { if (state.refinedLabels.some((label, lIdx) => lIdx !== idx && label.name === targetName)) { return i18n.t('COMMON.WIDGETS.DATA_TABLE.FORM.ADD_LABELS.DUPLICATED_LABEL'); } - if (!isFieldNameValid(targetName, storeState.currentDataTable)) { + if (!isFieldNameValid(targetName, currentDataTable.data.value)) { return i18n.t('COMMON.WIDGETS.DATA_TABLE.FORM.DUPLICATED_FIELD_NAME'); } return undefined; diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAggregate.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAggregate.vue index b2bac9bb7a..5a3e440fae 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAggregate.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformAggregate.vue @@ -18,7 +18,7 @@ import { showErrorMessage } from '@/lib/helper/notice-alert-helper'; import { useProxyValue } from '@/common/composables/proxy-state'; import WidgetFormDataTableCardTransformFormWrapper from '@/common/modules/widgets/_components/WidgetFormDataTableCardTransformFormWrapper.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; import { DATA_TABLE_OPERATOR, } from '@/common/modules/widgets/_constants/data-table-constant'; @@ -40,7 +40,7 @@ const widgetGenerateState = widgetGenerateStore.state; /* Query */ const { dataTableList, -} = useWidgetFormQuery({ +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformContents.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformContents.vue index 09826559f2..7b37cb4929 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformContents.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformContents.vue @@ -2,8 +2,9 @@ import { computed, defineExpose, onMounted, reactive, watch, } from 'vue'; +import { useRoute } from 'vue-router/composables'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import { cloneDeep, intersection, isEmpty, isEqual, } from 'lodash'; @@ -14,6 +15,7 @@ import type { PrivateDataTableModel } from '@/api-clients/dashboard/private-data import type { DataTableDeleteParameters } from '@/api-clients/dashboard/public-data-table/schema/api-verbs/delete'; import type { DataTableTransformParameters } from '@/api-clients/dashboard/public-data-table/schema/api-verbs/transform'; import type { PublicDataTableModel } from '@/api-clients/dashboard/public-data-table/schema/model'; +import { useServiceQueryKey } from '@/query/query-key/use-service-query-key'; import { i18n } from '@/translations'; import { showErrorMessage, showSuccessMessage } from '@/lib/helper/notice-alert-helper'; @@ -43,9 +45,10 @@ import WidgetFormDataTableCardTransformValueMapping import { useDataTableCascadeUpdate, } from '@/common/modules/widgets/_composables/use-data-table-cascade-update'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; +import { useWidgetQuery } from '@/common/modules/widgets/_composables/use-widget-query'; import { - DATA_TABLE_TYPE, type DATA_TABLE_OPERATOR, DEFAULT_TRANSFORM_DATA_TABLE_VALUE_MAP, + DATA_TABLE_TYPE, DATA_TABLE_OPERATOR, DEFAULT_TRANSFORM_DATA_TABLE_VALUE_MAP, } from '@/common/modules/widgets/_constants/data-table-constant'; import { sanitizeWidgetOptions } from '@/common/modules/widgets/_helpers/widget-options-helper'; import { useWidgetGenerateStore } from '@/common/modules/widgets/_store/widget-generate-store'; @@ -59,8 +62,7 @@ import type { JoinOptions, ValueMappingOptions, ConcatOptions, AggregateOptions, AggregateFunction, } from '@/common/modules/widgets/types/widget-model'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; -import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; @@ -75,27 +77,35 @@ interface Props { type DataTableModel = PublicDataTableModel|PrivateDataTableModel; const props = defineProps(); +const route = useRoute(); +const dashboardId = computed(() => route.params.dashboardId); const widgetGenerateStore = useWidgetGenerateStore(); const widgetGenerateState = widgetGenerateStore.state; -const dashboardDetailStore = useDashboardDetailInfoStore(); -const dashboardDetailState = dashboardDetailStore.state; /* Querys */ const { dashboard, -} = useDashboardDetailQuery({ - dashboardId: computed(() => dashboardDetailState.dashboardId), +} = useDashboardGetQuery({ + dashboardId, }); const { widget, - dataTableList, + keys: widgetKeys, + fetcher: widgetFetcher, +} = useWidgetQuery({ + widgetId: computed(() => widgetGenerateState.widgetId), +}); +const { api, - keys, - fetcher, - queryClient, -} = useWidgetFormQuery({ + keys: dataTableKeys, + fetcher: dataTableFetcher, + dataTableList, +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); +const queryClient = useQueryClient(); + + const { cascadeUpdateDataTable, } = useDataTableCascadeUpdate({ @@ -191,9 +201,20 @@ const getAggregateFunctionMap = () => { }, {} as AggregateFunction); }; + +/* Query Keys */ +const { withSuffix: privateDataTableGetQueryKey } = useServiceQueryKey('dashboard', 'private-data-table', 'get'); +const { withSuffix: publicDataTableGetQueryKey } = useServiceQueryKey('dashboard', 'public-data-table', 'get'); +const { withSuffix: privateDataTableLoadQueryKey } = useServiceQueryKey('dashboard', 'private-data-table', 'load'); +const { withSuffix: publicDataTableLoadQueryKey } = useServiceQueryKey('dashboard', 'public-data-table', 'load'); +const { withSuffix: privateWidgetLoadQueryKey } = useServiceQueryKey('dashboard', 'private-widget', 'load'); +const { withSuffix: publicWidgetLoadQueryKey } = useServiceQueryKey('dashboard', 'public-widget', 'load'); +const { withSuffix: privateWidgetLoadSumQueryKey } = useServiceQueryKey('dashboard', 'private-widget', 'load-sum'); +const { withSuffix: publicWidgetLoadSumQueryKey } = useServiceQueryKey('dashboard', 'public-widget', 'load-sum'); + /* APIs */ const syncDataTableList = async (data: DataTableModel, unsavedId?: string) => { - const dataTableListQueryKey = state.isPrivate ? keys.privateDataTableListQueryKey : keys.publicDataTableListQueryKey; + const dataTableListQueryKey = state.isPrivate ? dataTableKeys.privateDataTableListQueryKey : dataTableKeys.publicDataTableListQueryKey; await queryClient.setQueryData(dataTableListQueryKey.value, (oldData: ListResponse) => { if (oldData.results) { return { @@ -210,31 +231,26 @@ const syncDataTableList = async (data: DataTableModel, unsavedId?: string) => { }); }; const invalidateLoadQueries = async (data: DataTableModel) => { - await queryClient.invalidateQueries({ - queryKey: [ - ...(state.isPrivate ? keys.privateDataTableLoadQueryKey.value : keys.publicDataTableLoadQueryKey.value), - data.data_table_id, - ], - }); - await queryClient.invalidateQueries({ - queryKey: [ - ...(state.isPrivate ? keys.privateWidgetLoadQueryKey.value : keys.publicWidgetLoadQueryKey.value), - dashboardDetailState.dashboardId, - widgetGenerateState.widgetId, - ], - }); - await queryClient.invalidateQueries({ - queryKey: [ - ...(state.isPrivate ? keys.privateWidgetLoadSumQueryKey.value : keys.publicWidgetLoadSumQueryKey.value), - dashboardDetailState.dashboardId, - widgetGenerateState.widgetId, - ], - }); + if (!widgetGenerateState.widgetId) return; + if (data.data_table_id.startsWith('private')) { + await Promise.all([ + queryClient.invalidateQueries({ queryKey: privateDataTableLoadQueryKey(state.dataTableId) }), + queryClient.invalidateQueries({ queryKey: privateWidgetLoadQueryKey(widgetGenerateState.widgetId) }), + queryClient.invalidateQueries({ queryKey: privateWidgetLoadSumQueryKey(widgetGenerateState.widgetId) }), + ]); + } else { + await Promise.all([ + queryClient.invalidateQueries({ queryKey: publicDataTableLoadQueryKey(state.dataTableId) }), + queryClient.invalidateQueries({ queryKey: publicWidgetLoadQueryKey(widgetGenerateState.widgetId) }), + queryClient.invalidateQueries({ queryKey: publicWidgetLoadSumQueryKey(widgetGenerateState.widgetId) }), + ]); + } }; const { mutateAsync: updateDataTableMutation } = useMutation({ - mutationFn: fetcher.updateDataTableFn, + mutationFn: dataTableFetcher.updateDataTableFn, onSuccess: async (data) => { await syncDataTableList(data); + await queryClient.invalidateQueries({ queryKey: state.isPrivate ? privateDataTableGetQueryKey(data.data_table_id) : publicDataTableGetQueryKey(data.data_table_id) }); await invalidateLoadQueries(data); setFailStatus(false); @@ -246,11 +262,11 @@ const { mutateAsync: updateDataTableMutation } = useMutation({ }, }); const { mutateAsync: updateWidget } = useMutation({ - mutationFn: fetcher.updateWidgetFn, + mutationFn: widgetFetcher.updateWidgetFn, onSuccess: (data) => { const widgetQueryKey = widgetGenerateState.widgetId?.startsWith('private') - ? keys.privateWidgetGetQueryKey - : keys.publicWidgetGetQueryKey; + ? widgetKeys.privateWidgetGetQueryKey + : widgetKeys.publicWidgetGetQueryKey; queryClient.setQueryData(widgetQueryKey.value, () => data); }, onError: (e) => { @@ -421,6 +437,9 @@ const handleCancelModal = () => { modalState.visible = false; }; const handleUpdateDataTable = async () => { + if (!widgetGenerateState.widgetId) { + throw new Error('Widget ID is required'); + } state.loading = true; const result = await updateDataTable(); if (result) { @@ -448,7 +467,7 @@ const clearDataTableInvalidStatus = async (dataTableId: string) => { delete _allDataTableInvalidMap[dataTableId]; widgetGenerateStore.setAllDataTableInvalidMap(_allDataTableInvalidMap); - const dataTableListQueryKey = state.isPrivate ? keys.privateDataTableListQueryKey : keys.publicDataTableListQueryKey; + const dataTableListQueryKey = state.isPrivate ? dataTableKeys.privateDataTableListQueryKey : dataTableKeys.publicDataTableListQueryKey; await queryClient.setQueryData(dataTableListQueryKey.value, (oldData: ListResponse) => { if (oldData.results) { return { diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformDataTableDropdown.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformDataTableDropdown.vue index 4cff59106e..65569beee9 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformDataTableDropdown.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformDataTableDropdown.vue @@ -9,7 +9,7 @@ import { PI, PContextMenu, PFieldTitle } from '@cloudforet/mirinae'; import type { MenuItem } from '@cloudforet/mirinae/types/controls/context-menu/type'; import { useProxyValue } from '@/common/composables/proxy-state'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; import { DATA_TABLE_TYPE } from '@/common/modules/widgets/_constants/data-table-constant'; import { useWidgetGenerateStore } from '@/common/modules/widgets/_store/widget-generate-store'; import type { TransformDataTableInfo } from '@/common/modules/widgets/types/widget-data-table-type'; @@ -34,7 +34,7 @@ const widgetGenerateState = widgetGenerateStore.state; /* Query */ const { dataTableList, -} = useWidgetFormQuery({ +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformEvaluate.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformEvaluate.vue index e942f3bbec..220c471d2e 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformEvaluate.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformEvaluate.vue @@ -22,7 +22,7 @@ import WidgetFormDataTableCardTransformFormWrapper from '@/common/modules/widgets/_components/WidgetFormDataTableCardTransformFormWrapper.vue'; import WidgetFormDataTableGlobalVariableViewButton from '@/common/modules/widgets/_components/WidgetFormDataTableGlobalVariableViewButton.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; import { DATA_TABLE_FIELD_TYPE, DATA_TABLE_OPERATOR } from '@/common/modules/widgets/_constants/data-table-constant'; import { useWidgetGenerateStore } from '@/common/modules/widgets/_store/widget-generate-store'; import type { TransformDataTableInfo, TransformDataTableProps } from '@/common/modules/widgets/types/widget-data-table-type'; @@ -52,7 +52,7 @@ const widgetGenerateState = widgetGenerateStore.state; /* Query */ const { dataTableList, -} = useWidgetFormQuery({ +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformJoin.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformJoin.vue index 335ff707f2..65c94e75f3 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformJoin.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformJoin.vue @@ -13,7 +13,7 @@ import type { SelectDropdownMenuItem } from '@cloudforet/mirinae/types/controls/ import { useProxyValue } from '@/common/composables/proxy-state'; import WidgetFormDataTableCardTransformFormWrapper from '@/common/modules/widgets/_components/WidgetFormDataTableCardTransformFormWrapper.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; import { DATA_TABLE_OPERATOR, JOIN_TYPE, } from '@/common/modules/widgets/_constants/data-table-constant'; @@ -47,7 +47,7 @@ const widgetGenerateState = widgetGenerateStore.state; /* Query */ const { dataTableList, -} = useWidgetFormQuery({ +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformPivotForm.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformPivotForm.vue index 7d4f8ee90e..cd5e50b501 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformPivotForm.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformPivotForm.vue @@ -18,7 +18,7 @@ import { showErrorMessage } from '@/lib/helper/notice-alert-helper'; import { useProxyValue } from '@/common/composables/proxy-state'; import WidgetFormDataTableCardTransformFormWrapper from '@/common/modules/widgets/_components/WidgetFormDataTableCardTransformFormWrapper.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; import { DATA_TABLE_OPERATOR, DEFAULT_TRANSFORM_DATA_TABLE_VALUE_MAP, } from '@/common/modules/widgets/_constants/data-table-constant'; @@ -39,7 +39,7 @@ const widgetGenerateState = widgetGenerateStore.state; const { dataTableList, api, -} = useWidgetFormQuery({ +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformValueMapping.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformValueMapping.vue index 9ddd1aca9b..3aa564b6dc 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformValueMapping.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableCardTransformValueMapping.vue @@ -19,7 +19,7 @@ import { i18n } from '@/translations'; import { useProxyValue } from '@/common/composables/proxy-state'; import WidgetFormDataTableCardTransformFormWrapper from '@/common/modules/widgets/_components/WidgetFormDataTableCardTransformFormWrapper.vue'; -import { useWidgetFormQuery } from '@/common/modules/widgets/_composables/use-widget-form-query'; +import { useWidgetDataTableListQuery } from '@/common/modules/widgets/_composables/use-widget-data-table-list-query'; import { DATA_TABLE_FIELD_TYPE, DATA_TABLE_OPERATOR, @@ -46,7 +46,7 @@ const widgetGenerateState = widgetGenerateStore.state; /* Query */ const { dataTableList, -} = useWidgetFormQuery({ +} = useWidgetDataTableListQuery({ widgetId: computed(() => widgetGenerateState.widgetId), }); diff --git a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableGlobalVariableViewButton.vue b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableGlobalVariableViewButton.vue index 92686f51fe..7092613f88 100644 --- a/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableGlobalVariableViewButton.vue +++ b/apps/web/src/common/modules/widgets/_components/WidgetFormDataTableGlobalVariableViewButton.vue @@ -1,21 +1,20 @@ diff --git a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardNameEditModal.vue b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardNameEditModal.vue index 085f0e4e73..d209a3af19 100644 --- a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardNameEditModal.vue +++ b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardNameEditModal.vue @@ -4,7 +4,7 @@ import { } from 'vue'; import { useRoute } from 'vue-router/composables'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import { PButtonModal, PFieldGroup, PTextInput } from '@cloudforet/mirinae'; @@ -17,7 +17,7 @@ import ErrorHandler from '@/common/composables/error/errorHandler'; import { useFormValidator } from '@/common/composables/form-validator'; import { useProxyValue } from '@/common/composables/proxy-state'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; import { useDashboardQuery } from '@/services/dashboards/composables/use-dashboard-query'; @@ -39,12 +39,12 @@ const { publicDashboardList, privateDashboardList, keys, - queryClient, } = useDashboardQuery(); +const queryClient = useQueryClient(); const { fetcher, keys: dashboardDetailKeys, -} = useDashboardDetailQuery({ +} = useDashboardGetQuery({ dashboardId: computed(() => props.dashboardId), }); const route = useRoute(); diff --git a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardRefreshDropdown.vue b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardRefreshDropdown.vue index 6ae95754cb..078f7f4356 100644 --- a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardRefreshDropdown.vue +++ b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardRefreshDropdown.vue @@ -5,7 +5,7 @@ import { } from 'vue'; import type { TranslateResult } from 'vue-i18n'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import { PIconButton, PSelectDropdown } from '@cloudforet/mirinae'; import type { MenuItem } from '@cloudforet/mirinae/types/controls/context-menu/type'; @@ -16,7 +16,7 @@ import type { PrivateDashboardModel } from '@/api-clients/dashboard/private-dash import type { PublicDashboardModel } from '@/api-clients/dashboard/public-dashboard/schema/model'; import { i18n } from '@/translations'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; import { useDashboardManageable } from '@/services/dashboards/composables/use-dashboard-manageable'; import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; @@ -41,12 +41,13 @@ const dashboardDetailState = dashboardDetailStore.state; /* Query */ const { - dashboard, keys, fetcher, queryClient, -} = useDashboardDetailQuery({ - dashboardId: computed(() => dashboardDetailState.dashboardId), + dashboard, keys, fetcher, +} = useDashboardGetQuery({ + dashboardId: computed(() => props.dashboardId), }); +const queryClient = useQueryClient(); const { isManageable } = useDashboardManageable({ - dashboardId: computed(() => dashboardDetailState.dashboardId), + dashboardId: computed(() => props.dashboardId), }); const state = reactive({ @@ -105,7 +106,7 @@ const handleSelectRefreshIntervalOption = (option) => { if (isManageable.value) { mutate({ - dashboard_id: dashboardDetailState.dashboardId, + dashboard_id: props.dashboardId, options: { ...(dashboard.value?.options || {}), refresh_interval_option: option, diff --git a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardReorderSidebar.vue b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardReorderSidebar.vue index b85dad62a9..e2c79f0ebf 100644 --- a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardReorderSidebar.vue +++ b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardReorderSidebar.vue @@ -3,9 +3,10 @@ import { computed, onUnmounted, reactive, watch, } from 'vue'; +import { useRoute } from 'vue-router/composables'; import draggable from 'vuedraggable'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import { PI, PButton, @@ -21,25 +22,28 @@ import { useDisplayStore } from '@/store/display/display-store'; import { WIDGET_COMPONENT_ICON_MAP } from '@/common/modules/widgets/_constants/widget-components-constant'; import { getWidgetConfig } from '@/common/modules/widgets/_helpers/widget-config-helper'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; -import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; - +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; +import { useDashboardWidgetListQuery } from '@/services/dashboards/composables/use-dashboard-widget-list-query'; type WidgetModel = PublicWidgetModel | PrivateWidgetModel; const displayStore = useDisplayStore(); -const dashboardDetailStore = useDashboardDetailInfoStore(); -const dashboardDetailState = dashboardDetailStore.state; +const route = useRoute(); +const dashboardId = computed(() => route.params.dashboardId); /* Query */ const { dashboard, - widgetList, keys, fetcher, - queryClient, -} = useDashboardDetailQuery({ - dashboardId: computed(() => dashboardDetailState.dashboardId), +} = useDashboardGetQuery({ + dashboardId, +}); +const { + widgetList, +} = useDashboardWidgetListQuery({ + dashboardId, }); +const queryClient = useQueryClient(); const state = reactive({ widgetList: computed(() => { const results: WidgetModel[] = []; @@ -61,7 +65,7 @@ const handleChangeWidgetOrder = () => { const _widgetIdList = state.widgetList.map((w) => w.widget_id); const _updatedLayouts = [{ widgets: _widgetIdList }]; updateDashboard({ - dashboard_id: dashboardDetailState.dashboardId || '', + dashboard_id: dashboardId.value || '', layouts: _updatedLayouts, }); }; @@ -84,7 +88,7 @@ const { mutate: updateDashboard } = useMutation( }, ); -watch(() => dashboardDetailState.dashboardId, (after, before) => { +watch(() => dashboardId.value, (after, before) => { if (after !== before) { displayStore.setVisibleSidebar(false); } diff --git a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardShareWithCodeModal.vue b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardShareWithCodeModal.vue index a76cba3710..92708e0b85 100644 --- a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardShareWithCodeModal.vue +++ b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardShareWithCodeModal.vue @@ -17,13 +17,14 @@ import { copyAnyData } from '@/lib/helper/copy-helper'; import { useProxyValue } from '@/common/composables/proxy-state'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; import { useDashboardQuery } from '@/services/dashboards/composables/use-dashboard-query'; +import { useDashboardWidgetListQuery } from '@/services/dashboards/composables/use-dashboard-widget-list-query'; import { getSharedDashboardLayouts } from '@/services/dashboards/helpers/dashboard-share-helper'; import type { SharedDashboardInfo } from '@/services/dashboards/types/shared-dashboard-type'; + type DataTableModel = PublicDataTableModel | PrivateDataTableModel; interface Props { visible: boolean; @@ -47,7 +48,7 @@ const { } = useDashboardQuery(); const { widgetList, -} = useDashboardDetailQuery({ +} = useDashboardWidgetListQuery({ dashboardId: computed(() => props.dashboardId), }); diff --git a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardToolsetDateDropdown.vue b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardToolsetDateDropdown.vue index 4f01e9ae5e..bc61c8d69e 100644 --- a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardToolsetDateDropdown.vue +++ b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardToolsetDateDropdown.vue @@ -2,8 +2,9 @@ import { computed, reactive, watch, } from 'vue'; +import { useRoute } from 'vue-router/composables'; -import { useMutation } from '@tanstack/vue-query'; +import { useMutation, useQueryClient } from '@tanstack/vue-query'; import dayjs from 'dayjs'; import { cloneDeep, range } from 'lodash'; @@ -18,7 +19,7 @@ import { i18n } from '@/translations'; import { useI18nDayjs } from '@/common/composables/i18n-dayjs'; import DashboardToolsetDateCustomModal from '@/services/dashboards/components/dashboard-detail/DashboardToolsetDateCustomModal.vue'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; import { useDashboardManageable } from '@/services/dashboards/composables/use-dashboard-manageable'; import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; @@ -33,18 +34,20 @@ const props = withDefaults(defineProps(), { const { i18nDayjs } = useI18nDayjs(); const dashboardDetailStore = useDashboardDetailInfoStore(); const dashboardDetailState = dashboardDetailStore.state; +const route = useRoute(); +const dashboardId = computed(() => route.params.dashboardId); /* Query */ const { dashboard, fetcher, keys, - queryClient, -} = useDashboardDetailQuery({ - dashboardId: computed(() => dashboardDetailState.dashboardId), +} = useDashboardGetQuery({ + dashboardId, }); +const queryClient = useQueryClient(); const { isManageable } = useDashboardManageable({ - dashboardId: computed(() => dashboardDetailState.dashboardId), + dashboardId, }); const state = reactive({ monthMenuItems: computed(() => { @@ -114,7 +117,7 @@ const handleSelectMonthMenuItem = (selected: string) => { if (isManageable.value && !props.widgetMode) { mutate({ - dashboard_id: dashboardDetailState.dashboardId, + dashboard_id: dashboardId.value, options: { ...(dashboard.value?.options || {}), date_range: state.selectedDateRange, diff --git a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardVariablesFormModal.vue b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardVariablesFormModal.vue index 8185722b9a..ec22ea9c1b 100644 --- a/apps/web/src/services/dashboards/components/dashboard-detail/DashboardVariablesFormModal.vue +++ b/apps/web/src/services/dashboards/components/dashboard-detail/DashboardVariablesFormModal.vue @@ -1,7 +1,8 @@ @@ -357,7 +314,7 @@ onUnmounted(() => { @change="handleQueryChange" @refresh="handleQueryChange()" /> - diff --git a/apps/web/src/services/project/v1/pages/ProjectDashboardPage.vue b/apps/web/src/services/project/v1/pages/ProjectDashboardPage.vue index 2ae48b1e25..a08f99ecd7 100644 --- a/apps/web/src/services/project/v1/pages/ProjectDashboardPage.vue +++ b/apps/web/src/services/project/v1/pages/ProjectDashboardPage.vue @@ -6,6 +6,8 @@ import { } from 'vue'; import { useRoute, useRouter } from 'vue-router/composables'; +import { useQueryClient } from '@tanstack/vue-query'; + import { PSkeleton } from '@cloudforet/mirinae'; @@ -19,7 +21,8 @@ import DashboardVariablesV2 from '@/services/dashboards/components/dashboard-det import DashboardWidgetContainerV2 from '@/services/dashboards/components/dashboard-detail/DashboardWidgetContainerV2.vue'; import type DashboardWidgetContainer from '@/services/dashboards/components/legacy/DashboardWidgetContainer.vue'; -import { useDashboardDetailQuery } from '@/services/dashboards/composables/use-dashboard-detail-query'; +import { useDashboardGetQuery } from '@/services/dashboards/composables/use-dashboard-get-query'; +import { useDashboardWidgetListQuery } from '@/services/dashboards/composables/use-dashboard-widget-list-query'; import { useDashboardDetailInfoStore } from '@/services/dashboards/stores/dashboard-detail-info-store'; import { PROJECT_ROUTE_V1 } from '@/services/project/v1/routes/route-constant'; @@ -40,17 +43,23 @@ const router = useRouter(); /* Query */ const { dashboard, + isError: dashboardError, + isLoading: dashboardLoading, +} = useDashboardGetQuery({ + dashboardId: computed(() => route.params.dashboardId), +}); +const { widgetList, - isError, - isLoading, - keys, - queryClient, -} = useDashboardDetailQuery({ + isLoading: widgetLoading, + isError: widgetError, + keys: widgetListKeys, +} = useDashboardWidgetListQuery({ dashboardId: computed(() => route.params.dashboardId), }); +const queryClient = useQueryClient(); const handleRefresh = async () => { - await queryClient.invalidateQueries({ queryKey: keys.publicWidgetListQueryKey.value }); + await queryClient.invalidateQueries({ queryKey: widgetListKeys.publicWidgetListQueryKey.value }); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore if (widgetContainerRef.value) widgetContainerRef.value.refreshAllWidget(); @@ -69,9 +78,9 @@ watch(widgetList, (_widgetList) => { dashboardDetailStore.setDashboardWidgets(_widgetList); } }); -watch(isError, (error) => { - if (error) { - ErrorHandler.handleError(error); +watch([dashboardError, widgetError], ([_dashboardError, _widgetError]) => { + if (_dashboardError || _widgetError) { + ErrorHandler.handleError(_dashboardError || _widgetError); router.push({ name: PROJECT_ROUTE_V1.DETAIL._NAME }); } }); @@ -105,18 +114,18 @@ onUnmounted(() => {
-
diff --git a/apps/web/src/services/project/v1/pages/ProjectDetailTabPage.vue b/apps/web/src/services/project/v1/pages/ProjectDetailTabPage.vue index c9fd3b2ceb..b0a1607593 100644 --- a/apps/web/src/services/project/v1/pages/ProjectDetailTabPage.vue +++ b/apps/web/src/services/project/v1/pages/ProjectDetailTabPage.vue @@ -32,6 +32,7 @@ import { useGnbStore } from '@/common/modules/navigations/stores/gnb-store'; import { BACKGROUND_COLOR } from '@/styles/colorsets'; +import { useDashboardFolderQuery } from '@/services/dashboards/composables/use-dashboard-folder-query'; import { useDashboardQuery } from '@/services/dashboards/composables/use-dashboard-query'; import ProjectAlertTab from '@/services/project/v1/components/ProjectAlertTab.vue'; import ProjectDetailTab from '@/services/project/v1/components/ProjectDetailTab.vue'; @@ -59,8 +60,10 @@ const { visibleContents } = useContentsAccessibility(MENU_ID.ALERT_MANAGER); /* Query */ const { publicDashboardList, - publicFolderList, } = useDashboardQuery(); +const { + publicFolderList, +} = useDashboardFolderQuery(); const storeState = reactive({ visibleAlertTab: computed(() => visibleContents.value && projectDetailPageState.visibleAlertTab), diff --git a/apps/web/src/services/project/v2/pages/ProjectDetailPage.vue b/apps/web/src/services/project/v2/pages/ProjectDetailPage.vue index da91f08b6a..847cec57ff 100644 --- a/apps/web/src/services/project/v2/pages/ProjectDetailPage.vue +++ b/apps/web/src/services/project/v2/pages/ProjectDetailPage.vue @@ -29,6 +29,7 @@ import { useGnbStore } from '@/common/modules/navigations/stores/gnb-store'; import { BACKGROUND_COLOR } from '@/styles/colorsets'; +import { useDashboardFolderQuery } from '@/services/dashboards/composables/use-dashboard-folder-query'; import { useDashboardQuery } from '@/services/dashboards/composables/use-dashboard-query'; import ProjectHeader from '@/services/project/v2/components/ProjectHeader.vue'; import ProjectTabs from '@/services/project/v2/components/ProjectTabs.vue'; @@ -49,9 +50,10 @@ const userStore = useUserStore(); /* Query */ const { publicDashboardList, - publicFolderList, } = useDashboardQuery(); - +const { + publicFolderList, +} = useDashboardFolderQuery(); const storeState = reactive({ projectGroups: computed(() => allReferenceStore.getters.projectGroup),