Merged PR 917: 画面遷移してもインターバルが初期化されないように修正

## 概要
[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キーリロードをした時にトークンチェックが走ること

## 動作確認状況
- ローカルで確認
- 行った修正がデグレを発生させていないことを確認できるか
  - 具体的にどのような確認をしたか
    - 各画面で取得系の処理が正しく動作することを確認

## 補足
- 相談、参考資料などがあれば
This commit is contained in:
saito.k 2024-07-02 06:43:41 +00:00
parent 35425c576a
commit df55be5e19
13 changed files with 51 additions and 49 deletions

View File

@ -11,6 +11,13 @@ import { selectSnackber } from "features/ui/selectors";
import { closeSnackbar } from "features/ui/uiSlice";
import { UNAUTHORIZED_TO_CONTINUE_ERROR_CODES } from "components/auth/constants";
import { clearUserInfo } from "features/login";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
/*
UpdateTokenTimerをApp.tsxに移動する2024627
App.tsxに移動する
*/
const App = (): JSX.Element => {
const dispatch = useDispatch();
@ -82,6 +89,7 @@ const App = (): JSX.Element => {
/>
<BrowserRouter>
<AppRouter />
<UpdateTokenTimer />
</BrowserRouter>
</>
);

View File

@ -1,4 +1,4 @@
import React, { useCallback } from "react";
import React, { useCallback, useLayoutEffect, useState } from "react";
import { AppDispatch } from "app/store";
import { decodeToken } from "common/decodeToken";
import { useInterval } from "common/useInterval";
@ -17,41 +17,58 @@ import { TOKEN_UPDATE_INTERVAL_MS, TOKEN_UPDATE_TIME } from "./constants";
export const UpdateTokenTimer = () => {
const dispatch: AppDispatch = useDispatch();
const navigate = useNavigate();
// トークンの更新中かどうか
const [isUpdating, setIsUpdating] = useState(false);
const delegattionToken = useSelector(selectDelegationAccessToken);
// 期限が分以内であれば更新APIを呼ぶ
const updateToken = useCallback(async () => {
// localStorageからトークンを取得
const jwt = loadAccessToken();
// 現在時刻を取得
const now = DateTime.local().toSeconds();
// selectorに以下の判定処理を移したかったが、初期表示時の値でしか判定できないのでComponent内に置く
if (jwt) {
const token = decodeToken(jwt);
if (token) {
const { exp } = token;
if (exp - now <= TOKEN_UPDATE_TIME) {
await dispatch(updateTokenAsync());
}
}
if (isUpdating) {
return;
}
// 代行操作トークン更新処理
if (delegattionToken) {
const token = decodeToken(delegattionToken);
if (token) {
const { exp } = token;
if (exp - now <= TOKEN_UPDATE_TIME) {
const { meta } = await dispatch(updateDelegationTokenAsync());
if (meta.requestStatus === "rejected") {
dispatch(cleanupDelegateAccount());
navigate("/partners");
setIsUpdating(true);
try {
// localStorageからトークンを取得
const jwt = loadAccessToken();
// 現在時刻を取得
const now = DateTime.local().toSeconds();
// selectorに以下の判定処理を移したかったが、初期表示時の値でしか判定できないのでComponent内に置く
if (jwt) {
const token = decodeToken(jwt);
if (token) {
const { exp } = token;
if (exp - now <= TOKEN_UPDATE_TIME) {
await dispatch(updateTokenAsync());
}
}
}
// 代行操作トークン更新処理
if (delegattionToken) {
const token = decodeToken(delegattionToken);
if (token) {
const { exp } = token;
if (exp - now <= TOKEN_UPDATE_TIME) {
const { meta } = await dispatch(updateDelegationTokenAsync());
if (meta.requestStatus === "rejected") {
dispatch(cleanupDelegateAccount());
navigate("/partners");
}
}
}
}
} catch (e) {
// eslint-disable-next-line no-console
console.error("Token update error:", e);
} finally {
setIsUpdating(false);
}
}, [dispatch, delegattionToken, navigate]);
}, [isUpdating, delegattionToken, dispatch, navigate]);
useLayoutEffect(() => {
updateToken();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useInterval(updateToken, TOKEN_UPDATE_INTERVAL_MS);

View File

@ -1,5 +1,4 @@
import { AppDispatch } from "app/store";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import React, { useCallback, useEffect, useState } from "react";
@ -106,7 +105,6 @@ const AccountPage: React.FC = (): JSX.Element => {
)}
<div className={styles.wrap}>
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div>
<div className={styles.pageHeader}>

View File

@ -1,6 +1,5 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import React, { useCallback, useEffect } from "react";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { isApproveTier } from "features/auth";
import { TIERS } from "components/auth/constants";
import Footer from "components/footer";
@ -166,7 +165,6 @@ export const LicenseOrderHistory: React.FC<LicenseOrderHistoryProps> = (
delegationAccessToken && <DelegationBar />
}
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div>
<div className={styles.pageHeader}>

View File

@ -1,5 +1,4 @@
import React, { useCallback, useEffect, useState } from "react";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import styles from "styles/app.module.scss";
@ -149,8 +148,6 @@ export const LicenseSummary: React.FC<LicenseSummaryProps> = (
>
{delegationAccessToken && <DelegationBar />}
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>

View File

@ -2,7 +2,6 @@ import React, { useCallback, useState, useEffect } from "react";
import Footer from "components/footer";
import Header from "components/header";
import styles from "styles/app.module.scss";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch } from "app/store";
import { getTranslationID } from "translation";
@ -263,7 +262,6 @@ const PartnerLicense: React.FC = (): JSX.Element => {
{!islicenseOrderHistoryOpen && !isViewDetailsOpen && (
<div className={styles.wrap}>
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>

View File

@ -1,6 +1,5 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import { AppDispatch } from "app/store";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import React, { useCallback, useEffect, useState } from "react";
@ -169,7 +168,6 @@ const PartnerPage: React.FC = (): JSX.Element => {
/>
<div className={styles.wrap}>
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div className={styles.pageHeader}>
<h1 className={styles.pageTitle}>

View File

@ -1,6 +1,5 @@
import React from "react";
import Header from "components/header";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useTranslation } from "react-i18next";
import { getTranslationID } from "translation";
import styles from "styles/app.module.scss";
@ -12,7 +11,6 @@ const SupportPage: React.FC = () => {
return (
<div className={styles.wrap}>
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div>
<div className={styles.pageHeader}>

View File

@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch } from "app/store";
import Header from "components/header";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useTranslation } from "react-i18next";
import { getTranslationID } from "translation";
import undo from "assets/images/undo.svg";
@ -69,7 +68,6 @@ export const TemplateFilePage: React.FC = () => {
>
{delegationAccessToken && <DelegationBar />}
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div>
<div className={styles.pageHeader}>

View File

@ -2,7 +2,6 @@ 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 { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import progress_activit from "assets/images/progress_activit.svg";
import undo from "assets/images/undo.svg";
import group_add from "assets/images/group_add.svg";
@ -93,7 +92,6 @@ const TypistGroupSettingPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken && <DelegationBar />}
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div>
<div className={styles.pageHeader}>

View File

@ -3,7 +3,6 @@ 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 { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import { useDispatch, useSelector } from "react-redux";
import {
listUsersAsync,
@ -153,7 +152,6 @@ const UserListPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken && <DelegationBar />}
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>

View File

@ -1,4 +1,3 @@
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import React, { useCallback, useEffect, useState } from "react";
@ -138,7 +137,6 @@ const WorktypeIdSettingPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken && <DelegationBar />}
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div>
<div className={styles.pageHeader}>

View File

@ -2,7 +2,6 @@ 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 { 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";
@ -83,7 +82,6 @@ const WorkflowPage: React.FC = (): JSX.Element => {
>
{delegationAccessToken && <DelegationBar />}
<Header />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>