From b5ecd6de151871740a1385e77ef66d1e45377924 Mon Sep 17 00:00:00 2001 From: "makabe.t" Date: Fri, 15 Sep 2023 08:28:18 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20410:=20=E7=94=BB=E9=9D=A2?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=EF=BC=88ActiveWorktypeID=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=82=BB=E3=83=AC=E3=82=AF=E3=83=88=E3=83=9C=E3=83=83=E3=82=AF?= =?UTF-8?q?=E3=82=B9=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2623: 画面実装(ActiveWorktypeID設定セレクトボックス)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2623) - WorktypeID設定画面でのActiveWorktypeID選択処理を実装しました。 ## レビューポイント - WorkTypeIDの変更時の処理に問題はないか - 画面の表示に問題はないか ## UIの変更 - [Task2623](https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88/Task2623?csf=1&web=1&e=sUPTbC) ## 動作確認状況 - ローカルで確認 --- dictation_client/src/api/api.ts | 16 ++---- .../features/workflow/worktype/operations.ts | 52 +++++++++++++++++++ .../features/workflow/worktype/selectors.ts | 3 ++ .../src/features/workflow/worktype/state.ts | 1 + .../workflow/worktype/worktypeSlice.ts | 16 +++++- .../src/pages/PartnerPage/index.tsx | 1 - .../src/pages/WorkTypeIdSettingPage/index.tsx | 39 +++++++++++++- dictation_client/src/translation/de.json | 29 ++++++++++- dictation_client/src/translation/en.json | 29 ++++++++++- dictation_client/src/translation/es.json | 29 ++++++++++- dictation_client/src/translation/fr.json | 29 ++++++++++- 11 files changed, 220 insertions(+), 24 deletions(-) diff --git a/dictation_client/src/api/api.ts b/dictation_client/src/api/api.ts index f5d0b72..aed73de 100644 --- a/dictation_client/src/api/api.ts +++ b/dictation_client/src/api/api.ts @@ -824,7 +824,7 @@ export interface GetRelationsResponse { * @type {string} * @memberof GetRelationsResponse */ - 'encryptionPassword': string | null; + 'encryptionPassword'?: string; /** * アカウントがデフォルトで利用するWorkTypeID(アカウントに紐づくWorkTypeIDから一つ指定。activeWorktypeがなければ空文字を返却する) * @type {string} @@ -969,7 +969,7 @@ export interface GetWorktypesResponse { * @type {number} * @memberof GetWorktypesResponse */ - 'acrive'?: number; + 'active'?: number; } /** * @@ -1307,12 +1307,6 @@ export interface PostUpdateUserRequest { * @interface PostWorktypeOptionItem */ export interface PostWorktypeOptionItem { - /** - * - * @type {number} - * @memberof PostWorktypeOptionItem - */ - 'id': number; /** * * @type {string} @@ -1682,7 +1676,7 @@ export interface UpdateAccountInfoRequest { * @type {number} * @memberof UpdateAccountInfoRequest */ - 'parentAccountId': number; + 'parentAccountId'?: number; /** * 代行操作許可 * @type {boolean} @@ -1694,13 +1688,13 @@ export interface UpdateAccountInfoRequest { * @type {number} * @memberof UpdateAccountInfoRequest */ - 'primaryAdminUserId': number; + 'primaryAdminUserId'?: number; /** * セカンダリ管理者ID * @type {number} * @memberof UpdateAccountInfoRequest */ - 'secondryAdminUserId': number; + 'secondryAdminUserId'?: number; } /** * diff --git a/dictation_client/src/features/workflow/worktype/operations.ts b/dictation_client/src/features/workflow/worktype/operations.ts index 1875d48..6cbd133 100644 --- a/dictation_client/src/features/workflow/worktype/operations.ts +++ b/dictation_client/src/features/workflow/worktype/operations.ts @@ -284,3 +284,55 @@ export const editOptionItemsAsync = createAsyncThunk< return thunkApi.rejectWithValue({ error }); } }); + +export const updateActiveWorktypeAsync = createAsyncThunk< + { + // return empty + }, + { id?: number | undefined }, + { + // rejectした時の返却値の型 + rejectValue: { + error: ErrorObject; + }; + } +>("workflow/updateActiveWorktypeAsync", async (args, thunkApi) => { + // 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); + const { id } = args; + + try { + await accountsApi.activeWorktype( + { id }, + { + headers: { authorization: `Bearer ${accessToken}` }, + } + ); + + return {}; + } catch (e) { + // e ⇒ errorObjectに変換" + const error = createErrorObject(e); + + let errorMessage = getTranslationID("common.message.internalServerError"); + + // ActiveWorktypeの保存に失敗した場合 + if (error.code === "E011003") { + errorMessage = getTranslationID( + "worktypeIdSetting.message.updateActiveWorktypeFailedError" + ); + } + + thunkApi.dispatch( + openSnackbar({ + level: "error", + message: errorMessage, + }) + ); + return thunkApi.rejectWithValue({ error }); + } +}); diff --git a/dictation_client/src/features/workflow/worktype/selectors.ts b/dictation_client/src/features/workflow/worktype/selectors.ts index 1f4aabc..bdd6bc1 100644 --- a/dictation_client/src/features/workflow/worktype/selectors.ts +++ b/dictation_client/src/features/workflow/worktype/selectors.ts @@ -70,3 +70,6 @@ export const selectHasErrorOptionItems = (state: RootState) => { // isOptionItemsLoadingを取得する export const selectIsOptionItemsLoading = (state: RootState) => state.worktype.apps.isOptionItemsLoading; + +export const selectActiveWorktypeId = (state: RootState) => + state.worktype.apps.activeWorktypeId; diff --git a/dictation_client/src/features/workflow/worktype/state.ts b/dictation_client/src/features/workflow/worktype/state.ts index 0475ab5..3acbae2 100644 --- a/dictation_client/src/features/workflow/worktype/state.ts +++ b/dictation_client/src/features/workflow/worktype/state.ts @@ -15,6 +15,7 @@ export interface Apps { worktypeId: string; description?: string; optionItems?: OptionItem[]; + activeWorktypeId?: number | undefined; } export interface Domain { diff --git a/dictation_client/src/features/workflow/worktype/worktypeSlice.ts b/dictation_client/src/features/workflow/worktype/worktypeSlice.ts index 833aa27..224e7e3 100644 --- a/dictation_client/src/features/workflow/worktype/worktypeSlice.ts +++ b/dictation_client/src/features/workflow/worktype/worktypeSlice.ts @@ -6,6 +6,7 @@ import { editWorktypeAsync, getOptionItemsAsync, listWorktypesAsync, + updateActiveWorktypeAsync, } from "./operations"; import { OptionItem, isOptionItemDefaultValueType } from "./types"; import { OPTION_ITEMS_DEFAULT_VALUE_TYPE } from "./constants"; @@ -20,6 +21,7 @@ const initialState: WorktypeState = { worktypeId: "", description: undefined, optionItems: undefined, + activeWorktypeId: undefined, }, domain: {}, }; @@ -82,9 +84,10 @@ export const worktypeSlice = createSlice({ state.apps.isLoading = true; }); builder.addCase(listWorktypesAsync.fulfilled, (state, action) => { - // TODO:Active WorktypeIDも取得する - const { worktypes } = action.payload; + const { worktypes, active } = action.payload; + state.domain.worktypes = worktypes; + state.apps.activeWorktypeId = active; state.apps.isLoading = false; }); builder.addCase(listWorktypesAsync.rejected, (state) => { @@ -137,6 +140,15 @@ export const worktypeSlice = createSlice({ builder.addCase(editOptionItemsAsync.rejected, (state) => { state.apps.isOptionItemsLoading = false; }); + builder.addCase(updateActiveWorktypeAsync.pending, (state) => { + state.apps.isLoading = true; + }); + builder.addCase(updateActiveWorktypeAsync.fulfilled, (state) => { + state.apps.isLoading = false; + }); + builder.addCase(updateActiveWorktypeAsync.rejected, (state) => { + state.apps.isLoading = false; + }); }, }); export const { diff --git a/dictation_client/src/pages/PartnerPage/index.tsx b/dictation_client/src/pages/PartnerPage/index.tsx index 617015b..38adaca 100644 --- a/dictation_client/src/pages/PartnerPage/index.tsx +++ b/dictation_client/src/pages/PartnerPage/index.tsx @@ -24,7 +24,6 @@ import personAdd from "../../assets/images/person_add.svg"; import { TIERS } from "../../components/auth/constants"; import { AddPartnerAccountPopup } from "./addPartnerAccountPopup"; import checkFill from "../../assets/images/check_fill.svg"; -import checkOutline from "../../assets/images/check_outline.svg"; const PartnerPage: React.FC = (): JSX.Element => { const dispatch: AppDispatch = useDispatch(); diff --git a/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx b/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx index d33fa1b..4fa599c 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"; @@ -14,8 +14,10 @@ import { changeWorktypeId, changeDescription, listWorktypesAsync, + updateActiveWorktypeAsync, selectIsLoading, selectWorktypes, + selectActiveWorktypeId, } from "features/workflow/worktype"; import { AppDispatch } from "app/store"; import { AddWorktypeIdPopup } from "./addWorktypeIdPopup"; @@ -27,6 +29,8 @@ const WorktypeIdSettingPage: React.FC = (): JSX.Element => { const [t] = useTranslation(); const isLoading = useSelector(selectIsLoading); const worktypes = useSelector(selectWorktypes); + const activeWorktypeId = useSelector(selectActiveWorktypeId); + const [selectedRow, setSelectedRow] = useState(NaN); // 追加Popupの表示制御 const [isShowAddPopup, setIsShowAddPopup] = useState(false); @@ -34,10 +38,34 @@ const WorktypeIdSettingPage: React.FC = (): JSX.Element => { const [isShowEditPopup, setIsShowEditPopup] = useState(false); const [isShowEditOptionItemPopup, setIsShowEditOptionItemPopup] = useState(false); + useEffect(() => { dispatch(listWorktypesAsync()); }, [dispatch]); + const onChangeActiveWorktype = useCallback( + async (e: React.ChangeEvent) => { + // ダイアログ確認 + if ( + // eslint-disable-next-line no-alert + !window.confirm(t(getTranslationID("common.message.dialogConfirm"))) + ) { + return; + } + const { value } = e.target; + const active = value === "" ? undefined : Number(value); + + const { meta } = await dispatch( + updateActiveWorktypeAsync({ id: active }) + ); + + if (meta.requestStatus === "fulfilled") { + dispatch(listWorktypesAsync()); + } + }, + [dispatch, t] + ); + return ( <> { "worktypeIdSetting.label.activeWorktypeId" ) )}:`} - + {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */} +