@balena/ui-shared-components 15.4.1-build-replace-lodash-with-es-toolkit-366e2166c19de2abc07d1f183588d670fe585847-1 → 15.5.0-build-revert-consolidate-fomrats-2ee7e5a82a73723817c8fdc34cef5f22f8b78626-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DownloadImageDialog/index.js +7 -3
- package/dist/components/DownloadImageDialog/utils.js +3 -6
- package/dist/components/DownloadImageDialog/version.js +2 -2
- package/dist/components/DropDownButton/index.js +2 -2
- package/dist/components/Form/Widgets/SelectWidget.js +3 -2
- package/dist/components/HighlightedName/index.d.ts +1 -3
- package/dist/components/HighlightedName/index.js +1 -1
- package/dist/components/RJST/Actions/Tags.js +1 -1
- package/dist/components/RJST/DataTypes/enum.js +1 -1
- package/dist/components/RJST/DataTypes/object.js +3 -2
- package/dist/components/RJST/DataTypes/utils.d.ts +1 -3
- package/dist/components/RJST/DataTypes/utils.js +1 -1
- package/dist/components/RJST/Filters/Filters.js +2 -2
- package/dist/components/RJST/Filters/utils.js +2 -1
- package/dist/components/RJST/components/Filters/FilterDescription.js +1 -1
- package/dist/components/RJST/components/Filters/FocusSearch.js +4 -4
- package/dist/components/RJST/components/Filters/SchemaSieve.js +1 -1
- package/dist/components/RJST/components/Widget/Formats/TxtWidget.js +3 -5
- package/dist/components/RJST/components/Widget/utils.js +1 -1
- package/dist/components/RJST/index.d.ts +4 -1
- package/dist/components/RJST/index.js +5 -4
- package/dist/components/RJST/schemaOps.js +5 -4
- package/dist/components/RJST/utils.js +1 -1
- package/dist/components/TagManagementDialog/index.js +3 -2
- package/dist/components/TagManagementDialog/tag-management-service.js +2 -2
- package/dist/components/VirtualizedAutocomplete/index.js +3 -3
- package/dist/contexts/UiSharedComponentsContextProvider.d.ts +0 -2
- package/dist/hooks/useNavigate.d.ts +1 -0
- package/dist/hooks/useNavigate.js +6 -0
- package/dist/hooks/useTranslations.js +3 -6
- package/dist/utils/objects.d.ts +0 -6
- package/dist/utils/objects.js +0 -43
- package/package.json +4 -3
- package/dist/hooks/useUiSharedComponentsContext.d.ts +0 -1
- package/dist/hooks/useUiSharedComponentsContext.js +0 -6
|
@@ -5,7 +5,8 @@ import { FALLBACK_LOGO_UNKNOWN_DEVICE, isUrlAccessible, stripVersionBuild, } fro
|
|
|
5
5
|
import { GENERIC_X86_MINIMUM_SUPPORTED_SECUREBOOT_VERSION, GENERIC_X86_SLUG, ImageForm, } from './ImageForm';
|
|
6
6
|
import { ApplicationInstructions } from './ApplicationInstructions';
|
|
7
7
|
import { DropDownButton } from '../DropDownButton';
|
|
8
|
-
import
|
|
8
|
+
import pickBy from 'lodash/pickBy';
|
|
9
|
+
import debounce from 'lodash/debounce';
|
|
9
10
|
import { OsTypesEnum } from './models';
|
|
10
11
|
import { uniq } from '../../utils/arrays';
|
|
11
12
|
import { enqueueSnackbar } from 'notistack';
|
|
@@ -82,7 +83,10 @@ const debounceDownloadSize = debounce(async (getDownloadSize, deviceType, rawVer
|
|
|
82
83
|
catch (_b) {
|
|
83
84
|
setDownloadSize(null);
|
|
84
85
|
}
|
|
85
|
-
}, 200
|
|
86
|
+
}, 200, {
|
|
87
|
+
trailing: true,
|
|
88
|
+
leading: false,
|
|
89
|
+
});
|
|
86
90
|
export const DownloadImageDialog = ({ open, applicationId, releaseId, compatibleDeviceTypes, initialDeviceType, initialOsVersions, isInitialDefault, downloadUrl, onDownloadStart, getSupportedOsVersions, getSupportedOsTypes, downloadConfig, getDownloadSize, getDockerArtifact, hasEsrVersions, onClose, onFieldChange, dialogActions, authToken, }) => {
|
|
87
91
|
var _a, _b, _c, _d;
|
|
88
92
|
const formElement = useRef(null);
|
|
@@ -184,7 +188,7 @@ export const DownloadImageDialog = ({ open, applicationId, releaseId, compatible
|
|
|
184
188
|
return;
|
|
185
189
|
}
|
|
186
190
|
// Debounce as the version changes right after the devicetype does, resulting in multiple requests.
|
|
187
|
-
debounceDownloadSize(getDownloadSize, formModel.deviceType, formModel.version, setDownloadSize);
|
|
191
|
+
void debounceDownloadSize(getDownloadSize, formModel.deviceType, formModel.version, setDownloadSize);
|
|
188
192
|
}, [formModel.deviceType, getDownloadSize, formModel.version]);
|
|
189
193
|
useEffect(() => {
|
|
190
194
|
if (!compatibleDeviceTypes || !getSupportedOsVersions) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import template from 'lodash/template';
|
|
1
2
|
import { OsTypesEnum } from './models';
|
|
2
3
|
// TODO: find a way to no release to a link but also not duplicate
|
|
3
4
|
export const FALLBACK_LOGO_UNKNOWN_DEVICE = 'https://dashboard.balena-cloud.com/img/unknown-device.svg';
|
|
@@ -7,12 +8,8 @@ export const OS_VARIANT_FULL_DISPLAY_TEXT_MAP = {
|
|
|
7
8
|
};
|
|
8
9
|
export const getExpanded = (obj) => { var _a; return (_a = (Array.isArray(obj) && obj[0])) !== null && _a !== void 0 ? _a : undefined; };
|
|
9
10
|
export const stripVersionBuild = (version) => version.replace(/(\.dev|\.prod)/, '');
|
|
10
|
-
//
|
|
11
|
-
export const interpolateMustache = (data, tpl) => tpl
|
|
12
|
-
var _a;
|
|
13
|
-
const trimmedKey = key.trim();
|
|
14
|
-
return (_a = data[trimmedKey]) !== null && _a !== void 0 ? _a : '';
|
|
15
|
-
});
|
|
11
|
+
// Use lodash templates to simulate moustache templating
|
|
12
|
+
export const interpolateMustache = (data, tpl) => template(tpl, { interpolate: /{{([\s\S]+?)}}/g })(data);
|
|
16
13
|
export const getOsTypeName = (osTypeSlug) => {
|
|
17
14
|
switch (osTypeSlug) {
|
|
18
15
|
case OsTypesEnum.DEFAULT:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uniq } from '../../utils/arrays';
|
|
2
|
-
import
|
|
2
|
+
import partition from 'lodash/partition';
|
|
3
3
|
export const transformVersions = (versions) => {
|
|
4
4
|
const optsByVersion = {};
|
|
5
5
|
versions.forEach((version) => {
|
|
@@ -29,7 +29,7 @@ export const getPreferredVersionOpts = (versionOpts) => {
|
|
|
29
29
|
// TODO: check if worth installing semver on ui-shared-components;
|
|
30
30
|
// const major = semver.major(v.strippedVersion);
|
|
31
31
|
const major = (_a = v.value.match(/\d+/)) === null || _a === void 0 ? void 0 : _a.join();
|
|
32
|
-
return
|
|
32
|
+
return major && parseInt(major, 10) > LEGACY_OS_VERSION_MAJOR;
|
|
33
33
|
});
|
|
34
34
|
const opts = supportedVersions.length ? supportedVersions : legacyVersions;
|
|
35
35
|
const lines = uniq(opts.map((option) => option.line));
|
|
@@ -4,7 +4,7 @@ import { useMemo, useState } from 'react';
|
|
|
4
4
|
import { Button, ButtonGroup, MenuItem, Menu } from '@mui/material';
|
|
5
5
|
import { ButtonWithTracking } from '../ButtonWithTracking';
|
|
6
6
|
import { useAnalyticsContext } from '../../contexts/AnalyticsContext';
|
|
7
|
-
import
|
|
7
|
+
import groupBy from 'lodash/groupBy';
|
|
8
8
|
import { Tooltip } from '../Tooltip';
|
|
9
9
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
10
10
|
import { faCaretDown, faCaretUp, faChevronDown, faChevronUp, } from '@fortawesome/free-solid-svg-icons';
|
|
@@ -25,7 +25,7 @@ export const DropDownButton = (_a) => {
|
|
|
25
25
|
if (!groupByProp) {
|
|
26
26
|
return items;
|
|
27
27
|
}
|
|
28
|
-
const grouped = groupBy(items, (item) =>
|
|
28
|
+
const grouped = groupBy(items, (item) => item[groupByProp]);
|
|
29
29
|
const entries = Object.entries(grouped);
|
|
30
30
|
const lastKey = (_a = entries.at(-1)) === null || _a === void 0 ? void 0 : _a[0];
|
|
31
31
|
return entries
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Autocomplete, Chip, TextField, FormControl, InputLabel, Typography, } from '@mui/material';
|
|
4
|
-
import
|
|
4
|
+
import omit from 'lodash/omit';
|
|
5
|
+
import isEqual from 'lodash/isEqual';
|
|
5
6
|
import { token } from '../../../utils/token';
|
|
6
7
|
const noneOption = {
|
|
7
8
|
disabled: false,
|
|
@@ -52,7 +53,7 @@ export const SelectWidget = ({ id, label, value, disabled, name, placeholder, on
|
|
|
52
53
|
return (
|
|
53
54
|
// eslint-disable-next-line react/jsx-key -- `key` is provided by getTagProps
|
|
54
55
|
_jsx(Chip, Object.assign({ label: option.label }, (((_a = option.schema) === null || _a === void 0 ? void 0 : _a.disabled)
|
|
55
|
-
? omit(tagProps,
|
|
56
|
+
? omit(tagProps, 'onDelete')
|
|
56
57
|
: tagProps))));
|
|
57
58
|
}), isOptionEqualToValue: (option, val) => isEqual(option, val), getOptionLabel: (option) => Array.isArray(option)
|
|
58
59
|
? option.map((o) => o.label).join(', ')
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { TypographyProps } from '@mui/material';
|
|
2
|
-
export declare const generateHexColorFromString: ((text: string) => string) &
|
|
3
|
-
cache: import("es-toolkit").MemoizeCache<any, string>;
|
|
4
|
-
};
|
|
2
|
+
export declare const generateHexColorFromString: ((text: string) => string) & import("lodash").MemoizedFunction;
|
|
5
3
|
export declare const isLight: (color?: string) => boolean;
|
|
6
4
|
type HighlightedNameProps = Omit<TypographyProps, 'children'> & {
|
|
7
5
|
children: string;
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import Color from 'color';
|
|
5
5
|
import ColorHash from 'color-hash';
|
|
6
|
-
import
|
|
6
|
+
import memoize from 'lodash/memoize';
|
|
7
7
|
import { Typography } from '@mui/material';
|
|
8
8
|
import { token } from '../../utils/token';
|
|
9
9
|
const colorHash = new ColorHash();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { parseDescriptionProperty } from '../schemaOps';
|
|
4
|
-
import
|
|
4
|
+
import get from 'lodash/get';
|
|
5
5
|
import { useTranslation } from '../../../hooks/useTranslations';
|
|
6
6
|
import { closeSnackbar, enqueueSnackbar } from 'notistack';
|
|
7
7
|
import { useQuery } from '@tanstack/react-query';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getDataTypeSchema, regexEscape } from './utils';
|
|
2
2
|
import { FULL_TEXT_SLUG, createModelFilter, } from '../components/Filters/SchemaSieve';
|
|
3
3
|
import { isJSONSchema, getRefSchema } from '../schemaOps';
|
|
4
|
-
import
|
|
4
|
+
import pick from 'lodash/pick';
|
|
5
|
+
import mapValues from 'lodash/mapValues';
|
|
5
6
|
const findValueByDescription = (obj, description) => {
|
|
6
7
|
return Object.values(obj !== null && obj !== void 0 ? obj : {}).find((property) => typeof property === 'object' &&
|
|
7
8
|
'description' in property &&
|
|
@@ -87,7 +88,7 @@ const getValueForOperation = (operator, schema, value) => {
|
|
|
87
88
|
return schemaProperty
|
|
88
89
|
? typeof value === 'string'
|
|
89
90
|
? { type: 'string', [schemaProperty]: value }
|
|
90
|
-
: pick(value,
|
|
91
|
+
: pick(value, schemaProperty)
|
|
91
92
|
: value;
|
|
92
93
|
};
|
|
93
94
|
const getTitleForOperation = (operator, schema, value) => {
|
|
@@ -7,7 +7,5 @@ export type CreateFilter<TOperatorSlugs> = (field: string, operator: TOperatorSl
|
|
|
7
7
|
enumNames?: string[];
|
|
8
8
|
}) => Schema | JSONSchema;
|
|
9
9
|
export declare const getDefaultDate: () => string;
|
|
10
|
-
export declare const normalizeDateTime: ((timestamp: string | number) => string | number | null) &
|
|
11
|
-
cache: import("es-toolkit").MemoizeCache<any, string | number | null>;
|
|
12
|
-
};
|
|
10
|
+
export declare const normalizeDateTime: ((timestamp: string | number) => string | number | null) & import("lodash").MemoizedFunction;
|
|
13
11
|
export declare const getDataTypeSchema: (schemaField: Partial<JSONSchema>, index: number, operators: Record<string, string>, valueSchema: Partial<JSONSchema>) => JSONSchema;
|
|
@@ -3,10 +3,10 @@ import React from 'react';
|
|
|
3
3
|
import { PersistentFilters } from './PersistentFilters';
|
|
4
4
|
import { Filters as FiltersComponent, } from '../components/Filters';
|
|
5
5
|
import { modifySchemaWithRefSchemes, removeFieldsWithNoFilter, removeRefSchemeSeparatorsFromFilters, } from './utils';
|
|
6
|
-
import {
|
|
6
|
+
import { useNavigate } from '../../../hooks/useNavigate';
|
|
7
7
|
const DEFAULT_RENDER_MODE = ['add', 'search', 'views'].slice();
|
|
8
8
|
export const Filters = ({ schema, filters, views, changeFilters, changeViews, viewsRestorationKey, renderMode, onSearch, persistFilters, }) => {
|
|
9
|
-
const
|
|
9
|
+
const navigate = useNavigate();
|
|
10
10
|
const filteredSchema = React.useMemo(() => removeFieldsWithNoFilter(schema), [schema]);
|
|
11
11
|
// This is the function that will rework the schema taking in consideration x-ref-scheme and x-foreign-key-scheme.
|
|
12
12
|
const reworkedSchema = React.useMemo(() => modifySchemaWithRefSchemes(filteredSchema), [filteredSchema]);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { convertRefSchemeToSchemaPath, getRefSchemeTitle, getRefSchemePrefix, isJSONSchema, parseDescription, parseDescriptionProperty, } from '../schemaOps';
|
|
2
|
-
import
|
|
2
|
+
import get from 'lodash/get';
|
|
3
|
+
import { isObjectEmpty } from '../../../utils/objects';
|
|
3
4
|
const X_FOREIGN_KEY_SCHEMA_SEPARATOR = '___ref_scheme_separator_';
|
|
4
5
|
export const removeFieldsWithNoFilter = (schema) => {
|
|
5
6
|
const processProperties = (properties, parentXNoFilterSet) => {
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { FULL_TEXT_SLUG, parseFilterDescription, } from './SchemaSieve';
|
|
5
5
|
import { isDateTimeFormat } from '../../DataTypes';
|
|
6
|
-
import
|
|
6
|
+
import isEqual from 'lodash/isEqual';
|
|
7
7
|
import { findInObject } from '../../utils';
|
|
8
8
|
import { isJSONSchema } from '../../schemaOps';
|
|
9
9
|
import { Tag } from '../../../Tag';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
3
|
+
import debounce from 'lodash/debounce';
|
|
4
|
+
import { useNavigate } from '../../../../hooks/useNavigate';
|
|
5
5
|
import { ajvFilter, createFullTextSearchFilter } from './SchemaSieve';
|
|
6
6
|
import { Box, styled, Typography } from '@mui/material';
|
|
7
7
|
import { convertToPineClientFilter } from '../../oData/jsonToOData';
|
|
@@ -34,7 +34,7 @@ const FocusItem = styled(Box)(({ hasGetBaseUrl }) => ({
|
|
|
34
34
|
}));
|
|
35
35
|
export const FocusSearch = ({ searchTerm, filtered, rjstContext, model, rowKey = 'id', }) => {
|
|
36
36
|
var _a;
|
|
37
|
-
const
|
|
37
|
+
const navigate = useNavigate();
|
|
38
38
|
const [searchResults, setSearchResults] = React.useState(null);
|
|
39
39
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
40
40
|
const inputSearch = (_a = rjstContext.sdk) === null || _a === void 0 ? void 0 : _a.inputSearch;
|
|
@@ -63,7 +63,7 @@ export const FocusSearch = ({ searchTerm, filtered, rjstContext, model, rowKey =
|
|
|
63
63
|
}, 300), [inputSearch, filtered]);
|
|
64
64
|
React.useEffect(() => {
|
|
65
65
|
const filter = createFullTextSearchFilter(model.schema, searchTerm);
|
|
66
|
-
debouncedSearch(filter);
|
|
66
|
+
void debouncedSearch(filter);
|
|
67
67
|
return () => {
|
|
68
68
|
debouncedSearch.cancel();
|
|
69
69
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getAllOperators, getDataModel, isDateTimeFormat, } from '../../DataTypes';
|
|
2
2
|
import ajvKeywords from 'ajv-keywords';
|
|
3
3
|
import addFormats from 'ajv-formats';
|
|
4
|
-
import
|
|
4
|
+
import pickBy from 'lodash/pickBy';
|
|
5
5
|
import Ajv from 'ajv';
|
|
6
6
|
import { enqueueSnackbar } from 'notistack';
|
|
7
7
|
import { isObjectEmpty } from '../../../../utils/objects';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import get from 'lodash/get';
|
|
3
|
+
import invokeMap from 'lodash/invokeMap';
|
|
3
4
|
import { UiOption, JsonTypes, widgetFactory, formatTimestamp } from '../utils';
|
|
4
5
|
import { Truncate } from '../../../../Truncate';
|
|
5
6
|
import { Typography } from '@mui/material';
|
|
@@ -10,10 +11,7 @@ const getArrayValue = (value, uiSchema) => {
|
|
|
10
11
|
if (typeof maxItems !== 'number') {
|
|
11
12
|
return '';
|
|
12
13
|
}
|
|
13
|
-
let arrayString = value
|
|
14
|
-
.slice(0, maxItems)
|
|
15
|
-
.map((item) => item === null || item === void 0 ? void 0 : item.toString())
|
|
16
|
-
.join(', ');
|
|
14
|
+
let arrayString = invokeMap(value.slice(0, maxItems), 'toString').join(', ');
|
|
17
15
|
if (maxItems && maxItems < value.length) {
|
|
18
16
|
arrayString += ` and ${value.length - maxItems} more...`;
|
|
19
17
|
}
|
|
@@ -6,6 +6,7 @@ import { rjstDefaultPermissions, rjstGetModelForCollection, rjstRunTransformers
|
|
|
6
6
|
import { rjstGetDisabledReason } from './utils';
|
|
7
7
|
import type { LensTemplate } from './Lenses';
|
|
8
8
|
import type { BoxProps } from '@mui/material';
|
|
9
|
+
import type { Format } from './components/Widget/utils';
|
|
9
10
|
import type { Pagination } from './components/Table/utils';
|
|
10
11
|
export interface NoDataInfo {
|
|
11
12
|
title?: string | React.ReactElement;
|
|
@@ -20,6 +21,8 @@ export interface RJSTProps<T> extends Omit<BoxProps, 'onChange'> {
|
|
|
20
21
|
model: RJSTModel<T>;
|
|
21
22
|
/** Array of data or data entity to display */
|
|
22
23
|
data: T[] | undefined;
|
|
24
|
+
/** Formats are custom widgets to render in the table cell. The type of format to display is described in the model. */
|
|
25
|
+
formats?: Format[];
|
|
23
26
|
/** Actions is an array of actions applicable on the selected items */
|
|
24
27
|
actions?: Array<RJSTAction<T>>;
|
|
25
28
|
/** The sdk is used to pass the method to handle tags when added removed or updated */
|
|
@@ -54,5 +57,5 @@ export interface RJSTProps<T> extends Omit<BoxProps, 'onChange'> {
|
|
|
54
57
|
noDataInfo?: NoDataInfo;
|
|
55
58
|
persistFilters?: boolean;
|
|
56
59
|
}
|
|
57
|
-
export declare const RJST: <T extends RJSTBaseResource<T>>({ model: modelRaw, data, actions, sdk, customSort, refresh, getBaseUrl, onEntityClick, onChange, pagination, customLenses, loading, rowKey, noDataInfo, persistFilters, ...boxProps }: RJSTProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
export declare const RJST: <T extends RJSTBaseResource<T>>({ model: modelRaw, data, formats, actions, sdk, customSort, refresh, getBaseUrl, onEntityClick, onChange, pagination, customLenses, loading, rowKey, noDataInfo, persistFilters, ...boxProps }: RJSTProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
58
61
|
export { rjstRunTransformers, rjstDefaultPermissions, rjstGetModelForCollection, rjstAddToSchema, type RJSTAction, type RJSTBaseResource, type RJSTRawModel, type RJSTModel, rjstJsonSchemaPick, rjstGetDisabledReason, getPropertyScheme, getSubSchemaFromRefScheme, parseDescription, parseDescriptionProperty, generateSchemaFromRefScheme, };
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { getFieldForFormat, rjstJsonSchemaPick, rjstAdaptRefScheme, rjstAddToSchema, generateSchemaFromRefScheme, getHeaderLink, getPropertyScheme, getSubSchemaFromRefScheme, parseDescription, parseDescriptionProperty, isJSONSchema, } from './schemaOps';
|
|
5
5
|
import { LensSelection } from './Lenses/LensSelection';
|
|
6
|
-
import
|
|
6
|
+
import isEqual from 'lodash/isEqual';
|
|
7
7
|
import { Filters } from './Filters/Filters';
|
|
8
8
|
import { Tags } from './Actions/Tags';
|
|
9
9
|
import { Update } from './Actions/Update';
|
|
@@ -12,11 +12,12 @@ import { rjstDefaultPermissions, rjstGetModelForCollection, rjstRunTransformers,
|
|
|
12
12
|
import { rjstGetDisabledReason, getFromLocalStorage, getTagsDisabledReason, setToLocalStorage, getSortingFunction, DEFAULT_ITEMS_PER_PAGE, } from './utils';
|
|
13
13
|
import { getLenses } from './Lenses';
|
|
14
14
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
15
|
+
import pickBy from 'lodash/pickBy';
|
|
15
16
|
import { NoRecordsFoundView } from './NoRecordsFoundView';
|
|
16
17
|
import { Box, Link, styled } from '@mui/material';
|
|
17
18
|
import { useTranslation } from '../../hooks/useTranslations';
|
|
18
19
|
import { useAnalyticsContext } from '../../contexts/AnalyticsContext';
|
|
19
|
-
import {
|
|
20
|
+
import { useNavigate } from '../../hooks/useNavigate';
|
|
20
21
|
import { convertToPineClientFilter, orderbyBuilder } from './oData/jsonToOData';
|
|
21
22
|
import { ajvFilter } from './components/Filters/SchemaSieve';
|
|
22
23
|
import { Spinner } from '../Spinner';
|
|
@@ -36,10 +37,10 @@ const HeaderGrid = styled(Box)(({ theme }) => ({
|
|
|
36
37
|
// any typing we have in lenses today.
|
|
37
38
|
export const RJST = (_a) => {
|
|
38
39
|
var _b, _c, _d, _e, _f;
|
|
39
|
-
var { model: modelRaw, data, actions, sdk, customSort, refresh, getBaseUrl, onEntityClick, onChange, pagination, customLenses, loading = false, rowKey, noDataInfo, persistFilters = true } = _a, boxProps = __rest(_a, ["model", "data", "actions", "sdk", "customSort", "refresh", "getBaseUrl", "onEntityClick", "onChange", "pagination", "customLenses", "loading", "rowKey", "noDataInfo", "persistFilters"]);
|
|
40
|
+
var { model: modelRaw, data, formats, actions, sdk, customSort, refresh, getBaseUrl, onEntityClick, onChange, pagination, customLenses, loading = false, rowKey, noDataInfo, persistFilters = true } = _a, boxProps = __rest(_a, ["model", "data", "formats", "actions", "sdk", "customSort", "refresh", "getBaseUrl", "onEntityClick", "onChange", "pagination", "customLenses", "loading", "rowKey", "noDataInfo", "persistFilters"]);
|
|
40
41
|
const { t } = useTranslation();
|
|
41
42
|
const { state: analytics } = useAnalyticsContext();
|
|
42
|
-
const
|
|
43
|
+
const navigate = useNavigate();
|
|
43
44
|
const modelRef = React.useRef(modelRaw);
|
|
44
45
|
// This allows the component to work even if
|
|
45
46
|
// consumers are passing a new model object every time.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import pick from 'lodash/pick';
|
|
2
3
|
import { findInObject } from './utils';
|
|
3
|
-
import {
|
|
4
|
+
import { isObjectEmpty } from '../../utils/objects';
|
|
4
5
|
export const isJson = (str) => {
|
|
5
6
|
try {
|
|
6
7
|
JSON.parse(str);
|
|
@@ -85,7 +86,7 @@ export const getRefSchemaPrefix = (propertySchema) => {
|
|
|
85
86
|
return propertySchema.type === 'array' ? `items.properties.` : `properties.`;
|
|
86
87
|
};
|
|
87
88
|
export const generateSchemaFromRefScheme = (schema, parentProperty, refScheme) => {
|
|
88
|
-
var _a, _b, _c;
|
|
89
|
+
var _a, _b, _c, _d;
|
|
89
90
|
const propertySchema = (_b = (_a = schema.properties) === null || _a === void 0 ? void 0 : _a[parentProperty]) !== null && _b !== void 0 ? _b : schema;
|
|
90
91
|
if (!refScheme) {
|
|
91
92
|
return propertySchema;
|
|
@@ -102,7 +103,7 @@ export const generateSchemaFromRefScheme = (schema, parentProperty, refScheme) =
|
|
|
102
103
|
if (ongoingIncrementalPath.length) {
|
|
103
104
|
typePaths.push(ongoingIncrementalPath);
|
|
104
105
|
}
|
|
105
|
-
return Object.assign(Object.assign(Object.assign({}, propertySchema), { description: JSON.stringify({ 'x-ref-scheme': [refScheme] }), title: (_c = get(propertySchema, convertedRefScheme).title) !== null &&
|
|
106
|
+
return Object.assign(Object.assign(Object.assign({}, propertySchema), { description: JSON.stringify({ 'x-ref-scheme': [refScheme] }), title: (_d = (_c = get(propertySchema, convertedRefScheme)) === null || _c === void 0 ? void 0 : _c.title) !== null && _d !== void 0 ? _d : propertySchema.title }), pick(propertySchema, typePaths));
|
|
106
107
|
};
|
|
107
108
|
export const getRefSchema = (schema, refSchemePrefix) => {
|
|
108
109
|
var _a;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getPropertyScheme } from './schemaOps';
|
|
2
2
|
import { toArray } from '../../utils/arrays';
|
|
3
|
-
import
|
|
3
|
+
import get from 'lodash/get';
|
|
4
4
|
import { JsonTypes } from './components/Widget/utils';
|
|
5
5
|
export const DEFAULT_ITEMS_PER_PAGE = 50;
|
|
6
6
|
export const diff = (a, b) => {
|
|
@@ -4,9 +4,10 @@ import { faTrashAlt } from '@fortawesome/free-solid-svg-icons/faTrashAlt';
|
|
|
4
4
|
import { faUndo } from '@fortawesome/free-solid-svg-icons/faUndo';
|
|
5
5
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
6
6
|
import { AddTagForm } from './AddTagForm';
|
|
7
|
-
import
|
|
7
|
+
import sortBy from 'lodash/sortBy';
|
|
8
8
|
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons/faPencilAlt';
|
|
9
9
|
import { getResourceTagSubmitInfo, groupResourcesByTags, } from './tag-management-service';
|
|
10
|
+
import partition from 'lodash/partition';
|
|
10
11
|
import { Button, DialogActions, DialogContent, Stack, styled, Table, TableBody, TableCell, TableHead, TableRow, TextField, Typography, } from '@mui/material';
|
|
11
12
|
import { useTranslation } from '../../hooks/useTranslations';
|
|
12
13
|
import { CollectionSummary } from '../CollectionSummary';
|
|
@@ -130,7 +131,7 @@ export const TagManagementDialog = ({ items, itemType, titleField, tagField, can
|
|
|
130
131
|
state: 'added',
|
|
131
132
|
};
|
|
132
133
|
slicedTags.push(newTag);
|
|
133
|
-
slicedTags = sortBy(slicedTags,
|
|
134
|
+
slicedTags = sortBy(slicedTags, 'tag_key');
|
|
134
135
|
}
|
|
135
136
|
setEditingTag(undefined);
|
|
136
137
|
setTags(slicedTags);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import groupBy from 'lodash/groupBy';
|
|
2
2
|
export const TAGS_COLUMN_KEY = 'Tags';
|
|
3
3
|
export const getTagKeyValueComposite = (tagKey, value) => `${tagKey}: ${value}`;
|
|
4
4
|
export const getResourceTags = (item, tagField) => { var _a; return ((_a = (tagField in item ? item[tagField] : null)) !== null && _a !== void 0 ? _a : []); };
|
|
@@ -12,7 +12,7 @@ export const groupResourcesByTags = (items, tagField) => {
|
|
|
12
12
|
item,
|
|
13
13
|
}));
|
|
14
14
|
});
|
|
15
|
-
const tagsByTagKeyValue = groupBy(resourceTagInfos,
|
|
15
|
+
const tagsByTagKeyValue = groupBy(resourceTagInfos, 'tag_key_value');
|
|
16
16
|
const tagsWithItems = Object.keys(tagsByTagKeyValue)
|
|
17
17
|
.sort()
|
|
18
18
|
.map((tagKeyValue) => {
|
|
@@ -2,7 +2,7 @@ import { __rest } from "tslib";
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createElement as _createElement } from "react";
|
|
4
4
|
import { Autocomplete, Box, ListItemButton, Stack } from '@mui/material';
|
|
5
|
-
import
|
|
5
|
+
import throttle from 'lodash/throttle';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import { forwardRef } from 'react';
|
|
8
8
|
import { VList } from 'virtua';
|
|
@@ -104,10 +104,10 @@ const VirtualizedAutocompleteBase = (_a, ref) => {
|
|
|
104
104
|
}), ListboxProps: {
|
|
105
105
|
isNextPageLoading,
|
|
106
106
|
pagination,
|
|
107
|
-
}, ListboxComponent: ListboxComponent, onInputChange: (event, input) => {
|
|
107
|
+
}, ListboxComponent: ListboxComponent, onInputChange: async (event, input) => {
|
|
108
108
|
// input change
|
|
109
109
|
if ((event === null || event === void 0 ? void 0 : event.type) === 'change') {
|
|
110
|
-
debouncedInputChange(input, []);
|
|
110
|
+
await debouncedInputChange(input, []);
|
|
111
111
|
}
|
|
112
112
|
}, getOptionLabel: getOptionLabel, value: value }, (loadNext === undefined ? {} : { filterOptions: (o) => o }))));
|
|
113
113
|
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { TFunction } from '../hooks/useTranslations';
|
|
2
2
|
import type { NavigateFunction } from 'react-router-dom';
|
|
3
|
-
import type { Format } from '../components/RJST/components/Widget/utils';
|
|
4
3
|
export interface UiSharedComponentsContextProviderInterface {
|
|
5
4
|
navigate?: NavigateFunction;
|
|
6
5
|
t?: TFunction;
|
|
7
6
|
externalTranslationMap?: Dictionary<string>;
|
|
8
|
-
RJSTFormats?: Format[];
|
|
9
7
|
}
|
|
10
8
|
export declare const UiSharedComponentsContextProvider: import("react").Context<UiSharedComponentsContextProviderInterface>;
|
|
11
9
|
export declare const UiSharedComponentsProvider: ({ children, ...otherProps }: UiSharedComponentsContextProviderInterface & {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useNavigate: () => import("react-router").NavigateFunction | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import template from 'lodash/template';
|
|
2
3
|
import { UiSharedComponentsContextProvider } from '../contexts/UiSharedComponentsContextProvider';
|
|
3
4
|
const translationMap = {
|
|
4
5
|
// TagManagement
|
|
@@ -85,12 +86,8 @@ const getTranslation = (str, opts) => {
|
|
|
85
86
|
translation =
|
|
86
87
|
(_a = translationMap[pluralKey]) !== null && _a !== void 0 ? _a : translationMap[str];
|
|
87
88
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// Look up the value in opts. If null/undefined, return empty string.
|
|
91
|
-
const value = opts[trimmedKey];
|
|
92
|
-
return value != null ? String(value) : '';
|
|
93
|
-
});
|
|
89
|
+
const compiled = template(translation, { interpolate: /{{([\s\S]+?)}}/g });
|
|
90
|
+
return compiled(opts);
|
|
94
91
|
};
|
|
95
92
|
export const useTranslation = () => {
|
|
96
93
|
const { t: externalT } = React.useContext(UiSharedComponentsContextProvider);
|
package/dist/utils/objects.d.ts
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
1
|
export declare const isObjectEmpty: (obj: Record<string, unknown> | object) => boolean;
|
|
2
|
-
/**
|
|
3
|
-
* Native replacement for Lodash's deep pick.
|
|
4
|
-
* Accepts an object and an array of paths (string arrays).
|
|
5
|
-
*/
|
|
6
|
-
export declare const pickDeep: (source: any, paths: string[][]) => any;
|
|
7
|
-
export declare const get: <T = any>(obj: any, path: string | string[], defaultValue?: T) => T | undefined;
|
package/dist/utils/objects.js
CHANGED
|
@@ -1,46 +1,3 @@
|
|
|
1
1
|
export const isObjectEmpty = (obj) => {
|
|
2
2
|
return Object.keys(obj).length === 0;
|
|
3
3
|
};
|
|
4
|
-
/**
|
|
5
|
-
* Native replacement for Lodash's deep pick.
|
|
6
|
-
* Accepts an object and an array of paths (string arrays).
|
|
7
|
-
*/
|
|
8
|
-
export const pickDeep = (source, paths) => {
|
|
9
|
-
const result = {};
|
|
10
|
-
for (const path of paths) {
|
|
11
|
-
// 1. Get the value deep inside the source
|
|
12
|
-
// (Using reduce to walk down the tree: source.prop.nested.val)
|
|
13
|
-
const value = path.reduce((acc, key) => acc === null || acc === void 0 ? void 0 : acc[key], source);
|
|
14
|
-
// 2. If found, rebuild that path in the 'result' object
|
|
15
|
-
if (value !== undefined) {
|
|
16
|
-
let current = result;
|
|
17
|
-
path.forEach((key, index) => {
|
|
18
|
-
var _a;
|
|
19
|
-
// If it's the last key, set the value
|
|
20
|
-
if (index === path.length - 1) {
|
|
21
|
-
current[key] = value;
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
// Otherwise, ensure the container object exists
|
|
25
|
-
(_a = current[key]) !== null && _a !== void 0 ? _a : (current[key] = {});
|
|
26
|
-
current = current[key];
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return result;
|
|
32
|
-
};
|
|
33
|
-
export const get = (obj, path, defaultValue) => {
|
|
34
|
-
let result;
|
|
35
|
-
// 1. Handle array path ['a', 'b'] directly
|
|
36
|
-
if (Array.isArray(path)) {
|
|
37
|
-
result = path.reduce((acc, key) => acc === null || acc === void 0 ? void 0 : acc[key], obj);
|
|
38
|
-
return result !== undefined ? result : defaultValue;
|
|
39
|
-
}
|
|
40
|
-
// 2. Handle string path 'a[0].b' -> 'a.0.b'
|
|
41
|
-
// This regex converts brackets to dots so we can split easily
|
|
42
|
-
const normalizedPath = path.replace(/\[(\d+)\]/g, '.$1');
|
|
43
|
-
// 3. Traverse
|
|
44
|
-
result = normalizedPath.split('.').reduce((acc, key) => acc === null || acc === void 0 ? void 0 : acc[key], obj);
|
|
45
|
-
return result !== undefined ? result : defaultValue;
|
|
46
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@balena/ui-shared-components",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.5.0-build-revert-consolidate-fomrats-2ee7e5a82a73723817c8fdc34cef5f22f8b78626-1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"files": [
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"color-hash": "^2.0.2",
|
|
40
40
|
"date-fns": "^4.1.0",
|
|
41
41
|
"dayjs": "^1.11.19",
|
|
42
|
-
"es-toolkit": "^1.43.0",
|
|
43
42
|
"jest": "^29.7.0",
|
|
43
|
+
"lodash": "^4.17.21",
|
|
44
44
|
"notistack": "^3.0.1",
|
|
45
45
|
"qs": "^6.14.0",
|
|
46
46
|
"react": "^18.2.0",
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"@storybook/react-webpack5": "^10.0.1",
|
|
68
68
|
"@types/color": "^4.2.0",
|
|
69
69
|
"@types/color-hash": "^2.0.0",
|
|
70
|
+
"@types/lodash": "^4.17.14",
|
|
70
71
|
"@types/node": "^22.18.13",
|
|
71
72
|
"@types/qs": "^6.9.18",
|
|
72
73
|
"@types/react": "^18.0.35",
|
|
@@ -136,7 +137,7 @@
|
|
|
136
137
|
},
|
|
137
138
|
"homepage": "https://github.com/balena-io/ui-shared-components#readme",
|
|
138
139
|
"versionist": {
|
|
139
|
-
"publishedAt": "2025-12-
|
|
140
|
+
"publishedAt": "2025-12-29T09:18:17.698Z"
|
|
140
141
|
},
|
|
141
142
|
"overrides": {
|
|
142
143
|
"storybook": "$storybook",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const useUiSharedComponentsContext: () => import("../contexts/UiSharedComponentsContextProvider").UiSharedComponentsContextProviderInterface;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { UiSharedComponentsContextProvider } from '../contexts/UiSharedComponentsContextProvider';
|
|
3
|
-
export const useUiSharedComponentsContext = () => {
|
|
4
|
-
const context = React.useContext(UiSharedComponentsContextProvider);
|
|
5
|
-
return context;
|
|
6
|
-
};
|