Merged PR 365: 画面実装(TypistGroup編集ポップアップ&TypistGroup設定画面)
## 概要 [Task2458: 画面実装(TypistGroup編集ポップアップ&TypistGroup設定画面)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2458) - タイピストグループ編集Popup作成 - Popupを呼び出す処理を追加 - 実行ボタンを「Save」に統一 - タスク一覧にも同様のボタンがあったので一緒に修正 ## レビューポイント - Popupを呼び出すときに選択したTypistGroupのIdを渡すようにしているが問題ないか - 引数として渡した方がわかりやすいと思ったのでこの実装にしました - Popupの項目をクリーンアップするタイミングをPopupが閉じたときに統一したが問題ないか ## 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/Task2458?csf=1&web=1&e=urD3Fa ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば
This commit is contained in:
parent
bba69651fe
commit
e82f66e32a
@ -2,6 +2,6 @@
|
||||
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
|
||||
"spaces": 2,
|
||||
"generator-cli": {
|
||||
"version": "6.6.0"
|
||||
"version": "7.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
6.6.0
|
||||
7.0.0
|
||||
File diff suppressed because it is too large
Load Diff
@ -144,7 +144,7 @@ export const toPathString = function (url: URL) {
|
||||
*/
|
||||
export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) {
|
||||
return <T = unknown, R = AxiosResponse<T>>(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs = {...axiosArgs.options, url: (configuration?.basePath || basePath) + axiosArgs.url};
|
||||
const axiosRequestArgs = {...axiosArgs.options, url: (configuration?.basePath || axios.defaults.baseURL || basePath) + axiosArgs.url};
|
||||
return axios.request<T, R>(axiosRequestArgs);
|
||||
};
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@ import {
|
||||
GetTypistGroupsResponse,
|
||||
GetTypistsResponse,
|
||||
CreateTypistGroupRequest,
|
||||
Typist,
|
||||
TypistGroup,
|
||||
} from "../../../api/api";
|
||||
import { Configuration } from "../../../api/configuration";
|
||||
import { ErrorObject, createErrorObject } from "../../../common/errors";
|
||||
@ -119,7 +121,124 @@ export const createTypistGroupAsync = createAsyncThunk<
|
||||
|
||||
const message =
|
||||
error.statusCode === 400
|
||||
? getTranslationID("typistGroupSetting.message.groupAddFailedError")
|
||||
? getTranslationID("typistGroupSetting.message.groupSaveFailedError")
|
||||
: getTranslationID("common.message.internalServerError");
|
||||
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message,
|
||||
})
|
||||
);
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
});
|
||||
|
||||
export const getTypistGroupAsync = createAsyncThunk<
|
||||
{
|
||||
typists: Typist[];
|
||||
typistGroup: TypistGroup;
|
||||
selectedTypistIds: number[];
|
||||
},
|
||||
{ typistGroupId: number },
|
||||
{
|
||||
// rejectした時の返却値の型
|
||||
rejectValue: {
|
||||
error: ErrorObject;
|
||||
};
|
||||
}
|
||||
>("workflow/getTypistGroupAsync", async (args, thunkApi) => {
|
||||
const { typistGroupId } = 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 {
|
||||
// タイピスト取得処理が別にあるが、storeの状態を意識せずに処理を行うためにここで取得する
|
||||
const { typists } = (
|
||||
await accountsApi.getTypists({
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
})
|
||||
).data;
|
||||
const { typistGroupName, typistIds } = (
|
||||
await accountsApi.getTypistGroup(typistGroupId, {
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
})
|
||||
).data;
|
||||
return {
|
||||
typists,
|
||||
typistGroup: { id: typistGroupId, name: typistGroupName },
|
||||
selectedTypistIds: typistIds,
|
||||
};
|
||||
} catch (e) {
|
||||
// e ⇒ errorObjectに変換"
|
||||
const error = createErrorObject(e);
|
||||
|
||||
const message = getTranslationID("common.message.internalServerError");
|
||||
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message,
|
||||
})
|
||||
);
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
});
|
||||
|
||||
export const updateTypistGroupAsync = createAsyncThunk<
|
||||
{
|
||||
/* Empty Object */
|
||||
},
|
||||
void,
|
||||
{
|
||||
// rejectした時の返却値の型
|
||||
rejectValue: {
|
||||
error: ErrorObject;
|
||||
};
|
||||
}
|
||||
>("workflow/updateTypistGroupAsync", async (args, thunkApi) => {
|
||||
// apiのConfigurationを取得する
|
||||
const { getState } = thunkApi;
|
||||
const state = getState() as RootState;
|
||||
const { configuration, accessToken } = state.auth;
|
||||
const { updateTypistGroupId, selectedTypists, groupName } =
|
||||
state.typistGroup.apps;
|
||||
const config = new Configuration(configuration);
|
||||
const accountsApi = new AccountsApi(config);
|
||||
if (!updateTypistGroupId) {
|
||||
throw new Error("updateTypistGroupId is undefined.");
|
||||
}
|
||||
|
||||
try {
|
||||
await accountsApi.updateTypistGroup(
|
||||
updateTypistGroupId,
|
||||
{
|
||||
typistGroupName: groupName,
|
||||
typistIds: selectedTypists.map((x) => x.id),
|
||||
},
|
||||
{
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
}
|
||||
);
|
||||
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "info",
|
||||
message: getTranslationID("common.message.success"),
|
||||
})
|
||||
);
|
||||
return {};
|
||||
} catch (e) {
|
||||
// e ⇒ errorObjectに変換"
|
||||
const error = createErrorObject(e);
|
||||
|
||||
const message =
|
||||
error.statusCode === 400
|
||||
? getTranslationID("typistGroupSetting.message.groupSaveFailedError")
|
||||
: getTranslationID("common.message.internalServerError");
|
||||
|
||||
thunkApi.dispatch(
|
||||
|
||||
@ -9,6 +9,7 @@ export interface Apps {
|
||||
isLoading: boolean;
|
||||
selectedTypists: Typist[];
|
||||
groupName: string;
|
||||
updateTypistGroupId?: number;
|
||||
}
|
||||
|
||||
export interface Domain {
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
||||
import { Typist } from "api";
|
||||
import { TypistGroupState } from "./state";
|
||||
import { listTypistGroupsAsync, listTypistsAsync } from "./operations";
|
||||
import {
|
||||
getTypistGroupAsync,
|
||||
listTypistGroupsAsync,
|
||||
listTypistsAsync,
|
||||
updateTypistGroupAsync,
|
||||
} from "./operations";
|
||||
|
||||
const initialState: TypistGroupState = {
|
||||
apps: {
|
||||
@ -19,9 +24,11 @@ export const typistGroupSlice = createSlice({
|
||||
name: "typistGroup",
|
||||
initialState,
|
||||
reducers: {
|
||||
cleanupAddCroup: (state) => {
|
||||
cleanupTypistGroup: (state) => {
|
||||
state.apps.groupName = "";
|
||||
state.apps.selectedTypists = [];
|
||||
state.apps.updateTypistGroupId = undefined;
|
||||
state.domain.typists = [];
|
||||
},
|
||||
addSelectedTypist: (state, action: PayloadAction<{ typist: Typist }>) => {
|
||||
const { typist } = action.payload;
|
||||
@ -70,11 +77,40 @@ export const typistGroupSlice = createSlice({
|
||||
builder.addCase(listTypistsAsync.rejected, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(getTypistGroupAsync.rejected, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(getTypistGroupAsync.pending, (state) => {
|
||||
state.apps.isLoading = true;
|
||||
});
|
||||
builder.addCase(getTypistGroupAsync.fulfilled, (state, action) => {
|
||||
const { typistGroup, selectedTypistIds, typists } = action.payload;
|
||||
// 対象タイピストグループのID・名前を設定
|
||||
state.apps.updateTypistGroupId = typistGroup.id;
|
||||
state.apps.groupName = typistGroup.name;
|
||||
|
||||
// 選択済みのタイピストを設定
|
||||
state.apps.selectedTypists = typists
|
||||
.filter((x) => selectedTypistIds.includes(x.id))
|
||||
.sort((a, b) => a.id - b.id);
|
||||
// すべてのタイピストを設定
|
||||
state.domain.typists = typists;
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(updateTypistGroupAsync.pending, (state) => {
|
||||
state.apps.isLoading = true;
|
||||
});
|
||||
builder.addCase(updateTypistGroupAsync.fulfilled, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(updateTypistGroupAsync.rejected, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
cleanupAddCroup,
|
||||
cleanupTypistGroup,
|
||||
addSelectedTypist,
|
||||
removeSelectedTypist,
|
||||
changeGroupName,
|
||||
|
||||
@ -8,13 +8,13 @@ import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
addSelectedTypist,
|
||||
listTypistsAsync,
|
||||
cleanupAddCroup,
|
||||
removeSelectedTypist,
|
||||
selectPoolTypists,
|
||||
selectSelectedTypists,
|
||||
selectGroupName,
|
||||
changeGroupName,
|
||||
selectAddGroupErrors,
|
||||
cleanupTypistGroup,
|
||||
} from "features/workflow/typistGroup";
|
||||
import {
|
||||
createTypistGroupAsync,
|
||||
@ -47,7 +47,6 @@ export const AddTypistGroupPopup: React.FC<AddTypistGroupPopupProps> = (
|
||||
// 開閉時のみ実行
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
dispatch(cleanupAddCroup());
|
||||
dispatch(listTypistsAsync());
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@ -57,7 +56,8 @@ export const AddTypistGroupPopup: React.FC<AddTypistGroupPopupProps> = (
|
||||
const closePopup = useCallback(() => {
|
||||
setIsPushAddButton(false);
|
||||
onClose(false);
|
||||
}, [onClose]);
|
||||
dispatch(cleanupTypistGroup());
|
||||
}, [dispatch, onClose]);
|
||||
|
||||
// グループ追加を実行
|
||||
const addTypistGroup = useCallback(async () => {
|
||||
@ -190,7 +190,7 @@ export const AddTypistGroupPopup: React.FC<AddTypistGroupPopupProps> = (
|
||||
<input
|
||||
type="button"
|
||||
name="submit"
|
||||
value={t(getTranslationID("typistGroupSetting.label.addGroup"))}
|
||||
value={t(getTranslationID("typistGroupSetting.label.save"))}
|
||||
className={`${styles.formSubmit} ${styles.marginBtm1} ${styles.isActive}`}
|
||||
onClick={addTypistGroup}
|
||||
/>
|
||||
|
||||
@ -0,0 +1,197 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import styles from "styles/app.module.scss";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Typist } from "api";
|
||||
import { AppDispatch } from "app/store";
|
||||
import { getTranslationID } from "translation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
addSelectedTypist,
|
||||
cleanupTypistGroup,
|
||||
removeSelectedTypist,
|
||||
selectPoolTypists,
|
||||
selectSelectedTypists,
|
||||
selectGroupName,
|
||||
changeGroupName,
|
||||
selectAddGroupErrors,
|
||||
} from "features/workflow/typistGroup";
|
||||
import {
|
||||
getTypistGroupAsync,
|
||||
listTypistGroupsAsync,
|
||||
updateTypistGroupAsync,
|
||||
} from "features/workflow/typistGroup/operations";
|
||||
import { openSnackbar } from "features/ui";
|
||||
import close from "../../assets/images/close.svg";
|
||||
|
||||
interface EditTypistGroupPopupProps {
|
||||
onClose: (isChanged: boolean) => void;
|
||||
isOpen: boolean;
|
||||
typistGroupId: number;
|
||||
}
|
||||
|
||||
export const EditTypistGroupPopup: React.FC<EditTypistGroupPopupProps> = (
|
||||
props
|
||||
) => {
|
||||
const { onClose, isOpen, typistGroupId } = props;
|
||||
const dispatch: AppDispatch = useDispatch();
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [isPushEditButton, setIsPushEditButton] = useState<boolean>(false);
|
||||
|
||||
const poolTypists = useSelector(selectPoolTypists);
|
||||
const selectedTypists = useSelector(selectSelectedTypists);
|
||||
const groupName = useSelector(selectGroupName);
|
||||
|
||||
const { hasErrorEmptyGroupName, hasErrorSelectedTypistsEmpty } =
|
||||
useSelector(selectAddGroupErrors);
|
||||
|
||||
// 表示時のみ実行
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
dispatch(getTypistGroupAsync({ typistGroupId }));
|
||||
}
|
||||
}, [dispatch, isOpen, typistGroupId]);
|
||||
|
||||
// ポップアップを閉じる処理
|
||||
const closePopup = useCallback(() => {
|
||||
setIsPushEditButton(false);
|
||||
onClose(false);
|
||||
dispatch(cleanupTypistGroup());
|
||||
}, [dispatch, onClose]);
|
||||
|
||||
// グループ更新を実行
|
||||
const editTypistGroup = useCallback(async () => {
|
||||
setIsPushEditButton(true);
|
||||
// 入力チェック
|
||||
if (hasErrorEmptyGroupName || hasErrorSelectedTypistsEmpty) {
|
||||
if (hasErrorSelectedTypistsEmpty) {
|
||||
dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message: t(
|
||||
getTranslationID(
|
||||
"typistGroupSetting.message.selectedTypistEmptyError"
|
||||
)
|
||||
),
|
||||
})
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// グループ追加APIを実行
|
||||
const { meta } = await dispatch(updateTypistGroupAsync());
|
||||
setIsPushEditButton(false);
|
||||
if (meta.requestStatus === "fulfilled") {
|
||||
closePopup();
|
||||
dispatch(listTypistGroupsAsync());
|
||||
dispatch(cleanupTypistGroup());
|
||||
}
|
||||
}, [
|
||||
t,
|
||||
closePopup,
|
||||
dispatch,
|
||||
hasErrorEmptyGroupName,
|
||||
hasErrorSelectedTypistsEmpty,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className={`${styles.modal} ${isOpen ? styles.isShow : ""}`}>
|
||||
<div className={styles.modalBox}>
|
||||
<p className={styles.modalTitle}>
|
||||
{t(getTranslationID("typistGroupSetting.label.editTypistGroup"))}
|
||||
<button type="button" onClick={closePopup}>
|
||||
<img src={close} className={styles.modalTitleIcon} alt="close" />
|
||||
</button>
|
||||
</p>
|
||||
<form className={styles.form}>
|
||||
<dl className={`${styles.formList} ${styles.hasbg}`}>
|
||||
<dt className={styles.formTitle} />
|
||||
<dt>{t(getTranslationID("typistGroupSetting.label.groupName"))}</dt>
|
||||
<dd>
|
||||
<input
|
||||
type="text"
|
||||
size={40}
|
||||
maxLength={50}
|
||||
className={styles.formInput}
|
||||
value={groupName}
|
||||
onChange={(e) =>
|
||||
dispatch(changeGroupName({ groupName: e.target.value }))
|
||||
}
|
||||
/>
|
||||
{isPushEditButton && hasErrorEmptyGroupName && (
|
||||
<span className={styles.formError}>
|
||||
{t(getTranslationID("common.message.inputEmptyError"))}
|
||||
</span>
|
||||
)}
|
||||
</dd>
|
||||
<dt className={styles.formTitle}>
|
||||
{t(getTranslationID("typistGroupSetting.label.transcriptionist"))}
|
||||
</dt>
|
||||
<dd className={`${styles.formChange} ${styles.last}`}>
|
||||
<ul className={styles.chooseMember}>
|
||||
<li className={styles.changeTitle}>
|
||||
{t(getTranslationID("typistGroupSetting.label.selected"))}
|
||||
</li>
|
||||
{selectedTypists.map((typist: Typist) => (
|
||||
<li key={typist.id}>
|
||||
<input
|
||||
type="checkbox"
|
||||
className={styles.formCheck}
|
||||
value={typist.name}
|
||||
id={`${typist.id}`}
|
||||
checked
|
||||
onClick={() => dispatch(removeSelectedTypist({ typist }))}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`${typist.id}`}
|
||||
title={t(
|
||||
getTranslationID("typistGroupSetting.label.remove")
|
||||
)}
|
||||
>
|
||||
{typist.name}
|
||||
</label>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p />
|
||||
<ul className={styles.holdMember}>
|
||||
<li className={styles.changeTitle}>
|
||||
{t(getTranslationID("typistGroupSetting.label.pool"))}
|
||||
</li>
|
||||
{poolTypists.map((typist: Typist) => (
|
||||
<li key={typist.id}>
|
||||
<input
|
||||
type="checkbox"
|
||||
className={styles.formCheck}
|
||||
value={typist.name}
|
||||
id={`${typist.id}`}
|
||||
onClick={() => dispatch(addSelectedTypist({ typist }))}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`${typist.id}`}
|
||||
title={t(
|
||||
getTranslationID("typistGroupSetting.label.add")
|
||||
)}
|
||||
>
|
||||
{typist.name}
|
||||
</label>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</dd>
|
||||
<dd className={`${styles.full} ${styles.alignCenter}`}>
|
||||
<input
|
||||
type="button"
|
||||
name="submit"
|
||||
value={t(getTranslationID("typistGroupSetting.label.save"))}
|
||||
className={`${styles.formSubmit} ${styles.marginBtm1} ${styles.isActive}`}
|
||||
onClick={editTypistGroup}
|
||||
/>
|
||||
</dd>
|
||||
</dl>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -16,6 +16,7 @@ import { AppDispatch } from "app/store";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getTranslationID } from "translation";
|
||||
import { AddTypistGroupPopup } from "./addTypistGroupPopup";
|
||||
import { EditTypistGroupPopup } from "./editTypistGroupPopup";
|
||||
|
||||
const TypistGroupSettingPage: React.FC = (): JSX.Element => {
|
||||
const dispatch: AppDispatch = useDispatch();
|
||||
@ -25,11 +26,21 @@ const TypistGroupSettingPage: React.FC = (): JSX.Element => {
|
||||
const typistGroup = useSelector(selectTypistGroups);
|
||||
|
||||
const [isAddPopupOpen, setIsAddPopupOpen] = useState(false);
|
||||
const [isEditPopupOpen, setIsEditPopupOpen] = useState(false);
|
||||
const [editTypistGroupId, setEditTypistGroupId] = useState<number>(NaN);
|
||||
const onAddPopupOpen = useCallback(() => {
|
||||
// typist一覧を取得
|
||||
setIsAddPopupOpen(true);
|
||||
}, [setIsAddPopupOpen]);
|
||||
|
||||
const onEditPopupOpen = useCallback(
|
||||
(typistGroupId: number) => {
|
||||
setEditTypistGroupId(typistGroupId);
|
||||
setIsEditPopupOpen(true);
|
||||
},
|
||||
[setIsEditPopupOpen]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(listTypistGroupsAsync());
|
||||
}, [dispatch]);
|
||||
@ -42,6 +53,13 @@ const TypistGroupSettingPage: React.FC = (): JSX.Element => {
|
||||
}}
|
||||
isOpen={isAddPopupOpen}
|
||||
/>
|
||||
<EditTypistGroupPopup
|
||||
onClose={() => {
|
||||
setIsEditPopupOpen(false);
|
||||
}}
|
||||
isOpen={isEditPopupOpen}
|
||||
typistGroupId={editTypistGroupId}
|
||||
/>
|
||||
<div className={styles.wrap}>
|
||||
<Header userName="XXXXXX" />
|
||||
<UpdateTokenTimer />
|
||||
@ -102,8 +120,12 @@ const TypistGroupSettingPage: React.FC = (): JSX.Element => {
|
||||
className={`${styles.menuAction} ${styles.inTable}`}
|
||||
>
|
||||
<li>
|
||||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
|
||||
<a
|
||||
className={`${styles.menuLink} ${styles.isActive}`}
|
||||
onClick={() => {
|
||||
onEditPopupOpen(group.id);
|
||||
}}
|
||||
>
|
||||
{t(
|
||||
getTranslationID(
|
||||
|
||||
@ -236,7 +236,7 @@
|
||||
"deleteDictation": "(de)Delete Dictation",
|
||||
"selectedTranscriptionist": "(de)Selected",
|
||||
"poolTranscriptionist": "(de)Pool",
|
||||
"saveChanges": "(de)Save changes"
|
||||
"saveChanges": "(de)Save"
|
||||
}
|
||||
},
|
||||
"cardLicenseIssuePopupPage": {
|
||||
@ -372,11 +372,13 @@
|
||||
"selected": "(de)Selected",
|
||||
"pool": "(de)Pool",
|
||||
"add": "(de)Add",
|
||||
"remove": "(de)Remove"
|
||||
"remove": "(de)Remove",
|
||||
"editTypistGroup": "(de)Edit Transcriptionist Group",
|
||||
"save": "(de)Save"
|
||||
},
|
||||
"message": {
|
||||
"selectedTypistEmptyError": "(de)TranscriptionistGroupには最低1名のメンバーが必要です。",
|
||||
"groupAddFailedError": "(de)TypistGroupの追加に失敗しました。画面を更新し、再度実行してください"
|
||||
"selectedTypistEmptyError": "(de)TranscriptionistがいないTranscriptionistGroupは保存できません。1名以上をTranscriptionistとして選択してください。",
|
||||
"groupSaveFailedError": "(de)TypistGroupの保存に失敗しました。画面を更新し、再度実行してください"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,7 +236,7 @@
|
||||
"deleteDictation": "Delete Dictation",
|
||||
"selectedTranscriptionist": "Selected",
|
||||
"poolTranscriptionist": "Pool",
|
||||
"saveChanges": "Save changes"
|
||||
"saveChanges": "Save"
|
||||
}
|
||||
},
|
||||
"cardLicenseIssuePopupPage": {
|
||||
@ -372,11 +372,13 @@
|
||||
"selected": "Selected",
|
||||
"pool": "Pool",
|
||||
"add": "Add",
|
||||
"remove": "Remove"
|
||||
"remove": "Remove",
|
||||
"editTypistGroup": "Edit Transcriptionist Group",
|
||||
"save": "Save"
|
||||
},
|
||||
"message": {
|
||||
"selectedTypistEmptyError": "TranscriptionistGroupには最低1名のメンバーが必要です。",
|
||||
"groupAddFailedError": "TypistGroupの追加に失敗しました。画面を更新し、再度実行してください"
|
||||
"selectedTypistEmptyError": "TranscriptionistがいないTranscriptionistGroupは保存できません。1名以上をTranscriptionistとして選択してください。",
|
||||
"groupSaveFailedError": "TypistGroupの保存に失敗しました。画面を更新し、再度実行してください"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,7 +236,7 @@
|
||||
"deleteDictation": "(es)Delete Dictation",
|
||||
"selectedTranscriptionist": "(es)Selected",
|
||||
"poolTranscriptionist": "(es)Pool",
|
||||
"saveChanges": "(es)Save changes"
|
||||
"saveChanges": "(es)Save"
|
||||
}
|
||||
},
|
||||
"cardLicenseIssuePopupPage": {
|
||||
@ -372,11 +372,13 @@
|
||||
"selected": "(es)Selected",
|
||||
"pool": "(es)Pool",
|
||||
"add": "(es)Add",
|
||||
"remove": "(es)Remove"
|
||||
"remove": "(es)Remove",
|
||||
"editTypistGroup": "(es)Edit Transcriptionist Group",
|
||||
"save": "(es)Save"
|
||||
},
|
||||
"message": {
|
||||
"selectedTypistEmptyError": "(es)TranscriptionistGroupには最低1名のメンバーが必要です。",
|
||||
"groupAddFailedError": "(es)TypistGroupの追加に失敗しました。画面を更新し、再度実行してください"
|
||||
"selectedTypistEmptyError": "(es)TranscriptionistがいないTranscriptionistGroupは保存できません。1名以上をTranscriptionistとして選択してください。",
|
||||
"groupSaveFailedError": "(es)TypistGroupの保存に失敗しました。画面を更新し、再度実行してください"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,7 +236,7 @@
|
||||
"deleteDictation": "(fr)Delete Dictation",
|
||||
"selectedTranscriptionist": "(fr)Selected",
|
||||
"poolTranscriptionist": "(fr)Pool",
|
||||
"saveChanges": "(fr)Save changes"
|
||||
"saveChanges": "(fr)Save"
|
||||
}
|
||||
},
|
||||
"cardLicenseIssuePopupPage": {
|
||||
@ -372,11 +372,13 @@
|
||||
"selected": "(fr)Selected",
|
||||
"pool": "(fr)Pool",
|
||||
"add": "(fr)Add",
|
||||
"remove": "(fr)Remove"
|
||||
"remove": "(fr)Remove",
|
||||
"editTypistGroup": "(fr)Edit Transcriptionist Group",
|
||||
"save": "(fr)Save"
|
||||
},
|
||||
"message": {
|
||||
"selectedTypistEmptyError": "(fr)TranscriptionistGroupには最低1名のメンバーが必要です。",
|
||||
"groupAddFailedError": "(fr)TypistGroupの追加に失敗しました。画面を更新し、再度実行してください"
|
||||
"selectedTypistEmptyError": "(fr)TranscriptionistがいないTranscriptionistGroupは保存できません。1名以上をTranscriptionistとして選択してください。",
|
||||
"groupSaveFailedError": "(fr)TypistGroupの保存に失敗しました。画面を更新し、再度実行してください"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user