From 8324fe5eb46c055cef5a44c6cd124d44f3ff4e99 Mon Sep 17 00:00:00 2001 From: minnakt Date: Fri, 15 Mar 2024 14:09:55 -0400 Subject: [PATCH 1/6] DEVPROD-1976: Migrate execution tasks table --- .../integration/task/execution_task_table.ts | 9 +- cypress/integration/task/task_actions.ts | 2 +- src/analytics/task/useTaskAnalytics.ts | 6 +- src/components/TasksTable/Columns.tsx | 155 ++++++++++++++++++ .../TasksTable/TasksTable.stories.tsx | 30 +++- src/components/TasksTable/index.tsx | 14 +- src/components/TasksTable/types.ts | 16 ++ .../task/taskTabs/ExecutionTasksTable.tsx | 115 ++++++++----- 8 files changed, 285 insertions(+), 62 deletions(-) create mode 100644 src/components/TasksTable/Columns.tsx create mode 100644 src/components/TasksTable/types.ts diff --git a/cypress/integration/task/execution_task_table.ts b/cypress/integration/task/execution_task_table.ts index 3ce45fd34b..9c890dc756 100644 --- a/cypress/integration/task/execution_task_table.ts +++ b/cypress/integration/task/execution_task_table.ts @@ -7,14 +7,17 @@ describe("Execution task table", () => { }); it("Should have a default sort order applied", () => { - cy.location("search").should("contain", "sorts=STATUS%3AASC"); + cy.location("search").should("contain", "sortBy=STATUS"); + cy.location("search").should("contain", "sortDir=ASC"); }); it("Updates the url when column headers are clicked", () => { cy.dataCy("tasks-table").find("th").contains("Name").click(); - cy.location("search").should("contain", "NAME%3AASC"); + cy.location("search").should("contain", "sortBy=NAME"); + cy.location("search").should("contain", "sortDir=ASC"); cy.dataCy("tasks-table").find("th").contains("Name").click(); - cy.location("search").should("contain", "NAME%3ADESC"); + cy.location("search").should("contain", "sortBy=NAME"); + cy.location("search").should("contain", "sortDir=DESC"); }); }); diff --git a/cypress/integration/task/task_actions.ts b/cypress/integration/task/task_actions.ts index 9f89a6f3d2..c9cc3fbf37 100644 --- a/cypress/integration/task/task_actions.ts +++ b/cypress/integration/task/task_actions.ts @@ -73,6 +73,6 @@ const tasks = { 1: "/task/evergreen_ubuntu1604_test_model_patch_5e823e1f28baeaa22ae00823d83e03082cd148ab_5e4ff3abe3c3317e352062e4_20_02_21_15_13_48", 2: "/task/evergreen_lint_lint_service_patch_5e823e1f28baeaa22ae00823d83e03082cd148ab_5e4ff3abe3c3317e352062e4_20_02_21_15_13_48", 3: "/task/evergreen_ubuntu1604_dist_patch_33016573166a36bd5f46b4111151899d5c4e95b1_5ecedafb562343215a7ff297_20_05_27_21_39_46", - 4: "/task/mci_ubuntu1604_display_asdf_patch_a1d2c8f70bf5c543de8b9641ac1ec08def1ddb26_5f74d99ab2373627c047c5e5_20_09_30_19_16_47/execution-tasks?execution=0&sorts=STATUS%3AASC", + 4: "/task/mci_ubuntu1604_display_asdf_patch_a1d2c8f70bf5c543de8b9641ac1ec08def1ddb26_5f74d99ab2373627c047c5e5_20_09_30_19_16_47/execution-tasks?execution=0", 5: "/task/evergreen_test_model_patch_5e823e1f28baeaa22ae00823d83e03082cd148ab_5e4ff3abe3c3317e352062e4_20_02_21_15_13_48", }; diff --git a/src/analytics/task/useTaskAnalytics.ts b/src/analytics/task/useTaskAnalytics.ts index a68225c558..4d609ac940 100644 --- a/src/analytics/task/useTaskAnalytics.ts +++ b/src/analytics/task/useTaskAnalytics.ts @@ -22,11 +22,7 @@ type Action = } | { name: "Sort Execution Tasks Table"; - sortBy: - | TaskSortCategory.Name - | TaskSortCategory.Status - | TaskSortCategory.BaseStatus - | TaskSortCategory.Variant; + sortBy: TaskSortCategory | TaskSortCategory[]; } | { name: "Restart" } | { name: "Schedule" } diff --git a/src/components/TasksTable/Columns.tsx b/src/components/TasksTable/Columns.tsx new file mode 100644 index 0000000000..326b95e3f6 --- /dev/null +++ b/src/components/TasksTable/Columns.tsx @@ -0,0 +1,155 @@ +import { LGColumnDef } from "@leafygreen-ui/table"; +import Tooltip from "@leafygreen-ui/tooltip"; +import pluralize from "pluralize"; +import { ConditionalWrapper } from "components/ConditionalWrapper"; +import { StyledRouterLink } from "components/styles"; +import TaskStatusBadge from "components/TaskStatusBadge"; +import { TreeDataEntry } from "components/TreeSelect"; +import { getVariantHistoryRoute } from "constants/routes"; +import { mergeTaskVariant } from "constants/task"; +import { zIndex } from "constants/tokens"; +import { TaskSortCategory } from "gql/generated/types"; +import { TaskStatus } from "types/task"; +import { TaskLink } from "./TaskLink"; +import { TaskTableInfo } from "./types"; + +export const getColumnsTemplate = ({ + baseStatusOptions = [], + isPatch = false, + onClickTaskLink = () => {}, + showTaskExecutionLabel = false, + statusOptions = [], +}: { + baseStatusOptions?: TreeDataEntry[]; + isPatch?: boolean; + onClickTaskLink?: (taskId: string) => void; + showTaskExecutionLabel?: boolean; + statusOptions?: TreeDataEntry[]; +}): LGColumnDef[] => [ + { + header: "Name", + accessorKey: "displayName", + id: TaskSortCategory.Name, + cell: ({ + getValue, + row: { + original: { execution, id }, + }, + }): JSX.Element => ( + + ), + meta: { + search: { + "data-cy": "task-name-filter-popover", + placeholder: "Task name regex", + }, + }, + enableSorting: true, + size: 300, + }, + { + accessorKey: "status", + id: TaskSortCategory.Status, + header: "Task Status", + cell: ({ + getValue, + row: { + original: { dependsOn, execution, id }, + }, + }) => { + const status = getValue() as string; + + return dependsOn?.length && getValue() === TaskStatus.Blocked ? ( + + + + } + > + Depends on {pluralize("task", dependsOn.length)}:{" "} + {dependsOn.map(({ name }) => `“${name}”`).join(", ")} + + ) : ( + getValue() && ( + + ) + ); + }, + meta: { + treeSelect: { + "data-cy": "status-filter-popover", + options: statusOptions, + }, + }, + enableSorting: true, + size: 80, + }, + { + id: TaskSortCategory.BaseStatus, + accessorKey: "baseTask.status", + header: `${isPatch ? "Base" : "Previous"} Status`, + cell: ({ + getValue, + row: { + original: { baseTask }, + }, + }) => + getValue() && ( + + ), + meta: { + treeSelect: { + "data-cy": "base-status-filter-popover", + options: baseStatusOptions, + }, + }, + enableSorting: true, + size: 80, + }, + { + accessorKey: "buildVariantDisplayName", + id: TaskSortCategory.Variant, + header: "Variant", + cell: ({ + getValue, + row: { + original: { buildVariant, projectIdentifier }, + }, + }) => ( + ( + + {children} + + )} + > + {getValue() as string} + + ), + meta: { + search: { + "data-cy": "variant-filter-popover", + placeholder: "Variant name regex", + }, + }, + enableSorting: true, + size: 250, + }, +]; diff --git a/src/components/TasksTable/TasksTable.stories.tsx b/src/components/TasksTable/TasksTable.stories.tsx index b430ecc62d..adfba27de1 100644 --- a/src/components/TasksTable/TasksTable.stories.tsx +++ b/src/components/TasksTable/TasksTable.stories.tsx @@ -1,5 +1,4 @@ import { CustomStoryObj, CustomMeta } from "test_utils/types"; - import TasksTable from "."; export default { @@ -21,6 +20,8 @@ export const VersionTasksTable: CustomStoryObj = { const tasks = [ { id: "some_id", + projectIdentifier: "evg", + execution: 0, aborted: false, displayName: "Some Fancy ID", version: "123", @@ -29,11 +30,17 @@ const tasks = [ buildVariantDisplayName: "Ubuntu 16.04", blocked: false, baseTask: { + id: "some_base_task", + execution: 0, status: "unscheduled", }, + executionTasksFull: [], + dependsOn: [], }, { id: "some_id_2", + projectIdentifier: "evg", + execution: 0, aborted: false, displayName: "Some other Fancy ID", version: "123", @@ -42,11 +49,17 @@ const tasks = [ buildVariantDisplayName: "Ubuntu 16.04", blocked: false, baseTask: { + id: "some_base_task_2", + execution: 0, status: "failed", }, + executionTasksFull: [], + dependsOn: [], }, { id: "some_id_3", + projectIdentifier: "evg", + execution: 0, aborted: false, displayName: "Some different Fancy ID", version: "234", @@ -55,8 +68,12 @@ const tasks = [ buildVariantDisplayName: "Windows 97", blocked: false, baseTask: { + id: "some_base_task_3", + execution: 0, status: "failed", }, + executionTasksFull: [], + dependsOn: [], }, ]; @@ -64,6 +81,8 @@ const nestedTasks = [ ...tasks, { id: "some_id_4", + projectIdentifier: "evg", + execution: 0, aborted: false, displayName: "Some Fancy Display Task", version: "234", @@ -72,6 +91,8 @@ const nestedTasks = [ buildVariantDisplayName: "Windows 97", blocked: false, baseTask: { + id: "some_base_task_4", + execution: 0, status: "failed", }, executionTasksFull: [ @@ -85,11 +106,15 @@ const nestedTasks = [ buildVariantDisplayName: "Windows 97", blocked: false, baseTask: { + id: "some_base_task_5", + execution: 0, status: "aborted", }, }, { id: "some_id_6", + projectIdentifier: "evg", + execution: 0, aborted: false, displayName: "Another execution task", version: "234", @@ -98,9 +123,12 @@ const nestedTasks = [ buildVariantDisplayName: "Windows 97", blocked: false, baseTask: { + id: "some_base_task_6", + execution: 0, status: "system-failed", }, }, ], + dependsOn: [], }, ]; diff --git a/src/components/TasksTable/index.tsx b/src/components/TasksTable/index.tsx index a171477321..6015a0c77f 100644 --- a/src/components/TasksTable/index.tsx +++ b/src/components/TasksTable/index.tsx @@ -24,19 +24,7 @@ import { import { TableOnChange, TaskStatus } from "types/task"; import { sortTasks } from "utils/statuses"; import { TaskLink } from "./TaskLink"; - -type TaskTableInfo = { - baseTask?: { - status: string; - }; - buildVariantDisplayName?: string; - dependsOn?: Array<{ name: string }>; - displayName: string; - executionTasksFull?: TaskTableInfo[]; - id: string; - projectIdentifier?: string; - status: string; -}; +import { TaskTableInfo } from "./types"; interface TasksTableProps { baseStatusSelectorProps?: TreeSelectProps; diff --git a/src/components/TasksTable/types.ts b/src/components/TasksTable/types.ts new file mode 100644 index 0000000000..454159b98f --- /dev/null +++ b/src/components/TasksTable/types.ts @@ -0,0 +1,16 @@ +export type TaskTableInfo = { + baseTask?: { + id: string; + execution: number; + status: string; + }; + buildVariant?: string; + buildVariantDisplayName?: string; + dependsOn?: Array<{ name: string }>; + displayName: string; + execution: number; + executionTasksFull?: TaskTableInfo[]; + id: string; + projectIdentifier?: string; + status: string; +}; diff --git a/src/pages/task/taskTabs/ExecutionTasksTable.tsx b/src/pages/task/taskTabs/ExecutionTasksTable.tsx index 570e6d2307..369390b9a0 100644 --- a/src/pages/task/taskTabs/ExecutionTasksTable.tsx +++ b/src/pages/task/taskTabs/ExecutionTasksTable.tsx @@ -1,13 +1,22 @@ -import { useEffect } from "react"; -import { useLocation } from "react-router-dom"; +import { useEffect, useMemo, useRef } from "react"; +import { LeafyGreenTable, useLeafyGreenTable } from "@leafygreen-ui/table"; +import { SortingState, Sorting } from "@tanstack/react-table"; import { useTaskAnalytics } from "analytics"; -import TasksTable from "components/TasksTable"; -import { SortOrder, TaskQuery, Task } from "gql/generated/types"; +import { BaseTable } from "components/Table/BaseTable"; +import { TablePlaceholder } from "components/Table/TablePlaceholder"; +import { TableQueryParams, onChangeHandler } from "components/Table/utils"; +import { getColumnsTemplate } from "components/TasksTable/Columns"; +import { TaskTableInfo } from "components/TasksTable/types"; +import { + TaskQuery, + TaskSortCategory, + SortDirection, +} from "gql/generated/types"; +import { useTableSort } from "hooks"; +import { useQueryParam } from "hooks/useQueryParam"; import { useUpdateURLQueryParams } from "hooks/useUpdateURLQueryParams"; -import { RequiredQueryParams, TableOnChange } from "types/task"; -import { queryString } from "utils"; -const { parseQueryString, parseSortString, toSortString } = queryString; +const { getDefaultOptions: getDefaultSorting } = Sorting; interface Props { execution: number; @@ -15,55 +24,83 @@ interface Props { isPatch: boolean; } -const useSorts = (): SortOrder[] => { - const location = useLocation(); - - const { sorts } = parseQueryString(location.search); - return parseSortString(sorts); -}; - export const ExecutionTasksTable: React.FC = ({ execution, executionTasksFull, isPatch, }) => { - const taskAnalytics = useTaskAnalytics(); + const { sendEvent } = useTaskAnalytics(); const updateQueryParams = useUpdateURLQueryParams(); - const sorts = useSorts(); + + const [sortBy] = useQueryParam(TableQueryParams.SortBy, ""); + const [sortDir] = useQueryParam(TableQueryParams.SortDir, ""); + + // Apply default sort if none is defined. useEffect(() => { - if (sorts.length === 0) { + if (!sortBy && !sortDir) { updateQueryParams({ - sorts: "STATUS:ASC", + sortBy: TaskSortCategory.Status, + sortDir: SortDirection.Asc, }); } }, []); // eslint-disable-line react-hooks/exhaustive-deps - const tableChangeHandler: TableOnChange = (...[, , sorter]) => { - updateQueryParams({ - sorts: toSortString(sorter), - [RequiredQueryParams.Execution]: `${execution}`, - }); - }; const uniqueExecutions = new Set([ execution, ...executionTasksFull.map((t) => t.execution), ]); + + const columns = useMemo( + () => + getColumnsTemplate({ + isPatch, + onClickTaskLink: () => sendEvent({ name: "Click Execution Task Link" }), + showTaskExecutionLabel: uniqueExecutions.size > 1, + }), + [isPatch, sendEvent, uniqueExecutions.size], + ); + + const tableSortHandler = useTableSort({ + sendAnalyticsEvents: (sorter: SortingState) => + sendEvent({ + name: "Sort Execution Tasks Table", + sortBy: sorter.map(({ id }) => id as TaskSortCategory), + }), + }); + + const tableContainerRef = useRef(null); + const table: LeafyGreenTable = + useLeafyGreenTable({ + columns, + containerRef: tableContainerRef, + data: executionTasksFull ?? [], + defaultColumn: { + enableColumnFilter: false, + }, + initialState: { + sorting: + sortBy && sortDir + ? [ + { + id: sortBy as TaskSortCategory, + desc: sortDir === SortDirection.Desc, + }, + ] + : [{ id: TaskSortCategory.Status, desc: false }], + }, + onSortingChange: onChangeHandler( + (s) => getDefaultSorting(table).onSortingChange(s), + tableSortHandler, + ), + }); + return ( - 1} - sorts={sorts} - tableChangeHandler={tableChangeHandler} - tasks={executionTasksFull} - onClickTaskLink={() => - taskAnalytics.sendEvent({ name: "Click Execution Task Link" }) - } - onColumnHeaderClick={(sortField) => - taskAnalytics.sendEvent({ - name: "Sort Execution Tasks Table", - sortBy: sortField, - }) - } + } + table={table} + shouldAlternateRowColor /> ); }; From ad6bab16509ec529fcdd412a8e8ad7e84fbbefab Mon Sep 17 00:00:00 2001 From: minnakt Date: Fri, 15 Mar 2024 14:18:52 -0400 Subject: [PATCH 2/6] Update snapshots --- .../TasksTable.stories.storyshot | 272 ++-- .../ExecutionTasksTable.stories.storyshot | 1396 ++++++++--------- 2 files changed, 819 insertions(+), 849 deletions(-) diff --git a/src/components/TasksTable/__snapshots__/TasksTable.stories.storyshot b/src/components/TasksTable/__snapshots__/TasksTable.stories.storyshot index 69a81de440..b5a8e838d0 100644 --- a/src/components/TasksTable/__snapshots__/TasksTable.stories.storyshot +++ b/src/components/TasksTable/__snapshots__/TasksTable.stories.storyshot @@ -280,11 +280,20 @@ exports[`Snapshot Tests TasksTable.stories BaseTaskTable 1`] = ` data-row-key="some_id" > + + + + + + + + + + + + + + + + - - + + + + `; @@ -410,394 +348,332 @@ exports[`Snapshot Tests ExecutionTasksTable.stories MultipleExecutions 1`] = ` exports[`Snapshot Tests ExecutionTasksTable.stories SingleExecution 1`] = `
-
-
-
-
+
- - - - - - - - - - - - - + + + + + + + + - - - - - + + + + + - - - -
-
- - Name - - - - - - - - - - - -
-
-
- - Task Status - - - - - - - - - - - -
-
-
- - Base Status - - - - - - - - - - - -
-
-
- - Variant - - - - - - - - - - - -
-
+
+ Task Status + +
+
+
+ Base Status +
+
+ Variant +
- -
- Succeeded -
-
-
- - - - Windows 97 - - -
+ +
+ +
+ + + + + + + + + + + + + -
-
+ + + +
`; From 132dc757135e3d55eb378948cb12c1c85bbb8754 Mon Sep 17 00:00:00 2001 From: minnakt Date: Fri, 15 Mar 2024 14:47:42 -0400 Subject: [PATCH 3/6] Fix tests --- cypress/integration/task/execution_task_table.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cypress/integration/task/execution_task_table.ts b/cypress/integration/task/execution_task_table.ts index 9c890dc756..14613cc2dc 100644 --- a/cypress/integration/task/execution_task_table.ts +++ b/cypress/integration/task/execution_task_table.ts @@ -12,11 +12,12 @@ describe("Execution task table", () => { }); it("Updates the url when column headers are clicked", () => { - cy.dataCy("tasks-table").find("th").contains("Name").click(); + const nameSortControl = "button[aria-label='Sort by Name']"; + cy.get(nameSortControl).click(); cy.location("search").should("contain", "sortBy=NAME"); cy.location("search").should("contain", "sortDir=ASC"); - cy.dataCy("tasks-table").find("th").contains("Name").click(); + cy.get(nameSortControl).click(); cy.location("search").should("contain", "sortBy=NAME"); cy.location("search").should("contain", "sortDir=DESC"); }); From 53c1a7a999219e82cb1133d60c27e081420c6a58 Mon Sep 17 00:00:00 2001 From: minnakt Date: Mon, 18 Mar 2024 14:05:59 -0400 Subject: [PATCH 4/6] add multisort --- .../integration/task/execution_task_table.ts | 6 +- src/gql/generated/types.ts | 2 + .../task/taskTabs/ExecutionTasksTable.tsx | 59 ++++++++++++++----- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/cypress/integration/task/execution_task_table.ts b/cypress/integration/task/execution_task_table.ts index 14613cc2dc..ee4f253668 100644 --- a/cypress/integration/task/execution_task_table.ts +++ b/cypress/integration/task/execution_task_table.ts @@ -14,11 +14,9 @@ describe("Execution task table", () => { it("Updates the url when column headers are clicked", () => { const nameSortControl = "button[aria-label='Sort by Name']"; cy.get(nameSortControl).click(); - cy.location("search").should("contain", "sortBy=NAME"); - cy.location("search").should("contain", "sortDir=ASC"); + cy.location("search").should("contain", "STATUS%3AASC%3BNAME%3AASC"); cy.get(nameSortControl).click(); - cy.location("search").should("contain", "sortBy=NAME"); - cy.location("search").should("contain", "sortDir=DESC"); + cy.location("search").should("contain", "STATUS%3AASC%3BNAME%3ADESC"); }); }); diff --git a/src/gql/generated/types.ts b/src/gql/generated/types.ts index 769810448e..d6bdf9964c 100644 --- a/src/gql/generated/types.ts +++ b/src/gql/generated/types.ts @@ -699,6 +699,7 @@ export type Host = { instanceType?: Maybe; lastCommunicationTime?: Maybe; noExpiration: Scalars["Boolean"]["output"]; + persistentDnsName: Scalars["String"]["output"]; provider: Scalars["String"]["output"]; runningTask?: Maybe; startedBy: Scalars["String"]["output"]; @@ -2532,6 +2533,7 @@ export type Task = { startTime?: Maybe; status: Scalars["String"]["output"]; stepbackInfo?: Maybe; + tags: Array; /** @deprecated Use files instead */ taskFiles: TaskFiles; taskGroup?: Maybe; diff --git a/src/pages/task/taskTabs/ExecutionTasksTable.tsx b/src/pages/task/taskTabs/ExecutionTasksTable.tsx index 369390b9a0..3829c62c7f 100644 --- a/src/pages/task/taskTabs/ExecutionTasksTable.tsx +++ b/src/pages/task/taskTabs/ExecutionTasksTable.tsx @@ -13,8 +13,9 @@ import { SortDirection, } from "gql/generated/types"; import { useTableSort } from "hooks"; -import { useQueryParam } from "hooks/useQueryParam"; +import { useQueryParams } from "hooks/useQueryParam"; import { useUpdateURLQueryParams } from "hooks/useUpdateURLQueryParams"; +import { parseSortString } from "utils/queryString"; const { getDefaultOptions: getDefaultSorting } = Sorting; @@ -32,12 +33,14 @@ export const ExecutionTasksTable: React.FC = ({ const { sendEvent } = useTaskAnalytics(); const updateQueryParams = useUpdateURLQueryParams(); - const [sortBy] = useQueryParam(TableQueryParams.SortBy, ""); - const [sortDir] = useQueryParam(TableQueryParams.SortDir, ""); + const [queryParams] = useQueryParams(); + const sortBy = queryParams[TableQueryParams.SortBy] as string; + const sortDir = queryParams[TableQueryParams.SortDir] as string; + const sorts = queryParams[TableQueryParams.Sorts] as string; - // Apply default sort if none is defined. + // Apply default sort if no sorting method is defined. useEffect(() => { - if (!sortBy && !sortDir) { + if (!sorts && !sortBy && !sortDir) { updateQueryParams({ sortBy: TaskSortCategory.Status, sortDir: SortDirection.Asc, @@ -50,6 +53,11 @@ export const ExecutionTasksTable: React.FC = ({ ...executionTasksFull.map((t) => t.execution), ]); + const initialSorting = useMemo( + () => getInitialSorting(queryParams), + [], // eslint-disable-line react-hooks/exhaustive-deps + ); + const columns = useMemo( () => getColumnsTemplate({ @@ -76,18 +84,13 @@ export const ExecutionTasksTable: React.FC = ({ data: executionTasksFull ?? [], defaultColumn: { enableColumnFilter: false, + enableMultiSort: true, }, initialState: { - sorting: - sortBy && sortDir - ? [ - { - id: sortBy as TaskSortCategory, - desc: sortDir === SortDirection.Desc, - }, - ] - : [{ id: TaskSortCategory.Status, desc: false }], + sorting: initialSorting, }, + isMultiSortEvent: () => true, // Override default requirement for shift-click to multisort. + maxMultiSortColCount: 2, onSortingChange: onChangeHandler( (s) => getDefaultSorting(table).onSortingChange(s), tableSortHandler, @@ -104,3 +107,31 @@ export const ExecutionTasksTable: React.FC = ({ /> ); }; + +const getInitialSorting = (queryParams: { + [key: string]: any; +}): SortingState => { + const { + [TableQueryParams.SortBy]: sortBy, + [TableQueryParams.SortDir]: sortDir, + [TableQueryParams.Sorts]: sorts, + } = queryParams; + + let initialSorting = [{ id: TaskSortCategory.Status, desc: false }]; + if (sortBy && sortDir) { + initialSorting = [ + { + id: sortBy as TaskSortCategory, + desc: sortDir === SortDirection.Desc, + }, + ]; + } else if (sorts) { + const parsedSorts = parseSortString(sorts); + initialSorting = parsedSorts.map(({ Direction, Key }) => ({ + id: Key as TaskSortCategory, + desc: Direction === SortDirection.Desc, + })); + } + + return initialSorting; +}; From 3d130eb090ce1849c811ac3eb97e8e483477e26d Mon Sep 17 00:00:00 2001 From: minnakt Date: Wed, 20 Mar 2024 10:41:16 -0400 Subject: [PATCH 5/6] codegen --- src/gql/generated/types.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/gql/generated/types.ts b/src/gql/generated/types.ts index d6bdf9964c..5e5be146a0 100644 --- a/src/gql/generated/types.ts +++ b/src/gql/generated/types.ts @@ -1058,6 +1058,7 @@ export type Mutation = { unschedulePatchTasks?: Maybe; unscheduleTask: Task; updateHostStatus: Scalars["Int"]["output"]; + updateParsleySettings?: Maybe; updatePublicKey: Array; updateSpawnHostStatus: Host; updateUserSettings: Scalars["Boolean"]["output"]; @@ -1316,6 +1317,10 @@ export type MutationUpdateHostStatusArgs = { status: Scalars["String"]["input"]; }; +export type MutationUpdateParsleySettingsArgs = { + opts: UpdateParsleySettingsInput; +}; + export type MutationUpdatePublicKeyArgs = { targetKeyName: Scalars["String"]["input"]; updateInfo: PublicKeyInput; @@ -1407,6 +1412,16 @@ export type ParsleyFilterInput = { expression: Scalars["String"]["input"]; }; +/** ParsleySettings contains information about a user's settings for Parsley. */ +export type ParsleySettings = { + __typename?: "ParsleySettings"; + sectionsEnabled: Scalars["Boolean"]["output"]; +}; + +export type ParsleySettingsInput = { + sectionsEnabled?: InputMaybe; +}; + /** Patch is a manually initiated version submitted to test local code changes. */ export type Patch = { __typename?: "Patch"; @@ -2867,6 +2882,15 @@ export type UiConfig = { userVoice?: Maybe; }; +export type UpdateParsleySettingsInput = { + parsleySettings: ParsleySettingsInput; +}; + +export type UpdateParsleySettingsPayload = { + __typename?: "UpdateParsleySettingsPayload"; + parsleySettings?: Maybe; +}; + /** * UpdateVolumeInput is the input to the updateVolume mutation. * Its fields determine how a given volume will be modified. @@ -2913,6 +2937,7 @@ export type User = { displayName: Scalars["String"]["output"]; emailAddress: Scalars["String"]["output"]; parsleyFilters: Array; + parsleySettings: ParsleySettings; patches: Patches; permissions: Permissions; subscriptions?: Maybe>; From e6f1790f4dbcaaf791ce79d90caca1061a617930 Mon Sep 17 00:00:00 2001 From: minnakt Date: Wed, 20 Mar 2024 11:24:18 -0400 Subject: [PATCH 6/6] sad codegen --- src/gql/generated/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gql/generated/types.ts b/src/gql/generated/types.ts index 2c912cd4ad..6cb14209a4 100644 --- a/src/gql/generated/types.ts +++ b/src/gql/generated/types.ts @@ -347,7 +347,6 @@ export type DispatcherSettingsInput = { }; export enum DispatcherVersion { - Revised = "REVISED", RevisedWithDependencies = "REVISED_WITH_DEPENDENCIES", }