Skip to content

feat(desktop): add project color mode functionality#1305

Closed
Ipriyankrajai wants to merge 3 commits into
superset-sh:mainfrom
Ipriyankrajai:feat/bg-color
Closed

feat(desktop): add project color mode functionality#1305
Ipriyankrajai wants to merge 3 commits into
superset-sh:mainfrom
Ipriyankrajai:feat/bg-color

Conversation

@Ipriyankrajai
Copy link
Copy Markdown
Contributor

@Ipriyankrajai Ipriyankrajai commented Feb 8, 2026

  • Introduced a new colorMode property for projects, allowing users to choose between "border" and "background" styles.
  • Updated project settings UI to include color mode selection.
  • Modified project-related components to support and display the selected color mode.
  • Added database migration to include the new color_mode column in the projects table.
  • Enhanced project thumbnail rendering based on the selected color mode.

Fixes #1185

Screen.Recording.2026-02-08.at.6.33.19.PM.mov

Summary by CodeRabbit

  • New Features

    • Added a "Color Style" setting (Border or Background) in Project Appearance; selection is saved and reflected across project thumbnails and sidebar.
    • Color mode options added to the project header color picker.
  • Refactor

    • Appearance layout reorganized to group color pills and the new Color Style control.
  • Removed

    • Removed the "Hide Image" control from the Appearance section.

- Introduced a new `colorMode` property for projects, allowing users to choose between "border" and "background" styles.
- Updated project settings UI to include color mode selection.
- Modified project-related components to support and display the selected color mode.
- Added database migration to include the new `color_mode` column in the projects table.
- Enhanced project thumbnail rendering based on the selected color mode.

This feature improves the customization options for project appearances in the application.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 8, 2026

📝 Walkthrough

Walkthrough

Adds a per-project colorMode ("border" | "background") everywhere: DB migration and schema/type exports, TRPC update/query surfaces, shared constants, and UI—settings, sidebar, header, and thumbnail—so project colors can be rendered as either a border or a filled background.

Changes

Cohort / File(s) Summary
Database Migration
packages/local-db/drizzle/0020_add_color_mode_to_projects.sql, packages/local-db/drizzle/meta/_journal.json, packages/local-db/drizzle/meta/0020_snapshot.json
Adds color_mode text column to projects and updates migration journal/snapshot.
Local DB Types & Schema
packages/local-db/src/schema/zod.ts, packages/local-db/src/schema/schema.ts
Introduces PROJECT_COLOR_MODES and ProjectColorMode type; wires colorMode column into projects table typing.
TRPC Routers & Queries
apps/desktop/src/lib/trpc/routers/projects/projects.ts, apps/desktop/src/lib/trpc/routers/workspaces/procedures/query.ts
Accepts/persists colorMode in project update mutation and exposes colorMode in workspace grouped query outputs.
Shared Constants
apps/desktop/src/shared/constants/project-colors.ts
Adds PROJECT_COLOR_MODE_DEFAULT and PROJECT_COLOR_MODE_LABELS for default and label mappings.
Project Settings UI
apps/desktop/src/renderer/routes/.../ProjectSettings/ProjectSettings.tsx
Reworks Appearance section: adds "Color Style" Select (border/background), removes standalone Hide Image control; mutates colorMode.
Sidebar & Header Prop Flow
apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/.../ProjectSection.tsx, .../ProjectHeader.tsx, WorkspaceSidebar.tsx
Adds colorMode prop to ProjectSection/ProjectHeader, threads colorMode from workspace groups into header and thumbnail UI, and adds color mode selection in header color submenu.
Project Thumbnail Rendering
apps/desktop/src/renderer/screens/main/components/.../ProjectThumbnail/ProjectThumbnail.tsx
Adds colorMode prop (defaults to PROJECT_COLOR_MODE_DEFAULT); implements border vs. background rendering paths, contrast utilities for text color when using background fills.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UI as Desktop UI
  participant TRPC as TRPC Router
  participant DB as Local DB

  User->>UI: change color style (border/background)
  UI->>TRPC: patch project { colorMode }
  TRPC->>DB: persist color_mode update
  DB-->>TRPC: ack
  TRPC-->>UI: updated project payload (includes colorMode)
  UI->>UI: re-render ProjectThumbnail / Header / Sidebar with new colorMode
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I nudged a schema, planted hue,
Border or background, pick what's new.
From DB to sidebar, colors dance,
Thumbnails dressed for every glance.
Hop—now projects wear a brighter view! 🎨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding project color mode functionality. It accurately reflects the primary feature introduced in the changeset.
Description check ✅ Passed The PR description adequately covers the main changes: colorMode property, settings UI updates, component modifications, database migration, and thumbnail rendering. It links to issue #1185, though some template sections are unused.
Linked Issues check ✅ Passed The PR fully implements the objectives from issue #1185: adds a user-selectable color mode property with 'border' and 'background' options, integrates it into project settings UI, and applies the mode throughout project-related components for visual distinction.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing the colorMode feature. Database migrations, schema updates, UI components, and constants are all necessary for the linked issue's requirements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectSection.tsx`:
- Line 29: Replace the inline union type for the colorMode prop with the shared
ProjectColorMode type: add an import for ProjectColorMode from
"@superset/local-db" at the top of ProjectSection.tsx and change the prop
declaration (currently colorMode: "border" | "background") to use
ProjectColorMode; update any related prop usages in ProjectSection /
ProjectHeader to ensure they accept the imported type.
🧹 Nitpick comments (10)
apps/desktop/src/lib/trpc/routers/workspaces/procedures/query.ts (2)

152-164: Use the ProjectColorMode type instead of inline literal union.

Line 159 duplicates the type definition as "border" | "background". Import and use ProjectColorMode from @superset/local-db to stay DRY and ensure the type updates automatically if new modes are added.

♻️ Proposed fix

Add to imports at line 1:

import { projects, workspaces, worktrees, type ProjectColorMode } from "@superset/local-db";

Then update line 159:

-					colorMode: "border" | "background";
+					colorMode: ProjectColorMode;

183-197: Hardcoded "border" fallback — use the named constant.

Line 189 uses a hardcoded "border" string as the fallback for colorMode. Import and use PROJECT_COLOR_MODE_DEFAULT from the shared constants to keep the default value centralized.

♻️ Proposed fix

Add to imports:

import { PROJECT_COLOR_MODE_DEFAULT } from "@shared/constants/project-colors";

Then:

-				colorMode: project.colorMode ?? "border",
+				colorMode: project.colorMode ?? PROJECT_COLOR_MODE_DEFAULT,

As per coding guidelines, "Extract hardcoded magic numbers, strings, and enums to named constants at module top instead of leaving them inline in logic."

apps/desktop/src/shared/constants/project-colors.ts (1)

19-25: Use PROJECT_COLOR_MODE_DEFAULT constant instead of hardcoding "border" fallbacks.

PROJECT_COLOR_MODE_DEFAULT is defined in this file, but the fallback in apps/desktop/src/lib/trpc/routers/workspaces/procedures/query.ts:189 hardcodes ?? "border" instead of using the constant. Additionally, similar hardcoded fallbacks appear in ProjectThumbnail.tsx:59 and ProjectSettings.tsx:276. Import and use PROJECT_COLOR_MODE_DEFAULT across these locations to maintain the default in one place and align with the guideline to extract hardcoded strings to named constants.

apps/desktop/src/lib/trpc/routers/projects/projects.ts (2)

782-786: Inconsistent indentation for patch fields.

Lines 782–785 are indented one level less than the sibling fields name and color (lines 774–781) inside z.object({...}). Same issue on lines 812–817 in the .set() call. Functionally harmless, but visually misleading.

🔧 Suggested fix
-				branchPrefixMode: z.enum(BRANCH_PREFIX_MODES).nullable().optional(),
-				branchPrefixCustom: z.string().nullable().optional(),
-				hideImage: z.boolean().optional(),
-				colorMode: z.enum(PROJECT_COLOR_MODES).nullable().optional(),
+					branchPrefixMode: z.enum(BRANCH_PREFIX_MODES).nullable().optional(),
+					branchPrefixCustom: z.string().nullable().optional(),
+					hideImage: z.boolean().optional(),
+					colorMode: z.enum(PROJECT_COLOR_MODES).nullable().optional(),

812-817: Same indentation inconsistency in the .set() call.

These spread entries are indented one level less than their siblings on lines 802–811.

🔧 Suggested fix
-				...(input.patch.hideImage !== undefined && {
-					hideImage: input.patch.hideImage,
-				}),
-				...(input.patch.colorMode !== undefined && {
-					colorMode: input.patch.colorMode,
-				}),
+					...(input.patch.hideImage !== undefined && {
+						hideImage: input.patch.hideImage,
+					}),
+					...(input.patch.colorMode !== undefined && {
+						colorMode: input.patch.colorMode,
+					}),
apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/components/ProjectSettings/ProjectSettings.tsx (1)

276-276: Use PROJECT_COLOR_MODE_DEFAULT instead of the hardcoded "border".

A PROJECT_COLOR_MODE_DEFAULT constant already exists in shared/constants/project-colors.ts. Using the magic string here diverges from that single source of truth.

🔧 Suggested fix

Update the import:

 import {
 	PROJECT_COLOR_DEFAULT,
+	PROJECT_COLOR_MODE_DEFAULT,
 	PROJECT_COLOR_MODE_LABELS,
 	PROJECT_COLORS,
 } from "shared/constants/project-colors";

Then:

-								value={project.colorMode ?? "border"}
+								value={project.colorMode ?? PROJECT_COLOR_MODE_DEFAULT}

As per coding guidelines, "Extract hardcoded magic numbers, strings, and enums to named constants at module top instead of leaving them inline in logic".

apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectThumbnail/ProjectThumbnail.tsx (4)

59-59: Use PROJECT_COLOR_MODE_DEFAULT for the default value.

PROJECT_COLOR_MODE_DEFAULT is already imported-adjacent (the file imports from shared/constants/project-colors). Hardcoding "border" here duplicates the default.

🔧 Suggested fix

Update the import:

-import { PROJECT_COLOR_DEFAULT } from "shared/constants/project-colors";
+import { PROJECT_COLOR_DEFAULT, PROJECT_COLOR_MODE_DEFAULT } from "shared/constants/project-colors";
-	colorMode = "border",
+	colorMode = PROJECT_COLOR_MODE_DEFAULT,

As per coding guidelines, "Extract hardcoded magic numbers, strings, and enums to named constants at module top instead of leaving them inline in logic".


38-53: Consider extracting color utility functions to a shared module.

getRelativeLuminance and getContrastTextColor are general-purpose color utilities. If contrast-based text coloring is needed elsewhere (e.g., other badge or label components), these would benefit from living in a shared utility file. Fine to keep co-located for now if this is the only consumer.

Also, the luminance threshold 0.4 (line 50) and alpha values (0.85, 0.95) are magic numbers — consider naming them for clarity.


86-91: getBorderStyle is called once — a plain expression would be simpler.

The function is immediately invoked once and assigned. A conditional expression or simple ternary would reduce indirection.

🔧 Suggested simplification
-	const getBorderStyle = () => {
-		if (isBackground || !hasCustomColor) return undefined;
-		return { borderColor: hexToRgba(projectColor, 0.6) };
-	};
-
-	const borderStyle = getBorderStyle();
+	const borderStyle =
+		!isBackground && hasCustomColor
+			? { borderColor: hexToRgba(projectColor, 0.6) }
+			: undefined;

115-132: Same note: getFallbackStyle is invoked once — inline or ternary would be simpler.

Similar to getBorderStyle, this function is created and immediately called. Consider inlining for readability.

@Ipriyankrajai
Copy link
Copy Markdown
Contributor Author

Closing this as we have remove image

@Ipriyankrajai Ipriyankrajai deleted the feat/bg-color branch February 8, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] Project Background Color (not just Border)

1 participant