Merged PR 223: ヘッダ修正(partnerタブ追加)

## 概要
[Task2154: ヘッダ修正(partnerタブ追加)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2154)

- 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず)
- 何をどう変更したか、追加したライブラリなど
・Partnerヘッダータグを追加
- このPull Requestでの対象/対象外
・リンクを押下した際の挙動は対象外
- 影響範囲(他の機能にも影響があるか)
新規タブなのでなし

## レビューポイント
- 特にレビューしてほしい箇所
特になし

## 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/Task2154?csf=1&web=1&e=jv7CDb

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

## 補足
- 相談、参考資料などがあれば
This commit is contained in:
oura.a 2023-07-18 06:13:23 +00:00 committed by 水本 祐希
parent 9739942bdf
commit fabcdc16f5
6 changed files with 111 additions and 10 deletions

View File

@ -16,3 +16,15 @@ export const USER_ROLES = {
AUTHOR: "author",
TYPIST: "typist",
} as const;
/**
*
* @const {string[]}
*/
export const TIERS = {
TIER1: "1",
TIER2: "2",
TIER3: "3",
TIER4: "4",
TIER5: "5",
} as const;

View File

@ -5,6 +5,7 @@ export const HEADER_MENUS_USER = "User";
export const HEADER_MENUS_LICENSE = "License";
export const HEADER_MENUS_DICTATIONS = "Dictations";
export const HEADER_MENUS_WORKFLOW = "Workflow";
export const HEADER_MENUS_PARTNER = "Partners";
export const HEADER_MENUS_XXX = "XXX"; // XXX 仮のタブ
export const HEADER_MENUS: { label: HeaderMenus; path: LoginedPaths }[] = [
@ -13,6 +14,7 @@ export const HEADER_MENUS: { label: HeaderMenus; path: LoginedPaths }[] = [
{ label: HEADER_MENUS_LICENSE, path: "/license" },
{ label: HEADER_MENUS_USER, path: "/user" },
{ label: HEADER_MENUS_WORKFLOW, path: "/workflow" },
{ label: HEADER_MENUS_PARTNER, path: "/partners" },
{ label: HEADER_MENUS_XXX, path: "/xxx" }, // XXX 仮のタブ
];
@ -21,4 +23,18 @@ export const HEADER_NAME = "ODMS Cloud";
/**
* adminのみに表示するヘッダータブ
*/
export const ADMIN_ONLY_TABS = [HEADER_MENUS_LICENSE, HEADER_MENUS_USER];
export const ADMIN_ONLY_TABS = [
HEADER_MENUS_LICENSE,
HEADER_MENUS_USER,
HEADER_MENUS_PARTNER,
];
/**
* 1~4
*/
export const TIER1_TO_TIER4_ONLY_TABS = [HEADER_MENUS_PARTNER];
/**
* admin,standardでなく15
*/
export const INVALID_ACCOUNT_TABS = [];

View File

@ -1,11 +1,10 @@
import React from "react";
import { isAdminUser } from "features/auth/utils";
import styles from "styles/app.module.scss";
import { getFilteredMenus } from "./utils";
import logo from "../../assets/images/OMS_logo_black.svg";
import ac from "../../assets/images/account_circle.svg";
import { LoginedPaths } from "./types";
import { ADMIN_ONLY_TABS, HEADER_MENUS, HEADER_NAME } from "./constants";
import { HEADER_NAME } from "./constants";
interface HeaderProps {
name: string;
@ -15,10 +14,7 @@ interface HeaderProps {
// ログイン後のヘッダー
const LoginedHeader: React.FC<HeaderProps> = (props: HeaderProps) => {
const { name, activePath } = props;
const isAdmin = isAdminUser();
const filteredMenus = isAdmin
? HEADER_MENUS
: HEADER_MENUS.filter((item) => !ADMIN_ONLY_TABS.includes(item.label));
const filterMenus = getFilteredMenus();
return (
<header className={styles.header}>
<div className={styles.headerLogo}>
@ -27,7 +23,7 @@ const LoginedHeader: React.FC<HeaderProps> = (props: HeaderProps) => {
<div className={styles.headerSub}>{HEADER_NAME}</div>
<div className={styles.headerMenu}>
<ul>
{filteredMenus.map((x) => (
{filterMenus.map((x) => (
<li key={x.label}>
<a
href={x.path}

View File

@ -8,6 +8,7 @@ export type HeaderMenus =
| "License"
| "Dictations"
| "Workflow"
| "Partners"
| "XXX";
// ログイン後に遷移しうるパス
@ -17,4 +18,5 @@ export type LoginedPaths =
| "/license"
| "/dictations"
| "/workflow"
| "/partners"
| "/xxx";

View File

@ -1,4 +1,16 @@
import {
isAdminUser,
isApproveTier,
isStandardUser,
} from "features/auth/utils";
import { LoginedPaths } from "./types";
import {
ADMIN_ONLY_TABS,
HEADER_MENUS,
TIER1_TO_TIER4_ONLY_TABS,
INVALID_ACCOUNT_TABS,
} from "./constants";
import { TIERS } from "../auth/constants";
// ログイン後のパスかどうか判定
export const isLoginPaths = (d: string): d is LoginedPaths => {
@ -10,6 +22,7 @@ export const isLoginPaths = (d: string): d is LoginedPaths => {
case "/license":
case "/dictations":
case "/workflow":
case "/partners":
case "/xxx":
return true;
default: {
@ -19,3 +32,40 @@ export const isLoginPaths = (d: string): d is LoginedPaths => {
}
}
};
// 権限、階層ごとに表示するヘッダーをわける
export const getFilteredMenus = () => {
const isAdmin = isAdminUser();
const isStandard = isStandardUser();
const isTier5 = isApproveTier([TIERS.TIER5]);
const tier1ToTier4 = isApproveTier([
TIERS.TIER1,
TIERS.TIER2,
TIERS.TIER3,
TIERS.TIER4,
]);
if (tier1ToTier4) {
if (isAdmin) {
return HEADER_MENUS;
}
if (isStandard) {
return HEADER_MENUS.filter(
(item) => !ADMIN_ONLY_TABS.includes(item.label)
);
}
}
if (isTier5) {
if (isAdmin) {
return HEADER_MENUS.filter(
(item) => !TIER1_TO_TIER4_ONLY_TABS.includes(item.label)
);
}
if (isStandard) {
return HEADER_MENUS.filter(
(item) => !ADMIN_ONLY_TABS.includes(item.label)
);
}
}
// admin,standardでなく、第15階層でもないアカウントに表示する空のヘッダータブ
return INVALID_ACCOUNT_TABS;
};

View File

@ -67,6 +67,20 @@ export const isAdminUser = (): boolean => {
return token.role.includes(ADMIN_ROLES.ADMIN);
};
/**
* is standard user standard権限を持つかどうかを返す
* @returns bool
*/
// TODO 上記の関数とまとめて汎用的な関数にリファクタリングする
export const isStandardUser = (): boolean => {
const jwt = loadAccessToken();
const token = jwt ? decodeToken(jwt) : null;
if (!token) {
return false;
}
return token.role.includes(ADMIN_ROLES.STANDARD);
};
/**
* is author user Authorかどうかを返す
* @returns bool
@ -81,7 +95,18 @@ export const isAuthorUser = (): boolean => {
};
/**
* is author user Authorかどうかを返す
* is approve tier
* @returns bool
*/
export const isApproveTier = (tiers: string[]): boolean => {
const jwt = loadAccessToken();
const token = jwt && decodeToken(jwt);
return !!token && tiers.includes(token.tier.toString());
};
/**
* is typist user Typistかどうかを返す
* @returns bool
*/
export const isTypistUser = (): boolean => {