Skip to content

Commit 7cd8220

Browse files
authored
Merge branch 'main' into hack-setup-scripts
2 parents 7cac92d + 0cce0d8 commit 7cd8220

File tree

8 files changed

+73
-25
lines changed

8 files changed

+73
-25
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ COPY --chown=1001 . .
1515
RUN npm clean-install --ignore-scripts && npm run build && npm run dist
1616

1717
# Runner image
18-
FROM registry.access.redhat.com/ubi9/nodejs-18-minimal:1-113.1717076360
18+
FROM registry.access.redhat.com/ubi9/nodejs-18-minimal:1-117
1919

2020
# Add ps package to allow liveness probe for k8s cluster
2121
# Add tar package to allow copying files with kubectl scp
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,58 @@
11
import { useLocalStorage } from "@migtools/lib-ui";
2+
import { ColumnSetting } from "../types";
3+
import { useEffect } from "react";
24

35
export interface ColumnState<TColumnKey extends string> {
46
id: TColumnKey;
57
label: string;
68
isVisible: boolean;
9+
isIdentity?: boolean;
710
}
811

912
export interface IColumnState<TColumnKey extends string> {
1013
columns: ColumnState<TColumnKey>[];
14+
defaultColumns: ColumnState<TColumnKey>[];
1115
setColumns: (newColumns: ColumnState<TColumnKey>[]) => void;
1216
}
1317

1418
interface IColumnStateArgs<TColumnKey extends string> {
15-
initialColumns: ColumnState<TColumnKey>[];
19+
initialColumns?: Partial<Record<TColumnKey, ColumnSetting>>;
1620
columnsKey: string;
21+
supportedColumns: Record<TColumnKey, string>;
1722
}
1823

19-
export const useColumnState = <TColumnKey extends string>(
20-
args: IColumnStateArgs<TColumnKey>
21-
): IColumnState<TColumnKey> => {
24+
export const useColumnState = <TColumnKey extends string>({
25+
initialColumns,
26+
supportedColumns,
27+
columnsKey,
28+
}: IColumnStateArgs<TColumnKey>): IColumnState<TColumnKey> => {
29+
const defaultColumns = (
30+
Object.entries(supportedColumns) as [TColumnKey, string][]
31+
).map(([id, label]) => ({
32+
id,
33+
label,
34+
isVisible: initialColumns?.[id]?.isVisible ?? true,
35+
isIdentity: initialColumns?.[id]?.isIdentity,
36+
}));
2237
const [columns, setColumns] = useLocalStorage<ColumnState<TColumnKey>[]>({
23-
key: args.columnsKey,
24-
defaultValue: args.initialColumns,
38+
key: columnsKey,
39+
defaultValue: defaultColumns,
2540
});
2641

27-
return { columns, setColumns };
42+
useEffect(() => {
43+
const valid = columns.filter(({ id }) =>
44+
defaultColumns.find((it) => id === it.id)
45+
);
46+
if (valid.length !== defaultColumns.length) {
47+
setColumns(
48+
defaultColumns.map((it) => ({
49+
...it,
50+
isVisible:
51+
valid.find(({ id }) => id === it.id)?.isVisible ?? it.isVisible,
52+
}))
53+
);
54+
}
55+
}, [defaultColumns, columns, setColumns]);
56+
57+
return { columns, setColumns, defaultColumns };
2858
};

client/src/app/hooks/table-controls/sorting/useSortState.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ export const useSortState = <
7373
): ISortState<TSortableColumnKey> => {
7474
const { isSortEnabled, persistTo = "state", persistenceKeyPrefix } = args;
7575
const sortableColumns = (isSortEnabled && args.sortableColumns) || [];
76-
const initialSort: IActiveSort<TSortableColumnKey> | null = sortableColumns[0]
77-
? { columnKey: sortableColumns[0], direction: "asc" }
78-
: null;
76+
const initialSort = (isSortEnabled && args.initialSort) || null;
77+
const defaultInitialSort: IActiveSort<TSortableColumnKey> | null =
78+
sortableColumns[0]
79+
? { columnKey: sortableColumns[0], direction: "asc" }
80+
: null;
7981

8082
// We won't need to pass the latter two type params here if TS adds support for partial inference.
8183
// See https://github.com/konveyor/tackle2-ui/issues/1456
@@ -85,7 +87,7 @@ export const useSortState = <
8587
"sortColumn" | "sortDirection"
8688
>({
8789
isEnabled: !!isSortEnabled,
88-
defaultValue: initialSort,
90+
defaultValue: initialSort ?? defaultInitialSort,
8991
persistenceKeyPrefix,
9092
// Note: For the discriminated union here to work without TypeScript getting confused
9193
// (e.g. require the urlParams-specific options when persistTo === "urlParams"),

client/src/app/hooks/table-controls/types.ts

+9
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ export type IFeaturePersistenceArgs<
104104
*/
105105
persistTo?: PersistTarget;
106106
};
107+
108+
export interface ColumnSetting {
109+
// visibility status, can change in time
110+
isVisible?: boolean;
111+
// column is always visible because it's needed to uniquely identify the row
112+
isIdentity?: boolean;
113+
}
114+
107115
/**
108116
* Table-level persistence-specific args
109117
* - Extra args needed for persisting state at the table level.
@@ -151,6 +159,7 @@ export type IUseTableControlStateArgs<
151159
/**
152160
* Initial state for the columns feature. If omitted, all columns are enabled by default.
153161
*/
162+
initialColumns?: Partial<Record<TColumnKey, ColumnSetting>>;
154163
} & IFilterStateArgs<TItem, TFilterCategoryKey> &
155164
ISortStateArgs<TSortableColumnKey> &
156165
IPaginationStateArgs & {

client/src/app/hooks/table-controls/useTableControlState.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,11 @@ export const useTableControlState = <
6868
persistTo: getPersistTo("activeItem"),
6969
});
7070

71-
const { columnNames, tableName } = args;
72-
73-
const initialColumns = Object.entries(columnNames).map(([id, label]) => ({
74-
id: id as TColumnKey,
75-
label: label as string,
76-
isVisible: true,
77-
}));
78-
71+
const { columnNames, tableName, initialColumns } = args;
7972
const columnState = useColumnState<TColumnKey>({
8073
columnsKey: tableName,
8174
initialColumns,
75+
supportedColumns: columnNames,
8276
});
8377
return {
8478
...args,

client/src/app/pages/applications/applications-table/applications-table.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ export const ApplicationsTable: React.FC = () => {
325325
isLoading: isFetchingApplications,
326326
sortableColumns: ["name", "businessService", "tags", "effort"],
327327
initialSort: { columnKey: "name", direction: "asc" },
328+
initialColumns: {
329+
name: { isIdentity: true },
330+
},
328331
initialFilterValues: deserializedFilterValues,
329332
getSortValues: (app) => ({
330333
name: app.name,
@@ -804,6 +807,7 @@ export const ApplicationsTable: React.FC = () => {
804807
<ManageColumnsToolbar
805808
columns={columnState.columns}
806809
setColumns={columnState.setColumns}
810+
defaultColumns={columnState.defaultColumns}
807811
/>
808812
</ToolbarGroup>
809813

client/src/app/pages/applications/applications-table/components/manage-columns-modal.tsx

+11-5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export interface ManagedColumnsProps<TColumnKey extends string> {
2525
saveLabel?: string;
2626
cancelLabel?: string;
2727
title?: string;
28+
restoreLabel?: string;
29+
defaultColumns: ColumnState<TColumnKey>[];
2830
}
2931

3032
export const ManageColumnsModal = <TColumnKey extends string>({
@@ -35,6 +37,8 @@ export const ManageColumnsModal = <TColumnKey extends string>({
3537
saveLabel = "Save",
3638
cancelLabel = "Cancel",
3739
title = "Manage Columns",
40+
restoreLabel = "Restore defaults",
41+
defaultColumns,
3842
}: ManagedColumnsProps<TColumnKey>) => {
3943
const [editedColumns, setEditedColumns] =
4044
useState<ColumnState<TColumnKey>[]>(columns);
@@ -47,6 +51,7 @@ export const ManageColumnsModal = <TColumnKey extends string>({
4751
}))
4852
);
4953
};
54+
const restoreDefaults = () => setEditedColumns([...defaultColumns]);
5055

5156
const onSave = () => {
5257
// If ordering is implemented, update accordingly
@@ -72,19 +77,20 @@ export const ManageColumnsModal = <TColumnKey extends string>({
7277
<Button key="cancel" variant="secondary" onClick={onClose}>
7378
{cancelLabel}
7479
</Button>,
80+
<Button key="restore" variant="link" onClick={restoreDefaults}>
81+
{restoreLabel}
82+
</Button>,
7583
]}
7684
>
7785
<DataList aria-label={title} id="table-column-management" isCompact>
78-
{editedColumns.map(({ id, label, isVisible }, index) => (
86+
{editedColumns.map(({ id, label, isVisible, isIdentity }, index) => (
7987
<DataListItem key={index}>
8088
<DataListItemRow className="custom-data-list-item-row">
8189
<DataListControl>
8290
<DataListCheck
8391
aria-labelledby={`check-${id}`}
84-
checked={isVisible}
85-
//TODO: Dynamic disable logic based on idProperty definition in useTableControlState.
86-
// Currently, any column whose name is 'name' will not be allowed to be hidden
87-
isDisabled={id === "name"}
92+
checked={isVisible || isIdentity}
93+
isDisabled={isIdentity}
8894
onChange={(e, checked) => onSelect(id, checked)}
8995
/>
9096
</DataListControl>

client/src/app/pages/applications/applications-table/components/manage-columns-toolbar.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ import { ColumnsIcon } from "@patternfly/react-icons";
1313

1414
interface ManageColumnsToolbarProps<TColumnKey extends string> {
1515
columns: ColumnState<TColumnKey>[];
16+
defaultColumns: ColumnState<TColumnKey>[];
1617
setColumns: (newColumns: ColumnState<TColumnKey>[]) => void;
1718
}
1819

1920
export const ManageColumnsToolbar = <TColumnKey extends string>({
2021
columns,
2122
setColumns,
23+
defaultColumns,
2224
}: ManageColumnsToolbarProps<TColumnKey>) => {
2325
const { t } = useTranslation();
2426
const [isOpen, setIsOpen] = useState(false);
@@ -46,6 +48,7 @@ export const ManageColumnsToolbar = <TColumnKey extends string>({
4648
saveLabel={t("actions.save")}
4749
cancelLabel={t("actions.cancel")}
4850
title={t("dialog.title.manageColumns")}
51+
defaultColumns={defaultColumns}
4952
/>
5053
)}
5154
</>

0 commit comments

Comments
 (0)