[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
This commit is contained in:
Aaryan Khandelwal 2026-01-23 13:34:20 +05:30 committed by GitHub
parent ba5ba5bf54
commit db8b67102d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
216 changed files with 4684 additions and 5454 deletions

View file

@ -1,57 +1,6 @@
// plane imports
import { EStartOfTheWeek } from "@plane/types";
export const PROFILE_SETTINGS = {
profile: {
key: "profile",
i18n_label: "profile.actions.profile",
href: `/settings/account`,
highlight: (pathname: string) => pathname === "/settings/account/",
},
security: {
key: "security",
i18n_label: "profile.actions.security",
href: `/settings/account/security`,
highlight: (pathname: string) => pathname === "/settings/account/security/",
},
activity: {
key: "activity",
i18n_label: "profile.actions.activity",
href: `/settings/account/activity`,
highlight: (pathname: string) => pathname === "/settings/account/activity/",
},
preferences: {
key: "preferences",
i18n_label: "profile.actions.preferences",
href: `/settings/account/preferences`,
highlight: (pathname: string) => pathname === "/settings/account/preferences",
},
notifications: {
key: "notifications",
i18n_label: "profile.actions.notifications",
href: `/settings/account/notifications`,
highlight: (pathname: string) => pathname === "/settings/account/notifications/",
},
"api-tokens": {
key: "api-tokens",
i18n_label: "profile.actions.api-tokens",
href: `/settings/account/api-tokens`,
highlight: (pathname: string) => pathname === "/settings/account/api-tokens/",
},
};
export const PROFILE_ACTION_LINKS: {
key: string;
i18n_label: string;
href: string;
highlight: (pathname: string) => boolean;
}[] = [
PROFILE_SETTINGS["profile"],
PROFILE_SETTINGS["security"],
PROFILE_SETTINGS["activity"],
PROFILE_SETTINGS["preferences"],
PROFILE_SETTINGS["notifications"],
PROFILE_SETTINGS["api-tokens"],
];
export const PROFILE_VIEWER_TAB = [
{
key: "summary",
@ -98,11 +47,6 @@ export const PREFERENCE_OPTIONS: {
title: "theme",
description: "select_or_customize_your_interface_color_scheme",
},
{
id: "start_of_week",
title: "First day of the week",
description: "This will change how all calendars in your app look.",
},
];
/**

View file

@ -1,52 +0,0 @@
import { PROFILE_SETTINGS } from "./profile";
import { WORKSPACE_SETTINGS } from "./workspace";
export enum WORKSPACE_SETTINGS_CATEGORY {
ADMINISTRATION = "administration",
FEATURES = "features",
DEVELOPER = "developer",
}
export enum PROFILE_SETTINGS_CATEGORY {
YOUR_PROFILE = "your profile",
DEVELOPER = "developer",
}
export enum PROJECT_SETTINGS_CATEGORY {
PROJECTS = "projects",
}
export const WORKSPACE_SETTINGS_CATEGORIES = [
WORKSPACE_SETTINGS_CATEGORY.ADMINISTRATION,
WORKSPACE_SETTINGS_CATEGORY.FEATURES,
WORKSPACE_SETTINGS_CATEGORY.DEVELOPER,
];
export const PROFILE_SETTINGS_CATEGORIES = [
PROFILE_SETTINGS_CATEGORY.YOUR_PROFILE,
PROFILE_SETTINGS_CATEGORY.DEVELOPER,
];
export const PROJECT_SETTINGS_CATEGORIES = [PROJECT_SETTINGS_CATEGORY.PROJECTS];
export const GROUPED_WORKSPACE_SETTINGS = {
[WORKSPACE_SETTINGS_CATEGORY.ADMINISTRATION]: [
WORKSPACE_SETTINGS["general"],
WORKSPACE_SETTINGS["members"],
WORKSPACE_SETTINGS["billing-and-plans"],
WORKSPACE_SETTINGS["export"],
],
[WORKSPACE_SETTINGS_CATEGORY.FEATURES]: [],
[WORKSPACE_SETTINGS_CATEGORY.DEVELOPER]: [WORKSPACE_SETTINGS["webhooks"]],
};
export const GROUPED_PROFILE_SETTINGS = {
[PROFILE_SETTINGS_CATEGORY.YOUR_PROFILE]: [
PROFILE_SETTINGS["profile"],
PROFILE_SETTINGS["preferences"],
PROFILE_SETTINGS["notifications"],
PROFILE_SETTINGS["security"],
PROFILE_SETTINGS["activity"],
],
[PROFILE_SETTINGS_CATEGORY.DEVELOPER]: [PROFILE_SETTINGS["api-tokens"]],
};

View file

@ -0,0 +1,3 @@
export * from "./profile";
export * from "./project";
export * from "./workspace";

View file

@ -0,0 +1,61 @@
// plane imports
import type { TProfileSettingsTabs } from "@plane/types";
export enum PROFILE_SETTINGS_CATEGORY {
YOUR_PROFILE = "your profile",
DEVELOPER = "developer",
}
export const PROFILE_SETTINGS_CATEGORIES: PROFILE_SETTINGS_CATEGORY[] = [
PROFILE_SETTINGS_CATEGORY.YOUR_PROFILE,
PROFILE_SETTINGS_CATEGORY.DEVELOPER,
];
export const PROFILE_SETTINGS: Record<
TProfileSettingsTabs,
{
key: TProfileSettingsTabs;
i18n_label: string;
}
> = {
general: {
key: "general",
i18n_label: "profile.actions.profile",
},
security: {
key: "security",
i18n_label: "profile.actions.security",
},
activity: {
key: "activity",
i18n_label: "profile.actions.activity",
},
preferences: {
key: "preferences",
i18n_label: "profile.actions.preferences",
},
notifications: {
key: "notifications",
i18n_label: "profile.actions.notifications",
},
"api-tokens": {
key: "api-tokens",
i18n_label: "profile.actions.api-tokens",
},
};
export const PROFILE_SETTINGS_TABS: TProfileSettingsTabs[] = Object.keys(PROFILE_SETTINGS) as TProfileSettingsTabs[];
export const GROUPED_PROFILE_SETTINGS: Record<
PROFILE_SETTINGS_CATEGORY,
{ key: TProfileSettingsTabs; i18n_label: string }[]
> = {
[PROFILE_SETTINGS_CATEGORY.YOUR_PROFILE]: [
PROFILE_SETTINGS["general"],
PROFILE_SETTINGS["preferences"],
PROFILE_SETTINGS["notifications"],
PROFILE_SETTINGS["security"],
PROFILE_SETTINGS["activity"],
],
[PROFILE_SETTINGS_CATEGORY.DEVELOPER]: [PROFILE_SETTINGS["api-tokens"]],
};

View file

@ -0,0 +1,116 @@
// plane imports
import { EUserProjectRoles } from "@plane/types";
import type { TProjectSettingsItem, TProjectSettingsTabs } from "@plane/types";
export enum PROJECT_SETTINGS_CATEGORY {
GENERAL = "general",
FEATURES = "features",
WORK_STRUCTURE = "work-structure",
EXECUTION = "execution",
}
export const PROJECT_SETTINGS_CATEGORIES: PROJECT_SETTINGS_CATEGORY[] = [
PROJECT_SETTINGS_CATEGORY.GENERAL,
PROJECT_SETTINGS_CATEGORY.FEATURES,
PROJECT_SETTINGS_CATEGORY.WORK_STRUCTURE,
PROJECT_SETTINGS_CATEGORY.EXECUTION,
];
export const PROJECT_SETTINGS: Record<TProjectSettingsTabs, TProjectSettingsItem> = {
general: {
key: "general",
i18n_label: "common.general",
href: ``,
access: [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER, EUserProjectRoles.GUEST],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/`,
},
members: {
key: "members",
i18n_label: "common.members",
href: `/members`,
access: [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER, EUserProjectRoles.GUEST],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/members/`,
},
features_cycles: {
key: "features_cycles",
i18n_label: "project_settings.features.cycles.short_title",
href: `/features/cycles`,
access: [EUserProjectRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/features/cycles/`,
},
features_modules: {
key: "features_modules",
i18n_label: "project_settings.features.modules.short_title",
href: `/features/modules`,
access: [EUserProjectRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/features/modules/`,
},
features_views: {
key: "features_views",
i18n_label: "project_settings.features.views.short_title",
href: `/features/views`,
access: [EUserProjectRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/features/views/`,
},
features_pages: {
key: "features_pages",
i18n_label: "project_settings.features.pages.short_title",
href: `/features/pages`,
access: [EUserProjectRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/features/pages/`,
},
features_intake: {
key: "features_intake",
i18n_label: "project_settings.features.intake.short_title",
href: `/features/intake`,
access: [EUserProjectRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/features/intake/`,
},
states: {
key: "states",
i18n_label: "common.states",
href: `/states`,
access: [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/states/`,
},
labels: {
key: "labels",
i18n_label: "common.labels",
href: `/labels`,
access: [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/labels/`,
},
estimates: {
key: "estimates",
i18n_label: "common.estimates",
href: `/estimates`,
access: [EUserProjectRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/estimates/`,
},
automations: {
key: "automations",
i18n_label: "project_settings.automations.label",
href: `/automations`,
access: [EUserProjectRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/automations/`,
},
};
export const PROJECT_SETTINGS_FLAT_MAP: TProjectSettingsItem[] = Object.values(PROJECT_SETTINGS);
export const GROUPED_PROJECT_SETTINGS: Record<PROJECT_SETTINGS_CATEGORY, TProjectSettingsItem[]> = {
[PROJECT_SETTINGS_CATEGORY.GENERAL]: [PROJECT_SETTINGS["general"], PROJECT_SETTINGS["members"]],
[PROJECT_SETTINGS_CATEGORY.FEATURES]: [
PROJECT_SETTINGS["features_cycles"],
PROJECT_SETTINGS["features_modules"],
PROJECT_SETTINGS["features_views"],
PROJECT_SETTINGS["features_pages"],
PROJECT_SETTINGS["features_intake"],
],
[PROJECT_SETTINGS_CATEGORY.WORK_STRUCTURE]: [
PROJECT_SETTINGS["states"],
PROJECT_SETTINGS["labels"],
PROJECT_SETTINGS["estimates"],
],
[PROJECT_SETTINGS_CATEGORY.EXECUTION]: [PROJECT_SETTINGS["automations"]],
};

View file

@ -0,0 +1,68 @@
// plane imports
import type { TWorkspaceSettingsItem, TWorkspaceSettingsTabs } from "@plane/types";
import { EUserWorkspaceRoles } from "@plane/types";
export enum WORKSPACE_SETTINGS_CATEGORY {
ADMINISTRATION = "administration",
FEATURES = "features",
DEVELOPER = "developer",
}
export const WORKSPACE_SETTINGS_CATEGORIES: WORKSPACE_SETTINGS_CATEGORY[] = [
WORKSPACE_SETTINGS_CATEGORY.ADMINISTRATION,
WORKSPACE_SETTINGS_CATEGORY.FEATURES,
WORKSPACE_SETTINGS_CATEGORY.DEVELOPER,
];
export const WORKSPACE_SETTINGS: Record<TWorkspaceSettingsTabs, TWorkspaceSettingsItem> = {
general: {
key: "general",
i18n_label: "workspace_settings.settings.general.title",
href: `/settings`,
access: [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/`,
},
members: {
key: "members",
i18n_label: "workspace_settings.settings.members.title",
href: `/settings/members`,
access: [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/members/`,
},
"billing-and-plans": {
key: "billing-and-plans",
i18n_label: "workspace_settings.settings.billing_and_plans.title",
href: `/settings/billing`,
access: [EUserWorkspaceRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/billing/`,
},
export: {
key: "export",
i18n_label: "workspace_settings.settings.exports.title",
href: `/settings/exports`,
access: [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/exports/`,
},
webhooks: {
key: "webhooks",
i18n_label: "workspace_settings.settings.webhooks.title",
href: `/settings/webhooks`,
access: [EUserWorkspaceRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/webhooks/`,
},
};
export const WORKSPACE_SETTINGS_ACCESS = Object.fromEntries(
Object.entries(WORKSPACE_SETTINGS).map(([_, { href, access }]) => [href, access])
);
export const GROUPED_WORKSPACE_SETTINGS: Record<WORKSPACE_SETTINGS_CATEGORY, TWorkspaceSettingsItem[]> = {
[WORKSPACE_SETTINGS_CATEGORY.ADMINISTRATION]: [
WORKSPACE_SETTINGS["general"],
WORKSPACE_SETTINGS["members"],
WORKSPACE_SETTINGS["billing-and-plans"],
WORKSPACE_SETTINGS["export"],
],
[WORKSPACE_SETTINGS_CATEGORY.FEATURES]: [],
[WORKSPACE_SETTINGS_CATEGORY.DEVELOPER]: [WORKSPACE_SETTINGS["webhooks"]],
};

View file

@ -1,9 +1,9 @@
import type { TStaticViewTypes, IWorkspaceSearchResults } from "@plane/types";
import { EUserWorkspaceRoles } from "@plane/types";
export const ORGANIZATION_SIZE = ["Just myself", "2-10", "11-50", "51-200", "201-500", "500+"];
export const ORGANIZATION_SIZE: string[] = ["Just myself", "2-10", "11-50", "51-200", "201-500", "500+"];
export const RESTRICTED_URLS = [
export const RESTRICTED_URLS: string[] = [
"404",
"accounts",
"api",
@ -71,62 +71,6 @@ export const RESTRICTED_URLS = [
"instance",
];
export const WORKSPACE_SETTINGS = {
general: {
key: "general",
i18n_label: "workspace_settings.settings.general.title",
href: `/settings`,
access: [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/`,
},
members: {
key: "members",
i18n_label: "workspace_settings.settings.members.title",
href: `/settings/members`,
access: [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/members/`,
},
"billing-and-plans": {
key: "billing-and-plans",
i18n_label: "workspace_settings.settings.billing_and_plans.title",
href: `/settings/billing`,
access: [EUserWorkspaceRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/billing/`,
},
export: {
key: "export",
i18n_label: "workspace_settings.settings.exports.title",
href: `/settings/exports`,
access: [EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/exports/`,
},
webhooks: {
key: "webhooks",
i18n_label: "workspace_settings.settings.webhooks.title",
href: `/settings/webhooks`,
access: [EUserWorkspaceRoles.ADMIN],
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/webhooks/`,
},
};
export const WORKSPACE_SETTINGS_ACCESS = Object.fromEntries(
Object.entries(WORKSPACE_SETTINGS).map(([_, { href, access }]) => [href, access])
);
export const WORKSPACE_SETTINGS_LINKS: {
key: string;
i18n_label: string;
href: string;
access: EUserWorkspaceRoles[];
highlight: (pathname: string, baseUrl: string) => boolean;
}[] = [
WORKSPACE_SETTINGS["general"],
WORKSPACE_SETTINGS["members"],
WORKSPACE_SETTINGS["billing-and-plans"],
WORKSPACE_SETTINGS["export"],
WORKSPACE_SETTINGS["webhooks"],
];
export const ROLE = {
[EUserWorkspaceRoles.GUEST]: "Guest",
[EUserWorkspaceRoles.MEMBER]: "Member",