Merged PR 729: 画面実装(ファイル削除設定ポップアップ画面)
## 概要 [Task3547: 画面実装(ファイル削除設定ポップアップ画面)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3547) - ファイル削除設定ポップアップの新規実装をしました。 ## レビューポイント - reduxとの連携部分の設計でNGな部分ないか? - 処理の抜け漏れないか? ## 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/Task3547?csf=1&web=1&e=0pu92Q ## 動作確認状況 - ローカルで一通りの動作確認しました。 ## 補足 - とくになし
This commit is contained in:
parent
eaf1b3c8b8
commit
548c7a05e9
@ -78,6 +78,18 @@ export interface Account {
|
||||
* @memberof Account
|
||||
*/
|
||||
'delegationPermission': boolean;
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof Account
|
||||
*/
|
||||
'autoFileDelete': boolean;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof Account
|
||||
*/
|
||||
'fileRetentionDays': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
@ -2077,6 +2089,25 @@ export interface UpdateAccountInfoRequest {
|
||||
*/
|
||||
'secondryAdminUserId'?: number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface UpdateFileDeleteSettingRequest
|
||||
*/
|
||||
export interface UpdateFileDeleteSettingRequest {
|
||||
/**
|
||||
* 自動ファイル削除をするかどうか
|
||||
* @type {boolean}
|
||||
* @memberof UpdateFileDeleteSettingRequest
|
||||
*/
|
||||
'autoFileDelete': boolean;
|
||||
/**
|
||||
* 文字起こし完了してから自動ファイル削除されるまでのファイルの保存期間
|
||||
* @type {number}
|
||||
* @memberof UpdateFileDeleteSettingRequest
|
||||
*/
|
||||
'retentionDays': number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
@ -3328,6 +3359,46 @@ export const AccountsApiAxiosParamCreator = function (configuration?: Configurat
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
* @param {UpdateFileDeleteSettingRequest} updateFileDeleteSettingRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
updateFileDeleteSetting: async (updateFileDeleteSettingRequest: UpdateFileDeleteSettingRequest, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'updateFileDeleteSettingRequest' is not null or undefined
|
||||
assertParamExists('updateFileDeleteSetting', 'updateFileDeleteSettingRequest', updateFileDeleteSettingRequest)
|
||||
const localVarPath = `/accounts/me/file-delete-setting`;
|
||||
// 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(updateFileDeleteSettingRequest, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
@ -3790,6 +3861,19 @@ export const AccountsApiFp = function(configuration?: Configuration) {
|
||||
const operationBasePath = operationServerMap['AccountsApi.updateAccountInfo']?.[index]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
* @param {UpdateFileDeleteSettingRequest} updateFileDeleteSettingRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async updateFileDeleteSetting(updateFileDeleteSettingRequest: UpdateFileDeleteSettingRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<object>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.updateFileDeleteSetting(updateFileDeleteSettingRequest, options);
|
||||
const index = configuration?.serverIndex ?? 0;
|
||||
const operationBasePath = operationServerMap['AccountsApi.updateFileDeleteSetting']?.[index]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
@ -4087,6 +4171,16 @@ export const AccountsApiFactory = function (configuration?: Configuration, baseP
|
||||
updateAccountInfo(updateAccountInfoRequest: UpdateAccountInfoRequest, options?: any): AxiosPromise<object> {
|
||||
return localVarFp.updateAccountInfo(updateAccountInfoRequest, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
* @param {UpdateFileDeleteSettingRequest} updateFileDeleteSettingRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
updateFileDeleteSetting(updateFileDeleteSettingRequest: UpdateFileDeleteSettingRequest, options?: any): AxiosPromise<object> {
|
||||
return localVarFp.updateFileDeleteSetting(updateFileDeleteSettingRequest, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
@ -4425,6 +4519,18 @@ export class AccountsApi extends BaseAPI {
|
||||
return AccountsApiFp(this.configuration).updateAccountInfo(updateAccountInfoRequest, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
* @param {UpdateFileDeleteSettingRequest} updateFileDeleteSettingRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AccountsApi
|
||||
*/
|
||||
public updateFileDeleteSetting(updateFileDeleteSettingRequest: UpdateFileDeleteSettingRequest, options?: AxiosRequestConfig) {
|
||||
return AccountsApiFp(this.configuration).updateFileDeleteSetting(updateFileDeleteSettingRequest, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @summary
|
||||
@ -7309,46 +7415,6 @@ export const UsersApiAxiosParamCreator = function (configuration?: Configuration
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
localVarRequestOptions.data = serializeDataIfNeeded(postUpdateUserRequest, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* ユーザーを削除します
|
||||
* @summary
|
||||
* @param {PostDeleteUserRequest} postDeleteUserRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
updeateUser: async (postDeleteUserRequest: PostDeleteUserRequest, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'postDeleteUserRequest' is not null or undefined
|
||||
assertParamExists('updeateUser', 'postDeleteUserRequest', postDeleteUserRequest)
|
||||
const localVarPath = `/users/delete`;
|
||||
// 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(postDeleteUserRequest, localVarRequestOptions, configuration)
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
@ -7529,19 +7595,6 @@ export const UsersApiFp = function(configuration?: Configuration) {
|
||||
const operationBasePath = operationServerMap['UsersApi.updateUser']?.[index]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* ユーザーを削除します
|
||||
* @summary
|
||||
* @param {PostDeleteUserRequest} postDeleteUserRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async updeateUser(postDeleteUserRequest: PostDeleteUserRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<object>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.updeateUser(postDeleteUserRequest, options);
|
||||
const index = configuration?.serverIndex ?? 0;
|
||||
const operationBasePath = operationServerMap['UsersApi.updeateUser']?.[index]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -7678,16 +7731,6 @@ export const UsersApiFactory = function (configuration?: Configuration, basePath
|
||||
updateUser(postUpdateUserRequest: PostUpdateUserRequest, options?: any): AxiosPromise<object> {
|
||||
return localVarFp.updateUser(postUpdateUserRequest, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* ユーザーを削除します
|
||||
* @summary
|
||||
* @param {PostDeleteUserRequest} postDeleteUserRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
updeateUser(postDeleteUserRequest: PostDeleteUserRequest, options?: any): AxiosPromise<object> {
|
||||
return localVarFp.updeateUser(postDeleteUserRequest, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@ -7849,18 +7892,6 @@ export class UsersApi extends BaseAPI {
|
||||
public updateUser(postUpdateUserRequest: PostUpdateUserRequest, options?: AxiosRequestConfig) {
|
||||
return UsersApiFp(this.configuration).updateUser(postUpdateUserRequest, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* ユーザーを削除します
|
||||
* @summary
|
||||
* @param {PostDeleteUserRequest} postDeleteUserRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof UsersApi
|
||||
*/
|
||||
public updeateUser(postDeleteUserRequest: PostDeleteUserRequest, options?: AxiosRequestConfig) {
|
||||
return UsersApiFp(this.configuration).updeateUser(postDeleteUserRequest, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import {
|
||||
updateAccountInfoAsync,
|
||||
getAccountRelationsAsync,
|
||||
deleteAccountAsync,
|
||||
updateFileDeleteSettingAsync,
|
||||
} from "./operations";
|
||||
|
||||
const initialState: AccountState = {
|
||||
@ -15,6 +16,8 @@ const initialState: AccountState = {
|
||||
tier: 0,
|
||||
country: "",
|
||||
delegationPermission: false,
|
||||
autoFileDelete: false,
|
||||
fileRetentionDays: 0,
|
||||
},
|
||||
},
|
||||
dealers: [],
|
||||
@ -29,6 +32,8 @@ const initialState: AccountState = {
|
||||
secondryAdminUserId: undefined,
|
||||
},
|
||||
isLoading: false,
|
||||
autoFileDelete: false,
|
||||
fileRetentionDays: 0,
|
||||
},
|
||||
};
|
||||
|
||||
@ -64,6 +69,20 @@ export const accountSlice = createSlice({
|
||||
const { secondryAdminUserId } = action.payload;
|
||||
state.apps.updateAccountInfo.secondryAdminUserId = secondryAdminUserId;
|
||||
},
|
||||
changeAutoFileDelete: (
|
||||
state,
|
||||
action: PayloadAction<{ autoFileDelete: boolean }>
|
||||
) => {
|
||||
const { autoFileDelete } = action.payload;
|
||||
state.apps.autoFileDelete = autoFileDelete;
|
||||
},
|
||||
changeFileRetentionDays: (
|
||||
state,
|
||||
action: PayloadAction<{ fileRetentionDays: number }>
|
||||
) => {
|
||||
const { fileRetentionDays } = action.payload;
|
||||
state.apps.fileRetentionDays = fileRetentionDays;
|
||||
},
|
||||
cleanupApps: (state) => {
|
||||
state.domain = initialState.domain;
|
||||
},
|
||||
@ -85,6 +104,10 @@ export const accountSlice = createSlice({
|
||||
action.payload.accountInfo.account.primaryAdminUserId;
|
||||
state.apps.updateAccountInfo.secondryAdminUserId =
|
||||
action.payload.accountInfo.account.secondryAdminUserId;
|
||||
state.apps.autoFileDelete =
|
||||
action.payload.accountInfo.account.autoFileDelete;
|
||||
state.apps.fileRetentionDays =
|
||||
action.payload.accountInfo.account.fileRetentionDays;
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(getAccountRelationsAsync.rejected, (state) => {
|
||||
@ -99,6 +122,15 @@ export const accountSlice = createSlice({
|
||||
builder.addCase(updateAccountInfoAsync.rejected, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(updateFileDeleteSettingAsync.pending, (state) => {
|
||||
state.apps.isLoading = true;
|
||||
});
|
||||
builder.addCase(updateFileDeleteSettingAsync.fulfilled, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(updateFileDeleteSettingAsync.rejected, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(deleteAccountAsync.pending, (state) => {
|
||||
state.apps.isLoading = true;
|
||||
});
|
||||
@ -115,6 +147,8 @@ export const {
|
||||
changeDealerPermission,
|
||||
changePrimaryAdministrator,
|
||||
changeSecondryAdministrator,
|
||||
changeAutoFileDelete,
|
||||
changeFileRetentionDays,
|
||||
cleanupApps,
|
||||
} = accountSlice.actions;
|
||||
export default accountSlice.reducer;
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
UpdateAccountInfoRequest,
|
||||
UsersApi,
|
||||
DeleteAccountRequest,
|
||||
UpdateFileDeleteSettingRequest,
|
||||
} from "../../api/api";
|
||||
import { Configuration } from "../../api/configuration";
|
||||
import { ViewAccountRelationsInfo } from "./types";
|
||||
@ -112,6 +113,58 @@ export const updateAccountInfoAsync = createAsyncThunk<
|
||||
}
|
||||
});
|
||||
|
||||
export const updateFileDeleteSettingAsync = createAsyncThunk<
|
||||
{
|
||||
/* Empty Object */
|
||||
},
|
||||
{ autoFileDelete: boolean; fileRetentionDays: number },
|
||||
{
|
||||
// rejectした時の返却値の型
|
||||
rejectValue: {
|
||||
error: ErrorObject;
|
||||
};
|
||||
}
|
||||
>("accounts/updateFileDeleteSettingAsync", async (args, thunkApi) => {
|
||||
// apiのConfigurationを取得する
|
||||
const { getState } = thunkApi;
|
||||
const state = getState() as RootState;
|
||||
const { configuration } = state.auth;
|
||||
const accessToken = getAccessToken(state.auth);
|
||||
const config = new Configuration(configuration);
|
||||
const accountApi = new AccountsApi(config);
|
||||
|
||||
const requestParam: UpdateFileDeleteSettingRequest = {
|
||||
autoFileDelete: args.autoFileDelete,
|
||||
retentionDays: args.fileRetentionDays,
|
||||
};
|
||||
|
||||
try {
|
||||
await accountApi.updateFileDeleteSetting(requestParam, {
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
});
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "info",
|
||||
message: getTranslationID("common.message.success"),
|
||||
})
|
||||
);
|
||||
return {};
|
||||
} catch (e) {
|
||||
const error = createErrorObject(e);
|
||||
|
||||
const errorMessage = getTranslationID("common.message.internalServerError");
|
||||
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message: errorMessage,
|
||||
})
|
||||
);
|
||||
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
});
|
||||
|
||||
export const deleteAccountAsync = createAsyncThunk<
|
||||
{
|
||||
/* Empty Object */
|
||||
|
||||
@ -16,3 +16,18 @@ export const selectIsLoading = (state: RootState) =>
|
||||
state.account.apps.isLoading;
|
||||
export const selectUpdateAccountInfo = (state: RootState) =>
|
||||
state.account.apps.updateAccountInfo;
|
||||
export const selectFileDeleteSetting = (state: RootState) => {
|
||||
const { autoFileDelete, fileRetentionDays } = state.account.apps;
|
||||
return {
|
||||
autoFileDelete,
|
||||
fileRetentionDays,
|
||||
};
|
||||
};
|
||||
export const selectInputValidationErrors = (state: RootState) => {
|
||||
const { fileRetentionDays } = state.account.apps;
|
||||
const hasFileRetentionDaysError =
|
||||
fileRetentionDays <= 0 || fileRetentionDays >= 1000;
|
||||
return {
|
||||
hasFileRetentionDaysError,
|
||||
};
|
||||
};
|
||||
|
||||
@ -19,4 +19,6 @@ export interface Domain {
|
||||
export interface Apps {
|
||||
updateAccountInfo: UpdateAccountInfoRequest;
|
||||
isLoading: boolean;
|
||||
autoFileDelete: boolean;
|
||||
fileRetentionDays: number;
|
||||
}
|
||||
|
||||
@ -12,6 +12,8 @@ const initialState: PartnerLicensesState = {
|
||||
tier: 0,
|
||||
country: "",
|
||||
delegationPermission: false,
|
||||
autoFileDelete: false,
|
||||
fileRetentionDays: 0,
|
||||
},
|
||||
total: 0,
|
||||
ownPartnerLicense: {
|
||||
|
||||
@ -448,43 +448,43 @@ export const deleteUserAsync = createAsyncThunk<
|
||||
// ユーザーに有効なライセンスが割り当たっているため削除不可
|
||||
if (error.code === "E014007") {
|
||||
errorMessage = getTranslationID(
|
||||
"userListPage.message.UserDeletionLicenseActiveError"
|
||||
"userListPage.message.userDeletionLicenseActiveError"
|
||||
);
|
||||
}
|
||||
// 管理者ユーザーため削除不可
|
||||
if (error.code === "E014002") {
|
||||
errorMessage = getTranslationID(
|
||||
"userListPage.message.AdminUserDeletionError"
|
||||
"userListPage.message.adminUserDeletionError"
|
||||
);
|
||||
}
|
||||
// タイピストユーザーで担当タスクがあるため削除不可
|
||||
if (error.code === "E014009") {
|
||||
errorMessage = getTranslationID(
|
||||
"userListPage.message.TypistUserDeletionTranscriptionTaskError"
|
||||
"userListPage.message.typistUserDeletionTranscriptionTaskError"
|
||||
);
|
||||
}
|
||||
// タイピストユーザーでルーティングルールに設定されているため削除不可
|
||||
if (error.code === "E014004") {
|
||||
errorMessage = getTranslationID(
|
||||
"userListPage.message.TypistDeletionRoutingRuleError"
|
||||
"userListPage.message.typistDeletionRoutingRuleError"
|
||||
);
|
||||
}
|
||||
// タイピストユーザーでTranscriptionistGroupに所属しているため削除不可
|
||||
if (error.code === "E014005") {
|
||||
errorMessage = getTranslationID(
|
||||
"userListPage.message.TypistUserDeletionTranscriptionistGroupError"
|
||||
"userListPage.message.typistUserDeletionTranscriptionistGroupError"
|
||||
);
|
||||
}
|
||||
// Authorユーザーで同一AuthorIDのタスクがあるため削除不可
|
||||
if (error.code === "E014006") {
|
||||
errorMessage = getTranslationID(
|
||||
"userListPage.message.AuthorUserDeletionTranscriptionTaskError"
|
||||
"userListPage.message.authorUserDeletionTranscriptionTaskError"
|
||||
);
|
||||
}
|
||||
// Authorユーザーで同一AuthorIDがルーティングルールに設定されているため削除不可
|
||||
if (error.code === "E014003") {
|
||||
errorMessage = getTranslationID(
|
||||
"userListPage.message.AuthorDeletionRoutingRuleError"
|
||||
"userListPage.message.authorDeletionRoutingRuleError"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,169 @@
|
||||
import React, { useCallback, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
selectInputValidationErrors,
|
||||
selectFileDeleteSetting,
|
||||
updateFileDeleteSettingAsync,
|
||||
selectIsLoading,
|
||||
getAccountRelationsAsync,
|
||||
} from "features/account";
|
||||
import { AppDispatch } from "app/store";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styles from "../../styles/app.module.scss";
|
||||
import { getTranslationID } from "../../translation";
|
||||
import close from "../../assets/images/close.svg";
|
||||
import {
|
||||
changeAutoFileDelete,
|
||||
changeFileRetentionDays,
|
||||
} from "../../features/account/accountSlice";
|
||||
import progress_activit from "../../assets/images/progress_activit.svg";
|
||||
|
||||
interface FileDeleteSettingPopupProps {
|
||||
// eslint-disable-next-line react/no-unused-prop-types
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const FileDeleteSettingPopup: React.FC<FileDeleteSettingPopupProps> = (
|
||||
props
|
||||
) => {
|
||||
const { onClose } = props;
|
||||
|
||||
const dispatch: AppDispatch = useDispatch();
|
||||
const [t] = useTranslation();
|
||||
|
||||
const isLoading = useSelector(selectIsLoading);
|
||||
const fileDeleteSetting = useSelector(selectFileDeleteSetting);
|
||||
const { hasFileRetentionDaysError } = useSelector(
|
||||
selectInputValidationErrors
|
||||
);
|
||||
|
||||
const closePopup = useCallback(() => {
|
||||
if (isLoading) return;
|
||||
onClose();
|
||||
}, [isLoading, onClose]);
|
||||
|
||||
const [isPushSubmitButton, setIsPushSubmitButton] = useState<boolean>(false);
|
||||
|
||||
const onUpdateFileDeleteSetting = useCallback(async () => {
|
||||
if (isLoading) return;
|
||||
setIsPushSubmitButton(true);
|
||||
if (hasFileRetentionDaysError) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { meta } = await dispatch(
|
||||
updateFileDeleteSettingAsync({
|
||||
autoFileDelete: fileDeleteSetting.autoFileDelete,
|
||||
fileRetentionDays: fileDeleteSetting.fileRetentionDays,
|
||||
})
|
||||
);
|
||||
setIsPushSubmitButton(false);
|
||||
if (meta.requestStatus === "fulfilled") {
|
||||
closePopup();
|
||||
dispatch(getAccountRelationsAsync());
|
||||
}
|
||||
}, [
|
||||
closePopup,
|
||||
dispatch,
|
||||
fileDeleteSetting.autoFileDelete,
|
||||
fileDeleteSetting.fileRetentionDays,
|
||||
hasFileRetentionDaysError,
|
||||
isLoading,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className={`${styles.modal} ${styles.isShow}`}>
|
||||
<div className={styles.modalBox}>
|
||||
<p className={styles.modalTitle}>
|
||||
{t(getTranslationID("fileDeleteSettingPopup.label.title"))}
|
||||
<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(
|
||||
"fileDeleteSettingPopup.label.autoFileDeleteCheck"
|
||||
)
|
||||
)}
|
||||
</dt>
|
||||
<dd className={styles.last}>
|
||||
<p>
|
||||
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
className={styles.formCheck}
|
||||
checked={fileDeleteSetting.autoFileDelete}
|
||||
onChange={(e) => {
|
||||
dispatch(
|
||||
changeAutoFileDelete({
|
||||
autoFileDelete: e.target.checked,
|
||||
})
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
</p>
|
||||
<p className={styles.txWsline}>
|
||||
{t(
|
||||
getTranslationID(
|
||||
"fileDeleteSettingPopup.label.daysAnnotation"
|
||||
)
|
||||
)}
|
||||
</p>
|
||||
<input
|
||||
type="number"
|
||||
min={1}
|
||||
max={999}
|
||||
value={fileDeleteSetting.fileRetentionDays}
|
||||
className={`${styles.formInput} ${styles.short}`}
|
||||
disabled={!fileDeleteSetting.autoFileDelete}
|
||||
onChange={(e) => {
|
||||
dispatch(
|
||||
changeFileRetentionDays({
|
||||
fileRetentionDays: Number(e.target.value),
|
||||
})
|
||||
);
|
||||
}}
|
||||
/>{" "}
|
||||
{t(getTranslationID("fileDeleteSettingPopup.label.days"))}
|
||||
{isPushSubmitButton && hasFileRetentionDaysError && (
|
||||
<span className={styles.formError}>
|
||||
{t(
|
||||
getTranslationID(
|
||||
"fileDeleteSettingPopup.label.daysValidationError"
|
||||
)
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</dd>
|
||||
<dd className={`${styles.full} ${styles.alignCenter}`}>
|
||||
<input
|
||||
type="button"
|
||||
name="submit"
|
||||
value={t(
|
||||
getTranslationID("fileDeleteSettingPopup.label.saveButton")
|
||||
)}
|
||||
className={`${styles.formSubmit} ${styles.marginBtm1} ${
|
||||
!isLoading ? styles.isActive : ""
|
||||
}`}
|
||||
onClick={onUpdateFileDeleteSetting}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</dd>
|
||||
<img
|
||||
style={{ display: isLoading ? "inline" : "none" }}
|
||||
src={progress_activit}
|
||||
className={styles.icLoading}
|
||||
alt="Loading"
|
||||
/>
|
||||
</dl>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -23,6 +23,7 @@ import { getTranslationID } from "translation";
|
||||
import { TIERS } from "components/auth/constants";
|
||||
import { isApproveTier } from "features/auth";
|
||||
import { DeleteAccountPopup } from "./deleteAccountPopup";
|
||||
import { FileDeleteSettingPopup } from "./fileDeleteSettingPopup";
|
||||
import progress_activit from "../../assets/images/progress_activit.svg";
|
||||
|
||||
const AccountPage: React.FC = (): JSX.Element => {
|
||||
@ -40,10 +41,17 @@ const AccountPage: React.FC = (): JSX.Element => {
|
||||
const [isDeleteAccountPopupOpen, setIsDeleteAccountPopupOpen] =
|
||||
useState(false);
|
||||
|
||||
const [isFileDeleteSettingPopupOpen, setIsFileDeleteSettingPopupOpen] =
|
||||
useState(false);
|
||||
|
||||
const onDeleteAccountOpen = useCallback(() => {
|
||||
setIsDeleteAccountPopupOpen(true);
|
||||
}, [setIsDeleteAccountPopupOpen]);
|
||||
|
||||
const onDeleteFileDeleteSettingOpen = useCallback(() => {
|
||||
setIsFileDeleteSettingPopupOpen(true);
|
||||
}, [setIsFileDeleteSettingPopupOpen]);
|
||||
|
||||
// 階層表示用
|
||||
const tierNames: { [key: number]: string } = {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
@ -89,6 +97,13 @@ const AccountPage: React.FC = (): JSX.Element => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isFileDeleteSettingPopupOpen && (
|
||||
<FileDeleteSettingPopup
|
||||
onClose={() => {
|
||||
setIsFileDeleteSettingPopupOpen(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div className={styles.wrap}>
|
||||
<Header />
|
||||
<UpdateTokenTimer />
|
||||
@ -102,12 +117,13 @@ const AccountPage: React.FC = (): JSX.Element => {
|
||||
|
||||
<section className={styles.account}>
|
||||
<div className={styles.boxFlex}>
|
||||
{/* File Delete Setting は現状不要のため非表示
|
||||
<ul className={`${styles.menuAction} ${styles.box100}`}>
|
||||
<li>
|
||||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
|
||||
<a
|
||||
href="account_setting.html"
|
||||
className={`${styles.menuLink} ${styles.isActive}`}
|
||||
onClick={onDeleteFileDeleteSettingOpen}
|
||||
data-tag="open-file-delete-setting-popup"
|
||||
>
|
||||
<img
|
||||
src="images/file_delete.svg"
|
||||
@ -120,7 +136,6 @@ const AccountPage: React.FC = (): JSX.Element => {
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
*/}
|
||||
|
||||
<div className={styles.marginRgt3}>
|
||||
<dl className={styles.listVertical}>
|
||||
|
||||
@ -129,13 +129,13 @@
|
||||
"roleChangeError": "Die Benutzerrolle kann nicht geändert werden. Die angezeigten Informationen sind möglicherweise veraltet. Aktualisieren Sie daher bitte den Bildschirm, um den neuesten Status anzuzeigen.",
|
||||
"encryptionPasswordCorrectError": "Das Verschlüsselungskennwort entspricht nicht den Regeln.",
|
||||
"alreadyLicenseDeallocatedError": "Die zugewiesene Lizenz wurde bereits storniert. Die angezeigten Informationen sind möglicherweise veraltet. Aktualisieren Sie daher bitte den Bildschirm, um den neuesten Status anzuzeigen.",
|
||||
"UserDeletionLicenseActiveError": "(de)ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"TypistDeletionRoutingRuleError": "(de)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"AdminUserDeletionError": "(de)ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"TypistUserDeletionTranscriptionTaskError": "(de)ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"AuthorUserDeletionTranscriptionTaskError": "(de)ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"TypistUserDeletionTranscriptionistGroupError": "(de)ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"AuthorDeletionRoutingRuleError": "(de)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
"userDeletionLicenseActiveError": "(de)ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"typistDeletionRoutingRuleError": "(de)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"adminUserDeletionError": "(de)ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"typistUserDeletionTranscriptionTaskError": "(de)ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"authorUserDeletionTranscriptionTaskError": "(de)ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"typistUserDeletionTranscriptionistGroupError": "(de)ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"authorDeletionRoutingRuleError": "(de)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
},
|
||||
"label": {
|
||||
"title": "Benutzer",
|
||||
@ -570,5 +570,15 @@
|
||||
"job": "Aufgabe",
|
||||
"close": "Schließen"
|
||||
}
|
||||
},
|
||||
"fileDeleteSettingPopup": {
|
||||
"label": {
|
||||
"title": "(de)Auto File Delete Setting",
|
||||
"autoFileDeleteCheck": "(de)Auto file delete",
|
||||
"daysAnnotation": "(de)Number of days from transcription finished to delete the files.",
|
||||
"days": "(de)Days",
|
||||
"saveButton": "(de)Save Settings",
|
||||
"daysValidationError": "(de)Daysには1~999の数字を入力してください。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,13 +129,13 @@
|
||||
"roleChangeError": "Unable to change the User Role. The displayed information may be outdated, so please refresh the screen to see the latest status.",
|
||||
"encryptionPasswordCorrectError": "Encryption password does not meet the rules.",
|
||||
"alreadyLicenseDeallocatedError": "Assigned license has already been canceled. The displayed information may be outdated, so please refresh the screen to see the latest status.",
|
||||
"UserDeletionLicenseActiveError": "ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"TypistDeletionRoutingRuleError": "ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"AdminUserDeletionError": "ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"TypistUserDeletionTranscriptionTaskError": "ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"AuthorUserDeletionTranscriptionTaskError": "ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"TypistUserDeletionTranscriptionistGroupError": "ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"AuthorDeletionRoutingRuleError": "ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
"userDeletionLicenseActiveError": "ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"typistDeletionRoutingRuleError": "ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"adminUserDeletionError": "ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"typistUserDeletionTranscriptionTaskError": "ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"authorUserDeletionTranscriptionTaskError": "ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"typistUserDeletionTranscriptionistGroupError": "ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"authorDeletionRoutingRuleError": "ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
},
|
||||
"label": {
|
||||
"title": "User",
|
||||
@ -570,5 +570,15 @@
|
||||
"job": "Job",
|
||||
"close": "Close"
|
||||
}
|
||||
},
|
||||
"fileDeleteSettingPopup": {
|
||||
"label": {
|
||||
"title": "Auto File Delete Setting",
|
||||
"autoFileDeleteCheck": "Auto file delete",
|
||||
"daysAnnotation": "Number of days from transcription finished to delete the files.",
|
||||
"days": "Days",
|
||||
"saveButton": "Save Settings",
|
||||
"daysValidationError": "Daysには1~999の数字を入力してください。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,13 +129,13 @@
|
||||
"roleChangeError": "No se puede cambiar la función de usuario. La información mostrada puede estar desactualizada, así que actualice la pantalla para ver el estado más reciente.",
|
||||
"encryptionPasswordCorrectError": "La contraseña de cifrado no cumple con las reglas.",
|
||||
"alreadyLicenseDeallocatedError": "La licencia asignada ya ha sido cancelada. La información mostrada puede estar desactualizada, así que actualice la pantalla para ver el estado más reciente.",
|
||||
"UserDeletionLicenseActiveError": "(es)ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"TypistDeletionRoutingRuleError": "(es)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"AdminUserDeletionError": "(es)ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"TypistUserDeletionTranscriptionTaskError": "(es)ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"AuthorUserDeletionTranscriptionTaskError": "(es)ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"TypistUserDeletionTranscriptionistGroupError": "(es)ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"AuthorDeletionRoutingRuleError": "(es)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
"userDeletionLicenseActiveError": "(es)ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"typistDeletionRoutingRuleError": "(es)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"adminUserDeletionError": "(es)ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"typistUserDeletionTranscriptionTaskError": "(es)ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"authorUserDeletionTranscriptionTaskError": "(es)ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"typistUserDeletionTranscriptionistGroupError": "(es)ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"authorDeletionRoutingRuleError": "(es)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
},
|
||||
"label": {
|
||||
"title": "Usuario",
|
||||
@ -570,5 +570,15 @@
|
||||
"job": "Trabajo",
|
||||
"close": "Cerrar"
|
||||
}
|
||||
},
|
||||
"fileDeleteSettingPopup": {
|
||||
"label": {
|
||||
"title": "(es)Auto File Delete Setting",
|
||||
"autoFileDeleteCheck": "(es)Auto file delete",
|
||||
"daysAnnotation": "(es)Number of days from transcription finished to delete the files.",
|
||||
"days": "(es)Days",
|
||||
"saveButton": "(es)Save Settings",
|
||||
"daysValidationError": "(es)Daysには1~999の数字を入力してください。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,13 +129,13 @@
|
||||
"roleChangeError": "Impossible de modifier le rôle de l'utilisateur. Les informations affichées peuvent être obsolètes, veuillez donc actualiser l'écran pour voir le dernier statut.",
|
||||
"encryptionPasswordCorrectError": "Le mot de passe de cryptage n'est pas conforme aux règles.",
|
||||
"alreadyLicenseDeallocatedError": "La licence attribuée a déjà été annulée. Les informations affichées peuvent être obsolètes, veuillez donc actualiser l'écran pour voir le dernier statut.",
|
||||
"UserDeletionLicenseActiveError": "(fr)ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"TypistDeletionRoutingRuleError": "(fr)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"AdminUserDeletionError": "(fr)ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"TypistUserDeletionTranscriptionTaskError": "(fr)ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"AuthorUserDeletionTranscriptionTaskError": "(fr)ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"TypistUserDeletionTranscriptionistGroupError": "(fr)ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"AuthorDeletionRoutingRuleError": "(fr)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
"userDeletionLicenseActiveError": "(fr)ユーザーの削除に失敗しました。対象ユーザーのライセンス割り当てを解除してください。",
|
||||
"typistDeletionRoutingRuleError": "(fr)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象Transcriptionistを外してください。",
|
||||
"adminUserDeletionError": "(fr)ユーザーの削除に失敗しました。アカウント画面で対象ユーザーをPrimary/Secondary Administratorから外してください。",
|
||||
"typistUserDeletionTranscriptionTaskError": "(fr)ユーザーの削除に失敗しました。Dictation画面でタスクのルーティングから対象Transcriptionistを外してください。",
|
||||
"authorUserDeletionTranscriptionTaskError": "(fr)ユーザーの削除に失敗しました。Dictation画面で対象AuthorのAuthorIDが設定されているタスクの中で、文字起こしが未完了のタスクを削除またはFinishedにしてください。",
|
||||
"typistUserDeletionTranscriptionistGroupError": "(fr)ユーザーの削除に失敗しました。Workflow画面でTranscriptionistGroupから対象Transcriptionistを外してください。",
|
||||
"authorDeletionRoutingRuleError": "(fr)ユーザーの削除に失敗しました。Workflow画面でルーティングルールから対象AuthorのAuthorIDを外してください。"
|
||||
},
|
||||
"label": {
|
||||
"title": "Utilisateur",
|
||||
@ -570,5 +570,15 @@
|
||||
"job": "Tâches",
|
||||
"close": "Fermer"
|
||||
}
|
||||
},
|
||||
"fileDeleteSettingPopup": {
|
||||
"label": {
|
||||
"title": "(fr)Auto File Delete Setting",
|
||||
"autoFileDeleteCheck": "(fr)Auto file delete",
|
||||
"daysAnnotation": "(fr)Number of days from transcription finished to delete the files.",
|
||||
"days": "(fr)Days",
|
||||
"saveButton": "(fr)Save Settings",
|
||||
"daysValidationError": "(fr)Daysには1~999の数字を入力してください。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user