2025-01-21 05:23:54 +00:00

456 lines
18 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useCallback, useEffect, useState } from "react";
import Footer from "components/footer";
import Header from "components/header";
import styles from "styles/app.module.scss";
import { getTranslationID } from "translation";
import { useTranslation } from "react-i18next";
import { AppDispatch } from "app/store";
import { useDispatch, useSelector } from "react-redux";
import {
getCompanyNameAsync,
getLicenseSummaryAsync,
selectLicenseSummaryInfo,
selectCompanyName,
selectIsLoading,
updateRestrictionStatusAsync,
} from "features/license/licenseSummary";
import { selectDelegationAccessToken } from "features/auth/selectors";
import { DelegationBar } from "components/delegate";
import { TIERS } from "components/auth/constants";
import { isAdminUser, isApproveTier } from "features/auth/utils";
import { PartnerLicenseInfo, SearchPartner } from "../../api";
import postAdd from "../../assets/images/post_add.svg";
import history from "../../assets/images/history.svg";
import key from "../../assets/images/key.svg";
import block from "../../assets/images/block.svg";
import circle from "../../assets/images/circle.svg";
import returnLabel from "../../assets/images/undo.svg";
import { LicenseOrderPopup } from "./licenseOrderPopup";
import { CardLicenseActivatePopup } from "./cardLicenseActivatePopup";
import { TrialLicenseIssuePopup } from "./trialLicenseIssuePopup";
// eslint-disable-next-line import/no-named-as-default
import LicenseOrderHistory from "./licenseOrderHistory";
interface LicenseSummaryProps {
onReturn?: () => void;
selectedRow?: PartnerLicenseInfo | SearchPartner;
}
export const LicenseSummary: React.FC<LicenseSummaryProps> = (
props
): JSX.Element => {
const { onReturn, selectedRow } = props;
const dispatch: AppDispatch = useDispatch();
const [t] = useTranslation();
// 代行操作用のトークンを取得する
const delegationAccessToken = useSelector(selectDelegationAccessToken);
const isLoading = useSelector(selectIsLoading);
// popup制御関係
const [islicenseOrderPopupOpen, setIslicenseOrderPopupOpen] = useState(false);
const [isCardLicenseActivatePopupOpen, setIsCardLicenseActivatePopupOpen] =
useState(false);
const [isTrialLicenseIssuePopupOpen, setIsTrialLicenseIssuePopupOpen] =
useState(false);
const onlicenseOrderOpen = useCallback(() => {
setIslicenseOrderPopupOpen(true);
}, [setIslicenseOrderPopupOpen]);
const onCardLicenseActivateOpen = useCallback(() => {
setIsCardLicenseActivatePopupOpen(true);
}, [setIsCardLicenseActivatePopupOpen]);
const onTrialLicenseIssueOpen = useCallback(() => {
setIsTrialLicenseIssuePopupOpen(true);
}, [setIsTrialLicenseIssuePopupOpen]);
// 呼び出し画面制御関係
const [islicenseOrderHistoryOpen, setIsLicenseOrderHistoryOpen] =
useState(false);
const onLicenseOrderHistoryOpen = useCallback(() => {
setIsLicenseOrderHistoryOpen(true);
}, [setIsLicenseOrderHistoryOpen]);
// apiからの値取得関係
const licenseSummaryInfo = useSelector(selectLicenseSummaryInfo);
const companyName = useSelector(selectCompanyName);
const isTier1 = isApproveTier([TIERS.TIER1]);
const isTier2 = isApproveTier([TIERS.TIER2]);
const isAdmin = isAdminUser();
useEffect(() => {
dispatch(getLicenseSummaryAsync({ selectedRow }));
dispatch(getCompanyNameAsync({ selectedRow }));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dispatch]);
// Return押下時の処理
const returnClick = useCallback(() => {
if (onReturn) {
onReturn();
}
}, [onReturn]);
const onStorageAvailableChange = useCallback(
async (e: React.ChangeEvent<HTMLInputElement>) => {
if (
/* eslint-disable-next-line no-alert */
!window.confirm(
t(
getTranslationID(
"LicenseSummaryPage.message.storageUnavalableSwitchingConfirm"
)
)
)
) {
return;
}
const restricted = e.target.checked;
const accountId = selectedRow?.accountId;
// 本関数が実行されるときはselectedRowが存在する前提のため、accountIdが存在しない場合の処理は不要
if (!accountId) return;
const { meta } = await dispatch(
updateRestrictionStatusAsync({ accountId, restricted })
);
if (meta.requestStatus === "fulfilled") {
dispatch(getLicenseSummaryAsync({ selectedRow }));
}
},
[dispatch, selectedRow, t]
);
return (
<>
{/* isPopupOpenがfalseの場合はポップアップのhtmlを生成しないように対応。これによりポップアップは都度生成されて初期化の考慮が減る */}
{islicenseOrderPopupOpen && (
<LicenseOrderPopup
onClose={() => {
setIslicenseOrderPopupOpen(false);
dispatch(getLicenseSummaryAsync({ selectedRow }));
}}
/>
)}
{isCardLicenseActivatePopupOpen && (
<CardLicenseActivatePopup
onClose={() => {
setIsCardLicenseActivatePopupOpen(false);
}}
/>
)}
{isTrialLicenseIssuePopupOpen && (
<TrialLicenseIssuePopup
onClose={() => {
setIsTrialLicenseIssuePopupOpen(false);
dispatch(getLicenseSummaryAsync({ selectedRow }));
}}
selectedRow={selectedRow}
/>
)}
{islicenseOrderHistoryOpen && (
<LicenseOrderHistory
onReturn={() => {
setIsLicenseOrderHistoryOpen(false);
}}
selectedRow={selectedRow}
/>
)}
{!islicenseOrderHistoryOpen && (
<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("LicenseSummaryPage.label.title"))}
</h1>
</div>
<section className={styles.license}>
<div className={styles.boxFlex}>
<h2 className="">{companyName}</h2>
<ul className={`${styles.menuAction} ${styles.box100}`}>
<li>
{/* 他アカウントのライセンス情報を見ている場合は、前画面に戻る用のreturnボタンを表示 */}
{selectedRow && (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<a
className={`${styles.menuLink} ${styles.isActive}`}
onClick={returnClick}
>
<img
src={returnLabel}
alt=""
className={styles.menuIcon}
/>
{t(getTranslationID("common.label.return"))}
</a>
)}
</li>
<li>
{/* 他アカウントのライセンス情報を見ている場合は、ライセンス注文ボタンを非表示 */}
{!selectedRow && (
// 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(
"LicenseSummaryPage.label.orderLicense"
)
)}
</a>
)}
</li>
<li>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
className={`${styles.menuLink} ${styles.isActive}`}
onClick={onLicenseOrderHistoryOpen}
>
<img src={history} alt="" className={styles.menuIcon} />
{t(
getTranslationID(
"LicenseSummaryPage.label.orderHistory"
)
)}
</a>
</li>
<li>
{/* 他アカウントのライセンス情報を見ている場合は、カードライセンス取り込みボタンを非表示 */}
{!selectedRow && (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<a
className={`${styles.menuLink} ${styles.isActive}`}
onClick={onCardLicenseActivateOpen}
>
<img src={key} alt="" className={styles.menuIcon} />
{t(
getTranslationID(
"LicenseSummaryPage.label.activateLicenseKey"
)
)}
</a>
)}
</li>
<li>
{/* 第一階層、第二階層の管理者が第五階層アカウントのライセンス情報を見ている場合は、トライアルライセンス注文ボタンを表示 */}
{selectedRow &&
isAdmin &&
selectedRow.tier.toString() === TIERS.TIER5 &&
(isTier1 || isTier2) && (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<a
className={`${styles.menuLink} ${styles.isActive}`}
onClick={onTrialLicenseIssueOpen}
>
<img
src={postAdd}
alt=""
className={styles.menuIcon}
/>
{t(
getTranslationID(
"LicenseSummaryPage.label.issueTrialLicense"
)
)}
</a>
)}
</li>
</ul>
<div className={styles.marginRgt3}>
<dl
className={`${styles.listVertical} ${styles.marginBtm3}`}
>
<h4 className={styles.listHeader}>
{t(
getTranslationID(
"LicenseSummaryPage.label.licenseLabel"
)
)}
</h4>
<dt>
{t(
getTranslationID(
"LicenseSummaryPage.label.totalLicense"
)
)}
</dt>
<dd>{licenseSummaryInfo.totalLicense}</dd>
<dt>
{t(
getTranslationID(
"LicenseSummaryPage.label.freeLicense"
)
)}
</dt>
<dd>{licenseSummaryInfo.freeLicense}</dd>
<dt>
{t(
getTranslationID(
"LicenseSummaryPage.label.reusableLicense"
)
)}
</dt>
<dd>{licenseSummaryInfo.reusableLicense}</dd>
<dt>
{t(
getTranslationID(
"LicenseSummaryPage.label.allocatedLicense"
)
)}
</dt>
<dd>{licenseSummaryInfo.allocatedLicense}</dd>
<dt>
{t(
getTranslationID(
"LicenseSummaryPage.label.expiringWithin14daysLicense"
)
)}
</dt>
<dd>{licenseSummaryInfo.expiringWithin14daysLicense}</dd>
<dt>
{t(
getTranslationID("LicenseSummaryPage.label.shortage")
)}
</dt>
<dd>
<span
className={
licenseSummaryInfo.shortage > 0
? styles.isAlert
: ""
}
>
{licenseSummaryInfo.shortage}
</span>
</dd>
<dt>
{t(
getTranslationID(
"LicenseSummaryPage.label.issueRequesting"
)
)}
</dt>
<dd>{licenseSummaryInfo.issueRequesting}</dd>
</dl>
</div>
<div>
{isTier1 && isAdmin && (
<p
className={`${styles.checkAvail} ${styles.alignRight}`}
>
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label>
<input
type="checkbox"
className={styles.formCheck}
checked={licenseSummaryInfo.isStorageAvailable}
disabled={isLoading}
onChange={onStorageAvailableChange}
/>
{t(
getTranslationID(
"LicenseSummaryPage.label.storageUnavailableCheckbox"
)
)}
</label>
</p>
)}
<dl
className={`${styles.listVertical} ${styles.marginBtm3}`}
>
<h4 className={styles.listHeader}>
{t(
getTranslationID(
"LicenseSummaryPage.label.storageLabel"
)
)}
</h4>
<dt>
{t(
getTranslationID(
"LicenseSummaryPage.label.storageSize"
)
)}
</dt>
<dd>
{/** Byte単位で受け取った値をGB単位で表示するため1000^3で割っている小数点以下第三位まで表示で第四位で四捨五入 */}
{(
licenseSummaryInfo.storageSize /
1000 /
1000 /
1000
).toFixed(3)}
GB
</dd>
<dt>
{t(
getTranslationID("LicenseSummaryPage.label.usedSize")
)}
</dt>
<dd>
{/** Byte単位で受け取った値をGB単位で表示するため1000^3で割っている小数点以下第三位まで表示で第四位で四捨五入 */}
{(
licenseSummaryInfo.usedSize /
1000 /
1000 /
1000
).toFixed(3)}
GB
</dd>
<dt className={styles.overLine}>
{t(
getTranslationID(
"LicenseSummaryPage.label.storageAvailable"
)
)}
</dt>
<dd>
{licenseSummaryInfo.isStorageAvailable && (
<img
src={block}
alt=""
className={styles.icInTable}
/>
)}
{!licenseSummaryInfo.isStorageAvailable && (
<img
src={circle}
alt=""
className={styles.icInTable}
/>
)}
</dd>
</dl>
</div>
</div>
</section>
</div>
</main>
<Footer />
</div>
)}
</>
);
};
LicenseSummary.defaultProps = {
onReturn: undefined,
};
export default LicenseSummary;