Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
feat: display policy name on workspace title (#362)
Browse files Browse the repository at this point in the history
* Add Dashboard free plan button, fix styles, add updatedAt on project card

* rename callback

* Refactoring, add unique notification for policy violation

* add policy to workspace settings page

* refactor some code

* add policy modal to dashboard

* refactor and fix ci error

* Fixes

* fixes

* regen i18n

* Hide updatedAt from dashboard since backend isn't implemented yet

* Add unique messages

* add policy modal to settings page

* refactor policy component

* i18n support, title and description

* Fix policy reached notifications

* Update src/i18n/translations/ja.yml

Co-authored-by: HideBa <49897538+HideBa@users.noreply.github.com>

* Update src/i18n/translations/ja.yml

Co-authored-by: HideBa <49897538+HideBa@users.noreply.github.com>

Co-authored-by: HideBa <49897538+HideBa@users.noreply.github.com>
  • Loading branch information
KaWaite and HideBa committed Dec 1, 2022
1 parent e302cc6 commit c1c6327
Show file tree
Hide file tree
Showing 44 changed files with 883 additions and 338 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -111,6 +111,7 @@
"core-js": "3.26.0",
"crypto-js": "4.1.1",
"date-fns": "2.29.3",
"dayjs": "^1.11.6",
"detect-browser": "5.3.0",
"formik": "2.2.9",
"github-markdown-css": "5.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/app.tsx
Expand Up @@ -35,7 +35,7 @@ function AppRoutes() {
{ path: "/login", element: <LoginPage /> },
{ path: "/signup", element: <SignupPage /> },
{ path: "/password-reset", element: <PasswordResetPage /> },
{ path: "/dashboard/:teamId", element: <Dashboard /> },
{ path: "/dashboard/:workspaceId", element: <Dashboard /> },
{ path: "/edit/:sceneId", element: <EarthEditor /> },
{ path: "/edit/:sceneId/preview", element: <Preview /> },
{ path: "/settings", element: <Navigate to="/settings/account" /> },
Expand Down
7 changes: 4 additions & 3 deletions src/components/atoms/HelpButton/index.tsx
Expand Up @@ -14,6 +14,7 @@ export type Props = {
description?: string;
balloonDirection?: Placement;
gap?: number;
mouseEnterDelay?: number;
img?: {
imagePath: string;
alt?: string;
Expand All @@ -27,6 +28,7 @@ const HelpButton: React.FC<Props> = ({
description,
balloonDirection,
gap,
mouseEnterDelay = 500,
img,
children,
}) => {
Expand All @@ -53,19 +55,18 @@ const HelpButton: React.FC<Props> = ({
});
const [visible, setVisible] = useState(false);
const [isMouseEnter, setIsMouseEnter] = useState(false);
const mouseEnterSec = 500;

useEffect(() => {
if (isMouseEnter) {
const timer = setTimeout(() => {
setVisible(true);
}, mouseEnterSec);
}, mouseEnterDelay);
return () => clearTimeout(timer);
} else {
setVisible(false);
return;
}
}, [isMouseEnter]);
}, [isMouseEnter, mouseEnterDelay]);

return (
<div ref={wrapperRef} className={className}>
Expand Down
4 changes: 2 additions & 2 deletions src/components/atoms/Icon/index.tsx
Expand Up @@ -78,7 +78,7 @@ const Icon: React.FC<Props> = ({
const StyledImg = styled.img<{ size?: string; notransition?: boolean }>`
width: ${({ size }) => size};
height: ${({ size }) => size};
${({ notransition }) => !notransition && "transition: all 0.4s;"}
${({ notransition }) => !notransition && "transition: all 0.3s;"}
`;

const StyledSvg = styled(SVG)<{
Expand All @@ -94,7 +94,7 @@ const StyledSvg = styled(SVG)<{
color: ${({ color }) => color};
${({ stroke }) => `stroke: ${stroke};`}
transition-property: color, background;
${({ notransition }) => (!notransition ? "transition-duration: 0.4s;" : undefined)}
${({ notransition }) => (!notransition ? "transition-duration: 0.3s;" : undefined)}
`;

export default memo(Icon);
5 changes: 3 additions & 2 deletions src/components/atoms/Modal/ModalFrame/index.tsx
Expand Up @@ -6,13 +6,14 @@ import Icon from "@reearth/components/atoms/Icon";
import { styled } from "@reearth/theme";

export type Props = {
className?: string;
children?: ReactNode;
size?: "sm" | "md" | "lg";
isVisible?: boolean;
onClose?: () => void;
};

const Modal: React.FC<Props> = ({ size, isVisible, onClose, children }) => {
const Modal: React.FC<Props> = ({ className, size, isVisible, onClose, children }) => {
const ref = useRef<HTMLDivElement>(null);
useClickAway(ref, () => onClose?.());

Expand All @@ -29,7 +30,7 @@ const Modal: React.FC<Props> = ({ size, isVisible, onClose, children }) => {

return state === "unmounted" ? null : (
<Bg state={state}>
<Wrapper ref={ref} size={size}>
<Wrapper className={className} ref={ref} size={size}>
{onClose && (
<CloseButton onClick={handleClose}>
<Icon icon="cancel" />
Expand Down
8 changes: 5 additions & 3 deletions src/components/atoms/Modal/index.tsx
Expand Up @@ -4,17 +4,19 @@ import Wrapper from "@reearth/components/atoms/Modal/ModalFrame";
import Text from "@reearth/components/atoms/Text";
import { styled, useTheme } from "@reearth/theme";

interface Props {
type Props = {
className?: string;
title?: string;
size?: "sm" | "md" | "lg";
button1?: ReactNode;
button2?: ReactNode;
children?: ReactNode;
isVisible?: boolean;
onClose?: () => void;
}
};

const Modal: React.FC<Props> = ({
className,
title,
size,
button1,
Expand All @@ -25,7 +27,7 @@ const Modal: React.FC<Props> = ({
}) => {
const theme = useTheme();
return (
<Wrapper size={size} isVisible={isVisible} onClose={onClose}>
<Wrapper className={className} size={size} isVisible={isVisible} onClose={onClose}>
<Title size="l" weight="bold" color={theme.main.strongText}>
{title}
</Title>
Expand Down
4 changes: 2 additions & 2 deletions src/components/atoms/Notification/index.tsx
Expand Up @@ -14,15 +14,15 @@ export type Notification = {

export type Props = {
visible?: boolean;
setModal?: (show: boolean) => void;
notification?: Notification;
setModal?: (show: boolean) => void;
resetNotification?: () => void;
};

const NotificationBanner: React.FC<Props> = ({
visible,
setModal,
notification,
setModal,
resetNotification,
}) => {
const theme = useTheme();
Expand Down
6 changes: 2 additions & 4 deletions src/components/molecules/Common/Header/index.stories.tsx
Expand Up @@ -7,11 +7,11 @@ const defaultProps: Props = {
user: {
name: "Shinnosuke Komiya",
},
currentTeam: {
currentWorkspace: {
id: "1",
name: "Darwin Education",
},
teams: [
workspaces: [
{
id: "A",
name: "Team A",
Expand All @@ -21,8 +21,6 @@ const defaultProps: Props = {
name: "Team B",
},
],
onBack: () => action("onBack"),
onForward: () => action("onForward"),
onSignOut: () => action("signOut"),
};

Expand Down
50 changes: 23 additions & 27 deletions src/components/molecules/Common/Header/index.tsx
@@ -1,77 +1,73 @@
import { ReactNode } from "react";
import { Link } from "react-router-dom";

import Icon from "@reearth/components/atoms/Icon";
import WorkspaceCreationModal from "@reearth/components/molecules/Common/WorkspaceCreationModal";
import { styled, metrics, css } from "@reearth/theme";

import Profile from "./profile";
import type { User, Team, Project } from "./types";
import type { User, Workspace, Project } from "./types";

export type { User, Team, Project } from "./types";
export type { User, Workspace, Project } from "./types";

export interface Props {
className?: string;
children?: ReactNode;
user?: User;
currentTeam?: Team;
currentProject?: Project;
sceneId?: string;
teams: Team[];
currentWorkspace?: Workspace;
personalWorkspace?: boolean;
workspaces?: Workspace[];
icon?: React.ReactNode;
center?: React.ReactNode;
right?: React.ReactNode;
onBack?: () => void;
onForward?: () => void;
onSignOut?: () => void;
onCreateTeam?: (data: { name: string }) => Promise<void>;
onChangeTeam?: (teamId: string) => void;
modalShown?: boolean;
dashboard?: boolean;
onSignOut?: () => void;
onWorkspaceCreate?: (data: { name: string }) => Promise<void>;
onWorkspaceChange?: (workspaceId: string) => void;
openModal?: () => void;
onModalClose?: (r?: boolean) => void;
dashboard?: boolean;
}

const Header: React.FC<Props> = ({
className,
onSignOut,
user,
currentTeam,
currentProject,
teams,
currentWorkspace,
personalWorkspace,
workspaces,
center,
icon,
right,
onCreateTeam,
onChangeTeam,
modalShown,
dashboard,
onSignOut,
onWorkspaceCreate,
onWorkspaceChange,
openModal,
onModalClose,
dashboard,
}) => {
return (
<Wrapper className={className}>
<Content>
<LeftArea>
<StyledLink to={`/dashboard/${currentTeam?.id}`}>
<StyledLink to={`/dashboard/${currentWorkspace?.id}`}>
{!dashboard && <StyledIcon icon="dashboard" size={24} />}
</StyledLink>
{icon}
{onSignOut && onChangeTeam && (
{onSignOut && onWorkspaceChange && (
<>
<Profile
user={user}
currentTeam={currentTeam}
currentProject={currentProject}
teams={teams}
currentWorkspace={currentWorkspace}
personalWorkspace={personalWorkspace}
workspaces={workspaces}
onSignOut={onSignOut}
onChangeTeam={onChangeTeam}
onWorkspaceChange={onWorkspaceChange}
openModal={openModal}
/>
<WorkspaceCreationModal
open={modalShown}
onClose={onModalClose}
onSubmit={onCreateTeam}
onSubmit={onWorkspaceCreate}
/>
</>
)}
Expand Down
56 changes: 33 additions & 23 deletions src/components/molecules/Common/Header/profile.tsx
Expand Up @@ -8,25 +8,26 @@ import {
MenuListItem,
MenuListItemLabel,
} from "@reearth/components/molecules/Common/MenuList";
import TeamMenu from "@reearth/components/molecules/Common/TeamMenu";
import WorkspaceMenu from "@reearth/components/molecules/Common/WorkspaceMenu";
import { useT } from "@reearth/i18n";
import { styled, useTheme } from "@reearth/theme";

import { User, Team, Project } from "./types";
import { User, Workspace } from "./types";

export interface LoginProps {
export type LoginProps = {
user: User;
currentTeam: Team;
currentProject: Project;
}
export interface Props {
teams: Team[];
currentWorkspace: Workspace;
personalWorkspace?: boolean;
};
export type Props = {
workspaces?: Workspace[];
personalWorkspace?: boolean;
onSignOut: () => void;
onChangeTeam?: (teamId: string) => void;
onWorkspaceChange?: (workspaceId: string) => void;
openModal?: () => void;
}
};

const Label: React.FC<Pick<LoginProps, "user" | "currentTeam">> = ({ user, currentTeam }) => {
const Label: React.FC<LoginProps> = ({ user, personalWorkspace, currentWorkspace }) => {
const theme = useTheme();
return (
<LabelWrapper>
Expand All @@ -37,20 +38,23 @@ const Label: React.FC<Pick<LoginProps, "user" | "currentTeam">> = ({ user, curre
<LabelUserName size="m" weight="bold" color={theme.main.strongText}>
{user.name}
</LabelUserName>
<LabelTeamName size="xs" color={theme.main.strongText}>
{currentTeam.name}
</LabelTeamName>
{!personalWorkspace && (
<LabelWorkspaceName size="xs" color={theme.main.strongText}>
{currentWorkspace.name}
</LabelWorkspaceName>
)}
</LabelRight>
</LabelWrapper>
);
};

const HeaderProfile: React.FC<Props & Partial<LoginProps>> = ({
user = { name: "" },
currentTeam = { id: undefined, name: "" },
teams = [],
currentWorkspace = { id: undefined, name: "" },
personalWorkspace,
workspaces = [],
onSignOut,
onChangeTeam,
onWorkspaceChange,
openModal,
}) => {
const t = useT();
Expand All @@ -65,17 +69,23 @@ const HeaderProfile: React.FC<Props & Partial<LoginProps>> = ({
noHoverStyle
direction="down"
hasIcon
label={<Label user={user} currentTeam={currentTeam} />}>
label={
<Label
user={user}
personalWorkspace={personalWorkspace}
currentWorkspace={currentWorkspace}
/>
}>
<ChildrenWrapper>
<MenuList>
<MenuListItem>
<MenuListItemLabel linkTo={`/settings/account`} text={t("Account Settings")} />
</MenuListItem>
<MenuListItem noHover>
<TeamMenu
currentTeam={currentTeam}
teams={teams}
onChangeTeam={onChangeTeam}
<WorkspaceMenu
currentWorkspace={currentWorkspace}
workspaces={workspaces}
onWorkspaceChange={onWorkspaceChange}
openModal={openModal}
/>
</MenuListItem>
Expand Down Expand Up @@ -123,7 +133,7 @@ const LabelLeft = styled.div`
margin-right: 16px;
`;

const LabelTeamName = styled(Text)`
const LabelWorkspaceName = styled(Text)`
margin-top: 2px;
`;

Expand Down
7 changes: 6 additions & 1 deletion src/components/molecules/Common/Header/types.ts
Expand Up @@ -2,9 +2,14 @@ export type User = {
name: string;
};

export type Team = {
export type Workspace = {
id?: string;
name?: string;
members?: Array<any>;
policy?: {
id: string;
name: string;
} | null;
};

export type Project = {
Expand Down

0 comments on commit c1c6327

Please sign in to comment.