refactor: migrate admin icons to @makeplane/propel (#9730)

* refactor: migrate admin icons to @makeplane/propel

Replace confirmed icon symbols in apps/admin with their audited
@makeplane/propel/icons targets, merging into the imports the six
already-migrated files declared. Unresolved symbols (Menu, BrainCog)
and the LucideIcon type stay on lucide-react.

Lucide size props become explicit width/height. Loader keeps its
LoaderIcon alias so the call site is unchanged.

apps/admin already declared @makeplane/propel, so no dependency change
was needed.

* fix: restore Settings breadcrumb label after icon rename

The migration's identifier rename also rewrote the string literal, so the
breadcrumb displayed the icon component name instead of the label.
This commit is contained in:
Anmol Singh Bhatia
2026-09-02 17:47:17 +05:30
committed by GitHub
parent 2e3e293bd6
commit d6c4b902f7
20 changed files with 61 additions and 55 deletions

View File

@@ -5,7 +5,7 @@
*/
import { useForm } from "react-hook-form";
import { Lightbulb } from "lucide-react";
import { ThoughtsOutline } from "@makeplane/propel/icons";
import { Button } from "@makeplane/propel/components/button";
import type { IFormattedInstanceConfiguration, TInstanceAIConfigurationKeys } from "@plane/types";
// components
@@ -133,7 +133,7 @@ export function InstanceAIForm(props: IInstanceAIForm) {
/>
<div className="relative inline-flex items-center gap-1.5 rounded-sm border border-accent-subtle bg-accent-subtle px-4 py-2 text-caption-sm-regular text-accent-secondary">
<Lightbulb className="size-4" />
<ThoughtsOutline className="size-4" />
<div>
If you have a preferred AI models vendor, please get in{" "}
<a className="font-medium underline" href="https://plane.so/contact">

View File

@@ -8,7 +8,7 @@ import { useState } from "react";
import { isEmpty } from "lodash-es";
import Link from "next/link";
import { useForm } from "react-hook-form";
import { Monitor } from "lucide-react";
import { MonitorOutline } from "@makeplane/propel/icons";
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import { Button } from "@makeplane/propel/components/button";
@@ -248,7 +248,7 @@ export function InstanceGithubConfigForm(props: Props) {
{/* web service details */}
<div className="flex flex-col overflow-hidden rounded-lg">
<div className="flex items-center gap-x-3 bg-layer-3 px-6 py-3 text-11 font-medium text-secondary uppercase">
<Monitor className="h-3 w-3" />
<MonitorOutline className="h-3 w-3" />
Web
</div>
<div className="flex flex-col gap-y-4 bg-layer-1 px-6 py-4">

View File

@@ -8,7 +8,7 @@ import { useState } from "react";
import { isEmpty } from "lodash-es";
import Link from "next/link";
import { useForm } from "react-hook-form";
import { Monitor } from "lucide-react";
import { MonitorOutline } from "@makeplane/propel/icons";
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import { Button } from "@makeplane/propel/components/button";
@@ -240,7 +240,7 @@ export function InstanceGoogleConfigForm(props: Props) {
{/* web service details */}
<div className="flex flex-col overflow-hidden rounded-lg">
<div className="flex items-center gap-x-3 bg-layer-3 px-6 py-3 text-11 font-medium text-secondary uppercase">
<Monitor className="h-3 w-3" />
<MonitorOutline className="h-3 w-3" />
Web
</div>
<div className="flex flex-col gap-y-4 bg-layer-1 px-6 py-4">

View File

@@ -6,7 +6,7 @@
import { observer } from "mobx-react";
import { Controller, useForm } from "react-hook-form";
import { Telescope } from "lucide-react";
import { UsageOutline } from "@makeplane/propel/icons";
// plane imports
import { Button } from "@makeplane/propel/components/button";
import { Input } from "@makeplane/propel/components/input";
@@ -101,7 +101,7 @@ export const GeneralConfigurationForm = observer(function GeneralConfigurationFo
<div className="flex grow items-center gap-4">
<div className="shrink-0">
<div className="flex size-11 items-center justify-center rounded-lg bg-layer-1">
<Telescope className="size-5 text-tertiary" />
<UsageOutline className="size-5 text-tertiary" />
</div>
</div>
<div className="grow">

View File

@@ -7,7 +7,7 @@
import { Fragment, useEffect, useState } from "react";
import { observer } from "mobx-react";
import { useTheme as useNextTheme } from "next-themes";
import { LogOut, UserCog2, Palette } from "lucide-react";
import { AccessAndRolesOutline, LogOutOutline, PaletteOutline } from "@makeplane/propel/icons";
import { Menu, Transition } from "@headlessui/react";
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
@@ -55,7 +55,7 @@ export const AdminSidebarDropdown = observer(function AdminSidebarDropdown() {
className="flex w-full items-center gap-2 rounded-sm px-2 py-1 hover:bg-layer-1-hover"
onClick={handleThemeSwitch}
>
<Palette className="h-4 w-4 stroke-[1.5]" />
<PaletteOutline className="h-4 w-4 stroke-[1.5]" />
Switch to {resolvedTheme === "dark" ? "light" : "dark"} mode
</Menu.Item>
</div>
@@ -67,7 +67,7 @@ export const AdminSidebarDropdown = observer(function AdminSidebarDropdown() {
type="submit"
className="flex w-full items-center gap-2 rounded-sm px-2 py-1 hover:bg-layer-1-hover"
>
<LogOut className="h-4 w-4 stroke-[1.5]" />
<LogOutOutline className="h-4 w-4 stroke-[1.5]" />
Sign out
</Menu.Item>
</form>
@@ -95,7 +95,7 @@ export const AdminSidebarDropdown = observer(function AdminSidebarDropdown() {
})}
>
<div className="flex size-8 flex-shrink-0 items-center justify-center rounded-sm bg-layer-1">
<UserCog2 className="size-5 text-primary" />
<AccessAndRolesOutline className="size-5 text-primary" />
</div>
</Menu.Button>
{isSidebarCollapsed && (

View File

@@ -7,12 +7,18 @@
import { useState, useRef } from "react";
import { observer } from "mobx-react";
import Link from "next/link";
import { HelpCircle, MessageSquare, MoveLeft } from "lucide-react";
import { Transition } from "@headlessui/react";
import { WEB_BASE_URL } from "@plane/constants";
// plane internal packages
import { Tooltip } from "@makeplane/propel/components/tooltip";
import { Github, NewTabOutline, PagesOutline } from "@makeplane/propel/icons";
import {
ArrowNarrowLeftOutline,
ChatOutline,
Github,
HelpOutline,
NewTabOutline,
PagesOutline,
} from "@makeplane/propel/icons";
import { cn } from "@plane/utils";
// hooks
import { useInstance, useTheme } from "@/hooks/store";
@@ -27,7 +33,7 @@ const helpOptions = [
{
name: "Join our Forum",
href: "https://forum.plane.so",
Icon: MessageSquare,
Icon: ChatOutline,
},
{
name: "Report a bug",
@@ -87,7 +93,7 @@ export const AdminSidebarHelpSection = observer(function AdminSidebarHelpSection
}`}
onClick={() => setIsNeedHelpOpen((prev) => !prev)}
>
<HelpCircle className="size-4" />
<HelpOutline className="size-4" />
</button>
</Tooltip>
<Tooltip label="Toggle sidebar" side={isSidebarCollapsed ? "right" : "top"}>
@@ -99,7 +105,7 @@ export const AdminSidebarHelpSection = observer(function AdminSidebarHelpSection
}`}
onClick={() => toggleSidebar(!isSidebarCollapsed)}
>
<MoveLeft className={`size-4 duration-300 ${isSidebarCollapsed ? "rotate-180" : ""}`} />
<ArrowNarrowLeftOutline className={`size-4 duration-300 ${isSidebarCollapsed ? "rotate-180" : ""}`} />
</button>
</Tooltip>
</div>

View File

@@ -8,7 +8,7 @@ import { useState } from "react";
import { observer } from "mobx-react";
import Link from "next/link";
import useSWR from "swr";
import { Loader as LoaderIcon } from "lucide-react";
import { LoadingOutline as LoaderIcon } from "@makeplane/propel/icons";
// types
import { AnchorButton } from "@makeplane/propel/components/anchor-button";
import { Button } from "@makeplane/propel/components/button";

View File

@@ -4,11 +4,10 @@
* See the LICENSE file for details.
*/
import { Info } from "lucide-react";
// plane constants
import type { TAdminAuthErrorInfo } from "@plane/constants";
// icons
import { CloseOutline } from "@makeplane/propel/icons";
import { CloseOutline, InfoOutline } from "@makeplane/propel/icons";
type TAuthBanner = {
bannerData: TAdminAuthErrorInfo | undefined;
@@ -22,7 +21,7 @@ export function AuthBanner(props: TAuthBanner) {
return (
<div className="relative flex items-center gap-2 rounded-md border border-accent-strong/50 bg-accent-primary/10 p-2">
<div className="relative flex h-4 w-4 flex-shrink-0 items-center justify-center">
<Info size={16} className="text-accent-primary" />
<InfoOutline width={16} height={16} className="text-accent-primary" />
</div>
<div className="w-full text-13 font-medium text-accent-primary">{bannerData?.message}</div>
<button

View File

@@ -6,7 +6,7 @@
import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { Eye, EyeOff } from "lucide-react";
import { HideOutline, ShowOutline } from "@makeplane/propel/icons";
// plane internal packages
import type { EAdminAuthErrorCodes, TAdminAuthErrorInfo } from "@plane/constants";
import { API_BASE_URL } from "@plane/constants";
@@ -172,7 +172,7 @@ export function InstanceSignInForm() {
className="flex items-center justify-center text-placeholder"
onClick={() => setShowPassword(false)}
>
<EyeOff className="h-4 w-4" />
<HideOutline className="h-4 w-4" />
</button>
) : (
<button
@@ -181,7 +181,7 @@ export function InstanceSignInForm() {
className="flex items-center justify-center text-placeholder"
onClick={() => setShowPassword(true)}
>
<Eye className="h-4 w-4" />
<ShowOutline className="h-4 w-4" />
</button>
)}
</InputGroup>

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import Link from "next/link";
// icons
import { Settings2 } from "lucide-react";
import { SettingsOutline } from "@makeplane/propel/icons";
// plane internal packages
import { AnchorButton } from "@makeplane/propel/components/anchor-button";
import { Button } from "@makeplane/propel/components/button";
@@ -59,7 +59,7 @@ export const GiteaConfiguration = observer(function GiteaConfiguration(props: Pr
stretch="auto"
nativeButton={false}
render={<Link href="/authentication/gitea" />}
icon={<Settings2 className="h-4 w-4 p-0.5 text-tertiary" />}
icon={<SettingsOutline className="h-4 w-4 p-0.5 text-tertiary" />}
label="Configure"
/>
)}

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import Link from "next/link";
// icons
import { Settings2 } from "lucide-react";
import { SettingsOutline } from "@makeplane/propel/icons";
// plane internal packages
import { AnchorButton } from "@makeplane/propel/components/anchor-button";
import { Button } from "@makeplane/propel/components/button";
@@ -57,7 +57,7 @@ export const GithubConfiguration = observer(function GithubConfiguration(props:
stretch="auto"
nativeButton={false}
render={<Link href="/authentication/github" />}
icon={<Settings2 className="h-4 w-4 p-0.5 text-tertiary" />}
icon={<SettingsOutline className="h-4 w-4 p-0.5 text-tertiary" />}
label="Configure"
/>
)}

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import Link from "next/link";
// icons
import { Settings2 } from "lucide-react";
import { SettingsOutline } from "@makeplane/propel/icons";
// plane internal packages
import { AnchorButton } from "@makeplane/propel/components/anchor-button";
import { Button } from "@makeplane/propel/components/button";
@@ -57,7 +57,7 @@ export const GitlabConfiguration = observer(function GitlabConfiguration(props:
stretch="auto"
nativeButton={false}
render={<Link href="/authentication/gitlab" />}
icon={<Settings2 className="h-4 w-4 p-0.5 text-tertiary" />}
icon={<SettingsOutline className="h-4 w-4 p-0.5 text-tertiary" />}
label="Configure"
/>
)}

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import Link from "next/link";
// icons
import { Settings2 } from "lucide-react";
import { SettingsOutline } from "@makeplane/propel/icons";
// plane internal packages
import { AnchorButton } from "@makeplane/propel/components/anchor-button";
import { Button } from "@makeplane/propel/components/button";
@@ -57,7 +57,7 @@ export const GoogleConfiguration = observer(function GoogleConfiguration(props:
stretch="auto"
nativeButton={false}
render={<Link href="/authentication/google" />}
icon={<Settings2 className="h-4 w-4 p-0.5 text-tertiary" />}
icon={<SettingsOutline className="h-4 w-4 p-0.5 text-tertiary" />}
label="Configure"
/>
)}

View File

@@ -4,7 +4,7 @@
* See the LICENSE file for details.
*/
import { AlertCircle, CheckCircle2 } from "lucide-react";
import { TickCircleOutline, WarningCircleOutline } from "@makeplane/propel/icons";
type TBanner = {
type: "success" | "error";
@@ -22,10 +22,10 @@ export function Banner(props: TBanner) {
<div className="flex-shrink-0">
{type === "error" ? (
<span className="flex h-6 w-6 items-center justify-center rounded-full">
<AlertCircle className="h-5 w-5 text-danger-primary" aria-hidden="true" />
<WarningCircleOutline className="h-5 w-5 text-danger-primary" aria-hidden="true" />
</span>
) : (
<CheckCircle2 className="h-5 w-5 text-success-primary" aria-hidden="true" />
<TickCircleOutline className="h-5 w-5 text-success-primary" aria-hidden="true" />
)}
</div>
<div className="ml-1">

View File

@@ -8,7 +8,7 @@ import React, { useState } from "react";
import type { Control, FieldPath, FieldValues } from "react-hook-form";
import { Controller } from "react-hook-form";
// icons
import { Eye, EyeOff } from "lucide-react";
import { HideOutline, ShowOutline } from "@makeplane/propel/icons";
// plane internal packages
import { Input, InputGroup } from "@makeplane/propel/components/input";
@@ -71,7 +71,7 @@ export function ControllerInput<TFieldValues extends FieldValues = FieldValues>(
className="flex items-center justify-center text-placeholder"
onClick={() => setShowPassword(false)}
>
<EyeOff className="h-4 w-4" />
<HideOutline className="h-4 w-4" />
</button>
) : (
<button
@@ -80,7 +80,7 @@ export function ControllerInput<TFieldValues extends FieldValues = FieldValues>(
className="flex items-center justify-center text-placeholder"
onClick={() => setShowPassword(true)}
>
<Eye className="h-4 w-4" />
<ShowOutline className="h-4 w-4" />
</button>
))}
</InputGroup>

View File

@@ -9,7 +9,8 @@ import { observer } from "mobx-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
// icons
import { Menu, Settings } from "lucide-react";
import { Menu } from "lucide-react";
import { SettingsOutline } from "@makeplane/propel/icons";
// plane internal packages
import {
Breadcrumb,
@@ -74,7 +75,7 @@ export const AdminHeader = observer(function AdminHeader() {
<BreadcrumbItem>
<BreadcrumbLink
label="Settings"
icon={<Settings className="h-4 w-4 text-tertiary" />}
icon={<SettingsOutline className="h-4 w-4 text-tertiary" />}
render={<Link href="/general/" />}
/>
</BreadcrumbItem>

View File

@@ -4,7 +4,7 @@
* See the LICENSE file for details.
*/
import { CircleCheck } from "lucide-react";
import { TickCircleOutline } from "@makeplane/propel/icons";
// plane internal packages
import { E_PASSWORD_STRENGTH } from "@plane/constants";
import { cn, getPasswordCriteria, getPasswordStrength } from "@plane/utils";
@@ -120,7 +120,7 @@ export function PasswordStrengthIndicator({
{criteria.map((criterion) => (
<div key={criterion.key} className="flex items-center gap-1.5">
<div className="flex items-center justify-center p-0.5">
<CircleCheck
<TickCircleOutline
className={cn("h-3 w-3 flex-shrink-0", {
"text-success-primary": criterion.isValid,
"text-primary": !criterion.isValid,

View File

@@ -7,7 +7,7 @@
import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
// icons
import { Eye, EyeOff } from "lucide-react";
import { HideOutline, ShowOutline } from "@makeplane/propel/icons";
// plane internal packages
import { API_BASE_URL, E_PASSWORD_STRENGTH } from "@plane/constants";
import { Button } from "@makeplane/propel/components/button";
@@ -282,7 +282,7 @@ export function InstanceSetupForm() {
className="flex items-center justify-center text-placeholder"
onClick={() => handleShowPassword("password")}
>
<EyeOff className="h-4 w-4" />
<HideOutline className="h-4 w-4" />
</button>
) : (
<button
@@ -291,7 +291,7 @@ export function InstanceSetupForm() {
className="flex items-center justify-center text-placeholder"
onClick={() => handleShowPassword("password")}
>
<Eye className="h-4 w-4" />
<ShowOutline className="h-4 w-4" />
</button>
)}
</InputGroup>
@@ -325,7 +325,7 @@ export function InstanceSetupForm() {
className="flex items-center justify-center text-placeholder"
onClick={() => handleShowPassword("retypePassword")}
>
<EyeOff className="h-4 w-4" />
<HideOutline className="h-4 w-4" />
</button>
) : (
<button
@@ -334,7 +334,7 @@ export function InstanceSetupForm() {
className="flex items-center justify-center text-placeholder"
onClick={() => handleShowPassword("retypePassword")}
>
<Eye className="h-4 w-4" />
<ShowOutline className="h-4 w-4" />
</button>
)}
</InputGroup>

View File

@@ -4,7 +4,7 @@
* See the LICENSE file for details.
*/
import { KeyRound, Mails } from "lucide-react";
import { KeyOutline, MailOutline } from "@makeplane/propel/icons";
// types
import type {
TCoreInstanceAuthenticationModeKeys,
@@ -38,7 +38,7 @@ export const getCoreAuthenticationModesMap: (
name: "Unique codes",
description:
"Log in or sign up for Plane using codes sent via email. You need to have set up SMTP to use this method.",
icon: <Mails className="h-6 w-6 p-0.5 text-tertiary" />,
icon: <MailOutline className="h-6 w-6 p-0.5 text-tertiary" />,
config: <EmailCodesConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "ENABLE_MAGIC_LINK_LOGIN",
},
@@ -46,7 +46,7 @@ export const getCoreAuthenticationModesMap: (
key: "passwords-login",
name: "Passwords",
description: "Allow members to create accounts with passwords and use it with their email addresses to sign in.",
icon: <KeyRound className="h-6 w-6 p-0.5 text-tertiary" />,
icon: <KeyOutline className="h-6 w-6 p-0.5 text-tertiary" />,
config: <PasswordLoginConfiguration disabled={disabled} updateConfig={updateConfig} />,
enabledConfigKey: "ENABLE_EMAIL_PASSWORD",
},

View File

@@ -4,9 +4,9 @@
* See the LICENSE file for details.
*/
import { Image, BrainCog, Cog, Mail } from "lucide-react";
import { BrainCog } from "lucide-react";
// plane imports
import { LockOutline, WorkspaceOutline } from "@makeplane/propel/icons";
import { ImageOutline, LockOutline, MailOutline, SettingsOutline, WorkspaceOutline } from "@makeplane/propel/icons";
// types
import type { TSidebarMenuItem } from "./types";
@@ -14,13 +14,13 @@ export type TCoreSidebarMenuKey = "general" | "email" | "workspace" | "authentic
export const coreSidebarMenuLinks: Record<TCoreSidebarMenuKey, TSidebarMenuItem> = {
general: {
Icon: Cog,
Icon: SettingsOutline,
name: "General",
description: "Identify your instances and get key details.",
href: `/general/`,
},
email: {
Icon: Mail,
Icon: MailOutline,
name: "Email",
description: "Configure your SMTP controls.",
href: `/email/`,
@@ -44,7 +44,7 @@ export const coreSidebarMenuLinks: Record<TCoreSidebarMenuKey, TSidebarMenuItem>
href: `/ai/`,
},
image: {
Icon: Image,
Icon: ImageOutline,
name: "Images in Plane",
description: "Allow third-party image libraries.",
href: `/image/`,