diff --git a/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-clone-action.ts b/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-clone-action.ts index ce2442c18c..08a8c09ca3 100644 --- a/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-clone-action.ts +++ b/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-clone-action.ts @@ -3,7 +3,6 @@ import type { ComputedRef } from 'vue'; import { useMutation } from '@tanstack/vue-query'; import type { ListResponse } from '@/api-clients/_common/schema/api-verbs/list'; -import { RESOURCE_GROUP } from '@/api-clients/_common/schema/constant'; import type { DashboardCreateParams, DashboardModel } from '@/api-clients/dashboard/_types/dashboard-type'; import type { WidgetModel } from '@/api-clients/dashboard/_types/widget-type'; import { usePrivateDashboardApi } from '@/api-clients/dashboard/private-dashboard/composables/use-private-dashboard-api'; @@ -16,7 +15,6 @@ import { usePublicWidgetApi } from '@/api-clients/dashboard/public-widget/compos import { useAllReferenceStore } from '@/store/reference/all-reference-store'; import { useUserStore } from '@/store/user/user-store'; -import { useDashboardRouteContext } from '@/services/dashboard-shared/core/composables/use-dashboard-route-context'; import { getSharedDashboardLayouts } from '@/services/dashboard-shared/core/helpers/dashboard-share-helper'; @@ -35,9 +33,6 @@ export const useDashboardCloneAction = (options: UseDashboardCloneActionOptions) const { publicWidgetAPI } = usePublicWidgetApi(); const allReferenceStore = useAllReferenceStore(); const userStore = useUserStore(); - const { - entryPoint, - } = useDashboardRouteContext(); const { dashboardId, isPrivate, onSuccess, onError, onSettled, @@ -78,7 +73,7 @@ export const useDashboardCloneAction = (options: UseDashboardCloneActionOptions) const _sharedLayouts = await getSharedDashboardLayouts(dashboard.layouts, widgetList.results || [], allReferenceStore.getters.costDataSource); const _sharedDashboard: DashboardCreateParams = { - name: params.name, + ...params, layouts: _sharedLayouts, options: dashboard.options || {}, labels: dashboard.labels || [], @@ -86,15 +81,6 @@ export const useDashboardCloneAction = (options: UseDashboardCloneActionOptions) vars: dashboard.vars, vars_schema: dashboard.vars_schema, }; - if (entryPoint.value === 'ADMIN') { - (_sharedDashboard as PublicDashboardCreateParameters).resource_group = RESOURCE_GROUP.DOMAIN; - } else if (entryPoint.value === 'WORKSPACE') { - if (!isPrivate?.value) { - (_sharedDashboard as PublicDashboardCreateParameters).resource_group = RESOURCE_GROUP.WORKSPACE; - } - } else if (entryPoint.value === 'PROJECT') { - (_sharedDashboard as PublicDashboardCreateParameters).resource_group = RESOURCE_GROUP.PROJECT; - } if (isPrivate?.value) { diff --git a/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-delete-action.ts b/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-delete-action.ts index 6c94ab2e84..c02bf92fc8 100644 --- a/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-delete-action.ts +++ b/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-delete-action.ts @@ -41,8 +41,8 @@ export const useDashboardDeleteAction = (options: UseDashboardDeleteActionOption onSuccess: async (data, variables) => { const _dashboardId = variables.dashboard_id; const _isPrivate = _dashboardId.startsWith('private'); - const dashboardListQueryKey = _isPrivate ? privateDashboardGetQueryKey(_dashboardId) : publicDashboardGetQueryKey(_dashboardId); - queryClient.invalidateQueries({ queryKey: dashboardListQueryKey }); + const dashboardGetQueryKey = _isPrivate ? privateDashboardGetQueryKey(_dashboardId) : publicDashboardGetQueryKey(_dashboardId); + queryClient.invalidateQueries({ queryKey: dashboardGetQueryKey }); if (onSuccess) await onSuccess(data, variables); }, onError: (error, variables) => { diff --git a/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-folder-delete-action.ts b/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-folder-delete-action.ts new file mode 100644 index 0000000000..d2b203b14b --- /dev/null +++ b/apps/web/src/services/dashboard-shared/core/actions/use-dashboard-folder-delete-action.ts @@ -0,0 +1,90 @@ +import type { ComputedRef } from 'vue'; +import { computed } from 'vue'; + +import { + useMutation, useQueryClient, +} from '@tanstack/vue-query'; + +import type { DashboardDeleteParams, DashboardListParams } from '@/api-clients/dashboard/_types/dashboard-type'; +import type { FolderDeleteParams } from '@/api-clients/dashboard/_types/folder-type'; +import { usePrivateDashboardApi } from '@/api-clients/dashboard/private-dashboard/composables/use-private-dashboard-api'; +import { usePrivateFolderApi } from '@/api-clients/dashboard/private-folder/composables/use-private-folder-api'; +import { usePublicDashboardApi } from '@/api-clients/dashboard/public-dashboard/composables/use-public-dashboard-api'; +import { usePublicFolderApi } from '@/api-clients/dashboard/public-folder/composables/use-public-folder-api'; +import { useServiceQueryKey } from '@/query/query-key/use-service-query-key'; + +interface UseDashboardFolderDeleteActionOptions { + folderId: ComputedRef; + onSuccess?: (data: unknown, variables: FolderDeleteParams) => void|Promise; + onError?: (error: Error, variables: FolderDeleteParams) => void|Promise; + onSettled?: (data: unknown|undefined, error: Error|null, variables: FolderDeleteParams) => void|Promise; +} + +export const useDashboardFolderDeleteAction = (options: UseDashboardFolderDeleteActionOptions) => { + const { publicFolderAPI } = usePublicFolderApi(); + const { privateFolderAPI } = usePrivateFolderApi(); + const { publicDashboardAPI } = usePublicDashboardApi(); + const { privateDashboardAPI } = usePrivateDashboardApi(); + const queryClient = useQueryClient(); + const { withSuffix: publicFolderGetQueryKey } = useServiceQueryKey('dashboard', 'public-folder', 'get'); + const { withSuffix: privateFolderGetQueryKey } = useServiceQueryKey('dashboard', 'private-folder', 'get'); + const { withSuffix: publicDashboardGetQueryKey } = useServiceQueryKey('dashboard', 'public-dashboard', 'get'); + const { withSuffix: privateDashboardGetQueryKey } = useServiceQueryKey('dashboard', 'private-dashboard', 'get'); + + const { + folderId, onSuccess, onError, onSettled, + } = options; + + const isPrivate = computed(() => folderId.value?.startsWith('private')); + + const listDashboardFn = (params: DashboardListParams) => { + if (!folderId.value) throw new Error('Folder ID is not provided'); + const fetcher = isPrivate.value ? privateDashboardAPI.list : publicDashboardAPI.list; + return fetcher(params); + }; + const deleteDashboardFn = (params: DashboardDeleteParams) => { + if (!params.dashboard_id) throw new Error('Dashboard ID is not provided'); + const fetcher = isPrivate.value ? privateDashboardAPI.delete : publicDashboardAPI.delete; + return fetcher(params); + }; + + const deleteDashboardListByFolderId = async (_folderId: string) => { + const _dashboardList = await listDashboardFn({ + folder_id: _folderId, + }); + const _dashboardIds = _dashboardList.results?.map((d) => d.dashboard_id); + if (!_dashboardIds) return; + const _dashboardDeletePromises = _dashboardIds.map(async (id) => { + const _isPrivate = id.startsWith('private'); + await deleteDashboardFn({ dashboard_id: id }); + queryClient.invalidateQueries({ queryKey: _isPrivate ? privateDashboardGetQueryKey(id) : publicDashboardGetQueryKey(id) }); + }); + await Promise.all(_dashboardDeletePromises); + }; + + const deleteFolderFn = (params: FolderDeleteParams) => { + if (!folderId.value) throw new Error('Folder ID is not provided'); + const fetcher = isPrivate.value ? privateFolderAPI.delete : publicFolderAPI.delete; + return fetcher(params); + }; + + return useMutation({ + mutationFn: deleteFolderFn, + onSuccess: async (data, variables) => { + const _folderId = variables.folder_id; + const _isPrivate = _folderId.startsWith('private'); + const folderListQueryKey = _isPrivate ? privateFolderGetQueryKey(_folderId) : publicFolderGetQueryKey(_folderId); + queryClient.invalidateQueries({ queryKey: folderListQueryKey }); + + await deleteDashboardListByFolderId(_folderId); + + if (onSuccess) await onSuccess(data, variables); + }, + onError: (error, variables) => { + if (onError) onError(error, variables); + }, + onSettled: (data, error, variables) => { + if (onSettled) onSettled(data, error, variables); + }, + }); +}; diff --git a/apps/web/src/services/dashboard-shared/dashboard-detail/DashboardDetailBody.vue b/apps/web/src/services/dashboard-shared/dashboard-detail/DashboardDetailBody.vue index 9cdb4f9616..fa0cfb23a4 100644 --- a/apps/web/src/services/dashboard-shared/dashboard-detail/DashboardDetailBody.vue +++ b/apps/web/src/services/dashboard-shared/dashboard-detail/DashboardDetailBody.vue @@ -42,7 +42,7 @@ import { PROJECT_ROUTE_V2 } from '@/services/project/v2/routes/route-constant'; interface Props { dashboardId: string; dashboardItems?: Array; - folderItems?: Array; + folderItems: Array; } const props = withDefaults(defineProps(), { @@ -194,6 +194,7 @@ onUnmounted(() => { diff --git a/apps/web/src/services/project/v2/stores/project-page-modal-store.ts b/apps/web/src/services/project/v2/stores/project-page-modal-store.ts index 278cce665d..77a951105f 100644 --- a/apps/web/src/services/project/v2/stores/project-page-modal-store.ts +++ b/apps/web/src/services/project/v2/stores/project-page-modal-store.ts @@ -4,14 +4,21 @@ import { defineStore } from 'pinia'; export const useProjectPageModalStore = defineStore('project-page-modal', () => { const state = reactive({ + targetId: '' as string|undefined, + targetType: undefined as 'project'|'projectGroup'|undefined, + manageMemberModalVisible: false, deleteModalVisible: false, moveModalVisible: false, inviteMemberModalVisible: false, manageTagsModalVisible: false, projectFormModalVisible: false, - targetId: '' as string|undefined, - targetType: undefined as 'project'|'projectGroup'|undefined, + + folderFormModalVisible: false, + dashboardNameEditModalVisible: false, + dashboardChangeFolderModalVisible: false, + dashboardDeleteModalVisible: false, + dashboardCloneModalVisible: false, }); const actions = { @@ -109,7 +116,45 @@ export const useProjectPageModalStore = defineStore('project-page-modal', () => closeFormModal() { state.projectFormModalVisible = false; }, - // overal + openCreateFolderFormModal() { + state.targetId = undefined; + state.folderFormModalVisible = true; + }, + openEditFolderFormModal(targetFolderId: string) { + state.targetId = targetFolderId; + state.folderFormModalVisible = true; + }, + closeFolderFormModal() { + state.folderFormModalVisible = false; + }, + openDashboardNameEditModal(targetDashboardId: string) { + state.targetId = targetDashboardId; + state.dashboardNameEditModalVisible = true; + }, + closeDashboardNameEditModal() { + state.dashboardNameEditModalVisible = false; + }, + openDashboardChangeFolderModal(targetDashboardId: string) { + state.targetId = targetDashboardId; + state.dashboardChangeFolderModalVisible = true; + }, + closeDashboardChangeFolderModal() { + state.dashboardChangeFolderModalVisible = false; + }, + openDashboardDeleteModal(targetDashboardId: string) { + state.targetId = targetDashboardId; + state.dashboardDeleteModalVisible = true; + }, + closeDashboardDeleteModal() { + state.dashboardDeleteModalVisible = false; + }, + openDashboardCloneModal(targetDashboardId: string) { + state.targetId = targetDashboardId; + state.dashboardCloneModalVisible = true; + }, + closeDashboardCloneModal() { + state.dashboardCloneModalVisible = false; + }, resetTarget() { state.targetId = undefined; state.targetType = undefined;