Skip to content

Commit a7793b8

Browse files
authored
Merge pull request #222 from balena-io-modules/improve-rjst-typings
RJST: Improve typings & remove some duplicate checks
2 parents 22129f1 + 556eb04 commit a7793b8

File tree

6 files changed

+77
-85
lines changed

6 files changed

+77
-85
lines changed

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"zxcvbn": "^4.4.2"
5555
},
5656
"devDependencies": {
57-
"@balena/lint": "^9.2.1",
57+
"@balena/lint": "^9.3.0",
5858
"@storybook/addon-essentials": "^8.6.12",
5959
"@storybook/addon-interactions": "^8.6.12",
6060
"@storybook/addon-links": "^8.6.12",
@@ -89,7 +89,7 @@
8989
"test": "jest",
9090
"prepack": "npm run build",
9191
"lint": "balena-lint src",
92-
"lint:fix": "balena-lint --fix src",
92+
"lint-fix": "balena-lint --fix src",
9393
"prepare": "husky",
9494
"storybook": "storybook dev -p 6006",
9595
"build-storybook": "storybook build --docs",

src/components/RJST/Lenses/types/table.tsx

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ const sortData = <T extends object>(
103103
} else if (key.startsWith(TAG_COLUMN_PREFIX)) {
104104
if (title) {
105105
sortedData.sort((a, b) => {
106-
const item1tag = findTagOfTaggedResource(a, field as keyof T, title);
107-
const item2tag = findTagOfTaggedResource(b, field as keyof T, title);
106+
const item1tag = findTagOfTaggedResource(a, field, title);
107+
const item2tag = findTagOfTaggedResource(b, field, title);
108108

109109
if (!item1tag && !item2tag) {
110110
return 0;
@@ -124,8 +124,8 @@ const sortData = <T extends object>(
124124
}
125125
} else {
126126
sortedData.sort((a, b) => {
127-
const aValue = a[sort.field as keyof T];
128-
const bValue = b[sort.field as keyof T];
127+
const aValue = a[sort.field];
128+
const bValue = b[sort.field];
129129

130130
if (aValue < bValue) {
131131
return -sortDirectionMultiplier;
@@ -204,34 +204,37 @@ const TableRenderer = <T extends { id: number }>({
204204
return sortPref;
205205
}, [sort, model, columns, onSort]);
206206

207-
const handleAddTagClose = (selectedTagColumns: string[] | undefined) => {
208-
if (!selectedTagColumns?.length) {
209-
setShowAddTagDialog(false);
210-
return;
211-
}
207+
const { tagField } = rjstContext;
208+
const handleAddTagClose =
209+
tagField != null
210+
? (selectedTagColumns: string[] | undefined) => {
211+
if (!selectedTagColumns?.length) {
212+
setShowAddTagDialog(false);
213+
return;
214+
}
212215

213-
const additionalColumns = selectedTagColumns.map(
214-
(key: string, index: number) => {
215-
const field = rjstContext.tagField;
216-
return {
217-
title: key,
218-
label: `Tag: ${key}`,
219-
key: `${TAG_COLUMN_PREFIX}${key}`,
220-
selected: true,
221-
type: 'predefined',
222-
field,
223-
sortable: pagination.serverSide
224-
? `${field}(tag_key='${key}')/value`
225-
: true,
226-
index: index + 1 + columns.length,
227-
priority: '',
228-
render: tagKeyRender(key),
229-
} as RJSTEntityPropertyDefinition<T>;
230-
},
231-
);
232-
setColumns(columns.concat(additionalColumns));
233-
setShowAddTagDialog(false);
234-
};
216+
const additionalColumns = selectedTagColumns.map(
217+
(key: string, index: number) => {
218+
return {
219+
title: key,
220+
label: `Tag: ${key}`,
221+
key: `${TAG_COLUMN_PREFIX}${key}`,
222+
selected: true,
223+
type: 'predefined',
224+
field: tagField,
225+
sortable: pagination.serverSide
226+
? `${tagField}(tag_key='${key}')/value`
227+
: true,
228+
index: index + 1 + columns.length,
229+
priority: '',
230+
render: tagKeyRender(key),
231+
} satisfies RJSTEntityPropertyDefinition<T>;
232+
},
233+
);
234+
setColumns(columns.concat(additionalColumns));
235+
setShowAddTagDialog(false);
236+
}
237+
: undefined;
235238

236239
useEffect(() => {
237240
analytics.webTracker?.track('View table - columns', {
@@ -284,7 +287,7 @@ const TableRenderer = <T extends { id: number }>({
284287
});
285288
}}
286289
/>
287-
{showAddTagDialog && tagKeys?.length && (
290+
{showAddTagDialog && tagKeys?.length && handleAddTagClose != null && (
288291
<AddTagHandler
289292
columns={columns}
290293
tagKeys={tagKeys}

src/components/RJST/components/Table/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export type CheckedState = 'none' | 'some' | 'all';
66

77
export interface TableSortOptions<T> {
88
direction: Order;
9-
field: string;
9+
field: Extract<keyof T, string>;
1010
key: string;
1111
sortable: RJSTEntityPropertyDefinition<T>['sortable'];
1212
refScheme?: string;

src/components/RJST/index.tsx

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import {
4040
getFromLocalStorage,
4141
getTagsDisabledReason,
4242
setToLocalStorage,
43-
getSelected,
4443
getSortingFunction,
4544
DEFAULT_ITEMS_PER_PAGE,
4645
} from './utils';
@@ -725,12 +724,26 @@ const getColumnsFromSchema = <T extends RJSTBaseResource<T>>({
725724
customSort?: RJSTContext<T>['customSort'];
726725
priorities?: Priorities<T>;
727726
formats?: Format[];
728-
}) =>
729-
Object.entries(schema.properties ?? {})
730-
.filter(([_keyBy, val]) => isJSONSchema(val))
731-
.flatMap(([key, val]) => {
727+
}): Array<RJSTEntityPropertyDefinition<T>> => {
728+
const prioritySets = {
729+
primary: new Set(priorities?.primary ?? []),
730+
secondary: new Set(priorities?.secondary ?? []),
731+
};
732+
return (
733+
Object.entries(schema.properties ?? {}) as Array<
734+
[
735+
Extract<keyof T, string>,
736+
NonNullable<typeof schema.properties>[string] | undefined,
737+
]
738+
>
739+
)
740+
.filter((entry): entry is [Extract<keyof T, string>, JSONSchema] => {
741+
const [_key, val] = entry;
742+
return isJSONSchema(val);
743+
})
744+
.flatMap(([key, val]): Array<[Extract<keyof T, string>, JSONSchema]> => {
732745
const refScheme = getPropertyScheme(val);
733-
if (!refScheme || refScheme.length <= 1 || typeof val !== 'object') {
746+
if (!refScheme || refScheme.length <= 1) {
734747
return [[key, val]];
735748
}
736749
const entityFilterOnly = parseDescriptionProperty(val, 'x-filter-only');
@@ -761,34 +774,26 @@ const getColumnsFromSchema = <T extends RJSTBaseResource<T>>({
761774
});
762775
})
763776
.filter(([key, val]) => {
764-
const entryDescription = parseDescription(val as JSONSchema);
777+
const entryDescription = parseDescription(val);
765778
return (
766779
key !== idField &&
767780
(!entryDescription || !('x-filter-only' in entryDescription))
768781
);
769782
})
770783
.map(([key, val], index) => {
771-
if (typeof val !== 'object') {
772-
return;
773-
}
774784
const xNoSort = parseDescriptionProperty(val, 'x-no-sort');
775-
const definedPriorities = priorities ?? ({} as Priorities<T>);
776785
const refScheme = getPropertyScheme(val);
777-
const priority = definedPriorities.primary.find(
778-
(prioritizedKey) => prioritizedKey === key,
779-
)
786+
const priority = prioritySets.primary.has(key)
780787
? 'primary'
781-
: definedPriorities.secondary.find(
782-
(prioritizedKey) => prioritizedKey === key,
783-
)
788+
: prioritySets.secondary.has(key)
784789
? 'secondary'
785790
: 'tertiary';
786791
const widgetSchema = { ...val, title: undefined };
787792
// TODO: Refactor this logic to create an object structure and retrieve the correct property using the refScheme.
788793
// The customSort should look like: { user: { owns_items: [{ uuid: 'xx09x0' }] } }
789794
// The refScheme will reference the property path, e.g., owns_items[0].uuid.
790795
const fieldCustomSort =
791-
customSort?.[`${key}_${refScheme}`] ?? customSort?.[key as string];
796+
customSort?.[`${key}_${refScheme}`] ?? customSort?.[key];
792797
if (fieldCustomSort != null) {
793798
if (
794799
isServerSide &&
@@ -808,11 +813,12 @@ const getColumnsFromSchema = <T extends RJSTBaseResource<T>>({
808813
}
809814
}
810815
return {
811-
...getTitleAndLabel(t, val, key as string, refScheme?.[0]),
816+
...getTitleAndLabel(t, val, key, refScheme?.[0]),
812817
field: key,
813818
// This is used for storing columns and views
814819
key: refScheme ? `${key}_${refScheme[0]}_${index}` : `${key}_${index}`,
815-
selected: getSelected(key as keyof T, priorities),
820+
selected:
821+
!priorities || priority === 'primary' || priority === 'secondary',
816822
priority,
817823
type: 'predefined',
818824
refScheme: refScheme?.[0],
@@ -822,7 +828,7 @@ const getColumnsFromSchema = <T extends RJSTBaseResource<T>>({
822828
? false
823829
: typeof fieldCustomSort === 'function'
824830
? fieldCustomSort
825-
: getSortingFunction(key as string, val),
831+
: getSortingFunction(key, val),
826832
render: (fieldVal: string, entry: T) => {
827833
const calculatedField = rjstAdaptRefScheme(fieldVal, val);
828834
return (
@@ -834,8 +840,6 @@ const getColumnsFromSchema = <T extends RJSTBaseResource<T>>({
834840
/>
835841
);
836842
},
837-
};
838-
})
839-
.filter(
840-
(columnDef): columnDef is NonNullable<typeof columnDef> => !!columnDef,
841-
) as Array<RJSTEntityPropertyDefinition<T>>;
843+
} satisfies RJSTEntityPropertyDefinition<T>;
844+
});
845+
};

src/components/RJST/utils.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import type {
2-
RJSTBaseResource,
3-
Permissions,
4-
Priorities,
5-
RJSTTagsSdk,
6-
} from './schemaOps';
1+
import type { RJSTBaseResource, Permissions, RJSTTagsSdk } from './schemaOps';
72
import { getPropertyScheme } from './schemaOps';
83
import castArray from 'lodash/castArray';
94
import get from 'lodash/get';
@@ -184,13 +179,3 @@ export const getSortingFunction = <T>(
184179
}
185180
return (a: T, b: T) => diff(a[schemaKey], b[schemaKey]);
186181
};
187-
188-
export const getSelected = <T, K extends keyof T>(
189-
key: K,
190-
priorities?: Priorities<T>,
191-
) => {
192-
if (!priorities) {
193-
return true;
194-
}
195-
return priorities.primary.includes(key) || priorities.secondary.includes(key);
196-
};

0 commit comments

Comments
 (0)