Merged PR 454: ワークフロー一覧画面

## 概要
[Task2735: ワークフロー一覧画面](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2735)

- ワークフロー一覧画面のデザイン反映
- 多言語対応
- 一覧取得API呼び出し

## レビューポイント
- デザイン反映に問題はないか
- フォルダ構成はこれでよいか
  - workflow配下に直置き

## UIの変更
- https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88/Task2735?csf=1&web=1&e=IelNET

## 動作確認状況
- ローカルで確認

## 補足
- 相談、参考資料などがあれば
This commit is contained in:
saito.k 2023-10-03 02:15:57 +00:00
parent 1cc7a0141d
commit 088e6afc85
19 changed files with 806 additions and 31 deletions

View File

@ -335,6 +335,25 @@ export interface AudioUploadLocationResponse {
*/
'url': string;
}
/**
*
* @export
* @interface Author
*/
export interface Author {
/**
* Authorユーザーの内部ID
* @type {number}
* @memberof Author
*/
'id': number;
/**
* AuthorID
* @type {string}
* @memberof Author
*/
'authorId': string;
}
/**
*
* @export
@ -504,6 +523,37 @@ export interface CreateTypistGroupRequest {
*/
'typistIds': Array<number>;
}
/**
*
* @export
* @interface CreateWorkflowsRequest
*/
export interface CreateWorkflowsRequest {
/**
* Authornの内部ID
* @type {number}
* @memberof CreateWorkflowsRequest
*/
'authorId': number;
/**
* Worktypeの内部ID
* @type {number}
* @memberof CreateWorkflowsRequest
*/
'worktypeId'?: number;
/**
* ID
* @type {number}
* @memberof CreateWorkflowsRequest
*/
'templateId'?: number;
/**
* /
* @type {Array<WorkflowTypist>}
* @memberof CreateWorkflowsRequest
*/
'typists': Array<WorkflowTypist>;
}
/**
*
* @export
@ -606,6 +656,19 @@ export interface GetAllocatableLicensesResponse {
*/
'allocatableLicenses': Array<AllocatableLicenseInfo>;
}
/**
*
* @export
* @interface GetAuthorsResponse
*/
export interface GetAuthorsResponse {
/**
*
* @type {Array<Author>}
* @memberof GetAuthorsResponse
*/
'authors': Array<Author>;
}
/**
*
* @export
@ -989,6 +1052,19 @@ export interface GetUsersResponse {
*/
'users': Array<User>;
}
/**
*
* @export
* @interface GetWorkflowsResponse
*/
export interface GetWorkflowsResponse {
/**
*
* @type {Array<Workflow>}
* @memberof GetWorkflowsResponse
*/
'workflows': Array<Workflow>;
}
/**
*
* @export
@ -1963,6 +2039,100 @@ export interface User {
*/
'licenseStatus': string;
}
/**
*
* @export
* @interface Workflow
*/
export interface Workflow {
/**
* ID
* @type {number}
* @memberof Workflow
*/
'id': number;
/**
*
* @type {Author}
* @memberof Workflow
*/
'author': Author;
/**
*
* @type {WorkflowWorktype}
* @memberof Workflow
*/
'worktype'?: WorkflowWorktype;
/**
*
* @type {WorkflowTemplate}
* @memberof Workflow
*/
'template'?: WorkflowTemplate;
/**
* /
* @type {Array<Assignee>}
* @memberof Workflow
*/
'typists': Array<Assignee>;
}
/**
*
* @export
* @interface WorkflowTemplate
*/
export interface WorkflowTemplate {
/**
* ID
* @type {number}
* @memberof WorkflowTemplate
*/
'id': number;
/**
*
* @type {string}
* @memberof WorkflowTemplate
*/
'fileName': string;
}
/**
*
* @export
* @interface WorkflowTypist
*/
export interface WorkflowTypist {
/**
* ID
* @type {number}
* @memberof WorkflowTypist
*/
'typistId'?: number;
/**
* ID
* @type {number}
* @memberof WorkflowTypist
*/
'typistGroupId'?: number;
}
/**
*
* @export
* @interface WorkflowWorktype
*/
export interface WorkflowWorktype {
/**
* Worktypeの内部ID
* @type {number}
* @memberof WorkflowWorktype
*/
'id': number;
/**
* WorktypeID
* @type {string}
* @memberof WorkflowWorktype
*/
'worktypeId': string;
}
/**
*
* @export
@ -2271,6 +2441,40 @@ export const AccountsApiAxiosParamCreator = function (configuration?: Configurat
options: localVarRequestOptions,
};
},
/**
* Author一覧を取得します
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getAuthors: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/accounts/authors`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication bearer required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary
@ -2980,6 +3184,16 @@ export const AccountsApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.deleteAccount(deleteAccountRequest, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
* Author一覧を取得します
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getAuthors(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<GetAuthorsResponse>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.getAuthors(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @summary
@ -3235,6 +3449,15 @@ export const AccountsApiFactory = function (configuration?: Configuration, baseP
deleteAccount(deleteAccountRequest: DeleteAccountRequest, options?: any): AxiosPromise<object> {
return localVarFp.deleteAccount(deleteAccountRequest, options).then((request) => request(axios, basePath));
},
/**
* Author一覧を取得します
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getAuthors(options?: any): AxiosPromise<GetAuthorsResponse> {
return localVarFp.getAuthors(options).then((request) => request(axios, basePath));
},
/**
*
* @summary
@ -3488,6 +3711,17 @@ export class AccountsApi extends BaseAPI {
return AccountsApiFp(this.configuration).deleteAccount(deleteAccountRequest, options).then((request) => request(this.axios, this.basePath));
}
/**
* Author一覧を取得します
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof AccountsApi
*/
public getAuthors(options?: AxiosRequestConfig) {
return AccountsApiFp(this.configuration).getAuthors(options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary
@ -6481,3 +6715,179 @@ export class UsersApi extends BaseAPI {
/**
* WorkflowsApi - axios parameter creator
* @export
*/
export const WorkflowsApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @summary
* @param {CreateWorkflowsRequest} createWorkflowsRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createWorkflows: async (createWorkflowsRequest: CreateWorkflowsRequest, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'createWorkflowsRequest' is not null or undefined
assertParamExists('createWorkflows', 'createWorkflowsRequest', createWorkflowsRequest)
const localVarPath = `/workflows`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication bearer required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(createWorkflowsRequest, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getWorkflows: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/workflows`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication bearer required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
}
};
/**
* WorkflowsApi - functional programming interface
* @export
*/
export const WorkflowsApiFp = function(configuration?: Configuration) {
const localVarAxiosParamCreator = WorkflowsApiAxiosParamCreator(configuration)
return {
/**
*
* @summary
* @param {CreateWorkflowsRequest} createWorkflowsRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async createWorkflows(createWorkflowsRequest: CreateWorkflowsRequest, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<object>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.createWorkflows(createWorkflowsRequest, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getWorkflows(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<GetWorkflowsResponse>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.getWorkflows(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
}
};
/**
* WorkflowsApi - factory interface
* @export
*/
export const WorkflowsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
const localVarFp = WorkflowsApiFp(configuration)
return {
/**
*
* @summary
* @param {CreateWorkflowsRequest} createWorkflowsRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
createWorkflows(createWorkflowsRequest: CreateWorkflowsRequest, options?: any): AxiosPromise<object> {
return localVarFp.createWorkflows(createWorkflowsRequest, options).then((request) => request(axios, basePath));
},
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getWorkflows(options?: any): AxiosPromise<GetWorkflowsResponse> {
return localVarFp.getWorkflows(options).then((request) => request(axios, basePath));
},
};
};
/**
* WorkflowsApi - object-oriented interface
* @export
* @class WorkflowsApi
* @extends {BaseAPI}
*/
export class WorkflowsApi extends BaseAPI {
/**
*
* @summary
* @param {CreateWorkflowsRequest} createWorkflowsRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof WorkflowsApi
*/
public createWorkflows(createWorkflowsRequest: CreateWorkflowsRequest, options?: AxiosRequestConfig) {
return WorkflowsApiFp(this.configuration).createWorkflows(createWorkflowsRequest, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof WorkflowsApi
*/
public getWorkflows(options?: AxiosRequestConfig) {
return WorkflowsApiFp(this.configuration).getWorkflows(options).then((request) => request(this.axios, this.basePath));
}
}

View File

@ -17,6 +17,7 @@ import typistGroup from "features/workflow/typistGroup/typistGroupSlice";
import worktype from "features/workflow/worktype/worktypeSlice";
import account from "features/account/accountSlice";
import template from "features/workflow/template/templateSlice";
import workflow from "features/workflow/workflowSlice";
export const store = configureStore({
reducer: {
@ -38,6 +39,7 @@ export const store = configureStore({
worktype,
account,
template,
workflow,
},
});

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.8.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve">
<style type="text/css">
.st0{fill:#282828;}
</style>
<path class="st0" d="M24,32.3l-9.6-9.6l2.1-2.1l6,6V8h3v18.6l6-6l2.2,2.1L24,32.3z M11,40c-0.8,0-1.5-0.3-2.1-0.9
C8.3,38.5,8,37.8,8,37v-7.1h3V37h26v-7.1h3V37c0,0.8-0.3,1.5-0.9,2.1C38.5,39.7,37.8,40,37,40H11z"/>
</svg>

After

Width:  |  Height:  |  Size: 623 B

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.8.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve">
<style type="text/css">
.st0{fill:#282828;}
</style>
<path class="st0" d="M9,42c-0.8,0-1.5-0.3-2.1-0.9C6.3,40.5,6,39.8,6,39V28.5h3V39h30V9H9v10.5H6V9c0-0.8,0.3-1.5,0.9-2.1S8.2,6,9,6
h30c0.8,0,1.5,0.3,2.1,0.9C41.7,7.5,42,8.2,42,9v30c0,0.8-0.3,1.5-0.9,2.1C40.5,41.7,39.8,42,39,42H9z M20.6,33.6l-2.2-2.3l5.9-5.9
H6v-3h18.3l-5.9-5.9l2.2-2.2l9.7,9.6L20.6,33.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 721 B

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.7.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve">
<style type="text/css">
.st0{fill:#282828;}
</style>
<g>
<path class="st0" d="M25.7,23.7c2.5,0.6,4.8,0.2,6.7-1.2s2.9-3.4,2.9-6.1s-1-4.8-2.9-6.1c-1.9-1.3-4.1-1.7-6.7-1.1
c0.9,1.1,1.5,2.2,1.9,3.3c0.4,1.1,0.6,2.5,0.6,4s-0.2,2.8-0.6,3.9C27.2,21.5,26.6,22.6,25.7,23.7z"/>
<path class="st0" d="M17.8,24c2.2,0,4-0.7,5.4-2.1c1.4-1.4,2.1-3.2,2.1-5.4c0-2.2-0.7-4-2.1-5.4C21.8,9.6,20,9,17.8,9
s-4,0.7-5.4,2.1c-1.4,1.4-2.1,3.2-2.1,5.4c0,2.2,0.7,4,2.1,5.4C13.8,23.2,15.5,24,17.8,24z M14.5,13.2c0.8-0.8,1.9-1.3,3.2-1.3
s2.4,0.4,3.2,1.3c0.9,0.9,1.3,1.9,1.3,3.2c0,1.3-0.4,2.4-1.3,3.2C20.1,20.5,19,21,17.8,21s-2.4-0.4-3.2-1.3
c-0.9-0.8-1.3-1.9-1.3-3.2C13.2,15.1,13.7,14.1,14.5,13.2z"/>
<path class="st0" d="M44,36.5c0-0.6-0.1-1.3-0.2-2.1l1.9-1.5l-1.8-2.8l-2.1,1c-0.4-0.4-1-0.8-1.7-1.2c-0.7-0.4-1.4-0.7-2-0.9
l-0.3-2.5h-3l-0.2,2.5c-0.7,0.2-1.4,0.5-2.1,0.9c-0.7,0.4-1.3,0.8-1.7,1.2l-2.1-1l-1.8,2.8l1.9,1.5c-0.2,0.8-0.2,1.5-0.2,2.1
c0,0.6,0.1,1.3,0.2,2.1l-1.9,1.5l1.8,2.7l2.1-1c0.4,0.5,1,0.9,1.7,1.3c0.7,0.4,1.4,0.7,2.1,0.9l0.2,2.4h3l0.3-2.4
c0.7-0.2,1.3-0.5,2-0.9c0.7-0.4,1.3-0.8,1.7-1.3l2.1,1l1.8-2.7l-1.9-1.5C43.9,37.8,44,37.1,44,36.5z M39.9,40.1
c-1,1-2.2,1.5-3.6,1.5c-1.5,0-2.7-0.5-3.7-1.5s-1.5-2.2-1.5-3.6c0-1.5,0.5-2.7,1.5-3.7s2.2-1.5,3.7-1.5c1.5,0,2.7,0.5,3.6,1.5
s1.5,2.2,1.5,3.7C41.3,38,40.8,39.2,39.9,40.1z"/>
<path class="st0" d="M5,37v-1.7c0-0.5,0.1-1,0.4-1.5s0.7-0.8,1.2-1.1c2.4-1.1,4.3-1.8,5.9-2.2c1.6-0.4,3.3-0.5,5.2-0.5
s3.7,0.2,5.2,0.5c0.4,0.1,0.9,0.2,1.4,0.4c0.7-0.8,1.5-1.6,2.4-2.3c-1.1-0.4-2.2-0.7-3.1-1c-1.9-0.5-3.8-0.7-5.9-0.7
s-4,0.2-5.9,0.7c-1.9,0.5-4,1.2-6.4,2.3c-1,0.5-1.9,1.2-2.5,2.1c-0.6,1-0.9,2-0.9,3.2V40h19.1c0-1,0.1-2,0.3-3H5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.9.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve">
<style type="text/css">
.st0{fill:#282828;}
</style>
<path class="st0" d="M9,42c-0.8,0-1.5-0.3-2.1-0.9C6.3,40.5,6,39.8,6,39V9c0-0.8,0.3-1.5,0.9-2.1S8.2,6,9,6h15v3H9v30h15v3H9z
M33.3,32.7l-2.1-2.1l5.1-5.1H18v-3h18.2l-5.1-5.1l2.1-2.1L42,24L33.3,32.7z"/>
</svg>

After

Width:  |  Height:  |  Size: 614 B

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.7.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve">
<style type="text/css">
.st0{fill:#282828;}
</style>
<path class="st0" d="M6.6,40v-3h6.2l-0.7-0.7c-2-2-3.4-4-4.3-6.1s-1.3-4.1-1.3-6c0-3.6,1-6.9,3.1-9.8s4.8-4.8,8.2-5.9v3.1
c-2.5,1-4.6,2.6-6.1,4.9s-2.3,4.9-2.3,7.7c0,1.7,0.3,3.4,0.9,4.9c0.6,1.6,1.6,3,3,4.2l1.5,1.3v-5.9h3V40H6.6z M41.5,23.3h-3
c-0.1-1.7-0.4-3.3-1-4.7c-0.6-1.5-1.5-2.8-2.8-3.9l-1.5-1.4v5.8h-3V8h11.2v3h-6.2l0.8,0.7c1.9,1.8,3.3,3.8,4.2,5.8
S41.5,21.4,41.5,23.3z M31.9,42.6v-6.5h-6.5v-3.9h6.5v-6.5h3.9v6.5h6.5v3.9h-6.5v6.5H31.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 857 B

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.7.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve">
<style type="text/css">
.st0{fill:#282828;}
</style>
<path class="st0" d="M11,44c-0.8,0-1.5-0.3-2.1-0.9C8.3,42.5,8,41.8,8,41V7c0-0.8,0.3-1.5,0.9-2.1C9.5,4.3,10.2,4,11,4h17l12,12v5.8
h-3V18H26V7H11v34h13v3H11z M11,41V7V41z M34.9,45.7l-0.2-2.4c-0.7-0.2-1.4-0.5-2.1-0.9c-0.7-0.4-1.3-0.8-1.7-1.3l-2.1,1L27,39.5
l1.9-1.5c-0.2-0.8-0.2-1.5-0.2-2.1s0.1-1.3,0.2-2.1L27,32.3l1.8-2.8l2.1,1c0.4-0.4,1-0.8,1.7-1.2c0.7-0.4,1.4-0.7,2.1-0.9l0.2-2.5h3
l0.3,2.5c0.7,0.2,1.3,0.5,2,0.9s1.3,0.8,1.7,1.2l2.1-1l1.8,2.8l-1.9,1.5c0.2,0.8,0.2,1.5,0.2,2.1S44,37.2,43.9,38l1.9,1.5L44,42.2
l-2.1-1c-0.4,0.5-1,0.9-1.7,1.3c-0.7,0.4-1.4,0.7-2,0.9l-0.3,2.4H34.9z M36.4,41c1.5,0,2.7-0.5,3.6-1.5c1-1,1.5-2.2,1.5-3.7
S41,33.2,40,32.2c-1-1-2.2-1.5-3.6-1.5c-1.5,0-2.7,0.5-3.7,1.5c-1,1-1.5,2.2-1.5,3.6s0.5,2.7,1.5,3.7C33.7,40.5,34.9,41,36.4,41z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.7.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="レイヤー_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 48 48" style="enable-background:new 0 0 48 48;" xml:space="preserve">
<style type="text/css">
.st0{fill:#282828;}
</style>
<path class="st0" d="M9,40c-0.8,0-1.5-0.3-2.1-0.9C6.3,38.5,6,37.8,6,37V7c0-0.8,0.3-1.5,0.9-2.1S8.2,4,9,4h30
c0.8,0,1.5,0.3,2.1,0.9C41.7,5.5,42,6.2,42,7v15.1c-0.3,0-0.5-0.1-0.7-0.1c-0.2,0-0.5,0-0.7,0H39V7H9v30h6.9c0.2,0.5,0.3,1,0.5,1.5
s0.4,1,0.7,1.5H9z M9,34v3V7V34z M14.5,31.5H16c0.4-1.2,1-2.5,1.8-3.7c0.8-1.2,1.8-2.3,2.8-3.3h-6.1V31.5z M14.5,19.5h7v-7h-7V19.5z
M26.5,19.5h7v-7h-7V19.5z M31.5,45.8l-0.2-2.4c-0.7-0.2-1.4-0.5-2-0.9c-0.7-0.4-1.3-0.8-1.7-1.3l-2.1,1l-1.8-2.7l1.9-1.5
c-0.2-0.8-0.2-1.5-0.2-2.1c0-0.6,0.1-1.3,0.2-2.1l-1.9-1.5l1.8-2.7l2.1,1c0.4-0.4,1-0.8,1.7-1.2c0.7-0.4,1.4-0.7,2-0.9l0.2-2.5h3
l0.3,2.5c0.7,0.2,1.3,0.5,2,0.9s1.3,0.8,1.7,1.2l2.1-1l1.8,2.7l-1.9,1.5c0.2,0.8,0.2,1.5,0.2,2.1c0,0.6-0.1,1.3-0.2,2.1l1.9,1.5
l-1.8,2.7l-2.1-1c-0.4,0.5-1,0.9-1.7,1.3c-0.7,0.4-1.4,0.7-2,0.9l-0.3,2.4H31.5z M33,41.1c1.5,0,2.7-0.5,3.6-1.5
c1-1,1.5-2.2,1.5-3.6c0-1.5-0.5-2.7-1.5-3.7c-1-1-2.2-1.5-3.6-1.5c-1.5,0-2.7,0.5-3.7,1.5s-1.5,2.2-1.5,3.7c0,1.5,0.5,2.7,1.5,3.6
S31.5,41.1,33,41.1z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,4 @@
export * from "./workflowSlice";
export * from "./state";
export * from "./selectors";
export * from "./operations";

View File

@ -0,0 +1,42 @@
import { createAsyncThunk } from "@reduxjs/toolkit";
import { Configuration, GetWorkflowsResponse, WorkflowsApi } from "api";
import type { RootState } from "app/store";
import { ErrorObject, createErrorObject } from "common/errors";
import { openSnackbar } from "features/ui/uiSlice";
import { getTranslationID } from "translation";
export const listWorkflowAsync = createAsyncThunk<
GetWorkflowsResponse,
void,
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("workflow/listWorkflowAsync", async (args, thunkApi) => {
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration, accessToken } = state.auth;
const config = new Configuration(configuration);
const workflowsApi = new WorkflowsApi(config);
try {
const { data } = await workflowsApi.getWorkflows({
headers: { authorization: `Bearer ${accessToken}` },
});
return data;
} catch (e) {
// e ⇒ errorObjectに変換"
const error = createErrorObject(e);
thunkApi.dispatch(
openSnackbar({
level: "error",
message: getTranslationID("common.message.internalServerError"),
})
);
return thunkApi.rejectWithValue({ error });
}
});

View File

@ -0,0 +1,7 @@
import { RootState } from "app/store";
export const selectWorkflows = (state: RootState) =>
state.workflow.domain.workflows;
export const selectIsLoading = (state: RootState) =>
state.workflow.apps.isLoading;

View File

@ -0,0 +1,14 @@
import { Workflow } from "api";
export interface WorkflowState {
apps: Apps;
domain: Domain;
}
export interface Apps {
isLoading: boolean;
}
export interface Domain {
workflows?: Workflow[];
}

View File

@ -0,0 +1,32 @@
import { createSlice } from "@reduxjs/toolkit";
import { WorkflowState } from "./state";
import { listWorkflowAsync } from "./operations";
const initialState: WorkflowState = {
apps: {
isLoading: false,
},
domain: {},
};
export const workflowSlice = createSlice({
name: "workflow",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(listWorkflowAsync.pending, (state) => {
state.apps.isLoading = true;
});
builder.addCase(listWorkflowAsync.fulfilled, (state, action) => {
const { workflows } = action.payload;
state.domain.workflows = workflows;
state.apps.isLoading = false;
});
builder.addCase(listWorkflowAsync.rejected, (state) => {
state.apps.isLoading = false;
});
},
});
export default workflowSlice.reducer;

View File

@ -1,34 +1,163 @@
import React from "react";
import React, { useEffect } from "react";
import Header from "components/header";
import Footer from "components/footer";
import styles from "styles/app.module.scss";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import ruleAddImg from "assets/images/rule_add.svg";
import templateSettingImg from "assets/images/template_setting.svg";
import worktypeSettingImg from "assets/images/worktype_setting.svg";
import groupSettingImg from "assets/images/group_setting.svg";
import { AppDispatch } from "app/store";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { listWorkflowAsync } from "features/workflow/operations";
import { selectIsLoading, selectWorkflows } from "features/workflow";
import progress_activit from "assets/images/progress_activit.svg";
import { getTranslationID } from "translation";
const WorkflowPage: React.FC = (): JSX.Element => (
const WorkflowPage: React.FC = (): JSX.Element => {
const dispatch: AppDispatch = useDispatch();
const [t] = useTranslation();
const workflows = useSelector(selectWorkflows);
const isLoading = useSelector(selectIsLoading);
useEffect(() => {
dispatch(listWorkflowAsync());
}, [dispatch]);
return (
<div className={styles.wrap}>
<Header userName="XXXXXX" />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<span>
<a style={{ margin: 20 }} href="/workflow/typist-group">
Transcriptionist Group Setting
<div className={styles.pageHeader}>
<h1 className={styles.pageTitle}>
{t(getTranslationID("workflowPage.label.title"))}
</h1>
</div>
<section className={styles.workflow}>
<div>
<ul className={`${styles.menuAction} ${styles.alignRight}`}>
<li className={styles.floatLeft}>
<a className={`${styles.menuLink} ${styles.isActive}`}>
<img
src={ruleAddImg}
alt="addRoutingRule"
className={styles.menuIcon}
/>
{t(getTranslationID("workflowPage.label.addRoutingRule"))}
</a>
</span>
<span>
<a style={{ margin: 20 }} href="/workflow/worktype-id">
Worktype ID Setting
</li>
<li>
<a
href="/workflow/template"
className={`${styles.menuLink} ${styles.isActive}`}
>
<img
src={templateSettingImg}
alt="templateSetting"
className={styles.menuIcon}
/>
{t(getTranslationID("workflowPage.label.templateSetting"))}
</a>
</span>
<span>
<a style={{ margin: 20 }} href="/workflow/template">
Template File
</li>
<li>
<a
href="/workflow/worktype-id"
className={`${styles.menuLink} ${styles.isActive}`}
>
<img
src={worktypeSettingImg}
alt="worktypeIdSetting"
className={styles.menuIcon}
/>
{t(
getTranslationID("workflowPage.label.worktypeIdSetting")
)}
</a>
</span>
</li>
<li>
<a
href="/workflow/typist-group"
className={`${styles.menuLink} ${styles.isActive}`}
>
<img
src={groupSettingImg}
alt="typistGroupSetting"
className={styles.menuIcon}
/>
{t(
getTranslationID("workflowPage.label.typistGroupSetting")
)}
</a>
</li>
</ul>
<table className={`${styles.table} ${styles.workflow}`}>
<tr className={styles.tableHeader}>
<th className={styles.clm0}>{/** empty th */}</th>
<th>{t(getTranslationID("workflowPage.label.authorID"))}</th>
<th>{t(getTranslationID("workflowPage.label.worktype"))}</th>
<th>
{t(getTranslationID("workflowPage.label.transcriptionist"))}
</th>
<th>{t(getTranslationID("workflowPage.label.template"))}</th>
</tr>
{workflows?.map((workflow) => (
<tr key={workflow.id}>
<td className={styles.clm0}>
<ul className={styles.menuInTable}>
<li>
<a href="">
{t(getTranslationID("workflowPage.label.editRule"))}
</a>
</li>
<li>
<a href="">
{t(getTranslationID("common.label.delete"))}
</a>
</li>
</ul>
</td>
<td>{workflow.author.authorId}</td>
<td>{workflow.worktype?.worktypeId ?? "-"}</td>
<td className={styles.txWsline}>
{workflow.typists.map((typist, i) => (
<>
{typist.typistName}
{i !== workflow.typists.length - 1 && <br />}
</>
))}
</td>
<td>{workflow.template?.fileName ?? "-"}</td>
</tr>
))}
</table>
{!isLoading && workflows?.length === 0 && (
<p
style={{
margin: "10px",
textAlign: "center",
}}
>
{t(getTranslationID("common.message.listEmpty"))}
</p>
)}
{isLoading && (
<img
src={progress_activit}
className={styles.icLoading}
alt="Loading"
/>
)}
</div>
</section>
</div>
</main>
<Footer />
</div>
);
};
export default WorkflowPage;

View File

@ -356,7 +356,16 @@
},
"workflowPage": {
"label": {
"title": "Arbeitsablauf"
"title": "Arbeitsablauf",
"addRoutingRule": "(de)Add Routing Rule",
"templateSetting": "(de)Template Setting",
"worktypeIdSetting": "(de)WorktypeID Setting",
"typistGroupSetting": "(de)Transcriptionist Group Setting",
"authorID": "Autoren-ID",
"worktype": "Aufgabentypkennung",
"transcriptionist": "Transkriptionist",
"template": "(de)Template",
"editRule": "(de)Edit Rule"
}
},
"typistGroupSetting": {

View File

@ -356,7 +356,16 @@
},
"workflowPage": {
"label": {
"title": "Workflow"
"title": "Workflow",
"addRoutingRule": "Add Routing Rule",
"templateSetting": "Template Setting",
"worktypeIdSetting": "WorktypeID Setting",
"typistGroupSetting": "Transcriptionist Group Setting",
"authorID": "Author ID",
"worktype": "Worktype ID",
"transcriptionist": "Transcriptionist",
"template": "Template",
"editRule": "Edit Rule"
}
},
"typistGroupSetting": {

View File

@ -356,7 +356,16 @@
},
"workflowPage": {
"label": {
"title": "flujo de trabajo"
"title": "flujo de trabajo",
"addRoutingRule": "(es)Add Routing Rule",
"templateSetting": "(es)Template Setting",
"worktypeIdSetting": "(es)WorktypeID Setting",
"typistGroupSetting": "(es)Transcriptionist Group Setting",
"authorID": "ID de autor",
"worktype": "ID de tipo de trabajo",
"transcriptionist": "Transcriptor",
"template": "(es)Template",
"editRule": "(es)Edit Rule"
}
},
"typistGroupSetting": {

View File

@ -356,7 +356,16 @@
},
"workflowPage": {
"label": {
"title": "Flux de travail"
"title": "Flux de travail",
"addRoutingRule": "(fr)Add Routing Rule",
"templateSetting": "(fr)Template Setting",
"worktypeIdSetting": "(fr)WorktypeID Setting",
"typistGroupSetting": "(fr)Transcriptionist Group Setting",
"authorID": "Identifiant Auteur",
"worktype": "Identifiant du Type de travail",
"transcriptionist": "Transcriptionniste",
"template": "(fr)Template",
"editRule": "(fr)Edit Rule"
}
},
"typistGroupSetting": {