From 2fd815c01636847e9c49275fe1ccc8616d13512e Mon Sep 17 00:00:00 2001 From: Seth-Wadsworth Date: Wed, 4 Mar 2026 17:10:47 -0700 Subject: [PATCH 1/2] Update spreadsheet column behavior --- .../spreadsheet/issue-column.tsx | 27 +++++++++++++++++-- .../spreadsheet/spreadsheet-header-column.tsx | 18 +++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx b/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx index c639103967f..bcdd8a94bda 100644 --- a/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx @@ -13,6 +13,23 @@ import { SPREADSHEET_COLUMNS } from "@/plane-web/components/issues/issue-layouts import { shouldRenderColumn } from "@/plane-web/helpers/issue-filter.helper"; import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; +const COLUMN_WIDTHS: Partial> = { + state: "80px", + priority: "80px", + assignee: "120px", + estimate: "80px", + labels: "80px", + start_date: "120px", + due_date: "120px", + created_on: "120px", + updated_on: "120px", + link: "80px", + attachment_count: "80px", + sub_issue_count: "80px", + cycle: "120px", + modules: "120px", +}; + type Props = { displayProperties: IIssueDisplayProperties; issueDetail: TIssue; @@ -45,12 +62,18 @@ export const IssueColumn = observer(function IssueColumn(props: Props) { > { + void handleUpdateIssue(issue, data); + }} disabled={disableUserActions} onClose={() => tableCellRef?.current?.focus()} /> diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx b/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx index be12503cfc6..6caafdb4bba 100644 --- a/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx @@ -13,6 +13,23 @@ import { shouldRenderColumn } from "@/plane-web/helpers/issue-filter.helper"; import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; import { HeaderColumn } from "./columns/header-column"; +const COLUMN_WIDTHS: Partial> = { + state: "80px", + priority: "80px", + assignee: "120px", + estimate: "80px", + labels: "80px", + start_date: "120px", + due_date: "120px", + created_on: "120px", + updated_on: "120px", + link: "80px", + attachment_count: "80px", + sub_issue_count: "80px", + cycle: "120px", + modules: "120px", +}; + interface Props { displayProperties: IIssueDisplayProperties; property: keyof IIssueDisplayProperties; @@ -37,6 +54,7 @@ export const SpreadsheetHeaderColumn = observer(function SpreadsheetHeaderColumn > From 992c0639879ddf8d918f2ea116283b0cd36bfb57 Mon Sep 17 00:00:00 2001 From: Seth-Wadsworth Date: Sat, 7 Mar 2026 09:15:56 -0700 Subject: [PATCH 2/2] Extract column width logic and add tests --- .../spreadsheet/issue-column.logic.ts | 31 +++++++++++++ .../spreadsheet/issue-column.tsx | 28 ++--------- .../spreadsheet-header-column.logic.ts | 22 +++++++++ .../spreadsheet/spreadsheet-header-column.tsx | 20 +------- .../codemods/tests/issue-column.logic.test.ts | 46 +++++++++++++++++++ .../spreadsheet-header-column.logic.test.ts | 22 +++++++++ 6 files changed, 127 insertions(+), 42 deletions(-) create mode 100644 apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.logic.ts create mode 100644 apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.logic.ts create mode 100644 packages/codemods/tests/issue-column.logic.test.ts create mode 100644 packages/codemods/tests/spreadsheet-header-column.logic.test.ts diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.logic.ts b/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.logic.ts new file mode 100644 index 00000000000..e85e28b948b --- /dev/null +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.logic.ts @@ -0,0 +1,31 @@ +import type { IIssueDisplayProperties, TIssue } from "@plane/types"; + +export const COLUMN_WIDTHS: Partial> = { + state: "80px", + priority: "80px", + assignee: "120px", + estimate: "80px", + labels: "80px", + start_date: "120px", + due_date: "120px", + created_on: "120px", + updated_on: "120px", + link: "80px", + attachment_count: "80px", + sub_issue_count: "80px", + cycle: "120px", + modules: "120px", +}; + +export function getColumnWidth(property: keyof IIssueDisplayProperties): string { + return COLUMN_WIDTHS[property] ?? "auto"; +} + +export async function handleUpdateIssueLogic( + updateIssue: ((projectId: string | null, issueId: string, data: Partial) => Promise) | undefined, + issue: TIssue, + data: Partial +): Promise { + if (!updateIssue) return; + await updateIssue(issue.project_id, issue.id, data); +} diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx b/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx index bcdd8a94bda..57211ca7555 100644 --- a/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.tsx @@ -12,23 +12,7 @@ import type { IIssueDisplayProperties, TIssue } from "@plane/types"; import { SPREADSHEET_COLUMNS } from "@/plane-web/components/issues/issue-layouts/utils"; import { shouldRenderColumn } from "@/plane-web/helpers/issue-filter.helper"; import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; - -const COLUMN_WIDTHS: Partial> = { - state: "80px", - priority: "80px", - assignee: "120px", - estimate: "80px", - labels: "80px", - start_date: "120px", - due_date: "120px", - created_on: "120px", - updated_on: "120px", - link: "80px", - attachment_count: "80px", - sub_issue_count: "80px", - cycle: "120px", - modules: "120px", -}; +import { getColumnWidth, handleUpdateIssueLogic } from "./issue-column.logic"; type Props = { displayProperties: IIssueDisplayProperties; @@ -50,10 +34,6 @@ export const IssueColumn = observer(function IssueColumn(props: Props) { if (!Column) return null; - const handleUpdateIssue = async (issue: TIssue, data: Partial) => { - if (updateIssue) await updateIssue(issue.project_id, issue.id, data); - }; - return ( { - void handleUpdateIssue(issue, data); + void handleUpdateIssueLogic(updateIssue, issue, data); }} disabled={disableUserActions} onClose={() => tableCellRef?.current?.focus()} diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.logic.ts b/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.logic.ts new file mode 100644 index 00000000000..ea4c899c0f5 --- /dev/null +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.logic.ts @@ -0,0 +1,22 @@ +import type { IIssueDisplayProperties } from "@plane/types"; + +export const HEADER_COLUMN_WIDTHS: Partial> = { + state: "80px", + priority: "80px", + assignee: "120px", + estimate: "80px", + labels: "80px", + start_date: "120px", + due_date: "120px", + created_on: "120px", + updated_on: "120px", + link: "80px", + attachment_count: "80px", + sub_issue_count: "80px", + cycle: "120px", + modules: "120px", +}; + +export function getHeaderColumnWidth(property: keyof IIssueDisplayProperties): string { + return HEADER_COLUMN_WIDTHS[property] ?? "auto"; +} diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx b/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx index 6caafdb4bba..21ca3f99a50 100644 --- a/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.tsx @@ -12,23 +12,7 @@ import type { IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane import { shouldRenderColumn } from "@/plane-web/helpers/issue-filter.helper"; import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; import { HeaderColumn } from "./columns/header-column"; - -const COLUMN_WIDTHS: Partial> = { - state: "80px", - priority: "80px", - assignee: "120px", - estimate: "80px", - labels: "80px", - start_date: "120px", - due_date: "120px", - created_on: "120px", - updated_on: "120px", - link: "80px", - attachment_count: "80px", - sub_issue_count: "80px", - cycle: "120px", - modules: "120px", -}; +import { getHeaderColumnWidth } from "./spreadsheet-header-column.logic"; interface Props { displayProperties: IIssueDisplayProperties; @@ -54,7 +38,7 @@ export const SpreadsheetHeaderColumn = observer(function SpreadsheetHeaderColumn > diff --git a/packages/codemods/tests/issue-column.logic.test.ts b/packages/codemods/tests/issue-column.logic.test.ts new file mode 100644 index 00000000000..f61a7f9b582 --- /dev/null +++ b/packages/codemods/tests/issue-column.logic.test.ts @@ -0,0 +1,46 @@ +import { describe, it, expect, vi } from "vitest"; +import { + getColumnWidth, + handleUpdateIssueLogic, + COLUMN_WIDTHS, +} from "../../../apps/web/core/components/issues/issue-layouts/spreadsheet/issue-column.logic"; +import type { TIssue } from "@plane/types"; + +describe("issue-column.logic", () => { + describe("getColumnWidth", () => { + it("returns the correct width for known properties", () => { + for (const key of Object.keys(COLUMN_WIDTHS) as Array< + keyof typeof COLUMN_WIDTHS + >) { + expect(getColumnWidth(key)).toBe(COLUMN_WIDTHS[key]); + } + }); + + it("returns auto for unknown properties", () => { + // @ts-expect-error testing fallback + expect(getColumnWidth("unknown")).toBe("auto"); + }); + }); + + describe("handleUpdateIssueLogic", () => { + const issue = { + id: "123", + project_id: "p1", + } as unknown as TIssue; + + it("does nothing when updateIssue is undefined", async () => { + const result = await handleUpdateIssueLogic(undefined, issue, { + name: "x", + }); + expect(result).toBeUndefined(); + }); + + it("calls updateIssue with correct arguments", async () => { + const mock = vi.fn().mockResolvedValue(undefined); + + await handleUpdateIssueLogic(mock, issue, { name: "New Name" }); + + expect(mock).toHaveBeenCalledWith("p1", "123", { name: "New Name" }); + }); + }); +}); diff --git a/packages/codemods/tests/spreadsheet-header-column.logic.test.ts b/packages/codemods/tests/spreadsheet-header-column.logic.test.ts new file mode 100644 index 00000000000..7f4d1b28026 --- /dev/null +++ b/packages/codemods/tests/spreadsheet-header-column.logic.test.ts @@ -0,0 +1,22 @@ +import { describe, it, expect } from "vitest"; +import { + getHeaderColumnWidth, + HEADER_COLUMN_WIDTHS, +} from "../../../apps/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-header-column.logic"; + +describe("spreadsheet-header-column.logic", () => { + describe("getHeaderColumnWidth", () => { + it("returns correct width for known properties", () => { + for (const key of Object.keys(HEADER_COLUMN_WIDTHS) as Array< + keyof typeof HEADER_COLUMN_WIDTHS + >) { + expect(getHeaderColumnWidth(key)).toBe(HEADER_COLUMN_WIDTHS[key]); + } + }); + + it("returns auto for unknown properties", () => { + // @ts-expect-error testing fallback + expect(getHeaderColumnWidth("unknown")).toBe("auto"); + }); + }); +});