diff --git a/dictation_client/src/api/api.ts b/dictation_client/src/api/api.ts index 265a030..429e763 100644 --- a/dictation_client/src/api/api.ts +++ b/dictation_client/src/api/api.ts @@ -2561,6 +2561,44 @@ export const AccountsApiAxiosParamCreator = function (configuration?: Configurat options: localVarRequestOptions, }; }, + /** + * + * @summary + * @param {number} id Worktypeの内部ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteWorktype: async (id: number, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('deleteWorktype', 'id', id) + const localVarPath = `/accounts/worktypes/{id}/delete` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, /** * * @summary @@ -3340,6 +3378,17 @@ export const AccountsApiFp = function(configuration?: Configuration) { const localVarAxiosArgs = await localVarAxiosParamCreator.deleteAccountAndData(deleteAccountRequest, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, + /** + * + * @summary + * @param {number} id Worktypeの内部ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteWorktype(id: number, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteWorktype(id, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, /** * * @summary @@ -3616,6 +3665,16 @@ export const AccountsApiFactory = function (configuration?: Configuration, baseP deleteAccountAndData(deleteAccountRequest: DeleteAccountRequest, options?: any): AxiosPromise { return localVarFp.deleteAccountAndData(deleteAccountRequest, options).then((request) => request(axios, basePath)); }, + /** + * + * @summary + * @param {number} id Worktypeの内部ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteWorktype(id: number, options?: any): AxiosPromise { + return localVarFp.deleteWorktype(id, options).then((request) => request(axios, basePath)); + }, /** * * @summary @@ -3888,6 +3947,18 @@ export class AccountsApi extends BaseAPI { return AccountsApiFp(this.configuration).deleteAccountAndData(deleteAccountRequest, options).then((request) => request(this.axios, this.basePath)); } + /** + * + * @summary + * @param {number} id Worktypeの内部ID + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AccountsApi + */ + public deleteWorktype(id: number, options?: AxiosRequestConfig) { + return AccountsApiFp(this.configuration).deleteWorktype(id, options).then((request) => request(this.axios, this.basePath)); + } + /** * * @summary diff --git a/dictation_client/src/common/errors/code.ts b/dictation_client/src/common/errors/code.ts index 1867e14..559a39e 100644 --- a/dictation_client/src/common/errors/code.ts +++ b/dictation_client/src/common/errors/code.ts @@ -56,6 +56,7 @@ export const errorCodes = [ "E011001", // ワークタイプ重複エラー "E011002", // ワークタイプ登録上限超過エラー "E011003", // ワークタイプ不在エラー + "E011004", // ワークタイプ使用中エラー "E013001", // ワークフローのAuthorIDとWorktypeIDのペア重複エラー "E013002", // ワークフロー不在エラー ] as const; diff --git a/dictation_client/src/features/workflow/worktype/operations.ts b/dictation_client/src/features/workflow/worktype/operations.ts index 0e45d33..fa173c1 100644 --- a/dictation_client/src/features/workflow/worktype/operations.ts +++ b/dictation_client/src/features/workflow/worktype/operations.ts @@ -342,3 +342,75 @@ export const updateActiveWorktypeAsync = createAsyncThunk< return thunkApi.rejectWithValue({ error }); } }); + +export const deleteWorktypeAsync = createAsyncThunk< + { + /* Empty Object */ + }, + { worktypeId: number }, + { + // rejectした時の返却値の型 + rejectValue: { + error: ErrorObject; + }; + } +>("workflow/deleteWorktypeAsync", async (args, thunkApi) => { + const { worktypeId } = args; + // apiのConfigurationを取得する + const { getState } = thunkApi; + const state = getState() as RootState; + const { configuration, accessToken } = state.auth; + const config = new Configuration(configuration); + const accountsApi = new AccountsApi(config); + + try { + await accountsApi.deleteWorktype(worktypeId, { + headers: { authorization: `Bearer ${accessToken}` }, + }); + + thunkApi.dispatch( + openSnackbar({ + level: "info", + message: getTranslationID("common.message.success"), + }) + ); + return {}; + } catch (e) { + // e ⇒ errorObjectに変換" + const error = createErrorObject(e); + + if (error.statusCode === 400) { + if (error.code === "E011003") { + // ワークタイプが削除済みの場合は成功扱いとする + thunkApi.dispatch( + openSnackbar({ + level: "info", + message: getTranslationID("common.message.success"), + }) + ); + return {}; + } + + if (error.code === "E011004") { + // ワークタイプがワークフローで使用中の場合は削除できない + thunkApi.dispatch( + openSnackbar({ + level: "error", + message: getTranslationID( + "worktypeIdSetting.message.worktypeInUseError" + ), + }) + ); + return {}; + } + } + + thunkApi.dispatch( + openSnackbar({ + level: "error", + message: getTranslationID("common.message.internalServerError"), + }) + ); + return thunkApi.rejectWithValue({ error }); + } +}); diff --git a/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx b/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx index 2532f5a..0f4c03f 100644 --- a/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx +++ b/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx @@ -1,7 +1,7 @@ import { UpdateTokenTimer } from "components/auth/updateTokenTimer"; import Footer from "components/footer"; import Header from "components/header"; -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { getTranslationID } from "translation"; import styles from "styles/app.module.scss"; import undo from "assets/images/undo.svg"; @@ -18,6 +18,7 @@ import { selectIsLoading, selectWorktypes, selectActiveWorktypeId, + deleteWorktypeAsync, } from "features/workflow/worktype"; import { AppDispatch } from "app/store"; import { AddWorktypeIdPopup } from "./addWorktypeIdPopup"; @@ -86,6 +87,23 @@ const WorktypeIdSettingPage: React.FC = (): JSX.Element => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedActiveWorktypeId]); + // 削除ボタン押下時の処理 + const onDeleteWoktype = useCallback( + async (worktypeId: number) => { + if ( + /* eslint-disable-next-line no-alert */ + !window.confirm(t(getTranslationID("common.message.dialogConfirm"))) + ) { + return; + } + const { meta } = await dispatch(deleteWorktypeAsync({ worktypeId })); + if (meta.requestStatus === "fulfilled") { + dispatch(listWorktypesAsync()); + } + }, + [dispatch, t] + ); + return ( <> {
  • + {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */} onDeleteWoktype(worktype.id)} > {t(getTranslationID("common.label.delete"))} diff --git a/dictation_client/src/translation/de.json b/dictation_client/src/translation/de.json index ef72d08..b4a3c73 100644 --- a/dictation_client/src/translation/de.json +++ b/dictation_client/src/translation/de.json @@ -429,7 +429,8 @@ "optionItemInvalidError": "(de)Default valueがDefaultに設定されている場合、Initial valueは入力が必須です。", "optionItemSaveFailedError": "(de)オプションアイテムの保存に失敗しました。画面を更新し、再度実行してください", "optionItemIncorrectError": "(de)入力されたItem labelまたはInitial valueがルールを満たしていません。下記のルールを満たす値を入力してください", - "updateActiveWorktypeFailedError": "(de)Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください" + "updateActiveWorktypeFailedError": "(de)Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください", + "worktypeInUseError": "(de)このWorktype IDはルーティングルールで使用されているため削除できません。" } }, "templateFilePage": { @@ -499,13 +500,14 @@ "backToTopPageLink": "(de)Back to TOP Page" } }, - "AgreeToUsePage": { + "acceptToUsePage": { "label": { "title": "(de)Terms of Use has updated. Please confirm again.", "linkOfEula": "(de)Click here to read the terms of use.", "linkOfDpa": "(de)Click here to read the terms of use.", "checkBoxForConsent": "(de)Yes, I agree to the terms of use.", - "forOdds": "(de)for ODDS." + "forOdds": "(de)for ODDS.", + "button": "(de)Continue" } } } \ No newline at end of file diff --git a/dictation_client/src/translation/en.json b/dictation_client/src/translation/en.json index 65d747b..c1b4b22 100644 --- a/dictation_client/src/translation/en.json +++ b/dictation_client/src/translation/en.json @@ -429,7 +429,8 @@ "optionItemInvalidError": "Default valueがDefaultに設定されている場合、Initial valueは入力が必須です。", "optionItemSaveFailedError": "オプションアイテムの保存に失敗しました。画面を更新し、再度実行してください", "optionItemIncorrectError": "入力されたItem labelまたはInitial valueがルールを満たしていません。下記のルールを満たす値を入力してください", - "updateActiveWorktypeFailedError": "Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください" + "updateActiveWorktypeFailedError": "Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください", + "worktypeInUseError": "このWorktype IDはルーティングルールで使用されているため削除できません。" } }, "templateFilePage": { @@ -499,13 +500,14 @@ "backToTopPageLink": "Back to TOP Page" } }, - "AgreeToUsePage": { + "acceptToUsePage": { "label": { "title": "Terms of Use has updated. Please confirm again.", "linkOfEula": "Click here to read the terms of use.", "linkOfDpa": "Click here to read the terms of use.", "checkBoxForConsent": "Yes, I agree to the terms of use.", - "forOdds": "for ODDS." + "forOdds": "for ODDS.", + "button": "Continue" } } } \ No newline at end of file diff --git a/dictation_client/src/translation/es.json b/dictation_client/src/translation/es.json index 1ec83f0..1b4d410 100644 --- a/dictation_client/src/translation/es.json +++ b/dictation_client/src/translation/es.json @@ -429,7 +429,8 @@ "optionItemInvalidError": "(es)Default valueがDefaultに設定されている場合、Initial valueは入力が必須です。", "optionItemSaveFailedError": "(es)オプションアイテムの保存に失敗しました。画面を更新し、再度実行してください", "optionItemIncorrectError": "(es)入力されたItem labelまたはInitial valueがルールを満たしていません。下記のルールを満たす値を入力してください", - "updateActiveWorktypeFailedError": "(es)Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください" + "updateActiveWorktypeFailedError": "(es)Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください", + "worktypeInUseError": "(es)このWorktype IDはルーティングルールで使用されているため削除できません。" } }, "templateFilePage": { @@ -499,13 +500,14 @@ "backToTopPageLink": "(es)Back to TOP Page" } }, - "AgreeToUsePage": { + "acceptToUsePage": { "label": { "title": "(es)Terms of Use has updated. Please confirm again.", "linkOfEula": "(es)Click here to read the terms of use.", "linkOfDpa": "(es)Click here to read the terms of use.", "checkBoxForConsent": "(es)Yes, I agree to the terms of use.", - "forOdds": "(es)for ODDS." + "forOdds": "(es)for ODDS.", + "button": "(es)Continue" } } } \ No newline at end of file diff --git a/dictation_client/src/translation/fr.json b/dictation_client/src/translation/fr.json index 845f73d..23b2a94 100644 --- a/dictation_client/src/translation/fr.json +++ b/dictation_client/src/translation/fr.json @@ -429,7 +429,8 @@ "optionItemInvalidError": "(fr)Default valueがDefaultに設定されている場合、Initial valueは入力が必須です。", "optionItemSaveFailedError": "(fr)オプションアイテムの保存に失敗しました。画面を更新し、再度実行してください", "optionItemIncorrectError": "(fr)入力されたItem labelまたはInitial valueがルールを満たしていません。下記のルールを満たす値を入力してください", - "updateActiveWorktypeFailedError": "(fr)Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください" + "updateActiveWorktypeFailedError": "(fr)Active WorktypeIDの保存に失敗しました。画面を更新し、再度実行してください", + "worktypeInUseError": "(fr)このWorktype IDはルーティングルールで使用されているため削除できません。" } }, "templateFilePage": { @@ -499,13 +500,14 @@ "backToTopPageLink": "(fr)Back to TOP Page" } }, - "AgreeToUsePage": { + "acceptToUsePage": { "label": { "title": "(fr)Terms of Use has updated. Please confirm again.", "linkOfEula": "(fr)Click here to read the terms of use.", "linkOfDpa": "(fr)Click here to read the terms of use.", "checkBoxForConsent": "(fr)Yes, I agree to the terms of use.", - "forOdds": "(fr)for ODDS." + "forOdds": "(fr)for ODDS.", + "button": "(fr)Continue" } } } \ No newline at end of file