Skip to content

Commit

Permalink
teams page redesign (#563)
Browse files Browse the repository at this point in the history
  • Loading branch information
EduardZaydler authored Dec 10, 2024
1 parent bf1a9dd commit 960caeb
Show file tree
Hide file tree
Showing 22 changed files with 67 additions and 126 deletions.
4 changes: 3 additions & 1 deletion playwright/e2eTests/teamsOperations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ test("Add team", async ({ page, teamName, teamDescription, teamsPage }) => {
});

test("Edit team description", async ({ page, teamDescription, teamsPage, teamName }) => {
await teamsPage.teamCardKebab.click();
await teamsPage.editTeamButton.click();
await expect(teamsPage.nameInput("Team name")).toHaveValue(teamName);
await expect(teamsPage.teamDescription).toContainText(teamDescription);
Expand Down Expand Up @@ -64,7 +65,8 @@ test("Delete user", async ({ page, userName, teamsPage }) => {
});

test("Delete team", async ({ page, teamName, teamsPage }) => {
await teamsPage.deleteTeamButton(teamName + " changed").click();
await teamsPage.teamCardKebab.click();
await teamsPage.deleteTeamButton.click();
await page.getByRole("button", { name: "Confirm" }).click();
await expect(
page.locator(`:text("${teamName}"):right-of(span[data-tid='Delete team ${teamName}'])`)
Expand Down
3 changes: 1 addition & 2 deletions playwright/e2eTests/triggerOperations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ test("Set trigger maintenance for all intervals", async ({ triggerName, page })

const requestBody = JSON.parse(setMaintenanceRequest.postData() || "{}");
expect(requestBody).not.toBeNull();
expect(requestBody.trigger).toEqual(expectedTriggerTime);

expect(Math.abs(requestBody.trigger - expectedTriggerTime)).toBeLessThanOrEqual(1);
if (maintenance === Maintenance.off) {
await expect(page.getByText("Maintenance")).toBeVisible();
} else
Expand Down
8 changes: 5 additions & 3 deletions playwright/pages/teams.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,25 @@ export class TeamsPage {
readonly nameInput: (testId: string) => Locator;
readonly teamDescription: Locator;
readonly previewButton: Locator;
readonly teamCardKebab: Locator;
readonly editTeamButton: Locator;
readonly showUsersButton: Locator;
readonly addUserModalButton: Locator;
readonly deleteUserButton: (userName: string) => Locator;
readonly deleteTeamButton: (teamName: string) => Locator;
readonly deleteTeamButton: Locator;

constructor(page: Page) {
this.page = page;
this.addTeamButton = page.getByText("Add team");
this.nameInput = (testId) => page.locator(`label[data-tid='${testId}'] > span > input`);
this.teamDescription = page.locator("[data-tid='Team description']");
this.previewButton = page.getByText("Preview");
this.editTeamButton = page.getByRole("button", { name: "Edit Team" });
this.teamCardKebab = page.locator("[data-tid='Team card kebab']");
this.editTeamButton = page.getByRole("button", { name: "Edit" });
this.showUsersButton = page.getByText("Show users");
this.addUserModalButton = page.locator("[data-tid='Add user modal']");
this.deleteUserButton = (userName) => page.locator(`[data-tid="Delete user ${userName}"]`);
this.deleteTeamButton = (teamName) => page.locator(`[data-tid="Delete team ${teamName}"]`);
this.deleteTeamButton = page.getByRole("button", { name: "Delete" });
}

async gotoTeamsPage(): Promise<void> {
Expand Down
13 changes: 10 additions & 3 deletions src/Components/ChristmasMoodToggle/ChristmasMoodToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ import { Toggle } from "@skbkontur/react-ui/components/Toggle";
import { useChristmasMood } from "../../hooks/useChristmasMood";
import { useAppDispatch } from "../../store/hooks";
import { toggleChristmasMood } from "../../store/Reducers/UIReducer.slice";
import { useSelector } from "react-redux";
import { selectIsChristmasMood } from "../../store/Reducers/ConfigReducer.slice";

export const ChristmasMoodToggle: FC = () => {
const dispatch = useAppDispatch();
const [isChristmasMood, setChristmasMood] = useChristmasMood();
const isChristmasMoodEnabled = useSelector(selectIsChristmasMood);

const handleToggleChristmasMood = (selected: boolean) => {
setChristmasMood(selected);
dispatch(toggleChristmasMood(selected));
};
return (
<Toggle checked={isChristmasMood} onValueChange={handleToggleChristmasMood}>
<span style={{ color: "#fff" }}>New Year mood</span>
</Toggle>
<>
{isChristmasMoodEnabled ? (
<Toggle checked={isChristmasMood} onValueChange={handleToggleChristmasMood}>
<span style={{ color: "#fff" }}>New Year mood</span>
</Toggle>
) : null}
</>
);
};
1 change: 0 additions & 1 deletion src/Components/Grid/Grid.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
.grid {
display: grid;
align-items: baseline;
}
5 changes: 2 additions & 3 deletions src/Components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import RouterLink from "../RouterLink/RouterLink";
import svgLogo from "./moira-logo.svg";
import { AdminMenu } from "./Components/AdminMenu";
import { useSelector } from "react-redux";
import { selectIsChristmasMood, selectPlatform } from "../../store/Reducers/ConfigReducer.slice";
import { selectPlatform } from "../../store/Reducers/ConfigReducer.slice";
import { useGetConfigQuery } from "../../services/BaseApi";
import { Platform } from "../../Domain/Config";
import { ChristmasHatSVG } from "./Components/ChristmasHat";
Expand All @@ -29,7 +29,6 @@ export default function Header(): React.ReactElement {
const { isLoading } = useGetConfigQuery();
const theme = useTheme();
const { isChristmasMood } = useAppSelector(UIState);
const isChristmasMoodEnabled = useSelector(selectIsChristmasMood);

return (
<header
Expand All @@ -46,7 +45,7 @@ export default function Header(): React.ReactElement {
<img className={cn("logo-img")} src={svgLogo} alt="Moira" />
</Link>
<nav className={cn("menu")}>
{isChristmasMoodEnabled && <ChristmasMoodToggle />}
<ChristmasMoodToggle />
<ThemeSwitchModal />
<AdminMenu />
<RouterLink to={getPageLink("teams")} icon={<PeopleIcon />}>
Expand Down
7 changes: 6 additions & 1 deletion src/Components/Teams/TeamCard/TeamCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ export const TeamCard: FC<ITeamCardProps> = ({ team, isDeleting, onOpenDelete, o
className={cn("team-card")}
>
<Flexbox gap={5}>
<Kebab className={cn("team-card-kebab")} size="large">
<Kebab
data-tid="Team card kebab"
className={cn("team-card-kebab")}
size="large"
>
<MenuItem icon={<EditIcon />} onClick={openModal}>
Edit
</MenuItem>
Expand All @@ -100,6 +104,7 @@ export const TeamCard: FC<ITeamCardProps> = ({ team, isDeleting, onOpenDelete, o
onClick={handleConfirm}
use={"primary"}
width={100}
data-tid={`Delete team ${name}`}
>
Confirm
</Button>
Expand Down
10 changes: 2 additions & 8 deletions src/Components/Teams/Teams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,15 @@ import { Grid } from "../Grid/Grid";
import { TeamEditor } from "./TeamEditor/TeamEditor";
import { useGetUserTeamsQuery } from "../../services/TeamsApi";
import { useModal } from "../../hooks/useModal";
import { TeamWithUsers } from "../../Containers/TeamWithUsers";
import { TeamsList } from "../TeamsList/TeamsList";

export function Teams(): ReactElement {
const { isModalOpen, openModal, closeModal } = useModal();
const { data: teams } = useGetUserTeamsQuery();

return (
<>
{teams?.map((team) => {
return (
<div key={team.id}>
<TeamWithUsers team={team} />
</div>
);
})}
<TeamsList teams={teams} />
<Grid columns="100px" margin="24px 0">
<Button onClick={openModal}>Add team</Button>
</Grid>
Expand Down
23 changes: 23 additions & 0 deletions src/Components/TeamsList/TeamsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React, { FC, useState } from "react";
import { TeamCard } from "../../Components/Teams/TeamCard/TeamCard";
import { Grid } from "../../Components/Grid/Grid";
import { EmptyListText } from "../../Components/TriggerInfo/Components/EmptyListMessage/EmptyListText";
import { Team } from "../../Domain/Team";

export const TeamsList: FC<{ teams?: Team[] }> = ({ teams }) => {
const [deletingTeam, setDeletingTeam] = useState<Team | null>(null);
if (!teams?.length) return <EmptyListText text={"There are no teams"} />;
return (
<Grid gap="16px" columns="repeat(auto-fit, minmax(300px, 1fr))">
{teams?.map((team) => (
<TeamCard
key={team.id}
team={team}
isDeleting={deletingTeam?.id === team.id}
onOpenDelete={() => setDeletingTeam(team)}
onCloseDelete={() => setDeletingTeam(null)}
/>
))}
</Grid>
);
};
5 changes: 0 additions & 5 deletions src/Containers/AllTeamsContainer/AllTeamsContainer.less

This file was deleted.

30 changes: 5 additions & 25 deletions src/Containers/AllTeamsContainer/AllTeamsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,15 @@ import { setDocumentTitle } from "../../helpers/setDocumentTitle";
import { useAppDispatch, useAppSelector } from "../../store/hooks";
import { UIState } from "../../store/selectors";
import { useGetAllTeamsQuery } from "../../services/TeamsApi";
import classNames from "classnames/bind";
import { Team } from "../../Domain/Team";
import { Flexbox } from "../../Components/Flexbox/FlexBox";
import { SearchInput } from "../../Components/TriggerInfo/Components/SearchInput/SearchInput";
import { useDebounce } from "../../hooks/useDebounce";
import { Paging } from "@skbkontur/react-ui/components/Paging";
import transformPageFromHumanToProgrammer from "../../logic/transformPageFromHumanToProgrammer";
import { Select } from "@skbkontur/react-ui/components/Select";
import { EmptyListText } from "../../Components/TriggerInfo/Components/EmptyListMessage/EmptyListText";
import { TeamCard } from "../../Components/Teams/TeamCard/TeamCard";
import { setError } from "../../store/Reducers/UIReducer.slice";

import styles from "./AllTeamsContainer.less";

const cn = classNames.bind(styles);
import { TeamsList } from "../../Components/TeamsList/TeamsList";
import { useQueryState } from "../../hooks/useQueryState";

type SortDirection = "asc" | "desc";

Expand All @@ -29,8 +23,7 @@ const SORT_OPTIONS: Array<[SortDirection, string]> = [

const AllTeamsContainer: FC = () => {
const { error, isLoading } = useAppSelector(UIState);
const [deletingTeam, setDeletingTeam] = useState<Team | null>(null);
const [searchValue, setSearchValue] = useState("");
const [searchValue, setSearchValue] = useQueryState<string>("team", "");
const [activePage, setActivePage] = useState(1);
const [sortDirection, setSortDirection] = useState<SortDirection>("asc");
const debouncedSearchMetric = useDebounce(searchValue, 500);
Expand Down Expand Up @@ -75,21 +68,8 @@ const AllTeamsContainer: FC = () => {
items={SORT_OPTIONS}
/>
</Flexbox>
{teams?.list.length ? (
<div className={cn("teams-container")}>
{teams?.list.map((team) => (
<TeamCard
key={team.id}
team={team}
isDeleting={deletingTeam?.id === team.id}
onOpenDelete={() => setDeletingTeam(team)}
onCloseDelete={() => setDeletingTeam(null)}
/>
))}
</div>
) : (
<EmptyListText text={"There are no teams"} />
)}

<TeamsList teams={teams?.list} />

<Paging
shouldBeVisibleWithLessThanTwoPages={false}
Expand Down
2 changes: 1 addition & 1 deletion src/Containers/SettingsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const SettingsContainer: FC<ISettingsContainerProps> = ({ isTeamMember, history
<Flexbox align="baseline" direction="row" gap={4}>
<span>Shown for {team ? "team" : "user"}</span>
{isAdminLink ? (
<RouterLink to={getPageLink("team", team.id)}>
<RouterLink to={`${getPageLink("allTeams")}?team=${team.id}`}>
{team.name}
</RouterLink>
) : (
Expand Down
25 changes: 0 additions & 25 deletions src/Containers/TeamContainer.tsx

This file was deleted.

25 changes: 0 additions & 25 deletions src/Containers/TeamWithUsers.tsx

This file was deleted.

4 changes: 1 addition & 3 deletions src/Containers/TeamsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ const TeamsContainer = () => {
<Layout loading={isLoading} error={error}>
<LayoutContent>
<LayoutTitle>Teams</LayoutTitle>
<LayoutContent>
<Teams />
</LayoutContent>
<Teams />
</LayoutContent>
</Layout>
);
Expand Down
2 changes: 0 additions & 2 deletions src/Domain/Global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const PagesPaths = {
tags: "/tags",
patterns: "/patterns",
teams: "/teams",
team: "/teams/:teamId?",
contacts: "/contacts",
allTeams: "/teams/all",
};
Expand All @@ -27,7 +26,6 @@ export const PagesLinks = {
tags: "/tags",
patterns: "/patterns",
teams: "/teams",
team: "/teams/%id%",
docs: "//moira.readthedocs.org/",
contacts: "/contacts",
allTeams: "/teams/all",
Expand Down
2 changes: 0 additions & 2 deletions src/desktop.bundle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import Trigger, { TriggerProps } from "./pages/trigger/trigger";
import TriggerDesktop, { TriggerDesktopProps } from "./pages/trigger/trigger.desktop";
import { AdminRoute } from "./PrivateRoutes/AdminRoute";
import TeamsContainer from "./Containers/TeamsContainer";
import { TeamContainer } from "./Containers/TeamContainer";
import { TeamSettingsPrivateRoute } from "./PrivateRoutes/TeamSettingsPrivateRoute";
import AllTeamsContainer from "./Containers/AllTeamsContainer/AllTeamsContainer";
import { ChristmasLights } from "./Components/ChristmasLights/ChristmasLights";
Expand Down Expand Up @@ -80,7 +79,6 @@ function Desktop() {
<Route exact path={getPagePath("settings")} component={SettingsContainer} />
<Route exact path={getPagePath("teams")} component={TeamsContainer} />
<AdminRoute exact path={getPagePath("allTeams")} component={AllTeamsContainer} />
<AdminRoute exact path={getPagePath("team")} component={TeamContainer} />
<AdminRoute
exact
path={getPagePath("notifications")}
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/themes/useThemeFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const useThemeFeature = () => {
const resultTheme = isSystemTheme ? browserTheme : localValue;

document.body.dataset.theme = resultTheme;
}, [localValue]);
}, [localValue, isBrowserDarkThemeEnabled]);

return useFeatureFlag<EThemesNames>({ ...ThemeFlag, defaultValue: localValue });
};
4 changes: 2 additions & 2 deletions src/hooks/useChristmasMood.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ export const useChristmasMood = () => {
);

useEffect(() => {
if (localChristmasMood !== moodFromStore) {
if (localChristmasMood !== moodFromStore && isChristmasMoodApiff) {
dispatch(toggleChristmasMood(localChristmasMood));
}
}, [localChristmasMood, moodFromStore]);
}, [localChristmasMood, moodFromStore, isChristmasMoodApiff]);

return [localChristmasMood, setLocalChristmasMood] as const;
};
2 changes: 1 addition & 1 deletion src/hooks/useFeatureFlag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const useFeatureFlag = <T>(
return;
}
window.localStorage.setItem(key, JSON.stringify(value));
}, [value]);
}, [value, shouldPersist]);

return [value, setValue];
};
Loading

0 comments on commit 960caeb

Please sign in to comment.