Merged PR 269: 画面実装(注文履歴画面)

## 概要
[Task2260: 画面実装(注文履歴画面)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2260)

- 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず)
- 何をどう変更したか、追加したライブラリなど
- このPull Requestでの対象/対象外
Order Cancel/Issue/Issue Cancel機能について、はこちらで実装予定[注文履歴画面_画面遷移対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%2014-1?workitem=2273)
Return機能の挙動
userSlice.tsの修正部分(openapi.jsonからapi.ts生成時に画面側のDomainが原因でエラーになるため、一時的に修正)
- 影響範囲(他の機能にも影響があるか)

## レビューポイント
- 特にレビューしてほしい箇所
- 軽微なものや自明なものは記載不要
- 修正範囲が大きい場合などに記載
- 全体的にや仕様を満たしているか等は本当に必要な時のみ記載

## UIの変更
- Before/Afterのスクショなど
- スクショ置き場
https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88/Task2260?csf=1&web=1&e=PBcZUw

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

## 補足
- 相談、参考資料などがあれば
This commit is contained in:
maruyama.t 2023-08-01 01:35:19 +00:00
parent 3121e1e3ba
commit 8be20b7ca8
19 changed files with 990 additions and 160 deletions

View File

@ -15,7 +15,6 @@ import SignupCompletePage from "pages/SignupCompletePage";
import UserListPage from "pages/UserListPage";
import LicensePage from "pages/LicensePage";
import DictationPage from "pages/DictationPage";
import LicenseOrderHistoryPage from "pages/LicenseOrderHistoryPage";
import PartnerPage from "pages/PartnerPage";
const AppRouter: React.FC = () => (
@ -44,10 +43,6 @@ const AppRouter: React.FC = () => (
path="/license"
element={<RouteAuthGuard component={<LicensePage />} />}
/>
<Route
path="/licenseOrderHistory"
element={<RouteAuthGuard component={<LicenseOrderHistoryPage />} />}
/>
<Route
path="/xxx"
element={<RouteAuthGuard component={<SamplePage />} />}

View File

@ -375,7 +375,7 @@ export interface CreatePartnerAccountRequest {
* @type {string}
* @memberof CreatePartnerAccountRequest
*/
email?: string;
email: string;
}
/**
*
@ -495,6 +495,50 @@ export interface GetMyAccountResponse {
*/
account: Account;
}
/**
*
* @export
* @interface GetOrderHistoriesRequest
*/
export interface GetOrderHistoriesRequest {
/**
*
* @type {number}
* @memberof GetOrderHistoriesRequest
*/
limit: number;
/**
*
* @type {number}
* @memberof GetOrderHistoriesRequest
*/
offset: number;
/**
* ID
* @type {number}
* @memberof GetOrderHistoriesRequest
*/
accountId: number;
}
/**
*
* @export
* @interface GetOrderHistoriesResponce
*/
export interface GetOrderHistoriesResponce {
/**
*
* @type {number}
* @memberof GetOrderHistoriesResponce
*/
total: number;
/**
*
* @type {Array<LicenseOrder>}
* @memberof GetOrderHistoriesResponce
*/
orderHistories: Array<LicenseOrder>;
}
/**
*
* @export
@ -684,6 +728,43 @@ export interface IssueCardLicensesResponse {
*/
cardLicenseKeys: Array<string>;
}
/**
*
* @export
* @interface LicenseOrder
*/
export interface LicenseOrder {
/**
*
* @type {string}
* @memberof LicenseOrder
*/
orderDate: string;
/**
*
* @type {string}
* @memberof LicenseOrder
*/
issueDate: string;
/**
*
* @type {number}
* @memberof LicenseOrder
*/
numberOfOrder: number;
/**
* POナンバー
* @type {string}
* @memberof LicenseOrder
*/
poNumber: string;
/**
*
* @type {string}
* @memberof LicenseOrder
*/
status: string;
}
/**
*
* @export
@ -1178,13 +1259,13 @@ export interface User {
* @type {string}
* @memberof User
*/
authorId: string | null;
authorId?: string;
/**
*
* @type {string}
* @type {Array<string>}
* @memberof User
*/
typistGroupName: string | null;
typistGroupName: string;
/**
*
* @type {string}
@ -1215,6 +1296,36 @@ export interface User {
* @memberof User
*/
notification: boolean;
/**
*
* @type {boolean}
* @memberof User
*/
encryption: boolean;
/**
*
* @type {boolean}
* @memberof User
*/
prompt: boolean;
/**
*
* @type {string}
* @memberof User
*/
expiration?: string;
/**
*
* @type {number}
* @memberof User
*/
remaining?: number;
/**
* Normal/NoLicense/Alert/Renew
* @type {string}
* @memberof User
*/
licenseStatus: string;
}
/**
@ -1438,6 +1549,64 @@ export const AccountsApiAxiosParamCreator = function (
options: localVarRequestOptions,
};
},
/**
*
* @summary
* @param {GetOrderHistoriesRequest} getOrderHistoriesRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getOrderHistories: async (
getOrderHistoriesRequest: GetOrderHistoriesRequest,
options: AxiosRequestConfig = {}
): Promise<RequestArgs> => {
// verify required parameter 'getOrderHistoriesRequest' is not null or undefined
assertParamExists(
"getOrderHistories",
"getOrderHistoriesRequest",
getOrderHistoriesRequest
);
const localVarPath = `/accounts/order-histories`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = {
method: "POST",
...baseOptions,
...options,
};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication bearer required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration);
localVarHeaderParameter["Content-Type"] = "application/json";
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions =
baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {
...localVarHeaderParameter,
...headersFromBaseOptions,
...options.headers,
};
localVarRequestOptions.data = serializeDataIfNeeded(
getOrderHistoriesRequest,
localVarRequestOptions,
configuration
);
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary
@ -1693,6 +1862,34 @@ export const AccountsApiFp = function (configuration?: Configuration) {
configuration
);
},
/**
*
* @summary
* @param {GetOrderHistoriesRequest} getOrderHistoriesRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getOrderHistories(
getOrderHistoriesRequest: GetOrderHistoriesRequest,
options?: AxiosRequestConfig
): Promise<
(
axios?: AxiosInstance,
basePath?: string
) => AxiosPromise<GetOrderHistoriesResponce>
> {
const localVarAxiosArgs =
await localVarAxiosParamCreator.getOrderHistories(
getOrderHistoriesRequest,
options
);
return createRequestFunction(
localVarAxiosArgs,
globalAxios,
BASE_PATH,
configuration
);
},
/**
*
* @summary
@ -1839,6 +2036,21 @@ export const AccountsApiFactory = function (
.getMyAccount(options)
.then((request) => request(axios, basePath));
},
/**
*
* @summary
* @param {GetOrderHistoriesRequest} getOrderHistoriesRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getOrderHistories(
getOrderHistoriesRequest: GetOrderHistoriesRequest,
options?: any
): AxiosPromise<GetOrderHistoriesResponce> {
return localVarFp
.getOrderHistories(getOrderHistoriesRequest, options)
.then((request) => request(axios, basePath));
},
/**
*
* @summary
@ -1950,6 +2162,23 @@ export class AccountsApi extends BaseAPI {
.then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary
* @param {GetOrderHistoriesRequest} getOrderHistoriesRequest
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof AccountsApi
*/
public getOrderHistories(
getOrderHistoriesRequest: GetOrderHistoriesRequest,
options?: AxiosRequestConfig
) {
return AccountsApiFp(this.configuration)
.getOrderHistories(getOrderHistoriesRequest, options)
.then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary

View File

@ -12,6 +12,7 @@ import licenseSummary from "features/license/licenseSummary/licenseSummarySlice"
import partnerLicense from "features/license/partnerLicense/partnerLicenseSlice";
import dictation from "features/dictation/dictationSlice";
import partner from "features/partner/partnerSlice";
import licenseOrderHistory from "features/license/licenseOrderHistory/licenseOrderHistorySlice";
export const store = configureStore({
reducer: {
@ -25,6 +26,7 @@ export const store = configureStore({
licenseCardIssue,
licenseCardActivate,
licenseSummary,
licenseOrderHistory,
partnerLicense,
dictation,
partner,

View File

@ -0,0 +1,9 @@
export const LIMIT_ORDER_HISORY_NUM = 50;
export const STATUS = {
// eslint-disable-next-line @typescript-eslint/naming-convention
ISSUE_REQESTING: "Issue Requesting",
ISSUED: "Issued",
// eslint-disable-next-line @typescript-eslint/naming-convention
ORDER_CANCELED: "Order Canceled",
} as const;

View File

@ -0,0 +1,5 @@
export * from "./state";
export * from "./constants";
export * from "./operations";
export * from "./selectors";
export * from "./licenseOrderHistorySlice";

View File

@ -0,0 +1,48 @@
import { createSlice } from "@reduxjs/toolkit";
import { LicenseOrderHistoryState } from "./state";
import { getLicenseOrderHistoriesAsync } from "./operations";
import { LIMIT_ORDER_HISORY_NUM } from "./constants";
const initialState: LicenseOrderHistoryState = {
domain: {
total: 0,
orderHistories: [],
},
apps: {
limit: LIMIT_ORDER_HISORY_NUM,
offset: 0,
accountId: 0,
isLoading: false,
LicenseOrder: undefined,
},
};
export const licenseOrderHistorySlice = createSlice({
name: "licenseOrderHistory",
initialState,
reducers: {
cleanupApps: (state) => {
state.domain = initialState.domain;
},
},
extraReducers: (builder) => {
builder.addCase(getLicenseOrderHistoriesAsync.pending, (state) => {
state.apps.isLoading = true;
});
builder.addCase(
getLicenseOrderHistoriesAsync.fulfilled,
(state, action) => {
state.domain.total = action.payload.total;
state.domain.orderHistories = action.payload.orderHistories;
state.apps.isLoading = false;
}
);
builder.addCase(getLicenseOrderHistoriesAsync.rejected, (state) => {
state.apps.isLoading = false;
});
},
});
export const { cleanupApps } = licenseOrderHistorySlice.actions;
export default licenseOrderHistorySlice.reducer;

View File

@ -0,0 +1,56 @@
import { createAsyncThunk } from "@reduxjs/toolkit";
import type { RootState } from "app/store";
import { getTranslationID } from "translation";
import { openSnackbar } from "features/ui/uiSlice";
import { AccountsApi, GetOrderHistoriesResponce } from "../../../api/api";
import { Configuration } from "../../../api/configuration";
import { ErrorObject, createErrorObject } from "../../../common/errors";
export const getLicenseOrderHistoriesAsync = createAsyncThunk<
// 正常時の戻り値の型
GetOrderHistoriesResponce,
{
// パラメータ
limit: number;
offset: number;
accountId: number;
},
{
// rejectした時の返却値の型
rejectValue: {
error: ErrorObject;
};
}
>("licenses/licenseOrderHisotyAsync", async (args, thunkApi) => {
const { limit, offset, accountId } = args;
// apiのConfigurationを取得する
const { getState } = thunkApi;
const state = getState() as RootState;
const { configuration, accessToken } = state.auth;
const config = new Configuration(configuration);
const accountsApi = new AccountsApi(config);
try {
const res = await accountsApi.getOrderHistories(
{
limit,
offset,
accountId,
},
{
headers: { authorization: `Bearer ${accessToken}` },
}
);
return res.data;
} catch (e) {
// e ⇒ errorObjectに変換"
const error = createErrorObject(e);
thunkApi.dispatch(
openSnackbar({
level: "error",
message: getTranslationID("common.message.internalServerError"),
})
);
return thunkApi.rejectWithValue({ error });
}
});

View File

@ -0,0 +1,36 @@
import { RootState } from "app/store";
import { ceil, floor } from "lodash";
export const selectOrderHisory = (state: RootState) =>
state.licenseOrderHistory.domain.orderHistories;
export const selectTotal = (state: RootState) =>
state.licenseOrderHistory.domain.total;
export const seletctLimit = (state: RootState) =>
state.licenseOrderHistory.apps.limit;
export const selectOffset = (state: RootState) =>
state.licenseOrderHistory.apps.offset;
export const selectAccountId = (state: RootState) =>
state.licenseOrderHistory.apps.accountId;
export const selectTotalPage = (state: RootState) => {
const { limit } = state.licenseOrderHistory.apps;
const { total } = state.licenseOrderHistory.domain;
const page = ceil(total / limit);
return page;
};
export const selectCurrentPage = (state: RootState) => {
const { limit, offset } = state.licenseOrderHistory.apps;
const page = floor(offset / limit) + 1;
return page;
};
export const selectSelectedTask = (state: RootState) =>
state.licenseOrderHistory.apps.LicenseOrder;
export const selectIsLoading = (state: RootState) =>
state.licenseOrderHistory.apps.isLoading;

View File

@ -0,0 +1,19 @@
import { LicenseOrder } from "../../../api/api";
export interface LicenseOrderHistoryState {
domain: Domain;
apps: Apps;
}
export interface Domain {
total: number;
orderHistories: LicenseOrder[];
}
export interface Apps {
limit: number;
offset: number;
accountId: number;
LicenseOrder?: LicenseOrder;
isLoading: boolean;
}

View File

@ -16,6 +16,10 @@ const initialState: UsersState = {
autoRenew: true,
licenseAlert: true,
notification: true,
// XXX エラー回避、api.ts生成時にエラー発生
encryption: false,
prompt: false,
licenseStatus: "",
},
isLoading: false,
},
@ -42,7 +46,8 @@ export const userSlice = createSlice({
action: PayloadAction<{ authorId: string | undefined }>
) => {
const { authorId } = action.payload;
state.apps.addUser.authorId = authorId ?? null;
// XXX エラー回避、api.ts生成時にエラー発生、null → undefined
state.apps.addUser.authorId = authorId ?? undefined;
},
changeTypistGroupId: (
state,

View File

@ -0,0 +1,290 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
import React, { useCallback, useEffect } 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";
import { getTranslationID } from "translation";
import { useTranslation } from "react-i18next";
import { AppDispatch } from "app/store";
import { useDispatch, useSelector } from "react-redux";
import {
LIMIT_ORDER_HISORY_NUM,
STATUS,
getLicenseOrderHistoriesAsync,
selectAccountId,
selectCurrentPage,
selectIsLoading,
selectOrderHisory,
selectTotal,
selectTotalPage,
} from "features/license/licenseOrderHistory";
import undo from "../../assets/images/undo.svg";
import history from "../../assets/images/history.svg";
import progress_activit from "../../assets/images/progress_activit.svg";
interface LicenseOrderHistoryProps {
onReturn: () => void;
}
export const LicenseOrderHistory: React.FC<LicenseOrderHistoryProps> = (
props
): JSX.Element => {
const { onReturn } = props;
const dispatch: AppDispatch = useDispatch();
const [t] = useTranslation();
const total = useSelector(selectTotal);
const totalPage = useSelector(selectTotalPage);
const currentPage = useSelector(selectCurrentPage);
const accountId = useSelector(selectAccountId);
const isLoading = useSelector(selectIsLoading);
// Return押下時の処理
const returnGui = useCallback(() => {
if (isLoading) {
return;
}
onReturn();
}, [isLoading, onReturn]);
// ページネーションのボタンクリック時のアクション
const getFirstPage = useCallback(() => {
dispatch(
getLicenseOrderHistoriesAsync({
limit: LIMIT_ORDER_HISORY_NUM,
offset: 0,
accountId,
})
);
}, [dispatch, accountId]);
const getLastPage = useCallback(() => {
const lastPageOffset = (totalPage - 1) * LIMIT_ORDER_HISORY_NUM;
dispatch(
getLicenseOrderHistoriesAsync({
limit: LIMIT_ORDER_HISORY_NUM,
offset: lastPageOffset,
accountId,
})
);
}, [dispatch, totalPage, accountId]);
const getPrevPage = useCallback(() => {
const prevPageOffset = (currentPage - 2) * LIMIT_ORDER_HISORY_NUM;
dispatch(
getLicenseOrderHistoriesAsync({
limit: LIMIT_ORDER_HISORY_NUM,
offset: prevPageOffset,
accountId,
})
);
}, [dispatch, currentPage, accountId]);
const getNextPage = useCallback(() => {
const nextPageOffset = currentPage * LIMIT_ORDER_HISORY_NUM;
dispatch(
getLicenseOrderHistoriesAsync({
limit: LIMIT_ORDER_HISORY_NUM,
offset: nextPageOffset,
accountId,
})
);
}, [dispatch, currentPage, accountId]);
// apiからの値取得関係
const licenseOrderHistory = useSelector(selectOrderHisory);
useEffect(() => {
dispatch(
getLicenseOrderHistoriesAsync({
limit: LIMIT_ORDER_HISORY_NUM,
offset: 0,
accountId,
})
);
}, [dispatch, accountId]);
return (
<div className={styles.wrap}>
<Header userName="XXXXXX" />
<UpdateTokenTimer />
<main className={styles.main}>
<div className="">
<div className={styles.pageHeader}>
<h1 className={styles.pageTitle}>
{t(getTranslationID("orderHistoriesPage.label.title"))}
</h1>
</div>
<section className={styles.license}>
<div>
<h2 className="">
{t(getTranslationID("orderHistoriesPage.label.subTitle"))}
<p className={styles.brCrumb}>
<img src={history} alt="" className={styles.tlIcon} />
{t(getTranslationID("orderHistoriesPage.label.orderHistory"))}
</p>
</h2>
<ul className={styles.menuAction}>
<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={returnGui}
>
<img src={undo} alt="" className={styles.menuIcon} />
{t(getTranslationID("orderHistoriesPage.label.return"))}
</a>
</li>
</ul>
<div className={styles.tableWrap}>
<table className={`${styles.table} ${styles.history}`}>
<tr className={styles.tableHeader}>
<th>
{t(
getTranslationID("orderHistoriesPage.label.orderDate")
)}
</th>
<th>
{t(
getTranslationID("orderHistoriesPage.label.issueDate")
)}
</th>
<th>
{t(
getTranslationID(
"orderHistoriesPage.label.numberOfOrder"
)
)}
</th>
<th>
{t(getTranslationID("orderHistoriesPage.label.poNumber"))}
</th>
<th className={styles.noLine}>
{t(getTranslationID("orderHistoriesPage.label.status"))}
</th>
<th className={styles.noLine} />
<th className={styles.noLine} />
</tr>
{!isLoading &&
licenseOrderHistory.length !== 0 &&
licenseOrderHistory.map((x) => (
// eslint-disable-next-line react/jsx-key
<tr>
<td>{x.orderDate}</td>
<td>{x.issueDate}</td>
<td>{x.numberOfOrder}</td>
<td>{x.poNumber}</td>
<td>
{(() => {
// eslint-disable-next-line default-case
switch (x.status) {
case STATUS.ISSUE_REQESTING:
return t(
getTranslationID(
"orderHistoriesPage.label.issueRequesting"
)
);
case STATUS.ISSUED:
return t(
getTranslationID(
"orderHistoriesPage.label.issued"
)
);
case STATUS.ORDER_CANCELED:
return t(
getTranslationID(
"orderHistoriesPage.label.orderCanceled"
)
);
}
})()}
</td>
<td>
<ul
className={`${styles.menuAction} ${styles.inTable}`}
>
<li>
<a
href=""
className={`${styles.menuLink} ${styles.isActive}`}
>
{t(
getTranslationID(
"orderHistoriesPage.label.orderCancel"
)
)}
</a>
</li>
</ul>
</td>
</tr>
))}
</table>
</div>
{isLoading && (
<img
style={{ position: "sticky" }}
src={progress_activit}
className={styles.icLoading}
alt="Loading"
/>
)}
{/** pagenation */}
<div className={styles.pagenation}>
<nav className={styles.pagenationNav}>
<span className={styles.pagenationTotal}>{`${total} ${t(
getTranslationID("orderHistoriesPage.label.title")
)}`}</span>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
className={`${
!isLoading && currentPage !== 1 ? styles.isActive : ""
}`}
onClick={getFirstPage}
>
«
</a>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
className={`${
!isLoading && currentPage !== 1 ? styles.isActive : ""
}`}
onClick={getPrevPage}
>
</a>
{`${currentPage} of ${totalPage}`}
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
className={`${
!isLoading && currentPage < totalPage
? styles.isActive
: ""
}`}
onClick={getNextPage}
>
</a>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
className={`${
!isLoading && currentPage < totalPage
? styles.isActive
: ""
}`}
onClick={getLastPage}
>
»
</a>
</nav>
</div>
</div>
</section>
</div>
</main>
<Footer />
</div>
);
};
export default LicenseOrderHistory;

View File

@ -18,6 +18,8 @@ import block from "../../assets/images/block.svg";
import circle from "../../assets/images/circle.svg";
import { LicenseOrderPopup } from "./licenseOrderPopup";
import { CardLicenseActivatePopup } from "./cardLicenseActivatePopup";
// eslint-disable-next-line import/no-named-as-default
import LicenseOrderHistory from "./licenseOrderHistory";
const LicenseSummary: React.FC = (): JSX.Element => {
const dispatch: AppDispatch = useDispatch();
@ -36,6 +38,14 @@ const LicenseSummary: React.FC = (): JSX.Element => {
setIsCardLicenseActivatePopupOpen(true);
}, [setIsCardLicenseActivatePopupOpen]);
// 呼び出し画面制御関係
const [islicenseOrderHistoryOpen, setIsLicenseOrderHistoryOpen] =
useState(false);
const onLicenseOrderHistoryOpen = useCallback(() => {
setIsLicenseOrderHistoryOpen(true);
}, [setIsLicenseOrderHistoryOpen]);
// apiからの値取得関係
const licenseSummaryInfo = useSelector(selecLicenseSummaryInfo);
@ -61,6 +71,14 @@ const LicenseSummary: React.FC = (): JSX.Element => {
}}
/>
)}
{islicenseOrderHistoryOpen && (
<LicenseOrderHistory
onReturn={() => {
setIsLicenseOrderHistoryOpen(false);
}}
/>
)}
{!islicenseOrderHistoryOpen && (
<div className={styles.wrap}>
<Header userName="XXXXXX" />
@ -93,9 +111,10 @@ const LicenseSummary: React.FC = (): JSX.Element => {
</a>
</li>
<li>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
<a
href="/licenseOrderHistory"
className={`${styles.menuLink} ${styles.isActive}`}
onClick={onLicenseOrderHistoryOpen}
>
<img src={history} alt="" className={styles.menuIcon} />
{t(
@ -123,7 +142,9 @@ const LicenseSummary: React.FC = (): JSX.Element => {
<dl className={`${styles.listVertical} ${styles.marginBtm5}`}>
<dt>
{t(
getTranslationID("LicenseSummaryPage.label.totalLicense")
getTranslationID(
"LicenseSummaryPage.label.totalLicense"
)
)}
</dt>
<dd>{licenseSummaryInfo.totalLicense}</dd>
@ -209,6 +230,7 @@ const LicenseSummary: React.FC = (): JSX.Element => {
</main>
<Footer />
</div>
)}
</>
);
};

View File

@ -296,5 +296,24 @@
"viewDetails": "(de)View details",
"accounts": "(de)accounts"
}
},
"orderHistoriesPage": {
"label": {
"title": "(de)License",
"subTitle": "(de)EFGI Legal",
"orderHistory": "(de)Order History",
"return": "(de)Return",
"orderDate": "(de)Order date",
"issueDate": "(de)Issue date",
"numberOfOrder": "(de)Number of Order",
"poNumber": "(de)PO Number",
"status": "(de)Status",
"issueRequesting": "(de)Issue Requesting",
"issued": "(de)Issued",
"orderCanceled": "(de)Order Canceled",
"issue": "(de)Issue",
"issueCancel": "(de)Issue Cancel",
"orderCancel": "(de)Order Cancel"
}
}
}

View File

@ -296,5 +296,24 @@
"viewDetails": "View details",
"accounts": "accounts"
}
},
"orderHistoriesPage": {
"label": {
"title": "License",
"subTitle": "EFGI Legal",
"orderHistory": "Order History",
"return": "Return",
"orderDate": "Order date",
"issueDate": "Issue date",
"numberOfOrder": "Number of Order",
"poNumber": "PO Number",
"status": "Status",
"issueRequesting": "Issue Requesting",
"issued": "Issued",
"orderCanceled": "Order Canceled",
"issue": "Issue",
"issueCancel": "Issue Cancel",
"orderCancel": "Order Cancel"
}
}
}

View File

@ -296,5 +296,24 @@
"viewDetails": "(es)View details",
"accounts": "(es)accounts"
}
},
"orderHistoriesPage": {
"label": {
"title": "(es)License",
"subTitle": "(es)EFGI Legal",
"orderHistory": "(es)Order History",
"return": "(es)Return",
"orderDate": "(es)Order date",
"issueDate": "(es)Issue date",
"numberOfOrder": "(es)Number of Order",
"poNumber": "(es)PO Number",
"status": "(es)Status",
"issueRequesting": "(es)Issue Requesting",
"issued": "(es)Issued",
"orderCanceled": "(es)Order Canceled",
"issue": "(es)Issue",
"issueCancel": "(es)Issue Cancel",
"orderCancel": "(es)Order Cancel"
}
}
}

View File

@ -296,5 +296,24 @@
"viewDetails": "(fr)View details",
"accounts": "(fr)accounts"
}
},
"orderHistoriesPage": {
"label": {
"title": "(fr)License",
"subTitle": "(fr)EFGI Legal",
"orderHistory": "(fr)Order History",
"return": "(fr)Return",
"orderDate": "(fr)Order date",
"issueDate": "(fr)Issue date",
"numberOfOrder": "(fr)Number of Order",
"poNumber": "(fr)PO Number",
"status": "(fr)Status",
"issueRequesting": "(fr)Issue Requesting",
"issued": "(fr)Issued",
"orderCanceled": "(fr)Order Canceled",
"issue": "(fr)Issue",
"issueCancel": "(fr)Issue Cancel",
"orderCancel": "(fr)Order Cancel"
}
}
}

View File

@ -423,7 +423,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GetPartnerLicensesResponse"
"$ref": "#/components/schemas/GetOrderHistoriesResponce"
}
}
}
@ -1973,6 +1973,42 @@
},
"required": ["limit", "offset", "accountId"]
},
"LicenseOrder": {
"type": "object",
"properties": {
"orderDate": {
"format": "date-time",
"type": "string",
"description": "注文日付"
},
"issueDate": {
"format": "date-time",
"type": "string",
"description": "発行日付"
},
"numberOfOrder": { "type": "number", "description": "注文数" },
"poNumber": { "type": "string", "description": "POナンバー" },
"status": { "type": "string", "description": "注文状態" }
},
"required": [
"orderDate",
"issueDate",
"numberOfOrder",
"poNumber",
"status"
]
},
"GetOrderHistoriesResponce": {
"type": "object",
"properties": {
"total": { "type": "number", "description": "合計件数" },
"orderHistories": {
"type": "array",
"items": { "$ref": "#/components/schemas/LicenseOrder" }
}
},
"required": ["total", "orderHistories"]
},
"ConfirmRequest": {
"type": "object",
"properties": { "token": { "type": "string" } },

View File

@ -333,7 +333,7 @@ export class AccountsController {
@Post('order-histories')
@ApiResponse({
status: HttpStatus.OK,
type: GetPartnerLicensesResponse,
type: GetOrderHistoriesResponce,
description: '成功時のレスポンス',
})
@ApiResponse({
@ -372,6 +372,8 @@ export class AccountsController {
};
orderHistories.push(orderHistory);
const getOrderHistoriesResponce = new GetOrderHistoriesResponce();
getOrderHistoriesResponce.limit = 1;
getOrderHistoriesResponce.offset = 1;
getOrderHistoriesResponce.total = 1;
getOrderHistoriesResponce.orderHistories = orderHistories;
/* =

View File

@ -208,9 +208,9 @@ export class GetOrderHistoriesRequest {
export class LicenseOrder {
@ApiProperty({ description: '注文日付' })
orderDate: Date;
orderDate: string;
@ApiProperty({ description: '発行日付' })
issueDate: Date;
issueDate: string;
@ApiProperty({ description: '注文数' })
numberOfOrder: number;
@ApiProperty({ description: 'POナンバー' })