Skip to content

Commit db8b671

Browse files
authored
[WEB-5860] [WEB-5861] [WEB-5862] style: improved settings interface (#8520)
* style: improved profile settings * chore: minor improvements * style: improved workspace settings * style: workspace settings content * style: improved project settings * fix: project settings flat map * chore: add back navigation from settings pages * style: settings content * style: estimates list * refactor: remove old code * refactor: removed unnecessary line breaks * refactor: create a common component for page header * chore: add fade-in animation to sidebar * fix: formatting * fix: project settings sidebar header * fix: workspace settings sidebar header * fix: settings content wrapper scroll * chore: separate project settings features * fix: formatting * refactor: custom theme selector * refactor: settings headings * refactor: settings headings * fix: project settings sidebar padding * fix: sidebar header padding * fix: sidebar item permissions * fix: missing editable check * refactor: remove unused files * chore: remove unnecessary code * chore: add missing translations * fix: formatting
1 parent ba5ba5b commit db8b671

216 files changed

Lines changed: 4684 additions & 5454 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/web/app/(all)/[workspaceSlug]/(settings)/layout.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@ import { Outlet } from "react-router";
22
// components
33
import { ContentWrapper } from "@/components/core/content-wrapper";
44
import { ProjectsAppPowerKProvider } from "@/components/power-k/projects-app-provider";
5-
import { SettingsHeader } from "@/components/settings/header";
65

76
export default function SettingsLayout() {
87
return (
98
<>
109
<ProjectsAppPowerKProvider />
1110
<div className="relative flex size-full overflow-hidden rounded-lg border border-subtle">
1211
<main className="relative flex size-full flex-col overflow-hidden">
13-
{/* Header */}
14-
<SettingsHeader />
1512
{/* Content */}
16-
<ContentWrapper className="p-page-x md:flex w-full bg-surface-1">
13+
<ContentWrapper className="md:flex w-full bg-surface-1">
1714
<div className="size-full overflow-hidden">
1815
<Outlet />
1916
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { observer } from "mobx-react";
2+
// plane imports
3+
import { WORKSPACE_SETTINGS } from "@plane/constants";
4+
import { useTranslation } from "@plane/i18n";
5+
import { Breadcrumbs } from "@plane/ui";
6+
// components
7+
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
8+
import { SettingsPageHeader } from "@/components/settings/page-header";
9+
import { WORKSPACE_SETTINGS_ICONS } from "@/components/settings/workspace/sidebar/item-icon";
10+
11+
export const BillingWorkspaceSettingsHeader = observer(function BillingWorkspaceSettingsHeader() {
12+
// translation
13+
const { t } = useTranslation();
14+
// derived values
15+
const settingsDetails = WORKSPACE_SETTINGS["billing-and-plans"];
16+
const Icon = WORKSPACE_SETTINGS_ICONS["billing-and-plans"];
17+
18+
return (
19+
<SettingsPageHeader
20+
leftItem={
21+
<div className="flex items-center gap-2">
22+
<Breadcrumbs>
23+
<Breadcrumbs.Item
24+
component={
25+
<BreadcrumbLink
26+
label={t(settingsDetails.i18n_label)}
27+
icon={<Icon className="size-4 text-tertiary" />}
28+
/>
29+
}
30+
/>
31+
</Breadcrumbs>
32+
</div>
33+
}
34+
/>
35+
);
36+
});

apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/billing/page.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { observer } from "mobx-react";
33
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
44
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
55
import { PageHead } from "@/components/core/page-title";
6-
// hooks
76
import { SettingsContentWrapper } from "@/components/settings/content-wrapper";
7+
// hooks
88
import { useWorkspace } from "@/hooks/store/use-workspace";
99
import { useUserPermissions } from "@/hooks/store/user";
1010
// plane web components
1111
import { BillingRoot } from "@/plane-web/components/workspace/billing";
12+
// local imports
13+
import { BillingWorkspaceSettingsHeader } from "./header";
1214

1315
function BillingSettingsPage() {
1416
// store hooks
@@ -23,7 +25,7 @@ function BillingSettingsPage() {
2325
}
2426

2527
return (
26-
<SettingsContentWrapper size="lg">
28+
<SettingsContentWrapper header={<BillingWorkspaceSettingsHeader />} hugging>
2729
<PageHead title={pageTitle} />
2830
<BillingRoot />
2931
</SettingsContentWrapper>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { observer } from "mobx-react";
2+
// plane imports
3+
import { WORKSPACE_SETTINGS } from "@plane/constants";
4+
import { useTranslation } from "@plane/i18n";
5+
import { Breadcrumbs } from "@plane/ui";
6+
// components
7+
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
8+
import { SettingsPageHeader } from "@/components/settings/page-header";
9+
import { WORKSPACE_SETTINGS_ICONS } from "@/components/settings/workspace/sidebar/item-icon";
10+
11+
export const ExportsWorkspaceSettingsHeader = observer(function ExportsWorkspaceSettingsHeader() {
12+
// translation
13+
const { t } = useTranslation();
14+
// derived values
15+
const settingsDetails = WORKSPACE_SETTINGS.export;
16+
const Icon = WORKSPACE_SETTINGS_ICONS.export;
17+
18+
return (
19+
<SettingsPageHeader
20+
leftItem={
21+
<div className="flex items-center gap-2">
22+
<Breadcrumbs>
23+
<Breadcrumbs.Item
24+
component={
25+
<BreadcrumbLink
26+
label={t(settingsDetails.i18n_label)}
27+
icon={<Icon className="size-4 text-tertiary" />}
28+
/>
29+
}
30+
/>
31+
</Breadcrumbs>
32+
</div>
33+
}
34+
/>
35+
);
36+
});

apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/exports/page.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import { observer } from "mobx-react";
2-
// components
32
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
43
import { useTranslation } from "@plane/i18n";
54
import { cn } from "@plane/utils";
5+
// components
66
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
77
import { PageHead } from "@/components/core/page-title";
8-
import ExportGuide from "@/components/exporter/guide";
9-
// helpers
10-
// hooks
8+
import { ExportGuide } from "@/components/exporter/guide";
119
import { SettingsContentWrapper } from "@/components/settings/content-wrapper";
12-
import SettingsHeading from "@/components/settings/heading";
10+
import { SettingsHeading } from "@/components/settings/heading";
11+
// hooks
1312
import { useWorkspace } from "@/hooks/store/use-workspace";
1413
import { useUserPermissions } from "@/hooks/store/user";
14+
// local imports
15+
import { ExportsWorkspaceSettingsHeader } from "./header";
1516

1617
function ExportsPage() {
1718
// store hooks
@@ -34,10 +35,10 @@ function ExportsPage() {
3435
}
3536

3637
return (
37-
<SettingsContentWrapper size="lg">
38+
<SettingsContentWrapper header={<ExportsWorkspaceSettingsHeader />} hugging>
3839
<PageHead title={pageTitle} />
3940
<div
40-
className={cn("w-full", {
41+
className={cn("w-full flex flex-col gap-y-6", {
4142
"opacity-60": !canPerformWorkspaceMemberActions,
4243
})}
4344
>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { observer } from "mobx-react";
2+
// plane imports
3+
import { WORKSPACE_SETTINGS } from "@plane/constants";
4+
import { useTranslation } from "@plane/i18n";
5+
import { Breadcrumbs } from "@plane/ui";
6+
// components
7+
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
8+
import { SettingsPageHeader } from "@/components/settings/page-header";
9+
import { WORKSPACE_SETTINGS_ICONS } from "@/components/settings/workspace/sidebar/item-icon";
10+
11+
export const GeneralWorkspaceSettingsHeader = observer(function GeneralWorkspaceSettingsHeader() {
12+
// translation
13+
const { t } = useTranslation();
14+
// derived values
15+
const settingsDetails = WORKSPACE_SETTINGS.general;
16+
const Icon = WORKSPACE_SETTINGS_ICONS.general;
17+
18+
return (
19+
<SettingsPageHeader
20+
leftItem={
21+
<div className="flex items-center gap-2">
22+
<Breadcrumbs>
23+
<Breadcrumbs.Item
24+
component={
25+
<BreadcrumbLink
26+
label={t(settingsDetails.i18n_label)}
27+
icon={<Icon className="size-4 text-tertiary" />}
28+
/>
29+
}
30+
/>
31+
</Breadcrumbs>
32+
</div>
33+
}
34+
/>
35+
);
36+
});

apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/imports/page.tsx

Lines changed: 0 additions & 35 deletions
This file was deleted.

apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/integrations/page.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import useSWR from "swr";
44
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
55
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
66
import { PageHead } from "@/components/core/page-title";
7-
import { SingleIntegrationCard } from "@/components/integration";
8-
import { SettingsContentWrapper } from "@/components/settings/content-wrapper";
7+
import { SingleIntegrationCard } from "@/components/integration/single-integration-card";
98
import { IntegrationAndImportExportBanner } from "@/components/ui/integration-and-import-export-banner";
109
import { IntegrationsSettingsLoader } from "@/components/ui/loader/settings/integration";
1110
// constants
@@ -33,7 +32,7 @@ function WorkspaceIntegrationsPage() {
3332
if (!isAdmin) return <NotAuthorizedView section="settings" className="h-auto" />;
3433

3534
return (
36-
<SettingsContentWrapper size="lg">
35+
<>
3736
<PageHead title={pageTitle} />
3837
<section className="w-full overflow-y-auto">
3938
<IntegrationAndImportExportBanner bannerName="Integrations" />
@@ -47,7 +46,7 @@ function WorkspaceIntegrationsPage() {
4746
)}
4847
</div>
4948
</section>
50-
</SettingsContentWrapper>
49+
</>
5150
);
5251
}
5352

apps/web/app/(all)/[workspaceSlug]/(settings)/settings/(workspace)/layout.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import { Outlet } from "react-router";
44
// components
55
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
66
import { getWorkspaceActivePath, pathnameToAccessKey } from "@/components/settings/helper";
7-
import { SettingsMobileNav } from "@/components/settings/mobile";
7+
import { SettingsMobileNav } from "@/components/settings/mobile/nav";
88
// plane imports
99
import { WORKSPACE_SETTINGS_ACCESS } from "@plane/constants";
1010
import type { EUserWorkspaceRoles } from "@plane/types";
11+
// components
12+
import { WorkspaceSettingsSidebarRoot } from "@/components/settings/workspace/sidebar";
1113
// hooks
1214
import { useUserPermissions } from "@/hooks/store/user";
13-
// local components
14-
import { WorkspaceSettingsSidebar } from "./sidebar";
1515

1616
import type { Route } from "./+types/layout";
1717

@@ -34,18 +34,18 @@ const WorkspaceSettingLayout = observer(function WorkspaceSettingLayout({ params
3434
return (
3535
<>
3636
<SettingsMobileNav
37-
hamburgerContent={WorkspaceSettingsSidebar}
37+
hamburgerContent={WorkspaceSettingsSidebarRoot}
3838
activePath={getWorkspaceActivePath(pathname) || ""}
3939
/>
4040
<div className="inset-y-0 flex flex-row w-full h-full">
4141
{workspaceUserInfo && !isAuthorized ? (
4242
<NotAuthorizedView section="settings" className="h-auto" />
4343
) : (
44-
<div className="relative flex h-full w-full">
45-
<div className="hidden md:block">{<WorkspaceSettingsSidebar />}</div>
46-
<div className="w-full h-full overflow-y-scroll md:pt-page-y">
47-
<Outlet />
44+
<div className="relative flex size-full">
45+
<div className="h-full hidden md:block">
46+
<WorkspaceSettingsSidebarRoot />
4847
</div>
48+
<Outlet />
4949
</div>
5050
)}
5151
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { observer } from "mobx-react";
2+
// plane imports
3+
import { WORKSPACE_SETTINGS } from "@plane/constants";
4+
import { useTranslation } from "@plane/i18n";
5+
import { Breadcrumbs } from "@plane/ui";
6+
// components
7+
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
8+
import { SettingsPageHeader } from "@/components/settings/page-header";
9+
import { WORKSPACE_SETTINGS_ICONS } from "@/components/settings/workspace/sidebar/item-icon";
10+
11+
export const MembersWorkspaceSettingsHeader = observer(function MembersWorkspaceSettingsHeader() {
12+
// plane hooks
13+
const { t } = useTranslation();
14+
// derived values
15+
const settingsDetails = WORKSPACE_SETTINGS.members;
16+
const Icon = WORKSPACE_SETTINGS_ICONS.members;
17+
18+
return (
19+
<SettingsPageHeader
20+
leftItem={
21+
<div className="flex items-center gap-2">
22+
<Breadcrumbs>
23+
<Breadcrumbs.Item
24+
component={
25+
<BreadcrumbLink
26+
label={t(settingsDetails.i18n_label)}
27+
icon={<Icon className="size-4 text-tertiary" />}
28+
/>
29+
}
30+
/>
31+
</Breadcrumbs>
32+
</div>
33+
}
34+
/>
35+
);
36+
});

0 commit comments

Comments
 (0)