From 088e6afc856d55329af8fa39f2c12a3df8790f6b Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Tue, 3 Oct 2023 02:15:57 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20454:=20=E3=83=AF=E3=83=BC?= =?UTF-8?q?=E3=82=AF=E3=83=95=E3=83=AD=E3=83=BC=E4=B8=80=E8=A6=A7=E7=94=BB?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2735: ワークフロー一覧画面](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2735) - ワークフロー一覧画面のデザイン反映 - 多言語対応 - 一覧取得API呼び出し ## レビューポイント - デザイン反映に問題はないか - フォルダ構成はこれでよいか - workflow配下に直置き ## 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/Task2735?csf=1&web=1&e=IelNET ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば --- dictation_client/src/api/api.ts | 410 ++++++++++++++++++ dictation_client/src/app/store.ts | 2 + .../src/assets/images/download.svg | 10 + dictation_client/src/assets/images/exit.svg | 11 + .../src/assets/images/group_setting.svg | 25 ++ dictation_client/src/assets/images/logout.svg | 10 + .../src/assets/images/rule_add.svg | 12 + .../src/assets/images/template_setting.svg | 14 + .../src/assets/images/worktype_setting.svg | 17 + .../src/features/workflow/index.ts | 4 + .../src/features/workflow/operations.ts | 42 ++ .../src/features/workflow/selectors.ts | 7 + .../src/features/workflow/state.ts | 14 + .../src/features/workflow/workflowSlice.ts | 32 ++ .../src/pages/WorkflowPage/index.tsx | 183 ++++++-- dictation_client/src/translation/de.json | 11 +- dictation_client/src/translation/en.json | 11 +- dictation_client/src/translation/es.json | 11 +- dictation_client/src/translation/fr.json | 11 +- 19 files changed, 806 insertions(+), 31 deletions(-) create mode 100644 dictation_client/src/assets/images/download.svg create mode 100644 dictation_client/src/assets/images/exit.svg create mode 100644 dictation_client/src/assets/images/group_setting.svg create mode 100644 dictation_client/src/assets/images/logout.svg create mode 100644 dictation_client/src/assets/images/rule_add.svg create mode 100644 dictation_client/src/assets/images/template_setting.svg create mode 100644 dictation_client/src/assets/images/worktype_setting.svg create mode 100644 dictation_client/src/features/workflow/index.ts create mode 100644 dictation_client/src/features/workflow/operations.ts create mode 100644 dictation_client/src/features/workflow/selectors.ts create mode 100644 dictation_client/src/features/workflow/state.ts create mode 100644 dictation_client/src/features/workflow/workflowSlice.ts diff --git a/dictation_client/src/api/api.ts b/dictation_client/src/api/api.ts index eb4d4e2..36a1050 100644 --- a/dictation_client/src/api/api.ts +++ b/dictation_client/src/api/api.ts @@ -335,6 +335,25 @@ export interface AudioUploadLocationResponse { */ 'url': string; } +/** + * + * @export + * @interface Author + */ +export interface Author { + /** + * Authorユーザーの内部ID + * @type {number} + * @memberof Author + */ + 'id': number; + /** + * AuthorID + * @type {string} + * @memberof Author + */ + 'authorId': string; +} /** * * @export @@ -504,6 +523,37 @@ export interface CreateTypistGroupRequest { */ 'typistIds': Array; } +/** + * + * @export + * @interface CreateWorkflowsRequest + */ +export interface CreateWorkflowsRequest { + /** + * Authornの内部ID + * @type {number} + * @memberof CreateWorkflowsRequest + */ + 'authorId': number; + /** + * Worktypeの内部ID + * @type {number} + * @memberof CreateWorkflowsRequest + */ + 'worktypeId'?: number; + /** + * テンプレートの内部ID + * @type {number} + * @memberof CreateWorkflowsRequest + */ + 'templateId'?: number; + /** + * ルーティング候補のタイピストユーザー/タイピストグループ + * @type {Array} + * @memberof CreateWorkflowsRequest + */ + 'typists': Array; +} /** * * @export @@ -606,6 +656,19 @@ export interface GetAllocatableLicensesResponse { */ 'allocatableLicenses': Array; } +/** + * + * @export + * @interface GetAuthorsResponse + */ +export interface GetAuthorsResponse { + /** + * + * @type {Array} + * @memberof GetAuthorsResponse + */ + 'authors': Array; +} /** * * @export @@ -989,6 +1052,19 @@ export interface GetUsersResponse { */ 'users': Array; } +/** + * + * @export + * @interface GetWorkflowsResponse + */ +export interface GetWorkflowsResponse { + /** + * ワークフローの一覧 + * @type {Array} + * @memberof GetWorkflowsResponse + */ + 'workflows': Array; +} /** * * @export @@ -1963,6 +2039,100 @@ export interface User { */ 'licenseStatus': string; } +/** + * + * @export + * @interface Workflow + */ +export interface Workflow { + /** + * ワークフローの内部ID + * @type {number} + * @memberof Workflow + */ + 'id': number; + /** + * + * @type {Author} + * @memberof Workflow + */ + 'author': Author; + /** + * + * @type {WorkflowWorktype} + * @memberof Workflow + */ + 'worktype'?: WorkflowWorktype; + /** + * + * @type {WorkflowTemplate} + * @memberof Workflow + */ + 'template'?: WorkflowTemplate; + /** + * ルーティング候補のタイピストユーザー/タイピストグループ + * @type {Array} + * @memberof Workflow + */ + 'typists': Array; +} +/** + * + * @export + * @interface WorkflowTemplate + */ +export interface WorkflowTemplate { + /** + * テンプレートの内部ID + * @type {number} + * @memberof WorkflowTemplate + */ + 'id': number; + /** + * テンプレートのファイル名 + * @type {string} + * @memberof WorkflowTemplate + */ + 'fileName': string; +} +/** + * + * @export + * @interface WorkflowTypist + */ +export interface WorkflowTypist { + /** + * タイピストユーザーの内部ID + * @type {number} + * @memberof WorkflowTypist + */ + 'typistId'?: number; + /** + * タイピストグループの内部ID + * @type {number} + * @memberof WorkflowTypist + */ + 'typistGroupId'?: number; +} +/** + * + * @export + * @interface WorkflowWorktype + */ +export interface WorkflowWorktype { + /** + * Worktypeの内部ID + * @type {number} + * @memberof WorkflowWorktype + */ + 'id': number; + /** + * WorktypeID + * @type {string} + * @memberof WorkflowWorktype + */ + 'worktypeId': string; +} /** * * @export @@ -2271,6 +2441,40 @@ export const AccountsApiAxiosParamCreator = function (configuration?: Configurat options: localVarRequestOptions, }; }, + /** + * ログインしているユーザーのアカウント配下のAuthor一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAuthors: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/accounts/authors`; + // 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: 'GET', ...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 @@ -2980,6 +3184,16 @@ export const AccountsApiFp = function(configuration?: Configuration) { const localVarAxiosArgs = await localVarAxiosParamCreator.deleteAccount(deleteAccountRequest, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, + /** + * ログインしているユーザーのアカウント配下のAuthor一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getAuthors(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getAuthors(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, /** * * @summary @@ -3235,6 +3449,15 @@ export const AccountsApiFactory = function (configuration?: Configuration, baseP deleteAccount(deleteAccountRequest: DeleteAccountRequest, options?: any): AxiosPromise { return localVarFp.deleteAccount(deleteAccountRequest, options).then((request) => request(axios, basePath)); }, + /** + * ログインしているユーザーのアカウント配下のAuthor一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getAuthors(options?: any): AxiosPromise { + return localVarFp.getAuthors(options).then((request) => request(axios, basePath)); + }, /** * * @summary @@ -3488,6 +3711,17 @@ export class AccountsApi extends BaseAPI { return AccountsApiFp(this.configuration).deleteAccount(deleteAccountRequest, options).then((request) => request(this.axios, this.basePath)); } + /** + * ログインしているユーザーのアカウント配下のAuthor一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AccountsApi + */ + public getAuthors(options?: AxiosRequestConfig) { + return AccountsApiFp(this.configuration).getAuthors(options).then((request) => request(this.axios, this.basePath)); + } + /** * * @summary @@ -6481,3 +6715,179 @@ export class UsersApi extends BaseAPI { +/** + * WorkflowsApi - axios parameter creator + * @export + */ +export const WorkflowsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * アカウント内にワークフローを新規作成します + * @summary + * @param {CreateWorkflowsRequest} createWorkflowsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createWorkflows: async (createWorkflowsRequest: CreateWorkflowsRequest, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'createWorkflowsRequest' is not null or undefined + assertParamExists('createWorkflows', 'createWorkflowsRequest', createWorkflowsRequest) + const localVarPath = `/workflows`; + // 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(createWorkflowsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * アカウント内のワークフローの一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getWorkflows: async (options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/workflows`; + // 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: 'GET', ...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, + }; + }, + } +}; + +/** + * WorkflowsApi - functional programming interface + * @export + */ +export const WorkflowsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = WorkflowsApiAxiosParamCreator(configuration) + return { + /** + * アカウント内にワークフローを新規作成します + * @summary + * @param {CreateWorkflowsRequest} createWorkflowsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createWorkflows(createWorkflowsRequest: CreateWorkflowsRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createWorkflows(createWorkflowsRequest, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * アカウント内のワークフローの一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getWorkflows(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getWorkflows(options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * WorkflowsApi - factory interface + * @export + */ +export const WorkflowsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = WorkflowsApiFp(configuration) + return { + /** + * アカウント内にワークフローを新規作成します + * @summary + * @param {CreateWorkflowsRequest} createWorkflowsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createWorkflows(createWorkflowsRequest: CreateWorkflowsRequest, options?: any): AxiosPromise { + return localVarFp.createWorkflows(createWorkflowsRequest, options).then((request) => request(axios, basePath)); + }, + /** + * アカウント内のワークフローの一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getWorkflows(options?: any): AxiosPromise { + return localVarFp.getWorkflows(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * WorkflowsApi - object-oriented interface + * @export + * @class WorkflowsApi + * @extends {BaseAPI} + */ +export class WorkflowsApi extends BaseAPI { + /** + * アカウント内にワークフローを新規作成します + * @summary + * @param {CreateWorkflowsRequest} createWorkflowsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof WorkflowsApi + */ + public createWorkflows(createWorkflowsRequest: CreateWorkflowsRequest, options?: AxiosRequestConfig) { + return WorkflowsApiFp(this.configuration).createWorkflows(createWorkflowsRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * アカウント内のワークフローの一覧を取得します + * @summary + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof WorkflowsApi + */ + public getWorkflows(options?: AxiosRequestConfig) { + return WorkflowsApiFp(this.configuration).getWorkflows(options).then((request) => request(this.axios, this.basePath)); + } +} + + + diff --git a/dictation_client/src/app/store.ts b/dictation_client/src/app/store.ts index d42c776..e48a4ba 100644 --- a/dictation_client/src/app/store.ts +++ b/dictation_client/src/app/store.ts @@ -17,6 +17,7 @@ import typistGroup from "features/workflow/typistGroup/typistGroupSlice"; import worktype from "features/workflow/worktype/worktypeSlice"; import account from "features/account/accountSlice"; import template from "features/workflow/template/templateSlice"; +import workflow from "features/workflow/workflowSlice"; export const store = configureStore({ reducer: { @@ -38,6 +39,7 @@ export const store = configureStore({ worktype, account, template, + workflow, }, }); diff --git a/dictation_client/src/assets/images/download.svg b/dictation_client/src/assets/images/download.svg new file mode 100644 index 0000000..504fce3 --- /dev/null +++ b/dictation_client/src/assets/images/download.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/dictation_client/src/assets/images/exit.svg b/dictation_client/src/assets/images/exit.svg new file mode 100644 index 0000000..242dd28 --- /dev/null +++ b/dictation_client/src/assets/images/exit.svg @@ -0,0 +1,11 @@ + + + + + + diff --git a/dictation_client/src/assets/images/group_setting.svg b/dictation_client/src/assets/images/group_setting.svg new file mode 100644 index 0000000..b86f803 --- /dev/null +++ b/dictation_client/src/assets/images/group_setting.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/dictation_client/src/assets/images/logout.svg b/dictation_client/src/assets/images/logout.svg new file mode 100644 index 0000000..7cc7e86 --- /dev/null +++ b/dictation_client/src/assets/images/logout.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/dictation_client/src/assets/images/rule_add.svg b/dictation_client/src/assets/images/rule_add.svg new file mode 100644 index 0000000..4d4d6e6 --- /dev/null +++ b/dictation_client/src/assets/images/rule_add.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/dictation_client/src/assets/images/template_setting.svg b/dictation_client/src/assets/images/template_setting.svg new file mode 100644 index 0000000..54c8955 --- /dev/null +++ b/dictation_client/src/assets/images/template_setting.svg @@ -0,0 +1,14 @@ + + + + + + diff --git a/dictation_client/src/assets/images/worktype_setting.svg b/dictation_client/src/assets/images/worktype_setting.svg new file mode 100644 index 0000000..ad5cd24 --- /dev/null +++ b/dictation_client/src/assets/images/worktype_setting.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/dictation_client/src/features/workflow/index.ts b/dictation_client/src/features/workflow/index.ts new file mode 100644 index 0000000..460a995 --- /dev/null +++ b/dictation_client/src/features/workflow/index.ts @@ -0,0 +1,4 @@ +export * from "./workflowSlice"; +export * from "./state"; +export * from "./selectors"; +export * from "./operations"; diff --git a/dictation_client/src/features/workflow/operations.ts b/dictation_client/src/features/workflow/operations.ts new file mode 100644 index 0000000..41957aa --- /dev/null +++ b/dictation_client/src/features/workflow/operations.ts @@ -0,0 +1,42 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { Configuration, GetWorkflowsResponse, WorkflowsApi } from "api"; +import type { RootState } from "app/store"; +import { ErrorObject, createErrorObject } from "common/errors"; +import { openSnackbar } from "features/ui/uiSlice"; +import { getTranslationID } from "translation"; + +export const listWorkflowAsync = createAsyncThunk< + GetWorkflowsResponse, + void, + { + // rejectした時の返却値の型 + rejectValue: { + error: ErrorObject; + }; + } +>("workflow/listWorkflowAsync", async (args, thunkApi) => { + // apiのConfigurationを取得する + const { getState } = thunkApi; + const state = getState() as RootState; + const { configuration, accessToken } = state.auth; + const config = new Configuration(configuration); + const workflowsApi = new WorkflowsApi(config); + + try { + const { data } = await workflowsApi.getWorkflows({ + headers: { authorization: `Bearer ${accessToken}` }, + }); + + return data; + } 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/selectors.ts b/dictation_client/src/features/workflow/selectors.ts new file mode 100644 index 0000000..57745ed --- /dev/null +++ b/dictation_client/src/features/workflow/selectors.ts @@ -0,0 +1,7 @@ +import { RootState } from "app/store"; + +export const selectWorkflows = (state: RootState) => + state.workflow.domain.workflows; + +export const selectIsLoading = (state: RootState) => + state.workflow.apps.isLoading; diff --git a/dictation_client/src/features/workflow/state.ts b/dictation_client/src/features/workflow/state.ts new file mode 100644 index 0000000..6a9d838 --- /dev/null +++ b/dictation_client/src/features/workflow/state.ts @@ -0,0 +1,14 @@ +import { Workflow } from "api"; + +export interface WorkflowState { + apps: Apps; + domain: Domain; +} + +export interface Apps { + isLoading: boolean; +} + +export interface Domain { + workflows?: Workflow[]; +} diff --git a/dictation_client/src/features/workflow/workflowSlice.ts b/dictation_client/src/features/workflow/workflowSlice.ts new file mode 100644 index 0000000..dd94a79 --- /dev/null +++ b/dictation_client/src/features/workflow/workflowSlice.ts @@ -0,0 +1,32 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { WorkflowState } from "./state"; +import { listWorkflowAsync } from "./operations"; + +const initialState: WorkflowState = { + apps: { + isLoading: false, + }, + domain: {}, +}; + +export const workflowSlice = createSlice({ + name: "workflow", + initialState, + reducers: {}, + extraReducers: (builder) => { + builder.addCase(listWorkflowAsync.pending, (state) => { + state.apps.isLoading = true; + }); + builder.addCase(listWorkflowAsync.fulfilled, (state, action) => { + const { workflows } = action.payload; + + state.domain.workflows = workflows; + state.apps.isLoading = false; + }); + builder.addCase(listWorkflowAsync.rejected, (state) => { + state.apps.isLoading = false; + }); + }, +}); + +export default workflowSlice.reducer; diff --git a/dictation_client/src/pages/WorkflowPage/index.tsx b/dictation_client/src/pages/WorkflowPage/index.tsx index 0df685b..c7e8351 100644 --- a/dictation_client/src/pages/WorkflowPage/index.tsx +++ b/dictation_client/src/pages/WorkflowPage/index.tsx @@ -1,34 +1,163 @@ -import React from "react"; +import React, { useEffect } from "react"; import Header from "components/header"; import Footer from "components/footer"; import styles from "styles/app.module.scss"; import { UpdateTokenTimer } from "components/auth/updateTokenTimer"; +import ruleAddImg from "assets/images/rule_add.svg"; +import templateSettingImg from "assets/images/template_setting.svg"; +import worktypeSettingImg from "assets/images/worktype_setting.svg"; +import groupSettingImg from "assets/images/group_setting.svg"; +import { AppDispatch } from "app/store"; +import { useTranslation } from "react-i18next"; +import { useDispatch, useSelector } from "react-redux"; +import { listWorkflowAsync } from "features/workflow/operations"; +import { selectIsLoading, selectWorkflows } from "features/workflow"; +import progress_activit from "assets/images/progress_activit.svg"; +import { getTranslationID } from "translation"; -const WorkflowPage: React.FC = (): JSX.Element => ( - -); +const WorkflowPage: React.FC = (): JSX.Element => { + const dispatch: AppDispatch = useDispatch(); + const [t] = useTranslation(); + const workflows = useSelector(selectWorkflows); + const isLoading = useSelector(selectIsLoading); + + useEffect(() => { + dispatch(listWorkflowAsync()); + }, [dispatch]); + return ( +
+
+ +
+
+
+

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

+
+
+
+ + + + + + + + + + {workflows?.map((workflow) => ( + + + + + + + + + ))} +
{/** empty th */}{t(getTranslationID("workflowPage.label.authorID"))}{t(getTranslationID("workflowPage.label.worktype"))} + {t(getTranslationID("workflowPage.label.transcriptionist"))} + {t(getTranslationID("workflowPage.label.template"))}
+ + {workflow.author.authorId}{workflow.worktype?.worktypeId ?? "-"} + {workflow.typists.map((typist, i) => ( + <> + {typist.typistName} + {i !== workflow.typists.length - 1 &&
} + + ))} +
{workflow.template?.fileName ?? "-"}
+ {!isLoading && workflows?.length === 0 && ( +

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

+ )} + {isLoading && ( + Loading + )} +
+
+
+
+
+ ); +}; export default WorkflowPage; diff --git a/dictation_client/src/translation/de.json b/dictation_client/src/translation/de.json index 08a4c0f..2c89bc8 100644 --- a/dictation_client/src/translation/de.json +++ b/dictation_client/src/translation/de.json @@ -356,7 +356,16 @@ }, "workflowPage": { "label": { - "title": "Arbeitsablauf" + "title": "Arbeitsablauf", + "addRoutingRule": "(de)Add Routing Rule", + "templateSetting": "(de)Template Setting", + "worktypeIdSetting": "(de)WorktypeID Setting", + "typistGroupSetting": "(de)Transcriptionist Group Setting", + "authorID": "Autoren-ID", + "worktype": "Aufgabentypkennung", + "transcriptionist": "Transkriptionist", + "template": "(de)Template", + "editRule": "(de)Edit Rule" } }, "typistGroupSetting": { diff --git a/dictation_client/src/translation/en.json b/dictation_client/src/translation/en.json index 8db7771..b3ac4c8 100644 --- a/dictation_client/src/translation/en.json +++ b/dictation_client/src/translation/en.json @@ -356,7 +356,16 @@ }, "workflowPage": { "label": { - "title": "Workflow" + "title": "Workflow", + "addRoutingRule": "Add Routing Rule", + "templateSetting": "Template Setting", + "worktypeIdSetting": "WorktypeID Setting", + "typistGroupSetting": "Transcriptionist Group Setting", + "authorID": "Author ID", + "worktype": "Worktype ID", + "transcriptionist": "Transcriptionist", + "template": "Template", + "editRule": "Edit Rule" } }, "typistGroupSetting": { diff --git a/dictation_client/src/translation/es.json b/dictation_client/src/translation/es.json index d3c5ebb..fc13455 100644 --- a/dictation_client/src/translation/es.json +++ b/dictation_client/src/translation/es.json @@ -356,7 +356,16 @@ }, "workflowPage": { "label": { - "title": "flujo de trabajo" + "title": "flujo de trabajo", + "addRoutingRule": "(es)Add Routing Rule", + "templateSetting": "(es)Template Setting", + "worktypeIdSetting": "(es)WorktypeID Setting", + "typistGroupSetting": "(es)Transcriptionist Group Setting", + "authorID": "ID de autor", + "worktype": "ID de tipo de trabajo", + "transcriptionist": "Transcriptor", + "template": "(es)Template", + "editRule": "(es)Edit Rule" } }, "typistGroupSetting": { diff --git a/dictation_client/src/translation/fr.json b/dictation_client/src/translation/fr.json index f7f1676..ebc5dcd 100644 --- a/dictation_client/src/translation/fr.json +++ b/dictation_client/src/translation/fr.json @@ -356,7 +356,16 @@ }, "workflowPage": { "label": { - "title": "Flux de travail" + "title": "Flux de travail", + "addRoutingRule": "(fr)Add Routing Rule", + "templateSetting": "(fr)Template Setting", + "worktypeIdSetting": "(fr)WorktypeID Setting", + "typistGroupSetting": "(fr)Transcriptionist Group Setting", + "authorID": "Identifiant Auteur", + "worktype": "Identifiant du Type de travail", + "transcriptionist": "Transcriptionniste", + "template": "(fr)Template", + "editRule": "(fr)Edit Rule" } }, "typistGroupSetting": {