## 概要 [Task4248: 画面遷移してもインターバルが初期化されないように修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/4248) - UpdateTokenTimerを修正 - F5キーリロードの時もトークンをチェックする - UpdateTokenTimerを各画面ごとではなくApp.tsxに配置する - 画面遷移のたびにSetIntervalが初期化されるのを防ぐ - 各画面のUpdateTokenTimerを削除 - App.tsxで管理するため ## レビューポイント - いかの問題が解消されるかを可能であれば確認してほしい。 - Dictation画面でトークンのチェック~自動更新ができること - 画面遷移をしてもトークンチェックのインターバルが初期化されないこと - F5キーリロードをした時にトークンチェックが走ること ## 動作確認状況 - ローカルで確認 - 行った修正がデグレを発生させていないことを確認できるか - 具体的にどのような確認をしたか - 各画面で取得系の処理が正しく動作することを確認 ## 補足 - 相談、参考資料などがあれば
257 lines
9.8 KiB
TypeScript
257 lines
9.8 KiB
TypeScript
import React, { useCallback, useEffect, useState } from "react";
|
|
import Header from "components/header";
|
|
import Footer from "components/footer";
|
|
import styles from "styles/app.module.scss";
|
|
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 {
|
|
deleteWorkflowAsync,
|
|
listWorkflowAsync,
|
|
changeSelectedWorkflow,
|
|
selectIsLoading,
|
|
selectWorkflows,
|
|
} from "features/workflow";
|
|
import { DelegationBar } from "components/delegate";
|
|
import { selectDelegationAccessToken } from "features/auth/selectors";
|
|
import progress_activit from "assets/images/progress_activit.svg";
|
|
import { getTranslationID } from "translation";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { EditWorkflowPopup } from "./editworkflowPopup";
|
|
import { AddWorkflowPopup } from "./addworkflowPopup";
|
|
|
|
const WorkflowPage: React.FC = (): JSX.Element => {
|
|
const dispatch: AppDispatch = useDispatch();
|
|
const [t] = useTranslation();
|
|
const navigate = useNavigate();
|
|
|
|
// 追加Popupの表示制御
|
|
const [isShowAddPopup, setIsShowAddPopup] = useState<boolean>(false);
|
|
// 編集Popupの表示制御
|
|
const [isShowEditPopup, setIsShowEditPopup] = useState<boolean>(false);
|
|
// 代行操作用のトークンを取得する
|
|
const delegationAccessToken = useSelector(selectDelegationAccessToken);
|
|
const workflows = useSelector(selectWorkflows);
|
|
const isLoading = useSelector(selectIsLoading);
|
|
|
|
useEffect(() => {
|
|
dispatch(listWorkflowAsync());
|
|
}, [dispatch]);
|
|
|
|
// ワークフロー削除
|
|
const onDeleteWorkflow = useCallback(
|
|
async (workflowId: number) => {
|
|
if (
|
|
/* eslint-disable-next-line no-alert */
|
|
!window.confirm(t(getTranslationID("common.message.dialogConfirm")))
|
|
) {
|
|
return;
|
|
}
|
|
const { meta } = await dispatch(deleteWorkflowAsync({ workflowId }));
|
|
if (meta.requestStatus === "fulfilled") {
|
|
dispatch(listWorkflowAsync());
|
|
}
|
|
},
|
|
[dispatch, t]
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{isShowAddPopup && (
|
|
<AddWorkflowPopup
|
|
onClose={() => {
|
|
setIsShowAddPopup(false);
|
|
}}
|
|
/>
|
|
)}
|
|
{isShowEditPopup && (
|
|
<EditWorkflowPopup
|
|
onClose={() => {
|
|
setIsShowEditPopup(false);
|
|
}}
|
|
/>
|
|
)}
|
|
<div
|
|
className={`${styles.wrap} ${
|
|
delegationAccessToken ? styles.manage : ""
|
|
}`}
|
|
>
|
|
{delegationAccessToken && <DelegationBar />}
|
|
<Header />
|
|
<main className={styles.main}>
|
|
<div className="">
|
|
<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}>
|
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
|
|
<a
|
|
className={`${styles.menuLink} ${styles.isActive}`}
|
|
onClick={() => {
|
|
setIsShowAddPopup(true);
|
|
}}
|
|
>
|
|
<img
|
|
src={ruleAddImg}
|
|
alt="addRoutingRule"
|
|
className={styles.menuIcon}
|
|
/>
|
|
{t(getTranslationID("workflowPage.label.addRoutingRule"))}
|
|
</a>
|
|
</li>
|
|
<li>
|
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
|
|
<a
|
|
onClick={() => navigate("/workflow/template")}
|
|
className={`${styles.menuLink} ${styles.isActive}`}
|
|
>
|
|
<img
|
|
src={templateSettingImg}
|
|
alt="templateSetting"
|
|
className={styles.menuIcon}
|
|
/>
|
|
{t(
|
|
getTranslationID("workflowPage.label.templateSetting")
|
|
)}
|
|
</a>
|
|
</li>
|
|
<li>
|
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
|
|
<a
|
|
onClick={() => navigate("/workflow/worktype-id")}
|
|
className={`${styles.menuLink} ${styles.isActive}`}
|
|
>
|
|
<img
|
|
src={worktypeSettingImg}
|
|
alt="worktypeIdSetting"
|
|
className={styles.menuIcon}
|
|
/>
|
|
{t(
|
|
getTranslationID("workflowPage.label.worktypeIdSetting")
|
|
)}
|
|
</a>
|
|
</li>
|
|
<li>
|
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
|
|
<a
|
|
onClick={() => navigate("/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>
|
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
|
|
<a
|
|
onClick={() => {
|
|
dispatch(
|
|
changeSelectedWorkflow({
|
|
workflowId: workflow.id,
|
|
})
|
|
);
|
|
setIsShowEditPopup(true);
|
|
}}
|
|
>
|
|
{t(
|
|
getTranslationID("workflowPage.label.editRule")
|
|
)}
|
|
</a>
|
|
</li>
|
|
<li>
|
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
|
|
<a
|
|
onClick={() => {
|
|
onDeleteWorkflow(workflow.id);
|
|
}}
|
|
>
|
|
{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 === undefined || 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;
|