diff --git a/dictation_client/src/features/workflow/template/constants.ts b/dictation_client/src/features/workflow/template/constants.ts new file mode 100644 index 0000000..358c4c8 --- /dev/null +++ b/dictation_client/src/features/workflow/template/constants.ts @@ -0,0 +1,2 @@ +// アップロード可能なファイルサイズの上限(MB) +export const UPLOAD_FILE_SIZE_LIMIT: number = 5 * 1024 * 1024; diff --git a/dictation_client/src/features/workflow/template/selectors.ts b/dictation_client/src/features/workflow/template/selectors.ts index 45c3ccd..4a8522e 100644 --- a/dictation_client/src/features/workflow/template/selectors.ts +++ b/dictation_client/src/features/workflow/template/selectors.ts @@ -1,7 +1,26 @@ import { RootState } from "app/store"; +import { UPLOAD_FILE_SIZE_LIMIT } from "./constants"; export const selectTemplates = (state: RootState) => state.template.domain.templates; export const selectIsLoading = (state: RootState) => state.template.apps.isLoading; + +export const selectUploadFile = (state: RootState) => + state.template.apps.uploadFile; + +export const selectUploadFileError = (state: RootState) => { + const { uploadFile } = state.template.apps; + + // 必須チェック + if (!uploadFile) { + return { hasErrorRequired: true, hasErrorFileSize: false }; + } + // ファイルサイズチェック(5MB) + if (uploadFile.size > UPLOAD_FILE_SIZE_LIMIT) { + return { hasErrorRequired: false, hasErrorFileSize: true }; + } + + return { hasErrorRequired: false, hasErrorFileSize: false }; +}; diff --git a/dictation_client/src/features/workflow/template/state.ts b/dictation_client/src/features/workflow/template/state.ts index 8805a9a..8fd0172 100644 --- a/dictation_client/src/features/workflow/template/state.ts +++ b/dictation_client/src/features/workflow/template/state.ts @@ -7,6 +7,7 @@ export interface TemplateState { export interface Apps { isLoading: boolean; + uploadFile?: File; } export interface Domain { diff --git a/dictation_client/src/features/workflow/template/templateSlice.ts b/dictation_client/src/features/workflow/template/templateSlice.ts index 9bbcab2..a333321 100644 --- a/dictation_client/src/features/workflow/template/templateSlice.ts +++ b/dictation_client/src/features/workflow/template/templateSlice.ts @@ -1,20 +1,27 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { PayloadAction, createSlice } from "@reduxjs/toolkit"; import { TemplateState } from "./state"; import { listTemplateAsync } from "./operations"; const initialState: TemplateState = { apps: { isLoading: false, + uploadFile: undefined, }, - domain: { - templates: undefined, - }, + domain: {}, }; export const templateSlice = createSlice({ name: "template", initialState, - reducers: {}, + reducers: { + cleanupTemplate: (state) => { + state.apps.uploadFile = initialState.apps.uploadFile; + }, + changeUploadFile: (state, action: PayloadAction<{ file: File }>) => { + const { file } = action.payload; + state.apps.uploadFile = file; + }, + }, extraReducers: (builder) => { builder.addCase(listTemplateAsync.pending, (state) => { state.apps.isLoading = true; @@ -31,4 +38,6 @@ export const templateSlice = createSlice({ }, }); +export const { changeUploadFile, cleanupTemplate } = templateSlice.actions; + export default templateSlice.reducer; diff --git a/dictation_client/src/pages/AccountPage/index.tsx b/dictation_client/src/pages/AccountPage/index.tsx index d407582..8b6c52a 100644 --- a/dictation_client/src/pages/AccountPage/index.tsx +++ b/dictation_client/src/pages/AccountPage/index.tsx @@ -127,7 +127,8 @@ const AccountPage: React.FC = (): JSX.Element => { {isTier5 && !viewInfo.account.parentAccountName && (
{ dispatch( changePrimaryAdministrator({ @@ -269,7 +271,8 @@ const AccountPage: React.FC = (): JSX.Element => {
+ +
+
+ +
+ + + + + ); +}; diff --git a/dictation_client/src/pages/TemplateFilePage/index.tsx b/dictation_client/src/pages/TemplateFilePage/index.tsx index f0783ab..fbd9e4e 100644 --- a/dictation_client/src/pages/TemplateFilePage/index.tsx +++ b/dictation_client/src/pages/TemplateFilePage/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { AppDispatch } from "app/store"; import Header from "components/header"; @@ -7,13 +7,14 @@ import { useTranslation } from "react-i18next"; import { getTranslationID } from "translation"; import undo from "assets/images/undo.svg"; import styles from "styles/app.module.scss"; -import { - listTemplateAsync, - selectIsLoading, - selectTemplates, -} from "features/workflow/template"; import addTemplate from "assets/images/template_add.svg"; import progress_activit from "assets/images/progress_activit.svg"; +import { + selectTemplates, + listTemplateAsync, + selectIsLoading, +} from "features/workflow/template"; +import { AddTemplateFilePopup } from "./addTemplateFilePopup"; export const TemplateFilePage: React.FC = () => { const dispatch: AppDispatch = useDispatch(); @@ -21,89 +22,106 @@ export const TemplateFilePage: React.FC = () => { const templates = useSelector(selectTemplates); const isLoading = useSelector(selectIsLoading); + // 追加Popupの表示制御 + const [isShowAddPopup, setIsShowAddPopup] = useState(false); + useEffect(() => { dispatch(listTemplateAsync()); }, [dispatch]); return ( -
-
- -
-
-
-

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

-

- {t(getTranslationID("templateFilePage.label.title"))} -

-
-
-
+ <> + { + setIsShowAddPopup(false); + }} + isOpen={isShowAddPopup} + /> +
+
+ +
- - - - - - - {templates?.map((template) => ( - - - - - ))} - {!isLoading && templates?.length === 0 && ( -

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

- )} - {isLoading && ( - Loading - )} -
- {t(getTranslationID("templateFilePage.label.fileName"))} - {/** empty th */}
{template.name} - -
+
+

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

+

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

+
-
-
-
+
+
+ + + + + + + {templates?.map((template) => ( + + + + + ))} + {!isLoading && templates?.length === 0 && ( +

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

+ )} + {isLoading && ( + Loading + )} +
+ {t(getTranslationID("templateFilePage.label.fileName"))} + {/** empty th */}
{template.name} + +
+
+
+ + + ); }; diff --git a/dictation_client/src/styles/app.module.scss.d.ts b/dictation_client/src/styles/app.module.scss.d.ts index 66481cb..1e7a4c3 100644 --- a/dictation_client/src/styles/app.module.scss.d.ts +++ b/dictation_client/src/styles/app.module.scss.d.ts @@ -22,6 +22,7 @@ declare const classNames: { readonly buttonText: "buttonText"; readonly formList: "formList"; readonly formTitle: "formTitle"; + readonly alignCenter: "alignCenter"; readonly overLine: "overLine"; readonly full: "full"; readonly hasbg: "hasbg"; @@ -38,10 +39,13 @@ declare const classNames: { readonly formError: "formError"; readonly formConfirm: "formConfirm"; readonly formSubmit: "formSubmit"; + readonly formButtonFul: "formButtonFul"; readonly formButton: "formButton"; + readonly formDelete: "formDelete"; readonly formBack: "formBack"; readonly formButtonTx: "formButtonTx"; readonly formDone: "formDone"; + readonly formTrash: "formTrash"; readonly listVertical: "listVertical"; readonly listHeader: "listHeader"; readonly boxFlex: "boxFlex"; @@ -109,6 +113,11 @@ declare const classNames: { readonly isDisable: "isDisable"; readonly icCheckCircle: "icCheckCircle"; readonly icInTable: "icInTable"; + readonly manage: "manage"; + readonly manageInfo: "manageInfo"; + readonly txNormal: "txNormal"; + readonly manageIcon: "manageIcon"; + readonly manageIconClose: "manageIconClose"; readonly history: "history"; readonly cardHistory: "cardHistory"; readonly partner: "partner"; @@ -116,6 +125,7 @@ declare const classNames: { readonly displayOptions: "displayOptions"; readonly tableFilter: "tableFilter"; readonly tableFilter2: "tableFilter2"; + readonly mnBack: "mnBack"; readonly txWsline: "txWsline"; readonly hidePri: "hidePri"; readonly opPri: "opPri"; @@ -175,6 +185,7 @@ declare const classNames: { readonly op9: "op9"; readonly hideO10: "hideO10"; readonly op10: "op10"; + readonly property: "property"; readonly formChange: "formChange"; readonly chooseMember: "chooseMember"; readonly holdMember: "holdMember"; @@ -184,7 +195,6 @@ declare const classNames: { readonly template: "template"; readonly worktype: "worktype"; readonly selectMenu: "selectMenu"; - readonly alignCenter: "alignCenter"; readonly alignLeft: "alignLeft"; readonly alignRight: "alignRight"; readonly floatNone: "floatNone"; @@ -206,9 +216,7 @@ declare const classNames: { readonly paddSide1: "paddSide1"; readonly paddSide2: "paddSide2"; readonly paddSide3: "paddSide3"; - readonly txNormal: "txNormal"; readonly txIcon: "txIcon"; readonly txWswrap: "txWswrap"; - readonly required: "required"; }; export = classNames; diff --git a/dictation_client/src/translation/de.json b/dictation_client/src/translation/de.json index 7b85134..525eaae 100644 --- a/dictation_client/src/translation/de.json +++ b/dictation_client/src/translation/de.json @@ -417,7 +417,12 @@ "label": { "title": "(de)Template List", "addTemplate": "(de)Add Template", - "fileName": "(de)Flie Name" + "fileName": "(de)Flie Name", + "chooseFile": "(de)Choose File", + "notFileChosen": "(de)- Not file chosen -", + "fileSizeTerms": "(de)Flie Name", + "fileSizeError": "(de)選択されたファイルのサイズが大きすぎます。サイズが?MB以下のファイルを選択してください。", + "fileEmptyError": "(de)ファイル選択は必須です。ファイルを選択してください。" } }, "partnerPage": { @@ -468,4 +473,4 @@ "cancelButton": "(de)Cancel" } } -} \ No newline at end of file +} diff --git a/dictation_client/src/translation/en.json b/dictation_client/src/translation/en.json index f5d924a..d7de671 100644 --- a/dictation_client/src/translation/en.json +++ b/dictation_client/src/translation/en.json @@ -417,7 +417,12 @@ "label": { "title": "Template List", "addTemplate": "Add Template", - "fileName": "Flie Name" + "fileName": "Flie Name", + "chooseFile": "Choose File", + "notFileChosen": "- Not file chosen -", + "fileSizeTerms": "Flie Name", + "fileSizeError": "選択されたファイルのサイズが大きすぎます。サイズが?MB以下のファイルを選択してください。", + "fileEmptyError": "ファイル選択は必須です。ファイルを選択してください。" } }, "partnerPage": { @@ -468,4 +473,4 @@ "cancelButton": "Cancel" } } -} \ No newline at end of file +} diff --git a/dictation_client/src/translation/es.json b/dictation_client/src/translation/es.json index ba1c0e7..09e2a44 100644 --- a/dictation_client/src/translation/es.json +++ b/dictation_client/src/translation/es.json @@ -417,7 +417,12 @@ "label": { "title": "(es)Template List", "addTemplate": "(es)Add Template", - "fileName": "(es)Flie Name" + "fileName": "(es)Flie Name", + "chooseFile": "(es)Choose File", + "notFileChosen": "(es)- Not file chosen -", + "fileSizeTerms": "(es)Flie Name", + "fileSizeError": "(es)選択されたファイルのサイズが大きすぎます。サイズが?MB以下のファイルを選択してください。", + "fileEmptyError": "(es)ファイル選択は必須です。ファイルを選択してください。" } }, "partnerPage": { @@ -468,4 +473,4 @@ "cancelButton": "(es)Cancel" } } -} \ No newline at end of file +} diff --git a/dictation_client/src/translation/fr.json b/dictation_client/src/translation/fr.json index 8dcafec..3cb2566 100644 --- a/dictation_client/src/translation/fr.json +++ b/dictation_client/src/translation/fr.json @@ -417,7 +417,12 @@ "label": { "title": "(fr)Template List", "addTemplate": "(fr)Add Template", - "fileName": "(fr)Flie Name" + "fileName": "(fr)Flie Name", + "chooseFile": "(fr)Choose File", + "notFileChosen": "(fr)- Not file chosen -", + "fileSizeTerms": "(fr)Flie Name", + "fileSizeError": "(fr)選択されたファイルのサイズが大きすぎます。サイズが?MB以下のファイルを選択してください。", + "fileEmptyError": "(fr)ファイル選択は必須です。ファイルを選択してください。" } }, "partnerPage": { @@ -468,4 +473,4 @@ "cancelButton": "(fr)Cancel" } } -} \ No newline at end of file +}