456 lines
18 KiB
TypeScript
456 lines
18 KiB
TypeScript
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;
|