Merged PR 144: 画面実装(ライセンス情報画面(親))

## 概要
[Task1841: 画面実装(ライセンス情報画面(親))](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1841)

- タスク 1841: 画面実装(ライセンス情報画面(親))
- 階層情報を取得し、第五の場合とそれ以外の場合でページを振り分ける処理を実装しました
- 遷移先のページについてはレビュー対象外になります。
  ・第五階層のページ「licenseSummary.tsx」→タスク 1842: 画面実装(第5階層用ライセンス情報)で本実装
  ・第1-4階層のページ「partnerLicense.tsx」→本PBI対象外

## レビューポイント
- index.tsxについて、アクセストークンが不正だった場合の処理として、NotFoundPageに遷移させています。
  通常アクセストークンが不正なことはないと考えているため、そのためのエラーページを作るほどでもないと
  考えてこうしていますが、問題あれば指摘ください。

## UIの変更
- 無し

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

## 補足
- 無し
This commit is contained in:
masaaki 2023-06-09 07:35:35 +00:00
parent f126b0976e
commit 15ee0c2e98
3 changed files with 178 additions and 96 deletions

View File

@ -1,106 +1,38 @@
import { useMsal } from "@azure/msal-react";
import React, { useCallback, useState } from "react";
import { AppDispatch } from "app/store";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import { clearToken } from "features/auth";
import React, { useCallback } from "react";
import { loadAccessToken } from "features/auth/utils";
import { decodeToken } from "common/decodeToken";
import { useDispatch } from "react-redux";
import styles from "styles/app.module.scss";
import { getTranslationID } from "translation";
import { useTranslation } from "react-i18next";
import postAdd from "../../assets/images/post_add.svg";
import history from "../../assets/images/history.svg";
import key from "../../assets/images/key.svg";
import { LicenseOrderPopup } from "./licenseOrderPopup";
import { AppDispatch } from "app/store";
import { clearToken } from "features/auth";
import { useMsal } from "@azure/msal-react";
import { Token } from "common/token";
import LicenseSummary from "./licenseSummary";
import PartnerLicense from "./partnerLicense";
const LicensePage: React.FC = (): JSX.Element => {
const { instance } = useMsal();
const jwt = loadAccessToken();
const dispatch: AppDispatch = useDispatch();
const [t] = useTranslation();
const { instance } = useMsal();
const [islicenseOrderPopupOpen, setIslicenseOrderPopupOpen] = useState(false);
const redirectToTopPage = useCallback(() => {
dispatch(clearToken());
instance.logout({
postLogoutRedirectUri: "/",
});
}, [dispatch, instance]);
const onlicenseOrderOpen = useCallback(() => {
setIslicenseOrderPopupOpen(true);
}, [setIslicenseOrderPopupOpen]);
const token = decodeToken(jwt ?? "");
// 不正なアクセストークンの場合はトップページに遷移する
if (!token) {
redirectToTopPage();
}
const { tier } = token as Token;
return (
<>
{/* isPopupOpenがfalseの場合はポップアップのhtmlを生成しないように対応。これによりポップアップは都度生成されて初期化の考慮が減る */}
{islicenseOrderPopupOpen && (
<LicenseOrderPopup
onClose={() => {
setIslicenseOrderPopupOpen(false);
}}
/>
)}
{/* TODO 現状PBI1221はライセンス注文PUを起動するためのボタンのみ。別途ライセンス注文を実装するPBIで全般的に見直し。 */}
<div className={styles.wrap}>
<Header userName="XXXXXX" />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>
<h1 className={styles.pageTitle}>
{t(getTranslationID("LicensePage.label.title"))}
</h1>
</div>
<section className={styles.license}>
<div>
<h2 className="">
{t(getTranslationID("LicensePage.label.subTitle"))}
</h2>
<ul className={styles.menuAction}>
<li>
{/* TODO ライセンス注文ポップアップのタスクにて起動の実装を行うその際buttonに変更する想定 */}
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
className={`${styles.menuLink} ${styles.isActive}`}
onClick={onlicenseOrderOpen}
>
<img src={postAdd} alt="" className={styles.menuIcon} />
{t(getTranslationID("LicensePage.label.orderLicense"))}
</a>
</li>
<li>
<a href="" className={`${styles.menuLink}`}>
<img src={history} alt="" className={styles.menuIcon} />
{t(getTranslationID("LicensePage.label.orderHistory"))}
</a>
</li>
<li>
<a href="" className={`${styles.menuLink}`}>
<img src={key} alt="" className={styles.menuIcon} />
{t(
getTranslationID("LicensePage.label.importLicenseKey")
)}
</a>
</li>
</ul>
</div>
</section>
</div>
</main>
{/* TODO 画面デザインにはないが、試験時に便利なので配置しておく。ライセンス注文を実装するPBIで正式なサインアウトのレイアウトに直す */}
<div>
<button
type="button"
className={styles.buttonText}
onClick={() => {
instance.logout({ postLogoutRedirectUri: "/" });
dispatch(clearToken());
}}
>
sign out
</button>
</div>
<Footer />
</div>
</>
);
if (tier === 5) {
// 第五階層とそれ以外で表示画面を振り分ける
return <LicenseSummary />;
}
return <PartnerLicense />;
};
export default LicensePage;

View File

@ -0,0 +1,106 @@
import { useMsal } from "@azure/msal-react";
import React, { useCallback, useState } from "react";
import { AppDispatch } from "app/store";
import { UpdateTokenTimer } from "components/auth/updateTokenTimer";
import Footer from "components/footer";
import Header from "components/header";
import { clearToken } from "features/auth";
import { useDispatch } from "react-redux";
import styles from "styles/app.module.scss";
import { getTranslationID } from "translation";
import { useTranslation } from "react-i18next";
import postAdd from "../../assets/images/post_add.svg";
import history from "../../assets/images/history.svg";
import key from "../../assets/images/key.svg";
import { LicenseOrderPopup } from "./licenseOrderPopup";
const LicenseSummary: React.FC = (): JSX.Element => {
const { instance } = useMsal();
const dispatch: AppDispatch = useDispatch();
const [t] = useTranslation();
const [islicenseOrderPopupOpen, setIslicenseOrderPopupOpen] = useState(false);
const onlicenseOrderOpen = useCallback(() => {
setIslicenseOrderPopupOpen(true);
}, [setIslicenseOrderPopupOpen]);
return (
<>
{/* isPopupOpenがfalseの場合はポップアップのhtmlを生成しないように対応。これによりポップアップは都度生成されて初期化の考慮が減る */}
{islicenseOrderPopupOpen && (
<LicenseOrderPopup
onClose={() => {
setIslicenseOrderPopupOpen(false);
}}
/>
)}
{/* TODO 現状PBI1221はライセンス注文PUを起動するためのボタンのみ。別途ライセンス注文を実装するPBIで全般的に見直し。 */}
<div className={styles.wrap}>
<Header userName="XXXXXX" />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>
<h1 className={styles.pageTitle}>
{t(getTranslationID("LicensePage.label.title"))}
</h1>
</div>
<section className={styles.license}>
<div>
<h2 className="">
{t(getTranslationID("LicensePage.label.subTitle"))}
</h2>
<ul className={styles.menuAction}>
<li>
{/* TODO ライセンス注文ポップアップのタスクにて起動の実装を行うその際buttonに変更する想定 */}
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
className={`${styles.menuLink} ${styles.isActive}`}
onClick={onlicenseOrderOpen}
>
<img src={postAdd} alt="" className={styles.menuIcon} />
{t(getTranslationID("LicensePage.label.orderLicense"))}
</a>
</li>
<li>
<a href="" className={`${styles.menuLink}`}>
<img src={history} alt="" className={styles.menuIcon} />
{t(getTranslationID("LicensePage.label.orderHistory"))}
</a>
</li>
<li>
<a href="" className={`${styles.menuLink}`}>
<img src={key} alt="" className={styles.menuIcon} />
{t(
getTranslationID("LicensePage.label.importLicenseKey")
)}
</a>
</li>
</ul>
</div>
</section>
</div>
</main>
{/* TODO 画面デザインにはないが、試験時に便利なので配置しておく。ライセンス注文を実装するPBIで正式なサインアウトのレイアウトに直す */}
<div>
<button
type="button"
className={styles.buttonText}
onClick={() => {
instance.logout({ postLogoutRedirectUri: "/" });
dispatch(clearToken());
}}
>
sign out
</button>
</div>
<Footer />
</div>
</>
);
};
export default LicenseSummary;

View File

@ -0,0 +1,44 @@
import { useMsal } from "@azure/msal-react";
import React 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 { clearToken } from "features/auth";
import { useDispatch } from "react-redux";
import { AppDispatch } from "app/store";
const PartnerLicense: React.FC = (): JSX.Element => {
const { instance } = useMsal();
const dispatch: AppDispatch = useDispatch();
return (
// 表示確認用の仮画面
<div className={styles.wrap}>
<Header userName="XXXXXX" />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>
<h1 className={styles.pageTitle}></h1>
</div>
</div>
</main>
<div>
<button
type="button"
className={styles.buttonText}
onClick={() => {
instance.logout({ postLogoutRedirectUri: "/" });
dispatch(clearToken());
}}
>
sign out
</button>
</div>{" "}
<Footer />
</div>
);
};
export default PartnerLicense;