Merged PR 202: 画面実装(PlayBackボタン)
## 概要 [Task1997: 画面実装(PlayBackボタン)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1997) - Playbackボタン押下時の挙動を実装 - typist - 自身が割り当て候補となっているタスクをPlayBackする - 成功時、カスタムURLスキームでデスクトップアプリを起動する - author - 自身のAuthorIDと一致するタスクをPlayBackする - 成功時、カスタムURLスキームでデスクトップアプリを起動する - ログイン時の、カスタムURLスキームを実際のデスクトップアプリのスキーム名に修正 ## レビューポイント - playbackAsyncのなかでソート条件更新APIを一緒に呼び出しているが問題ないか - ソート条件を更新するタイミングはここで問題ないか - ユーザーがTypistの時のみ更新するようにしたが問題ないか ## 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/Task1997?csf=1&web=1&e=9kLaxo ## 動作確認状況 - ローカルで確認 ## 補足 - Authorの挙動はAPI側の実装が完了していないので、未確認
This commit is contained in:
parent
d6db89bc2c
commit
3a7bf60f3e
@ -2,3 +2,4 @@ VITE_STAGE=develop
|
||||
VITE_B2C_CLIENTID=5eb34cba-84b6-46f9-a0ea-bc5c41157d63
|
||||
VITE_B2C_AUTHORITY=https://adb2codmsdev.b2clogin.com/adb2codmsdev.onmicrosoft.com/b2c_1_signin_dev
|
||||
VITE_B2C_KNOWNAUTHORITIES=adb2codmsdev.b2clogin.com
|
||||
VITE_DESK_TOP_APP_SCHEME=odms-desktopapp
|
||||
@ -2,3 +2,4 @@ VITE_STAGE=local
|
||||
VITE_B2C_CLIENTID=XXXX-XXXX-XXXXX-XXXX
|
||||
VITE_B2C_AUTHORITY=https://adb2XXXX.XXXX.com/adb2XXXX.onmicrosoft.com/XXXX
|
||||
VITE_B2C_KNOWNAUTHORITIES=adb2cXXXX.XXXx.com
|
||||
VITE_DESK_TOP_APP_SCHEME=odms-desktopapp
|
||||
@ -2,3 +2,4 @@ VITE_STAGE=staging
|
||||
VITE_B2C_CLIENTID=5d8f0db9-4506-41d6-a5bb-5ec39f6eba8d
|
||||
VITE_B2C_AUTHORITY=https://adb2codmsstg.b2clogin.com/adb2codmsstg.onmicrosoft.com/b2c_1_signin_stg
|
||||
VITE_B2C_KNOWNAUTHORITIES=adb2codmsstg.b2clogin.com
|
||||
VITE_DESK_TOP_APP_SCHEME=odms-desktopapp
|
||||
@ -2408,7 +2408,7 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration
|
||||
/**
|
||||
* 指定した文字起こしタスクのチェックアウト候補を変更します。
|
||||
* @summary
|
||||
* @param {number} audioFileId
|
||||
* @param {number} audioFileId ODMS Cloud上の音声ファイルID
|
||||
* @param {PostCheckoutPermissionRequest} postCheckoutPermissionRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
@ -2736,7 +2736,7 @@ export const TasksApiFp = function(configuration?: Configuration) {
|
||||
/**
|
||||
* 指定した文字起こしタスクのチェックアウト候補を変更します。
|
||||
* @summary
|
||||
* @param {number} audioFileId
|
||||
* @param {number} audioFileId ODMS Cloud上の音声ファイルID
|
||||
* @param {PostCheckoutPermissionRequest} postCheckoutPermissionRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
@ -2848,7 +2848,7 @@ export const TasksApiFactory = function (configuration?: Configuration, basePath
|
||||
/**
|
||||
* 指定した文字起こしタスクのチェックアウト候補を変更します。
|
||||
* @summary
|
||||
* @param {number} audioFileId
|
||||
* @param {number} audioFileId ODMS Cloud上の音声ファイルID
|
||||
* @param {PostCheckoutPermissionRequest} postCheckoutPermissionRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
@ -2957,7 +2957,7 @@ export class TasksApi extends BaseAPI {
|
||||
/**
|
||||
* 指定した文字起こしタスクのチェックアウト候補を変更します。
|
||||
* @summary
|
||||
* @param {number} audioFileId
|
||||
* @param {number} audioFileId ODMS Cloud上の音声ファイルID
|
||||
* @param {PostCheckoutPermissionRequest} postCheckoutPermissionRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
@ -3163,7 +3163,7 @@ export const UsersApiAxiosParamCreator = function (configuration?: Configuration
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getSortCcriteria: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
getSortCriteria: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/users/sort-criteria`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
@ -3272,9 +3272,9 @@ export const UsersApiAxiosParamCreator = function (configuration?: Configuration
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
updateSortCcriteria: async (postSortCriteriaRequest: PostSortCriteriaRequest, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
updateSortCriteria: async (postSortCriteriaRequest: PostSortCriteriaRequest, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'postSortCriteriaRequest' is not null or undefined
|
||||
assertParamExists('updateSortCcriteria', 'postSortCriteriaRequest', postSortCriteriaRequest)
|
||||
assertParamExists('updateSortCriteria', 'postSortCriteriaRequest', postSortCriteriaRequest)
|
||||
const localVarPath = `/users/sort-criteria`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
@ -3353,8 +3353,8 @@ export const UsersApiFp = function(configuration?: Configuration) {
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getSortCcriteria(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<GetSortCriteriaResponse>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getSortCcriteria(options);
|
||||
async getSortCriteria(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<GetSortCriteriaResponse>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getSortCriteria(options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
@ -3385,8 +3385,8 @@ export const UsersApiFp = function(configuration?: Configuration) {
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async updateSortCcriteria(postSortCriteriaRequest: PostSortCriteriaRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<object>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.updateSortCcriteria(postSortCriteriaRequest, options);
|
||||
async updateSortCriteria(postSortCriteriaRequest: PostSortCriteriaRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<object>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.updateSortCriteria(postSortCriteriaRequest, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
}
|
||||
@ -3434,8 +3434,8 @@ export const UsersApiFactory = function (configuration?: Configuration, basePath
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getSortCcriteria(options?: any): AxiosPromise<GetSortCriteriaResponse> {
|
||||
return localVarFp.getSortCcriteria(options).then((request) => request(axios, basePath));
|
||||
getSortCriteria(options?: any): AxiosPromise<GetSortCriteriaResponse> {
|
||||
return localVarFp.getSortCriteria(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
@ -3463,8 +3463,8 @@ export const UsersApiFactory = function (configuration?: Configuration, basePath
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
updateSortCcriteria(postSortCriteriaRequest: PostSortCriteriaRequest, options?: any): AxiosPromise<object> {
|
||||
return localVarFp.updateSortCcriteria(postSortCriteriaRequest, options).then((request) => request(axios, basePath));
|
||||
updateSortCriteria(postSortCriteriaRequest: PostSortCriteriaRequest, options?: any): AxiosPromise<object> {
|
||||
return localVarFp.updateSortCriteria(postSortCriteriaRequest, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
@ -3518,8 +3518,8 @@ export class UsersApi extends BaseAPI {
|
||||
* @throws {RequiredError}
|
||||
* @memberof UsersApi
|
||||
*/
|
||||
public getSortCcriteria(options?: AxiosRequestConfig) {
|
||||
return UsersApiFp(this.configuration).getSortCcriteria(options).then((request) => request(this.axios, this.basePath));
|
||||
public getSortCriteria(options?: AxiosRequestConfig) {
|
||||
return UsersApiFp(this.configuration).getSortCriteria(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3553,8 +3553,8 @@ export class UsersApi extends BaseAPI {
|
||||
* @throws {RequiredError}
|
||||
* @memberof UsersApi
|
||||
*/
|
||||
public updateSortCcriteria(postSortCriteriaRequest: PostSortCriteriaRequest, options?: AxiosRequestConfig) {
|
||||
return UsersApiFp(this.configuration).updateSortCcriteria(postSortCriteriaRequest, options).then((request) => request(this.axios, this.basePath));
|
||||
public updateSortCriteria(postSortCriteriaRequest: PostSortCriteriaRequest, options?: AxiosRequestConfig) {
|
||||
return UsersApiFp(this.configuration).updateSortCriteria(postSortCriteriaRequest, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,5 +25,6 @@ export const errorCodes = [
|
||||
"E010301", // メールアドレス登録済みエラー
|
||||
"E010302", // authorId重複エラー
|
||||
"E010401", // PONumber重複エラー
|
||||
"E010601", // タスク変更不可エラー
|
||||
"E010601", // タスク変更不可エラー(タスクが変更できる状態でない、またはタスクが存在しない)
|
||||
"E010602", // タスク変更権限不足エラー
|
||||
] as const;
|
||||
|
||||
@ -79,3 +79,16 @@ export const isAuthorUser = (): boolean => {
|
||||
}
|
||||
return token.role.includes(USER_ROLES.AUTHOR);
|
||||
};
|
||||
|
||||
/**
|
||||
* is author user ログインしているユーザがAuthorかどうかを返す
|
||||
* @returns bool
|
||||
*/
|
||||
export const isTypistUser = (): boolean => {
|
||||
const jwt = loadAccessToken();
|
||||
const token = jwt ? decodeToken(jwt) : null;
|
||||
if (!token) {
|
||||
return false;
|
||||
}
|
||||
return token.role.includes(USER_ROLES.TYPIST);
|
||||
};
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
listTasksAsync,
|
||||
listTypistGroupsAsync,
|
||||
listTypistsAsync,
|
||||
playbackAsync,
|
||||
updateAssigneeAsync,
|
||||
} from "./operations";
|
||||
import {
|
||||
@ -131,6 +132,15 @@ export const dictationSlice = createSlice({
|
||||
builder.addCase(updateAssigneeAsync.rejected, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(playbackAsync.pending, (state) => {
|
||||
state.apps.isLoading = true;
|
||||
});
|
||||
builder.addCase(playbackAsync.fulfilled, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
builder.addCase(playbackAsync.rejected, (state) => {
|
||||
state.apps.isLoading = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ export const getSortColumnAsync = createAsyncThunk<
|
||||
const usersApi = new UsersApi(config);
|
||||
|
||||
try {
|
||||
const sort = await usersApi.getSortCcriteria({
|
||||
const sort = await usersApi.getSortCriteria({
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
});
|
||||
|
||||
@ -125,52 +125,6 @@ export const getSortColumnAsync = createAsyncThunk<
|
||||
}
|
||||
});
|
||||
|
||||
export const updateSortColumnAsync = createAsyncThunk<
|
||||
{
|
||||
/** empty */
|
||||
},
|
||||
{
|
||||
// パラメータ
|
||||
direction: DirectionType;
|
||||
paramName: SortableColumnType;
|
||||
},
|
||||
{
|
||||
// rejectした時の返却値の型
|
||||
rejectValue: {
|
||||
error: ErrorObject;
|
||||
};
|
||||
}
|
||||
>("dictations/updateSortColumnAsync", async (args, thunkApi) => {
|
||||
const { direction, paramName } = args;
|
||||
|
||||
// apiのConfigurationを取得する
|
||||
const { getState } = thunkApi;
|
||||
const state = getState() as RootState;
|
||||
const { configuration, accessToken } = state.auth;
|
||||
const config = new Configuration(configuration);
|
||||
const usersApi = new UsersApi(config);
|
||||
|
||||
try {
|
||||
await usersApi.updateSortCcriteria(
|
||||
{ direction, paramName },
|
||||
{
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
}
|
||||
);
|
||||
return {};
|
||||
} catch (e) {
|
||||
// e ⇒ errorObjectに変換"
|
||||
const error = createErrorObject(e);
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message: getTranslationID("common.message.internalServerError"),
|
||||
})
|
||||
);
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
});
|
||||
|
||||
export const listTypistsAsync = createAsyncThunk<
|
||||
GetTypistsResponse,
|
||||
void,
|
||||
@ -275,6 +229,12 @@ export const updateAssigneeAsync = createAsyncThunk<
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
}
|
||||
);
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "info",
|
||||
message: getTranslationID("common.message.success"),
|
||||
})
|
||||
);
|
||||
return {};
|
||||
} catch (e) {
|
||||
// e ⇒ errorObjectに変換"
|
||||
@ -300,3 +260,88 @@ export const updateAssigneeAsync = createAsyncThunk<
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
});
|
||||
|
||||
export const playbackAsync = createAsyncThunk<
|
||||
{
|
||||
/** empty */
|
||||
},
|
||||
{
|
||||
direction: DirectionType;
|
||||
paramName: SortableColumnType;
|
||||
audioFileId: number;
|
||||
isTypist: boolean;
|
||||
},
|
||||
{
|
||||
// rejectした時の返却値の型
|
||||
rejectValue: {
|
||||
error: ErrorObject;
|
||||
};
|
||||
}
|
||||
>("dictations/playbackAsync", async (args, thunkApi) => {
|
||||
const { audioFileId, direction, paramName, isTypist } = args;
|
||||
|
||||
// apiのConfigurationを取得する
|
||||
const { getState } = thunkApi;
|
||||
const state = getState() as RootState;
|
||||
const { configuration, accessToken } = state.auth;
|
||||
const config = new Configuration(configuration);
|
||||
const tasksApi = new TasksApi(config);
|
||||
const usersApi = new UsersApi(config);
|
||||
try {
|
||||
// ユーザーがタイピストである場合に、ソート条件を保存する
|
||||
if (isTypist) {
|
||||
await usersApi.updateSortCriteria(
|
||||
{ direction, paramName },
|
||||
{
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
}
|
||||
);
|
||||
}
|
||||
await tasksApi.checkout(audioFileId, {
|
||||
headers: { authorization: `Bearer ${accessToken}` },
|
||||
});
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "info",
|
||||
message: getTranslationID("common.message.success"),
|
||||
})
|
||||
);
|
||||
return {};
|
||||
} catch (e) {
|
||||
// e ⇒ errorObjectに変換"
|
||||
const error = createErrorObject(e);
|
||||
|
||||
// ステータスが[Uploaded,Inprogress,Pending]以外、またはタスクが存在しない場合
|
||||
if (error.code === "E010601") {
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message: getTranslationID(
|
||||
"dictationPage.message.taskToPlaybackNoExists"
|
||||
),
|
||||
})
|
||||
);
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
// タスクをチェックアウトする権限がない
|
||||
if (error.code === "E010602") {
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message: getTranslationID(
|
||||
"dictationPage.message.noPlaybackAuthorization"
|
||||
),
|
||||
})
|
||||
);
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
|
||||
thunkApi.dispatch(
|
||||
openSnackbar({
|
||||
level: "error",
|
||||
message: getTranslationID("common.message.internalServerError"),
|
||||
})
|
||||
);
|
||||
return thunkApi.rejectWithValue({ error });
|
||||
}
|
||||
});
|
||||
|
||||
@ -23,17 +23,17 @@ import {
|
||||
changeParamName,
|
||||
changeDirection,
|
||||
changeSelectedTask,
|
||||
updateSortColumnAsync,
|
||||
SortableColumnType,
|
||||
changeAssignee,
|
||||
listTypistsAsync,
|
||||
listTypistGroupsAsync,
|
||||
DirectionType,
|
||||
selectIsLoading,
|
||||
playbackAsync,
|
||||
} from "features/dictation";
|
||||
import { getTranslationID } from "translation";
|
||||
import { Task } from "api/api";
|
||||
import { isAdminUser, isAuthorUser } from "features/auth/utils";
|
||||
import { isAdminUser, isAuthorUser, isTypistUser } from "features/auth/utils";
|
||||
import { STATUS, LIMIT_TASK_NUM } from "../../features/dictation";
|
||||
import uploaded from "../../assets/images/uploaded.svg";
|
||||
import pending from "../../assets/images/pending.svg";
|
||||
@ -51,6 +51,7 @@ const DictationPage: React.FC = (): JSX.Element => {
|
||||
|
||||
const isAdmin = isAdminUser();
|
||||
const isAuthor = isAuthorUser();
|
||||
const isTypist = isTypistUser();
|
||||
// popup制御関係
|
||||
const [
|
||||
isChangeTranscriptionistPopupOpen,
|
||||
@ -316,14 +317,65 @@ const DictationPage: React.FC = (): JSX.Element => {
|
||||
[dispatch, sortDirection, sortableParamName]
|
||||
);
|
||||
|
||||
const onPlayBack = useCallback(() => {
|
||||
dispatch(
|
||||
updateSortColumnAsync({
|
||||
direction: sortDirection,
|
||||
paramName: sortableParamName,
|
||||
})
|
||||
);
|
||||
}, [dispatch, sortDirection, sortableParamName]);
|
||||
const onPlayBack = useCallback(
|
||||
async (audioFileId: number) => {
|
||||
if (
|
||||
/* eslint-disable-next-line no-alert */
|
||||
!window.confirm(t(getTranslationID("common.message.dialogConfirm")))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const { meta } = await dispatch(
|
||||
playbackAsync({
|
||||
audioFileId,
|
||||
direction: sortDirection,
|
||||
paramName: sortableParamName,
|
||||
isTypist,
|
||||
})
|
||||
);
|
||||
if (meta.requestStatus === "fulfilled") {
|
||||
const filter = getFilter(
|
||||
filterUploaded,
|
||||
filterInProgress,
|
||||
filterPending,
|
||||
filterFinished,
|
||||
filterBackup
|
||||
);
|
||||
dispatch(
|
||||
listTasksAsync({
|
||||
limit: LIMIT_TASK_NUM,
|
||||
offset: 0,
|
||||
filter,
|
||||
direction: sortDirection,
|
||||
paramName: sortableParamName,
|
||||
})
|
||||
);
|
||||
dispatch(listTypistsAsync());
|
||||
dispatch(listTypistGroupsAsync());
|
||||
|
||||
const url = `${
|
||||
import.meta.env.VITE_DESK_TOP_APP_SCHEME
|
||||
}:playback?audioId=${audioFileId}`;
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
},
|
||||
[
|
||||
dispatch,
|
||||
filterBackup,
|
||||
filterFinished,
|
||||
filterInProgress,
|
||||
filterPending,
|
||||
filterUploaded,
|
||||
isTypist,
|
||||
sortDirection,
|
||||
sortableParamName,
|
||||
t,
|
||||
]
|
||||
);
|
||||
|
||||
const onClosePopup = useCallback(
|
||||
(isChanged: boolean) => {
|
||||
@ -949,7 +1001,7 @@ const DictationPage: React.FC = (): JSX.Element => {
|
||||
<ul className={styles.menuInTable}>
|
||||
<li>
|
||||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
|
||||
<a onClick={onPlayBack}>
|
||||
<a onClick={() => onPlayBack(x.audioFileId)}>
|
||||
{t(
|
||||
getTranslationID(
|
||||
"dictationPage.label.playback"
|
||||
|
||||
@ -32,10 +32,11 @@ const LoginPage: React.FC = (): JSX.Element => {
|
||||
if (meta.requestStatus === "fulfilled") {
|
||||
const accessToken = loadAccessToken();
|
||||
const refreshToken = loadRefreshToken();
|
||||
/* TODO 1899:デスクトップアプリが無いためメモ帳を開くようにしている
|
||||
デスクトップアプリチームでスキーム名が決まり次第修正する
|
||||
*/
|
||||
const url = `note:login?accessToken=${accessToken}&refreshToken=${refreshToken}&language=${i18n.language}`; // カスタムURLスキーム
|
||||
const url = `${
|
||||
import.meta.env.VITE_DESK_TOP_APP_SCHEME
|
||||
}:login?accessToken=${accessToken}&refreshToken=${refreshToken}&language=${
|
||||
i18n.language
|
||||
}`; // カスタムURLスキーム
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
document.body.appendChild(a);
|
||||
|
||||
1
dictation_client/src/react-app-env.d.ts
vendored
1
dictation_client/src/react-app-env.d.ts
vendored
@ -6,6 +6,7 @@ interface ImportMetaEnv {
|
||||
readonly VITE_B2C_CLIENTID: string;
|
||||
readonly VITE_B2C_AUTHORITY: string;
|
||||
readonly VITE_B2C_KNOWNAUTHORITIES: string;
|
||||
readonly VITE_DESK_TOP_APP_SCHEME: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
|
||||
@ -174,6 +174,8 @@
|
||||
},
|
||||
"dictationPage": {
|
||||
"message": {
|
||||
"noPlaybackAuthorization": "(de)本タスクをPlayBackできる権限がありません。",
|
||||
"taskToPlaybackNoExists": "(de)タスクがすでに文字起こし完了済みまたは存在しないため、PlayBackできません。",
|
||||
"taskNotEditable": "(de)すでに文字起こし作業着手中またはタスクが存在しないため、タイピストを変更できません。"
|
||||
},
|
||||
"label": {
|
||||
|
||||
@ -174,6 +174,8 @@
|
||||
},
|
||||
"dictationPage": {
|
||||
"message": {
|
||||
"noPlaybackAuthorization": "本タスクをPlayBackできる権限がありません。",
|
||||
"taskToPlaybackNoExists": "タスクがすでに文字起こし完了済みまたは存在しないため、PlayBackできません。",
|
||||
"taskNotEditable": "すでに文字起こし作業着手中またはタスクが存在しないため、タイピストを変更できません。"
|
||||
},
|
||||
"label": {
|
||||
|
||||
@ -174,6 +174,8 @@
|
||||
},
|
||||
"dictationPage": {
|
||||
"message": {
|
||||
"noPlaybackAuthorization": "(es)本タスクをPlayBackできる権限がありません。",
|
||||
"taskToPlaybackNoExists": "(es)タスクがすでに文字起こし完了済みまたは存在しないため、PlayBackできません。",
|
||||
"taskNotEditable": "(es)すでに文字起こし作業着手中またはタスクが存在しないため、タイピストを変更できません。"
|
||||
},
|
||||
"label": {
|
||||
|
||||
@ -174,6 +174,8 @@
|
||||
},
|
||||
"dictationPage": {
|
||||
"message": {
|
||||
"noPlaybackAuthorization": "(fr)本タスクをPlayBackできる権限がありません。",
|
||||
"taskToPlaybackNoExists": "(fr)タスクがすでに文字起こし完了済みまたは存在しないため、PlayBackできません。",
|
||||
"taskNotEditable": "(fr)すでに文字起こし作業着手中またはタスクが存在しないため、タイピストを変更できません。"
|
||||
},
|
||||
"label": {
|
||||
|
||||
@ -510,7 +510,7 @@
|
||||
},
|
||||
"/users/sort-criteria": {
|
||||
"post": {
|
||||
"operationId": "updateSortCcriteria",
|
||||
"operationId": "updateSortCriteria",
|
||||
"summary": "",
|
||||
"description": "ログインしているユーザーのタスクソート条件を更新します",
|
||||
"parameters": [],
|
||||
@ -564,7 +564,7 @@
|
||||
"security": [{ "bearer": [] }]
|
||||
},
|
||||
"get": {
|
||||
"operationId": "getSortCcriteria",
|
||||
"operationId": "getSortCriteria",
|
||||
"summary": "",
|
||||
"description": "ログインしているユーザーのタスクソート条件を取得します",
|
||||
"parameters": [],
|
||||
|
||||
@ -249,7 +249,7 @@ export class UsersController {
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiOperation({
|
||||
operationId: 'updateSortCcriteria',
|
||||
operationId: 'updateSortCriteria',
|
||||
description: 'ログインしているユーザーのタスクソート条件を更新します',
|
||||
})
|
||||
@ApiBearerAuth()
|
||||
@ -297,7 +297,7 @@ export class UsersController {
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiOperation({
|
||||
operationId: 'getSortCcriteria',
|
||||
operationId: 'getSortCriteria',
|
||||
description: 'ログインしているユーザーのタスクソート条件を取得します',
|
||||
})
|
||||
@ApiBearerAuth()
|
||||
|
||||
@ -641,79 +641,79 @@ const makeOrder = (
|
||||
switch (sort_criteria) {
|
||||
case 'JOB_NUMBER':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
job_number: direction,
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'STATUS':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
status: direction,
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'TRANSCRIPTION_FINISHED_DATE':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
finished_at: direction,
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'TRANSCRIPTION_STARTED_DATE':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
started_at: direction,
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'AUTHOR_ID':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { author_id: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'ENCRYPTION':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { is_encrypted: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'FILE_LENGTH':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { duration: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'FILE_NAME':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { file_name: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'FILE_SIZE':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { file_size: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'RECORDING_FINISHED_DATE':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { finished_at: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'RECORDING_STARTED_DATE':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { started_at: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'UPLOAD_DATE':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { uploaded_at: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
case 'WORK_TYPE':
|
||||
return {
|
||||
priority: 'ASC',
|
||||
priority: 'DESC',
|
||||
file: { work_type_id: direction },
|
||||
id: 'ASC',
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user