Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ node_modules.nosync/
# Dev tools
.DS_Store
.vscode
.cursor
.idea
*.swp
*.bak
Expand Down
96 changes: 75 additions & 21 deletions apps/web/src/api-clients/_common/composables/use-api-query-key.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,81 @@
import { computed, reactive } from 'vue';
import { reactive, computed } from 'vue';


import type {
ResourceName, ServiceName, Verb,
} from '@/api-clients/_common/types/query-key-type';
ServiceName, ResourceName, Verb,
} from '@/query/_types/query-key-type';

import { useAppContextStore } from '@/store/app-context/app-context-store';
import { useUserWorkspaceStore } from '@/store/app-context/workspace/user-workspace-store';

/**
* Generates a computed query key for API requests, incorporating global parameters.
*
* @param service - The service name, representing the API service scope (e.g., 'dashboard').
* @param resource - The resource name, specifying the target API resource (e.g., 'public-data-table').
* @param verb - The API action verb, defining the type of request (e.g., 'get', 'list', 'update').
* @param additionalGlobalParams - Optional additional global parameters (e.g., workspace ID, admin mode).
* @returns A computed reference to the query key array, structured as `[service, resource, verb, { globalParams }]`.
*
* ### Example Usage:
* ```ts
* const queryKey = useAPIQueryKey('dashboard', 'public-data-table', 'get');
* ```
* The generated query key ensures:
* - **Type safety**: Prevents invalid API calls by enforcing a valid `service/resource/verb` combination.
* - **Auto-completion**: Provides intelligent suggestions based on predefined API structure.
* - **Cache management**: Enables precise cache invalidation and data synchronization.
*/

// type QueryKeyArrayWithDep = QueryKeyArray & {
// addDep: (deps: Record<string, unknown>) => QueryKeyArray;
// };
// type ExtractParams<T> = T extends (params: infer P) => any ? P : never;

// type VerbFunction<T> = {
// (params?: ExtractParams<T>): QueryKeyArrayWithDep;
// };

// type MapVerbToReturnType<T> = T extends (params: any) => any
// ? VerbFunction<T>
// : never;

// type UseAPIQueryResult = {
// [S in APIQueryKeyMapService]: {
// [R in APIQueryKeyMapResource<S>]: {
// [V in APIQueryKeyMapVerb<S, R>]: MapVerbToReturnType<(typeof API_QUERY_KEY_MAP)[S][R][V]>;
// };
// };
// };

// type APIQueryKeyValue = (params?: Record<string, unknown>) => QueryKeyArray;


// export const _useAPIQueryKey = (): ComputedRef<UseAPIQueryResult> => {
// const queryKeyAppContext = useQueryKeyAppContext('service');
// const globalContext = computed(() => queryKeyAppContext.value);


// const apiStructure = Object.entries(API_QUERY_KEY_MAP).reduce<Record<APIQueryKeyMapService, any>>((result, [serviceName, resources]) => {
// result[serviceName as APIQueryKeyMapService] = Object.entries(resources).reduce((resourceResult, [resourceName, verbs]) => {
// resourceResult[resourceName] = Object.entries(verbs).reduce((verbResult, [verb, queryKeyValue]) => {
// const staticKey = createImmutableObject([serviceName, resourceName, verb]);

// const verbFunction = <T extends APIQueryKeyValue>(params?: ExtractParams<T>) => {
// const baseKey = computed(() => (queryKeyValue as T)(params));
// const queryKey = [
// ...globalContext.value,
// ...staticKey,
// ...createImmutableObject(baseKey.value),
// ] as QueryKeyArray;

// (queryKey as QueryKeyArrayWithDep).addDep = (deps: Record<string, unknown>): QueryKeyArray => [
// ...globalContext.value,
// ...staticKey,
// ...createImmutableObject(baseKey.value),
// createImmutableObject(deps),
// ];

// return queryKey as QueryKeyArrayWithDep;
// };

// verbResult[verb] = verbFunction;
// return verbResult;
// }, {});
// return resourceResult;
// }, {});
// return result;
// }, {} as Record<APIQueryKeyMapService, any>);


// return computed(() => apiStructure as UseAPIQueryResult);
// };



// TODO: Deprecate this
interface GlobalQueryParams {
workspaceId?: string;
isAdminMode?: boolean;
Expand All @@ -52,3 +102,7 @@ export const useAPIQueryKey = <S extends ServiceName, R extends ResourceName<S>,

return computed(() => [service, resource, verb, { ...globalQueryParams }]);
};




22 changes: 9 additions & 13 deletions apps/web/src/api-clients/_common/composables/use-scoped-query.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
/**
* useScopedQuery - A custom wrapper around `useQuery` to enforce scope-based API fetching.
*
Expand All @@ -10,8 +8,8 @@
*
* ## Functionality
* - Extends `useQuery` with **grant scope validation**.
* - Runs queries only when **the users scope is valid** and the app is **ready**.
* - Uses Vues **reactivity** to dynamically compute the `enabled` state.
* - Runs queries only when **the user's scope is valid** and the app is **ready**.
* - Uses Vue's **reactivity** to dynamically compute the `enabled` state.
* - Supports both **static and reactive `enabled` values**.
*
* ## Parameters:
Expand Down Expand Up @@ -43,7 +41,7 @@

import type { MaybeRef } from '@vueuse/core';
import { toValue } from '@vueuse/core';
import { computed, reactive } from 'vue';
import { computed } from 'vue';

import type {
UseQueryOptions,
Expand All @@ -57,21 +55,19 @@ import { useUserStore } from '@/store/user/user-store';

export const useScopedQuery = <TQueryFnData = unknown, TError = unknown, TData = TQueryFnData>(
options: UseQueryOptions<TQueryFnData, TError, TData>,
requiredScopes: GrantScope[] = [],
requiredScopes: GrantScope[],
) => {
const appContextStore = useAppContextStore();
const userStore = useUserStore();

const _state = reactive({
currentGrantScope: computed<GrantScope>(() => userStore.state.currentGrantInfo?.scope || 'USER'),
isLoading: computed(() => appContextStore.getters.globalGrantLoading),
isValidScope: computed(() => requiredScopes.includes(_state.currentGrantScope)),
});
const currentGrantScope = computed<GrantScope>(() => userStore.state.currentGrantInfo?.scope || 'USER');
const isLoading = computed(() => appContextStore.getters.globalGrantLoading);
const isValidScope = computed(() => requiredScopes.includes(currentGrantScope.value));

const queryEnabled = computed<boolean>(() => {
const _inheritedEnabled = options?.enabled as MaybeRef<boolean> | undefined;
const _inheritedEnabled = ('enabled' in options ? options.enabled : undefined) as MaybeRef<boolean> | undefined;
if (_inheritedEnabled !== undefined && !toValue(_inheritedEnabled)) return false;
return _state.isValidScope && !_state.isLoading;
return isValidScope.value && !isLoading.value;
});

return useQuery<TQueryFnData, TError, TData>({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { privateDashboardKeys } from '@/api-clients/dashboard/private-dashboard/keys';
import { privateDataTableKeys } from '@/api-clients/dashboard/private-data-table/keys';
import { privateFolderKeys } from '@/api-clients/dashboard/private-folder/keys';
import { privateWidgetKeys } from '@/api-clients/dashboard/private-widget/keys';
import { publicDashboardKeys } from '@/api-clients/dashboard/public-dashboard/keys';
import { publicDataTableKeys } from '@/api-clients/dashboard/public-data-table/keys';
import { publicFolderKeys } from '@/api-clients/dashboard/public-folder/keys';
import { publicWidgetKeys } from '@/api-clients/dashboard/public-widget/keys';
import { commentKeys } from '@/api-clients/opsflow/comment/keys';
import { eventKeys } from '@/api-clients/opsflow/event/keys';
import { taskCategoryKeys } from '@/api-clients/opsflow/task-category/keys';
import { taskTypeKeys } from '@/api-clients/opsflow/task-type/keys';
import { taskKeys } from '@/api-clients/opsflow/task/keys';

export const API_QUERY_KEY_MAP = {
dashboard: {
publicFolder: publicFolderKeys,
publicDashboard: publicDashboardKeys,
publicDataTable: publicDataTableKeys,
publicWidget: publicWidgetKeys,
privateFolder: privateFolderKeys,
privateDashboard: privateDashboardKeys,
privateDataTable: privateDataTableKeys,
privateWidget: privateWidgetKeys,
},
opsflow: {
comment: commentKeys,
task: taskKeys,
taskCategory: taskCategoryKeys,
taskType: taskTypeKeys,
event: eventKeys,
},
} as const;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { apiQueryClient } from '@/query/clients';

export const invalidateServiceQuery = async (mode: 'admin' | 'workspace') => {
await apiQueryClient.invalidateQueries({
queryKey: ['service', mode],
});
};
9 changes: 9 additions & 0 deletions apps/web/src/api-clients/dashboard/private-dashboard/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { PrivateDashboardGetParameters } from '@/api-clients/dashboard/private-dashboard/schema/api-verbs/get';
import type { PrivateDashboardListParameters } from '@/api-clients/dashboard/private-dashboard/schema/api-verbs/list';



export const privateDashboardKeys = {
list: (params: PrivateDashboardListParameters) => ['private-dashboard', 'list', params] as const,
get: (idParam: PrivateDashboardGetParameters['dashboard_id']) => ['private-dashboard', 'get', idParam] as const,
};
10 changes: 10 additions & 0 deletions apps/web/src/api-clients/dashboard/private-data-table/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import type { DataTableGetParameters } from '@/api-clients/dashboard/private-data-table/schema/api-verbs/get';
import type { DataTableListParameters } from '@/api-clients/dashboard/private-data-table/schema/api-verbs/list';
import type { DataTableLoadParameters } from '@/api-clients/dashboard/private-data-table/schema/api-verbs/load';

export const privateDataTableKeys = {
list: (params: DataTableListParameters) => ['private-data-table', 'list', params] as const,
get: (idParam: DataTableGetParameters['data_table_id']) => ['private-data-table', 'get', idParam] as const,
load: (idParam: DataTableLoadParameters['data_table_id']) => ['private-data-table', 'load', idParam] as const,
};
7 changes: 7 additions & 0 deletions apps/web/src/api-clients/dashboard/private-folder/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { PrivateFolderGetParameters } from '@/api-clients/dashboard/private-folder/schema/api-verbs/get';
import type { PrivateFolderListParameters } from '@/api-clients/dashboard/private-folder/schema/api-verbs/list';

export const privateFolderKeys = {
list: (params: PrivateFolderListParameters) => ['private-folder', 'list', params] as const,
get: (idParam: PrivateFolderGetParameters['folder_id']) => ['private-folder', 'get', idParam] as const,
};
11 changes: 11 additions & 0 deletions apps/web/src/api-clients/dashboard/private-widget/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { PrivateWidgetGetParameters } from '@/api-clients/dashboard/private-widget/schema/api-verbs/get';
import type { PrivateWidgetListParameters } from '@/api-clients/dashboard/private-widget/schema/api-verbs/list';
import type { PrivateWidgetLoadParameters } from '@/api-clients/dashboard/private-widget/schema/api-verbs/load';
import type { PrivateWidgetLoadSumParameters } from '@/api-clients/dashboard/private-widget/schema/api-verbs/load-sum';

export const privateWidgetKeys = {
list: (params: PrivateWidgetListParameters) => ['private-widget', 'list', params] as const,
get: (idParam: PrivateWidgetGetParameters['widget_id']) => ['private-widget', 'get', idParam] as const,
load: (idParam: PrivateWidgetLoadParameters['widget_id']) => ['private-widget', 'load', idParam] as const,
loadSum: (idParam: PrivateWidgetLoadSumParameters['widget_id']) => ['private-widget', 'load-sum', idParam] as const,
};
7 changes: 7 additions & 0 deletions apps/web/src/api-clients/dashboard/public-dashboard/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { PublicDashboardGetParameters } from '@/api-clients/dashboard/public-dashboard/schema/api-verbs/get';
import type { PublicDashboardListParameters } from '@/api-clients/dashboard/public-dashboard/schema/api-verbs/list';

export const publicDashboardKeys = {
list: (params: PublicDashboardListParameters) => ['public-dashboard', 'list', params] as const,
get: (idParam: PublicDashboardGetParameters['dashboard_id']) => ['public-dashboard', 'get', idParam] as const,
};
9 changes: 9 additions & 0 deletions apps/web/src/api-clients/dashboard/public-data-table/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { DataTableGetParameters } from '@/api-clients/dashboard/public-data-table/schema/api-verbs/get';
import type { DataTableListParameters } from '@/api-clients/dashboard/public-data-table/schema/api-verbs/list';
import type { DataTableLoadParameters } from '@/api-clients/dashboard/public-data-table/schema/api-verbs/load';

export const publicDataTableKeys = {
list: (params: DataTableListParameters) => ['public-data-table', 'list', params] as const,
get: (idParam: DataTableGetParameters['data_table_id']) => ['public-data-table', 'get', idParam] as const,
load: (idParam: DataTableLoadParameters['data_table_id']) => ['public-data-table', 'load', idParam] as const,
};
7 changes: 7 additions & 0 deletions apps/web/src/api-clients/dashboard/public-folder/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { PublicFolderGetParameters } from '@/api-clients/dashboard/public-folder/schema/api-verbs/get';
import type { PublicFolderListParameters } from '@/api-clients/dashboard/public-folder/schema/api-verbs/list';

export const publicFolderKeys = {
list: (params: PublicFolderListParameters) => ['public-folder', 'list', params] as const,
get: (idParam: PublicFolderGetParameters['folder_id']) => ['public-folder', 'get', idParam] as const,
};
11 changes: 11 additions & 0 deletions apps/web/src/api-clients/dashboard/public-widget/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { PublicWidgetGetParameters } from '@/api-clients/dashboard/public-widget/schema/api-verbs/get';
import type { PublicWidgetListParameters } from '@/api-clients/dashboard/public-widget/schema/api-verbs/list';
import type { PublicWidgetLoadParameters } from '@/api-clients/dashboard/public-widget/schema/api-verbs/load';
import type { PublicWidgetLoadSumParameters } from '@/api-clients/dashboard/public-widget/schema/api-verbs/load-sum';

export const publicWidgetKeys = {
list: (params: PublicWidgetListParameters) => ['public-widget', 'list', params] as const,
get: (idParam: PublicWidgetGetParameters['widget_id']) => ['public-widget', 'get', idParam] as const,
load: (idParam: PublicWidgetLoadParameters['widget_id']) => ['public-widget', 'load', idParam] as const,
loadSum: (idParam: PublicWidgetLoadSumParameters['widget_id']) => ['public-widget', 'load-sum', idParam] as const,
};
7 changes: 7 additions & 0 deletions apps/web/src/api-clients/opsflow/comment/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { CommentGetParameters } from '@/api-clients/opsflow/comment/schema/api-verbs/get';
import type { CommentListParameters } from '@/api-clients/opsflow/comment/schema/api-verbs/list';

export const commentKeys = {
list: (params: CommentListParameters) => ['comment', 'list', params] as const,
get: (idParam: CommentGetParameters['comment_id']) => ['comment', 'get', idParam] as const,
};
5 changes: 5 additions & 0 deletions apps/web/src/api-clients/opsflow/event/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { EventListParameters } from '@/api-clients/opsflow/event/schema/api-verbs/list';

export const eventKeys = {
list: (params: EventListParameters) => ['event', 'list', params] as const,
};
7 changes: 7 additions & 0 deletions apps/web/src/api-clients/opsflow/task-category/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { TaskCategoryGetParameters } from '@/api-clients/opsflow/task-category/schema/api-verbs/get';
import type { TaskCategoryListParameters } from '@/api-clients/opsflow/task-category/schema/api-verbs/list';

export const taskCategoryKeys = {
list: (params: TaskCategoryListParameters) => ['task-category', 'list', params] as const,
get: (idParam: TaskCategoryGetParameters['category_id']) => ['task-category', 'get', idParam] as const,
};
7 changes: 7 additions & 0 deletions apps/web/src/api-clients/opsflow/task-type/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { TaskTypeGetParameters } from '@/api-clients/opsflow/task-type/schema/api-verbs/get';
import type { TaskTypeListParameters } from '@/api-clients/opsflow/task-type/schema/api-verbs/list';

export const taskTypeKeys = {
list: (params: TaskTypeListParameters) => ['task-type', 'list', params] as const,
get: (idParam: TaskTypeGetParameters['task_type_id']) => ['task-type', 'get', idParam] as const,
};
7 changes: 7 additions & 0 deletions apps/web/src/api-clients/opsflow/task/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { TaskGetParameters } from '@/api-clients/opsflow/task/schema/api-verbs/get';
import type { TaskListParameters } from '@/api-clients/opsflow/task/schema/api-verbs/list';

export const taskKeys = {
list: (params: TaskListParameters) => ['task', 'list', params] as const,
get: (idParam: TaskGetParameters['task_id']) => ['task', 'get', idParam] as const,
};
5 changes: 4 additions & 1 deletion apps/web/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import VTooltip from 'v-tooltip';
import SpaceDesignSystem from '@cloudforet/mirinae';

import directive from '@/directives';
import { apiQueryClient } from '@/query/clients';
import { SpaceRouter } from '@/router';
import { i18n } from '@/translations';

Expand All @@ -19,6 +20,7 @@ import { siteInit } from '@/lib/site-initializer';

import App from './App.vue';


import '@/styles/style.pcss';
// eslint-disable-next-line
import '@cloudforet/mirinae/css/light-style.css';
Expand All @@ -30,7 +32,8 @@ Vue.use(Fragment.Plugin);
Vue.use(VTooltip, { defaultClass: 'p-tooltip', defaultBoundariesElement: document.body });
Vue.use(PortalVue);
Vue.use(PiniaVuePlugin);
Vue.use(VueQueryPlugin);
Vue.use(VueQueryPlugin, { queryClient: apiQueryClient });


directive(Vue);

Expand Down
Loading
Loading