From f43e0f779ea16bc260271476ab15859d9a5ff523 Mon Sep 17 00:00:00 2001 From: "makabe.t" Date: Fri, 1 Sep 2023 06:42:58 +0000 Subject: [PATCH 01/14] =?UTF-8?q?Merged=20PR=20373:=20DB=E3=83=9E=E3=82=A4?= =?UTF-8?q?=E3=82=B0=E3=83=AC=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2515: DBマイグレーション](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2515) - オプションアイテムのテーブルを追加するマイグレーションファイルを追加しました。 ## レビューポイント - カラム項目は適切か ## UIの変更 - なし ## 動作確認状況 - ローカルで確認 - migrate up/down --- .../db/migrations/032-create_option_items.sql | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 dictation_server/db/migrations/032-create_option_items.sql diff --git a/dictation_server/db/migrations/032-create_option_items.sql b/dictation_server/db/migrations/032-create_option_items.sql new file mode 100644 index 0000000..a5a656a --- /dev/null +++ b/dictation_server/db/migrations/032-create_option_items.sql @@ -0,0 +1,15 @@ +-- +migrate Up +CREATE TABLE IF NOT EXISTS `option_items` ( + `id` BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT 'オプションアイテムID', + `worktype_id` BIGINT UNSIGNED NOT NULL COMMENT 'worktypeの内部ID', + `item_label` VARCHAR(50) NOT NULL COMMENT 'アイテムラベル', + `default_value_type` VARCHAR(16) NOT NULL COMMENT 'デフォルト値種別(Default/Blank/LastInput)', + `initial_value` VARCHAR(50) NOT NULL COMMENT 'オプションアイテム初期値', + `created_by` VARCHAR(255) COMMENT '作成者', + `created_at` TIMESTAMP DEFAULT now() COMMENT '作成時刻', + `updated_by` VARCHAR(255) COMMENT '更新者', + `updated_at` TIMESTAMP DEFAULT now() on UPDATE now() COMMENT '更新時刻' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; + +-- +migrate Down +DROP TABLE `option_items`; \ No newline at end of file From 7a453c80f89b5ddf3e24466ef863d9c5e49a4d19 Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Fri, 1 Sep 2023 07:27:36 +0000 Subject: [PATCH 02/14] =?UTF-8?q?Merged=20PR=20372:=20=E7=94=BB=E9=9D=A2?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=EF=BC=88WorktypeID=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E7=94=BB=E9=9D=A2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2506: 画面実装(WorktypeID設定画面)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2506) - WorktypeID設定画面を実装 - WorktypeID一覧を表示する - 各種ボタンを表示する - ActiveWorktypeIDのセレクトボックスを表示する - 言語切り替えの対応で同一の文言をcommonにまとめ、該当箇所を修正 ## レビューポイント - stateのdomain配下にあるAPIからの戻り値をOptionalにしたが問題ないか - 必須にすると画面初期表示時に「0件です」がちらつくため ## UIの変更 - 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/Task2506?csf=1&web=1&e=IHIC1Y ## 動作確認状況 - ローカルで確認 ## 補足 - Returnボタン以外のボタンの挙動はレビュー対象外 - Active WorkTypeIDの挙動はレビュー対象外 --- dictation_client/src/AppRouter.tsx | 5 + dictation_client/src/api/api.ts | 124 +++++++++++-- dictation_client/src/app/store.ts | 2 + .../src/assets/images/worktype_add.svg | 12 ++ .../src/features/workflow/worktype/index.ts | 4 + .../features/workflow/worktype/operations.ts | 45 +++++ .../features/workflow/worktype/selectors.ts | 7 + .../src/features/workflow/worktype/state.ts | 14 ++ .../workflow/worktype/worktypeSlice.ts | 31 ++++ .../changeTranscriptionistPopup.tsx | 2 +- .../pages/LicensePage/licenseOrderHistory.tsx | 2 +- .../src/pages/LicensePage/licenseSummary.tsx | 6 +- .../src/pages/LicensePage/partnerLicense.tsx | 4 +- .../addTypistGroupPopup.tsx | 2 +- .../editTypistGroupPopup.tsx | 2 +- .../pages/TypistGroupSettingPage/index.tsx | 8 +- .../src/pages/WorkTypeIdSettingPage/index.tsx | 170 ++++++++++++++++++ .../src/pages/WorkflowPage/index.tsx | 5 + dictation_client/src/translation/de.json | 26 +-- dictation_client/src/translation/en.json | 26 +-- dictation_client/src/translation/es.json | 26 +-- dictation_client/src/translation/fr.json | 26 +-- 22 files changed, 475 insertions(+), 74 deletions(-) create mode 100644 dictation_client/src/assets/images/worktype_add.svg create mode 100644 dictation_client/src/features/workflow/worktype/index.ts create mode 100644 dictation_client/src/features/workflow/worktype/operations.ts create mode 100644 dictation_client/src/features/workflow/worktype/selectors.ts create mode 100644 dictation_client/src/features/workflow/worktype/state.ts create mode 100644 dictation_client/src/features/workflow/worktype/worktypeSlice.ts create mode 100644 dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx diff --git a/dictation_client/src/AppRouter.tsx b/dictation_client/src/AppRouter.tsx index 08b7185..248c80b 100644 --- a/dictation_client/src/AppRouter.tsx +++ b/dictation_client/src/AppRouter.tsx @@ -18,6 +18,7 @@ import DictationPage from "pages/DictationPage"; import PartnerPage from "pages/PartnerPage"; import WorkflowPage from "pages/WorkflowPage"; import TypistGroupSettingPage from "pages/TypistGroupSettingPage"; +import WorktypeIdSettingPage from "pages/WorkTypeIdSettingPage"; const AppRouter: React.FC = () => ( @@ -66,6 +67,10 @@ const AppRouter: React.FC = () => ( path="/workflow/typist-group" element={} />} /> + } />} + /> } />} diff --git a/dictation_client/src/api/api.ts b/dictation_client/src/api/api.ts index e0430ca..429eb58 100644 --- a/dictation_client/src/api/api.ts +++ b/dictation_client/src/api/api.ts @@ -462,6 +462,25 @@ export interface CreateTypistGroupRequest { */ 'typistIds': Array; } +/** + * + * @export + * @interface CreateWorktypesRequest + */ +export interface CreateWorktypesRequest { + /** + * WorktypeID + * @type {string} + * @memberof CreateWorktypesRequest + */ + 'worktypeId': string; + /** + * Worktypeの説明 + * @type {string} + * @memberof CreateWorktypesRequest + */ + 'description'?: string; +} /** * * @export @@ -873,15 +892,15 @@ export interface GetUsersResponse { /** * * @export - * @interface GetWorkTypesResponse + * @interface GetWorktypesResponse */ -export interface GetWorkTypesResponse { +export interface GetWorktypesResponse { /** * - * @type {Array} - * @memberof GetWorkTypesResponse + * @type {Array} + * @memberof GetWorktypesResponse */ - 'workTypes': Array; + 'worktypes': Array; } /** * @@ -1609,25 +1628,25 @@ export interface User { /** * * @export - * @interface WorkType + * @interface Worktype */ -export interface WorkType { +export interface Worktype { /** - * WorkTypeのID + * WorktypeのID * @type {number} - * @memberof WorkType + * @memberof Worktype */ 'id': number; /** - * WorkTypeID + * WorktypeID * @type {string} - * @memberof WorkType + * @memberof Worktype */ - 'workTypeId': string; + 'worktypeId': string; /** - * WorkTypeの説明 + * Worktypeの説明 * @type {string} - * @memberof WorkType + * @memberof Worktype */ 'description'?: string; } @@ -1794,6 +1813,46 @@ export const AccountsApiAxiosParamCreator = function (configuration?: Configurat options: localVarRequestOptions, }; }, + /** + * + * @summary + * @param {CreateWorktypesRequest} createWorktypesRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createWorktype: async (createWorktypesRequest: CreateWorktypesRequest, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'createWorktypesRequest' is not null or undefined + assertParamExists('createWorktype', 'createWorktypesRequest', createWorktypesRequest) + const localVarPath = `/accounts/worktypes`; + // 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) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createWorktypesRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, /** * * @summary @@ -2256,6 +2315,17 @@ export const AccountsApiFp = function(configuration?: Configuration) { const localVarAxiosArgs = await localVarAxiosParamCreator.createTypistGroup(createTypistGroupRequest, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, + /** + * + * @summary + * @param {CreateWorktypesRequest} createWorktypesRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createWorktype(createWorktypesRequest: CreateWorktypesRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createWorktype(createWorktypesRequest, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, /** * * @summary @@ -2346,7 +2416,7 @@ export const AccountsApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getWorktypes(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + async getWorktypes(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { const localVarAxiosArgs = await localVarAxiosParamCreator.getWorktypes(options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, @@ -2423,6 +2493,16 @@ export const AccountsApiFactory = function (configuration?: Configuration, baseP createTypistGroup(createTypistGroupRequest: CreateTypistGroupRequest, options?: any): AxiosPromise { return localVarFp.createTypistGroup(createTypistGroupRequest, options).then((request) => request(axios, basePath)); }, + /** + * + * @summary + * @param {CreateWorktypesRequest} createWorktypesRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createWorktype(createWorktypesRequest: CreateWorktypesRequest, options?: any): AxiosPromise { + return localVarFp.createWorktype(createWorktypesRequest, options).then((request) => request(axios, basePath)); + }, /** * * @summary @@ -2505,7 +2585,7 @@ export const AccountsApiFactory = function (configuration?: Configuration, baseP * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getWorktypes(options?: any): AxiosPromise { + getWorktypes(options?: any): AxiosPromise { return localVarFp.getWorktypes(options).then((request) => request(axios, basePath)); }, /** @@ -2587,6 +2667,18 @@ export class AccountsApi extends BaseAPI { return AccountsApiFp(this.configuration).createTypistGroup(createTypistGroupRequest, options).then((request) => request(this.axios, this.basePath)); } + /** + * + * @summary + * @param {CreateWorktypesRequest} createWorktypesRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AccountsApi + */ + public createWorktype(createWorktypesRequest: CreateWorktypesRequest, options?: AxiosRequestConfig) { + return AccountsApiFp(this.configuration).createWorktype(createWorktypesRequest, options).then((request) => request(this.axios, this.basePath)); + } + /** * * @summary diff --git a/dictation_client/src/app/store.ts b/dictation_client/src/app/store.ts index 722801d..73c16f7 100644 --- a/dictation_client/src/app/store.ts +++ b/dictation_client/src/app/store.ts @@ -14,6 +14,7 @@ import dictation from "features/dictation/dictationSlice"; import partner from "features/partner/partnerSlice"; import licenseOrderHistory from "features/license/licenseOrderHistory/licenseOrderHistorySlice"; import typistGroup from "features/workflow/typistGroup/typistGroupSlice"; +import worktype from "features/workflow/worktype/worktypeSlice"; export const store = configureStore({ reducer: { @@ -32,6 +33,7 @@ export const store = configureStore({ dictation, partner, typistGroup, + worktype, }, }); diff --git a/dictation_client/src/assets/images/worktype_add.svg b/dictation_client/src/assets/images/worktype_add.svg new file mode 100644 index 0000000..a63ac00 --- /dev/null +++ b/dictation_client/src/assets/images/worktype_add.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/dictation_client/src/features/workflow/worktype/index.ts b/dictation_client/src/features/workflow/worktype/index.ts new file mode 100644 index 0000000..22036b3 --- /dev/null +++ b/dictation_client/src/features/workflow/worktype/index.ts @@ -0,0 +1,4 @@ +export * from "./worktypeSlice"; +export * from "./state"; +export * from "./selectors"; +export * from "./operations"; diff --git a/dictation_client/src/features/workflow/worktype/operations.ts b/dictation_client/src/features/workflow/worktype/operations.ts new file mode 100644 index 0000000..ad05f7c --- /dev/null +++ b/dictation_client/src/features/workflow/worktype/operations.ts @@ -0,0 +1,45 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import type { RootState } from "app/store"; +import { openSnackbar } from "features/ui/uiSlice"; +import { getTranslationID } from "translation"; +import { AccountsApi, GetWorktypesResponse } from "../../../api/api"; +import { Configuration } from "../../../api/configuration"; +import { ErrorObject, createErrorObject } from "../../../common/errors"; + +export const listWorktypesAsync = createAsyncThunk< + GetWorktypesResponse, + void, + { + // rejectした時の返却値の型 + rejectValue: { + error: ErrorObject; + }; + } +>("workflow/listWorktypesAsync", 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); + + try { + const worktypes = ( + await accountsApi.getWorktypes({ + headers: { authorization: `Bearer ${accessToken}` }, + }) + ).data; + + return worktypes; + } catch (e) { + // e ⇒ errorObjectに変換" + const error = createErrorObject(e); + thunkApi.dispatch( + openSnackbar({ + level: "error", + message: getTranslationID("common.message.internalServerError"), + }) + ); + return thunkApi.rejectWithValue({ error }); + } +}); diff --git a/dictation_client/src/features/workflow/worktype/selectors.ts b/dictation_client/src/features/workflow/worktype/selectors.ts new file mode 100644 index 0000000..343d665 --- /dev/null +++ b/dictation_client/src/features/workflow/worktype/selectors.ts @@ -0,0 +1,7 @@ +import { RootState } from "app/store"; + +export const selectWorktypes = (state: RootState) => + state.worktype.domain.worktypes; + +export const selectIsLoading = (state: RootState) => + state.worktype.apps.isLoading; diff --git a/dictation_client/src/features/workflow/worktype/state.ts b/dictation_client/src/features/workflow/worktype/state.ts new file mode 100644 index 0000000..365b7b7 --- /dev/null +++ b/dictation_client/src/features/workflow/worktype/state.ts @@ -0,0 +1,14 @@ +import { Worktype } from "api"; + +export interface WorktypeState { + apps: Apps; + domain: Domain; +} + +export interface Apps { + isLoading: boolean; +} + +export interface Domain { + worktypes?: Worktype[]; +} diff --git a/dictation_client/src/features/workflow/worktype/worktypeSlice.ts b/dictation_client/src/features/workflow/worktype/worktypeSlice.ts new file mode 100644 index 0000000..624f3bd --- /dev/null +++ b/dictation_client/src/features/workflow/worktype/worktypeSlice.ts @@ -0,0 +1,31 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { WorktypeState } from "./state"; +import { listWorktypesAsync } from "./operations"; + +const initialState: WorktypeState = { + apps: { + isLoading: false, + }, + domain: {}, +}; + +export const worktypeSlice = createSlice({ + name: "worktype", + initialState, + reducers: {}, + extraReducers: (builder) => { + builder.addCase(listWorktypesAsync.pending, (state) => { + state.apps.isLoading = true; + }); + builder.addCase(listWorktypesAsync.fulfilled, (state, action) => { + const { worktypes } = action.payload; + state.domain.worktypes = worktypes; + state.apps.isLoading = false; + }); + builder.addCase(listWorktypesAsync.rejected, (state) => { + state.apps.isLoading = false; + }); + }, +}); + +export default worktypeSlice.reducer; diff --git a/dictation_client/src/pages/DictationPage/changeTranscriptionistPopup.tsx b/dictation_client/src/pages/DictationPage/changeTranscriptionistPopup.tsx index e13e8dd..98d6b38 100644 --- a/dictation_client/src/pages/DictationPage/changeTranscriptionistPopup.tsx +++ b/dictation_client/src/pages/DictationPage/changeTranscriptionistPopup.tsx @@ -185,7 +185,7 @@ export const ChangeTranscriptionistPopup: React.FC< = ( onClick={returnGui} > - {t(getTranslationID("orderHistoriesPage.label.return"))} + {t(getTranslationID("common.label.return"))} diff --git a/dictation_client/src/pages/LicensePage/licenseSummary.tsx b/dictation_client/src/pages/LicensePage/licenseSummary.tsx index 202e968..1744105 100644 --- a/dictation_client/src/pages/LicensePage/licenseSummary.tsx +++ b/dictation_client/src/pages/LicensePage/licenseSummary.tsx @@ -126,11 +126,7 @@ export const LicenseSummary: React.FC = ( alt="" className={styles.menuIcon} /> - {t( - getTranslationID( - "partnerLicense.label.returnButton" - ) - )} + {t(getTranslationID("common.label.return"))} )} diff --git a/dictation_client/src/pages/LicensePage/partnerLicense.tsx b/dictation_client/src/pages/LicensePage/partnerLicense.tsx index b6653da..c93501d 100644 --- a/dictation_client/src/pages/LicensePage/partnerLicense.tsx +++ b/dictation_client/src/pages/LicensePage/partnerLicense.tsx @@ -277,9 +277,7 @@ const PartnerLicense: React.FC = (): JSX.Element => { alt="" className={styles.menuIcon} /> - {t( - getTranslationID("partnerLicense.label.returnButton") - )} + {t(getTranslationID("common.label.return"))} )} diff --git a/dictation_client/src/pages/TypistGroupSettingPage/addTypistGroupPopup.tsx b/dictation_client/src/pages/TypistGroupSettingPage/addTypistGroupPopup.tsx index 484522b..12000af 100644 --- a/dictation_client/src/pages/TypistGroupSettingPage/addTypistGroupPopup.tsx +++ b/dictation_client/src/pages/TypistGroupSettingPage/addTypistGroupPopup.tsx @@ -190,7 +190,7 @@ export const AddTypistGroupPopup: React.FC = ( diff --git a/dictation_client/src/pages/TypistGroupSettingPage/editTypistGroupPopup.tsx b/dictation_client/src/pages/TypistGroupSettingPage/editTypistGroupPopup.tsx index a20c6c7..faf85d4 100644 --- a/dictation_client/src/pages/TypistGroupSettingPage/editTypistGroupPopup.tsx +++ b/dictation_client/src/pages/TypistGroupSettingPage/editTypistGroupPopup.tsx @@ -184,7 +184,7 @@ export const EditTypistGroupPopup: React.FC = ( diff --git a/dictation_client/src/pages/TypistGroupSettingPage/index.tsx b/dictation_client/src/pages/TypistGroupSettingPage/index.tsx index 2d17ff1..6b1ff06 100644 --- a/dictation_client/src/pages/TypistGroupSettingPage/index.tsx +++ b/dictation_client/src/pages/TypistGroupSettingPage/index.tsx @@ -83,7 +83,7 @@ const TypistGroupSettingPage: React.FC = (): JSX.Element => { className={`${styles.menuLink} ${styles.isActive}`} > - {t(getTranslationID("typistGroupSetting.label.return"))} + {t(getTranslationID("common.label.return"))}
  • @@ -127,11 +127,7 @@ const TypistGroupSettingPage: React.FC = (): JSX.Element => { onEditPopupOpen(group.id); }} > - {t( - getTranslationID( - "typistGroupSetting.label.edit" - ) - )} + {t(getTranslationID("common.label.edit"))}
  • diff --git a/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx b/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx new file mode 100644 index 0000000..2a77caf --- /dev/null +++ b/dictation_client/src/pages/WorkTypeIdSettingPage/index.tsx @@ -0,0 +1,170 @@ +import { UpdateTokenTimer } from "components/auth/updateTokenTimer"; +import Footer from "components/footer"; +import Header from "components/header"; +import React, { useEffect, useState } from "react"; +import { getTranslationID } from "translation"; +import styles from "styles/app.module.scss"; +import undo from "assets/images/undo.svg"; +import worktype_add from "assets/images/worktype_add.svg"; +import progress_activit from "assets/images/progress_activit.svg"; +import { useTranslation } from "react-i18next"; +import { useDispatch, useSelector } from "react-redux"; +import { + listWorktypesAsync, + selectIsLoading, + selectWorktypes, +} from "features/workflow/worktype"; +import { AppDispatch } from "app/store"; + +const WorktypeIdSettingPage: React.FC = (): JSX.Element => { + const dispatch: AppDispatch = useDispatch(); + const [t] = useTranslation(); + const isLoading = useSelector(selectIsLoading); + const worktypes = useSelector(selectWorktypes); + const [selectedRow, setSelectedRow] = useState(NaN); + useEffect(() => { + dispatch(listWorktypesAsync()); + }, [dispatch]); + + return ( +
    +
    + +
    +
    +
    +

    + {t(getTranslationID("workflowPage.label.title"))} +

    +

    + {t(getTranslationID("worktypeIdSetting.label.title"))} +

    +
    +
    +
    + + + + + + + + {worktypes?.map((worktype) => ( + { + setSelectedRow(worktype.id); + }} + onMouseLeave={() => { + setSelectedRow(NaN); + }} + > + + + + + ))} +
    + {t(getTranslationID("worktypeIdSetting.label.worktypeId"))} + + {t(getTranslationID("worktypeIdSetting.label.description"))} + {/** empty th */}
    {worktype.worktypeId}{worktype.description} + +
    + {!isLoading && worktypes?.length === 0 && ( +

    + {t(getTranslationID("common.message.listEmpty"))} +

    + )} + {isLoading && ( + Loading + )} +
    +
    +
    +
    +
    +
    + ); +}; + +export default WorktypeIdSettingPage; diff --git a/dictation_client/src/pages/WorkflowPage/index.tsx b/dictation_client/src/pages/WorkflowPage/index.tsx index e817a00..6d57be9 100644 --- a/dictation_client/src/pages/WorkflowPage/index.tsx +++ b/dictation_client/src/pages/WorkflowPage/index.tsx @@ -15,6 +15,11 @@ const WorkflowPage: React.FC = (): JSX.Element => ( Transcriptionist Group Setting + + + Worktype ID Setting + +