From 67c57abb63dc165a63ca4911ae7fbe7e438ef719 Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Tue, 21 Apr 2026 13:45:08 +1000 Subject: [PATCH] chore: tighten `.vscode` IDE and typescript configuration (#24537) This branch tightens import hygiene and editor guidance to reduce accidental use of legacy or discouraged patterns. It also updates consumers too, by propagating the new `lucide-react` import convention across the existing UI surfaces that reference those icons. - Updated `.vscode/settings.json` to prefer non-relative imports and improve TypeScript auto-import behavior. - Re-enabled and expanded Biome restricted-import enforcement in `biome.jsonc` for migration guardrails. - Added/used `lucide-react` `-Icon` naming conventions for clarity and consistency. - Updated consumers too across components, modules, and pages so the new import rules are applied end-to-end. --- .vscode/settings.json | 18 +++++++++- biome.jsonc | 32 ++++++++--------- site/src/@types/lucide-react.d.ts | 3 ++ .../components/AnimatedIcons/ChevronDown.tsx | 2 +- .../Autocomplete/Autocomplete.stories.tsx | 6 ++-- .../components/Autocomplete/Autocomplete.tsx | 8 +++-- site/src/components/Badge/Badge.stories.tsx | 24 ++++++------- site/src/components/Breadcrumb/Breadcrumb.tsx | 4 +-- site/src/components/Checkbox/Checkbox.tsx | 6 ++-- .../Collapsible/Collapsible.stories.tsx | 4 +-- site/src/components/Command/Command.tsx | 4 +-- .../components/DropdownMenu/DropdownMenu.tsx | 4 +-- site/src/components/Filter/Filter.tsx | 4 +-- .../MultiSelectCombobox.tsx | 8 ++--- .../OrganizationAutocomplete.tsx | 4 +-- site/src/components/RadioGroup/RadioGroup.tsx | 4 +-- site/src/components/Select/Select.tsx | 10 +++--- site/src/components/TagInput/TagInput.tsx | 4 +-- .../management/DeploymentSidebarView.tsx | 4 +-- .../management/OrganizationSidebarView.tsx | 6 ++-- .../NotificationsInbox/InboxItem.tsx | 4 +-- .../modules/resources/AgentApps/AgentApps.tsx | 4 +-- .../resources/AgentDevcontainerCard.tsx | 4 +-- .../AgentDevcontainerMoreActions.tsx | 4 +-- .../modules/resources/PortForwardButton.tsx | 2 +- site/src/modules/users/AISeatCell.tsx | 6 ++-- .../DynamicParameter/DynamicParameter.tsx | 34 +++++++++---------- .../WorkspaceMoreActions.tsx | 4 +-- .../UserOrGroupAutocomplete.tsx | 4 +-- .../WorkspaceSharingForm.tsx | 6 ++-- .../AgentsPage/components/AgentChatInput.tsx | 9 +++-- .../ChatElements/CompactOrgSelector.tsx | 4 +-- .../LimitsTab/GroupLimitsSection.tsx | 6 ++-- .../pages/CreateUserPage/CreateUserForm.tsx | 4 +-- .../CreateWorkspacePageView.tsx | 4 +-- .../ExternalAuthButton.tsx | 6 ++-- .../AnnouncementBannerItem.tsx | 4 +-- .../IdpOrgSyncPage/ExportPolicyButton.tsx | 4 +-- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 8 ++--- .../OverviewPage/OverviewPageView.tsx | 2 +- .../PremiumPage/PremiumPageView.tsx | 17 ++++++---- .../src/pages/GroupsPage/GroupMembersPage.tsx | 4 +-- .../CreateOrganizationPageView.tsx | 4 +-- .../CustomRolesPage/CustomRolesPageView.tsx | 4 +-- .../IdpSyncPage/IdpGroupSyncForm.tsx | 8 ++--- .../IdpSyncPage/IdpRoleSyncForm.tsx | 8 ++--- .../OrganizationMembersPageView.tsx | 10 ++++-- site/src/pages/TaskPage/TaskAppIframe.tsx | 8 +++-- site/src/pages/TasksPage/TasksTable.tsx | 4 +-- .../TemplateInsightsPage.tsx | 2 +- .../pages/TemplatePage/TemplatePageHeader.tsx | 4 +-- .../TemplatePrebuildsPage.tsx | 4 +-- .../TemplatePermissionsPageView.tsx | 6 ++-- .../UserOrGroupAutocomplete.tsx | 4 +-- .../pages/TemplatesPage/TemplatesFilter.tsx | 4 +-- .../ExternalAuthPage/ExternalAuthPageView.tsx | 4 +-- .../SecurityPage/SingleSignOnSection.tsx | 2 +- .../UsersPage/UsersTable/UsersTableBody.tsx | 4 +-- .../pages/WorkspacePage/WorkspaceTopbar.tsx | 4 +-- .../pages/WorkspaceSettingsPage/Sidebar.tsx | 2 +- .../WorkspaceParametersPageExperimental.tsx | 4 +-- .../WorkspacesPage/BatchUpdateModalForm.tsx | 4 +-- .../pages/WorkspacesPage/WorkspacesTable.tsx | 4 +-- 63 files changed, 218 insertions(+), 183 deletions(-) create mode 100644 site/src/@types/lucide-react.d.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 762ed91595..9008f766c6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -62,5 +62,21 @@ "[markdown]": { "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" }, - "biome.lsp.bin": "site/node_modules/.bin/biome" + "biome.lsp.bin": "site/node_modules/.bin/biome", + + // Prefer type only imports. + "typescript.preferences.preferTypeOnlyAutoImports": true, + // Prefer aliased/non-relative imports (e.g. "#/...") over "../../...". + "typescript.preferences.importModuleSpecifier": "non-relative", + "javascript.preferences.importModuleSpecifier": "non-relative", + // We discourage people from various older libraries that + // are no longer recommended/being migrated from. + "typescript.preferences.autoImportSpecifierExcludeRegexes": [ + // discourage people from using MUI components + "^@mui(?:/.*)?$", + // discourage people from using Emotion CSS + "^@emotion(?:/.*)?$", + // we prefer people use `lodash/foo` over `lodash` + "^lodash$" + ] } diff --git a/biome.jsonc b/biome.jsonc index 4583f5465d..7a172ebaad 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -51,8 +51,8 @@ "message": "React 19 no longer requires forwardRef. Use ref as a prop instead.", "importNames": ["forwardRef"] }, - // "@mui/material/Alert": "Use components/Alert/Alert instead.", - // "@mui/material/AlertTitle": "Use components/Alert/Alert instead.", + "@mui/material/Alert": "Use components/Alert/Alert instead.", + "@mui/material/AlertTitle": "Use components/Alert/Alert instead.", // "@mui/material/Autocomplete": "Use shadcn/ui Combobox instead.", "@mui/material/Avatar": "Use components/Avatar/Avatar instead.", "@mui/material/Box": "Use a
with Tailwind classes instead.", @@ -61,7 +61,7 @@ // "@mui/material/CardActionArea": "Use shadcn/ui Card component instead.", // "@mui/material/CardContent": "Use shadcn/ui Card component instead.", // "@mui/material/Checkbox": "Use shadcn/ui Checkbox component instead.", - // "@mui/material/Chip": "Use components/Badge or Tailwind styles instead.", + "@mui/material/Chip": "Use components/Badge or Tailwind styles instead.", // "@mui/material/CircularProgress": "Use components/Spinner/Spinner instead.", // "@mui/material/Collapse": "Use shadcn/ui Collapsible instead.", // "@mui/material/CssBaseline": "Use Tailwind CSS base styles instead.", @@ -74,48 +74,48 @@ // "@mui/material/Drawer": "Use shadcn/ui Sheet component instead.", // "@mui/material/FormControl": "Use native form elements with Tailwind instead.", // "@mui/material/FormControlLabel": "Use shadcn/ui Label with form components instead.", - // "@mui/material/FormGroup": "Use a
with Tailwind classes instead.", + "@mui/material/FormGroup": "Use a
with Tailwind classes instead.", // "@mui/material/FormHelperText": "Use a

with Tailwind classes instead.", - // "@mui/material/FormLabel": "Use shadcn/ui Label component instead.", - // "@mui/material/Grid": "Use Tailwind grid utilities instead.", - // "@mui/material/IconButton": "Use components/Button/Button with variant='icon' instead.", + "@mui/material/FormLabel": "Use shadcn/ui Label component instead.", + "@mui/material/Grid": "Use Tailwind grid utilities instead.", + "@mui/material/IconButton": "Use components/Button/Button with variant='icon' instead.", // "@mui/material/InputAdornment": "Use Tailwind positioning in input wrapper instead.", // "@mui/material/InputBase": "Use shadcn/ui Input component instead.", - // "@mui/material/LinearProgress": "Use a progress bar with Tailwind instead.", + "@mui/material/LinearProgress": "Use a progress bar with Tailwind instead.", // "@mui/material/Link": "Use React Router Link or native tags instead.", // "@mui/material/List": "Use native

{!canViewMembers && (
- +

You do not have permission to view members other than yourself.

@@ -189,7 +193,7 @@ export const OrganizationMembersPageView: FC< variant="subtle" aria-label="Open menu" > -
diff --git a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx index 185c32e1dc..bf5def8e5d 100644 --- a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx @@ -1,4 +1,4 @@ -import { EllipsisVertical, UserPlusIcon } from "lucide-react"; +import { EllipsisVerticalIcon, UserPlusIcon } from "lucide-react"; import { type FC, useState } from "react"; import type { Group, @@ -315,7 +315,7 @@ export const TemplatePermissionsPageView: FC< variant="subtle" aria-label="Open menu" > -
)} open={open} diff --git a/site/src/pages/TemplatesPage/TemplatesFilter.tsx b/site/src/pages/TemplatesPage/TemplatesFilter.tsx index 31301acbff..0ba45245de 100644 --- a/site/src/pages/TemplatesPage/TemplatesFilter.tsx +++ b/site/src/pages/TemplatesPage/TemplatesFilter.tsx @@ -12,12 +12,12 @@ import { SelectFilter, type SelectFilterOption, } from "#/components/Filter/SelectFilter"; -import { useDashboard } from "#/modules/dashboard/useDashboard"; import { DEFAULT_USER_FILTER_WIDTH, type UserFilterMenu, UserMenu, -} from "../../components/Filter/UserFilter"; +} from "#/components/Filter/UserFilter"; +import { useDashboard } from "#/modules/dashboard/useDashboard"; interface TemplatesFilterProps { filter: UseFilterResult; diff --git a/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx b/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx index f0268b80cb..67191dd16f 100644 --- a/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx +++ b/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx @@ -1,5 +1,5 @@ import { useTheme } from "@emotion/react"; -import { EllipsisVertical, RefreshCcwIcon } from "lucide-react"; +import { EllipsisVerticalIcon, RefreshCcwIcon } from "lucide-react"; import { type FC, useCallback, useEffect, useState } from "react"; import { useQuery } from "react-query"; import { externalAuthProvider } from "#/api/queries/externalAuth"; @@ -178,7 +178,7 @@ const ExternalAuthRow: FC = ({ diff --git a/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx b/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx index 0a01148541..4226868ee9 100644 --- a/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx +++ b/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx @@ -1,6 +1,6 @@ import Link from "@mui/material/Link"; import TextField from "@mui/material/TextField"; -import { CircleCheck as CircleCheckIcon, KeyIcon } from "lucide-react"; +import { CircleCheckIcon, KeyIcon } from "lucide-react"; import { type FC, useState } from "react"; import { useMutation } from "react-query"; import { API } from "#/api/api"; diff --git a/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx b/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx index fea556928d..2f915c0e50 100644 --- a/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx +++ b/site/src/pages/UsersPage/UsersTable/UsersTableBody.tsx @@ -2,7 +2,7 @@ import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; import { BanIcon, - EllipsisVertical, + EllipsisVerticalIcon, KeyIcon, ShieldIcon, TrashIcon, @@ -207,7 +207,7 @@ export const UsersTableBody: FC = ({ variant="subtle" aria-label="Open menu" > -