diff --git a/apps/web/src/api-clients/opsflow/_types/task-field-type.ts b/apps/web/src/api-clients/opsflow/_types/task-field-type.ts index 1cb2a8e12a..ee7c81085b 100644 --- a/apps/web/src/api-clients/opsflow/_types/task-field-type.ts +++ b/apps/web/src/api-clients/opsflow/_types/task-field-type.ts @@ -17,7 +17,8 @@ export interface TaskFieldOptions { // union of all task field options } /* task field options by type */ -interface TextTaskFieldOptions { +export interface TextTaskFieldOptions { + description?: string; example?: string; max_length?: number; } diff --git a/apps/web/src/api-clients/opsflow/task-category/composables/use-task-category-api.ts b/apps/web/src/api-clients/opsflow/task-category/composables/use-task-category-api.ts index e69de29bb2..0ddeca22a7 100644 --- a/apps/web/src/api-clients/opsflow/task-category/composables/use-task-category-api.ts +++ b/apps/web/src/api-clients/opsflow/task-category/composables/use-task-category-api.ts @@ -0,0 +1,55 @@ +import type { ComputedRef } from 'vue'; + +import type { QueryKey } from '@tanstack/vue-query'; + +import { SpaceConnector } from '@cloudforet/core-lib/space-connector'; + +import { useAPIQueryKey } from '@/api-clients/_common/composables/use-query-key'; +import type { ListResponse } from '@/api-clients/_common/schema/api-verbs/list'; +import type { TaskCategoryCreateParameters } from '@/api-clients/opsflow/task-category/schema/api-verbs/create'; +import type { TaskCategoryDeleteParameters } from '@/api-clients/opsflow/task-category/schema/api-verbs/delete'; +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'; +import type { TaskCategoryUpdateParameters } from '@/api-clients/opsflow/task-category/schema/api-verbs/update'; +import type { TaskCategoryModel } from '@/api-clients/opsflow/task-category/schema/model'; + +interface UseTaskCategoryApiReturn { + taskCategoryQueryKey: ComputedRef; + taskCategoryListQueryKey: ComputedRef; + taskCategoryAPI: { + create: (params: TaskCategoryCreateParameters) => Promise; + update: (params: TaskCategoryUpdateParameters) => Promise; + delete: (params: TaskCategoryDeleteParameters) => Promise; + get: (params: TaskCategoryGetParameters) => Promise; + list: (params: TaskCategoryListParameters) => Promise>; + } +} + +export const useTaskCategoryApi = (): UseTaskCategoryApiReturn => { + const taskCategoryQueryKey = useAPIQueryKey('opsflow/task-category/get'); + const taskCategoryListQueryKey = useAPIQueryKey('opsflow/task-category/list'); + + const actions = { + async create(params: TaskCategoryCreateParameters) { + return SpaceConnector.clientV2.opsflow.taskCategory.create(params); + }, + async update(params: TaskCategoryUpdateParameters) { + return SpaceConnector.clientV2.opsflow.taskCategory.update(params); + }, + async delete(params: TaskCategoryDeleteParameters) { + return SpaceConnector.clientV2.opsflow.taskCategory.delete(params); + }, + async get(params: TaskCategoryGetParameters) { + return SpaceConnector.clientV2.opsflow.taskCategory.get(params); + }, + async list(params: TaskCategoryListParameters) { + return SpaceConnector.clientV2.opsflow.taskCategory.list>(params); + }, + }; + + return { + taskCategoryQueryKey, + taskCategoryListQueryKey, + taskCategoryAPI: actions, + }; +}; diff --git a/apps/web/src/api-clients/opsflow/task-type/composables/use-task-type-api.ts b/apps/web/src/api-clients/opsflow/task-type/composables/use-task-type-api.ts index e69de29bb2..e0bf5089b4 100644 --- a/apps/web/src/api-clients/opsflow/task-type/composables/use-task-type-api.ts +++ b/apps/web/src/api-clients/opsflow/task-type/composables/use-task-type-api.ts @@ -0,0 +1,60 @@ +import type { ComputedRef } from 'vue'; + +import type { QueryKey } from '@tanstack/vue-query'; + +import { SpaceConnector } from '@cloudforet/core-lib/space-connector'; + +import { useAPIQueryKey } from '@/api-clients/_common/composables/use-query-key'; +import type { ListResponse } from '@/api-clients/_common/schema/api-verbs/list'; +import type { TaskTypeCreateParameters } from '@/api-clients/opsflow/task-type/schema/api-verbs/create'; +import type { TaskTypeDeleteParameters } from '@/api-clients/opsflow/task-type/schema/api-verbs/delete'; +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'; +import type { TaskTypeUpdateParameters } from '@/api-clients/opsflow/task-type/schema/api-verbs/update'; +import type { TaskTypeUpdateFieldsParameters } from '@/api-clients/opsflow/task-type/schema/api-verbs/update-fields'; +import type { TaskTypeModel } from '@/api-clients/opsflow/task-type/schema/model'; + +interface UseTaskTypeApiReturn { + taskTypeQueryKey: ComputedRef; + taskTypeListQueryKey: ComputedRef; + taskTypeAPI: { + create: (params: TaskTypeCreateParameters) => Promise; + update: (params: TaskTypeUpdateParameters) => Promise; + delete: (params: TaskTypeDeleteParameters) => Promise; + get: (params: TaskTypeGetParameters) => Promise; + list: (params: TaskTypeListParameters) => Promise>; + updateFields: (params: TaskTypeUpdateFieldsParameters) => Promise; + } +} + +export const useTaskTypeApi = (): UseTaskTypeApiReturn => { + const taskTypeQueryKey = useAPIQueryKey('opsflow/task-type/get'); + const taskTypeListQueryKey = useAPIQueryKey('opsflow/task-type/list'); + + const actions = { + async create(params: TaskTypeCreateParameters) { + return SpaceConnector.clientV2.opsflow.taskType.create(params); + }, + async update(params: TaskTypeUpdateParameters) { + return SpaceConnector.clientV2.opsflow.taskType.update(params); + }, + async delete(params: TaskTypeDeleteParameters) { + return SpaceConnector.clientV2.opsflow.taskType.delete(params); + }, + async get(params: TaskTypeGetParameters) { + return SpaceConnector.clientV2.opsflow.taskType.get(params); + }, + async list(params: TaskTypeListParameters) { + return SpaceConnector.clientV2.opsflow.taskType.list>(params); + }, + async updateFields(params: TaskTypeUpdateFieldsParameters) { + return SpaceConnector.clientV2.opsflow.taskType.updateFields(params); + }, + }; + + return { + taskTypeQueryKey, + taskTypeListQueryKey, + taskTypeAPI: actions, + }; +}; diff --git a/apps/web/src/api-clients/opsflow/task/composables/use-task-api.ts b/apps/web/src/api-clients/opsflow/task/composables/use-task-api.ts index e69de29bb2..e60c0f83de 100644 --- a/apps/web/src/api-clients/opsflow/task/composables/use-task-api.ts +++ b/apps/web/src/api-clients/opsflow/task/composables/use-task-api.ts @@ -0,0 +1,70 @@ +import type { ComputedRef } from 'vue'; + +import type { QueryKey } from '@tanstack/vue-query'; + +import { SpaceConnector } from '@cloudforet/core-lib/space-connector'; + +import { useAPIQueryKey } from '@/api-clients/_common/composables/use-query-key'; +import type { ListResponse } from '@/api-clients/_common/schema/api-verbs/list'; +import type { TaskChangeAssigneeParameters } from '@/api-clients/opsflow/task/schema/api-verbs/change-assignee'; +import type { TaskChangeStatusParameters } from '@/api-clients/opsflow/task/schema/api-verbs/change-status'; +import type { TaskCreateParameters } from '@/api-clients/opsflow/task/schema/api-verbs/create'; +import type { TaskDeleteParameters } from '@/api-clients/opsflow/task/schema/api-verbs/delete'; +import type { TaskGetParameters } from '@/api-clients/opsflow/task/schema/api-verbs/get'; +import type { TaskListParameters } from '@/api-clients/opsflow/task/schema/api-verbs/list'; +import type { TaskUpdateParameters } from '@/api-clients/opsflow/task/schema/api-verbs/update'; +import type { TaskUpdateDescriptionParameters } from '@/api-clients/opsflow/task/schema/api-verbs/update-description'; +import type { TaskModel } from '@/api-clients/opsflow/task/schema/model'; + +interface UseTaskApiReturn { + taskQueryKey: ComputedRef; + taskListQueryKey: ComputedRef; + taskAPI: { + create: (params: TaskCreateParameters) => Promise; + update: (params: TaskUpdateParameters) => Promise; + delete: (params: TaskDeleteParameters) => Promise; + get: (params: TaskGetParameters) => Promise; + list: (params: TaskListParameters) => Promise>; + changeAssignee: (params: TaskChangeAssigneeParameters) => Promise; + changeStatus: (params: TaskChangeStatusParameters) => Promise; + updateDescription: (params: TaskUpdateDescriptionParameters) => Promise; + } +} + +export const useTaskApi = (): UseTaskApiReturn => { + const taskQueryKey = useAPIQueryKey('opsflow/task/get'); + const taskListQueryKey = useAPIQueryKey('opsflow/task/list'); + + const actions = { + async create(params: TaskCreateParameters) { + return SpaceConnector.clientV2.opsflow.task.create(params); + }, + async update(params: TaskUpdateParameters) { + return SpaceConnector.clientV2.opsflow.task.update(params); + }, + async delete(params: TaskDeleteParameters) { + return SpaceConnector.clientV2.opsflow.task.delete(params); + }, + async get(params: TaskGetParameters) { + return SpaceConnector.clientV2.opsflow.task.get(params); + }, + async list(params: TaskListParameters) { + return SpaceConnector.clientV2.opsflow.task.list>(params); + }, + async changeAssignee(params: TaskChangeAssigneeParameters) { + return SpaceConnector.clientV2.opsflow.task.changeAssignee(params); + }, + async changeStatus(params: TaskChangeStatusParameters) { + return SpaceConnector.clientV2.opsflow.task.changeStatus(params); + }, + async updateDescription(params: TaskUpdateDescriptionParameters) { + return SpaceConnector.clientV2.opsflow.task.updateDescription(params); + }, + }; + + return { + taskQueryKey, + taskListQueryKey, + taskAPI: actions, + }; +}; diff --git a/apps/web/src/common/components/editor/text-editor-nodes.pcss b/apps/web/src/common/components/editor/text-editor-nodes.pcss index 8602905579..a39d91c52a 100644 --- a/apps/web/src/common/components/editor/text-editor-nodes.pcss +++ b/apps/web/src/common/components/editor/text-editor-nodes.pcss @@ -157,6 +157,7 @@ @apply bg-gray-100 rounded-lg; margin-top: 0.75rem; padding: 0.5rem 1rem; + white-space: pre-wrap; > code { font-family: $font-code; font-size: 0.875rem; diff --git a/apps/web/src/services/ops-flow/components/BoardTaskNameField.vue b/apps/web/src/services/ops-flow/components/BoardTaskNameField.vue index 125cbdc1ed..5a7a2d92e4 100644 --- a/apps/web/src/services/ops-flow/components/BoardTaskNameField.vue +++ b/apps/web/src/services/ops-flow/components/BoardTaskNameField.vue @@ -25,9 +25,11 @@ const props = defineProps<{ taskId: props.taskId, }, }" + class="leading-lg" :highlight="!props.linkNewTab" :action-icon="props.linkNewTab ? 'internal-link' : 'none'" :new-tab="props.linkNewTab" + line-height="1.25" /> diff --git a/apps/web/src/services/ops-flow/components/BoardTaskTable.vue b/apps/web/src/services/ops-flow/components/BoardTaskTable.vue index b16db8fe1b..c0be3b96cd 100644 --- a/apps/web/src/services/ops-flow/components/BoardTaskTable.vue +++ b/apps/web/src/services/ops-flow/components/BoardTaskTable.vue @@ -1,10 +1,14 @@ @@ -85,25 +105,23 @@ onBeforeUnmount(() => { theme-color="alert" :header-title="headerTitle" :size="deletable ? 'sm' : 'md'" - :loading="loading" - :loading-backdrop="taskManagementPageState.loadingAssociatedTasksToCategory" + :is-loading="isDeleting" + :loading-backdrop="isLoading" @confirm="handleConfirm" @close="handleCloseOrCancel" @cancel="handleCloseOrCancel" @closed="handleClosed" > diff --git a/apps/web/src/services/ops-flow/components/TaskContentBaseForm.vue b/apps/web/src/services/ops-flow/components/TaskContentBaseForm.vue index 898a900faa..7d346da2b5 100644 --- a/apps/web/src/services/ops-flow/components/TaskContentBaseForm.vue +++ b/apps/web/src/services/ops-flow/components/TaskContentBaseForm.vue @@ -10,6 +10,7 @@ import type { SelectDropdownMenuItem } from '@cloudforet/mirinae/types/controls/ import type { TaskCategoryModel } from '@/api-clients/opsflow/task-category/schema/model'; import type { TaskTypeModel } from '@/api-clients/opsflow/task-type/schema/model'; +import { useTaskApi } from '@/api-clients/opsflow/task/composables/use-task-api'; import type { TaskModel } from '@/api-clients/opsflow/task/schema/model'; import type { TaskStatusType } from '@/api-clients/opsflow/task/schema/type'; import { i18n } from '@/translations'; @@ -23,7 +24,6 @@ import ErrorHandler from '@/common/composables/error/errorHandler'; import { useFormValidator } from '@/common/composables/form-validator'; import { useCategoryField } from '@/services/ops-flow/composables/use-category-field'; -import { useTaskAPI } from '@/services/ops-flow/composables/use-task-api'; import { useTaskStatusField } from '@/services/ops-flow/composables/use-task-status-field'; import { useTaskTypeField } from '@/services/ops-flow/composables/use-task-type-field'; import { TASK_STATUS_LABELS } from '@/services/ops-flow/constants/task-status-label-constant'; @@ -71,6 +71,10 @@ const handleUpdateSelectedCategory = (items: SelectDropdownMenuItem[]) => { } initRelatedFieldsByCategorySelection(category); }; +const taskCategoryDesciprion = computed(() => { + if (!taskContentFormGetters.currentCategory) return ''; + return taskContentFormGetters.currentCategory.description; +}); /* task type */ const { @@ -96,9 +100,13 @@ const handleUpdateSelectedTaskType = async (items: SelectDropdownMenuItem[]) => initRelatedFieldsByTaskTypeSelection(category, taskType); } }; +const taskTypeDescription = computed(() => { + if (!taskContentFormState.currentTaskType) return ''; + return taskContentFormState.currentTaskType.description; +}); /* status */ -const taskAPI = useTaskAPI(); +const { taskAPI } = useTaskApi(); const { selectedStatusItems, taskStatusValidator, @@ -114,7 +122,10 @@ const changeStatus = async (statusId: string) => { if (!taskContentFormState.originTask) { throw new Error('Origin task is not defined'); } - await taskAPI.changeStatus(taskContentFormState.originTask.task_id, statusId); + await taskAPI.changeStatus({ + task_id: taskContentFormState.originTask.task_id, + status_id: statusId, + }); showSuccessMessage(i18n.t('OPSFLOW.ALT_S_UPDATE_TARGET', { target: i18n.t('OPSFLOW.STATUS') }), ''); } catch (e) { ErrorHandler.handleRequestError(e, i18n.t('OPSFLOW.ALT_E_UPDATE_TARGET', { target: i18n.t('OPSFLOW.STATUS') })); @@ -272,50 +283,57 @@ createModeInitWatchStop = watch([() => taskContentFormState.currentCategoryId, (