@balena/ui-shared-components 15.4.1-build-secureboot-ensure-esr-supports-5db87ab5f253f42b01518c94f565c45895eccb6f-1 → 15.4.1-build-replace-lodash-with-es-toolkit-366e2166c19de2abc07d1f183588d670fe585847-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/ImageForm.js +4 -4
- package/dist/components/DownloadImageDialog/index.js +3 -7
- package/dist/components/DownloadImageDialog/utils.js +6 -3
- package/dist/components/DownloadImageDialog/version.js +2 -2
- package/dist/components/DropDownButton/index.js +2 -2
- package/dist/components/Form/Widgets/SelectWidget.js +2 -3
- package/dist/components/HighlightedName/index.d.ts +3 -1
- 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 +2 -3
- package/dist/components/RJST/DataTypes/utils.d.ts +3 -1
- package/dist/components/RJST/DataTypes/utils.js +1 -1
- package/dist/components/RJST/Filters/utils.js +1 -2
- package/dist/components/RJST/components/Filters/FilterDescription.js +1 -1
- package/dist/components/RJST/components/Filters/FocusSearch.js +2 -2
- package/dist/components/RJST/components/Filters/SchemaSieve.js +1 -1
- package/dist/components/RJST/components/Widget/Formats/TxtWidget.js +5 -3
- package/dist/components/RJST/components/Widget/utils.js +1 -1
- package/dist/components/RJST/index.js +1 -2
- package/dist/components/RJST/schemaOps.js +4 -5
- package/dist/components/RJST/utils.js +1 -1
- package/dist/components/TagManagementDialog/index.js +2 -3
- package/dist/components/TagManagementDialog/tag-management-service.js +2 -2
- package/dist/components/VirtualizedAutocomplete/index.js +3 -3
- package/dist/hooks/useTranslations.js +6 -3
- package/dist/utils/objects.d.ts +6 -0
- package/dist/utils/objects.js +43 -0
- package/package.json +3 -4
|
@@ -53,10 +53,10 @@ export const ImageForm = memo(function ImageForm({ compatibleDeviceTypes, osVers
|
|
|
53
53
|
const versionSelectionOpts = useMemo(() => (showAllVersions ? selectionOpts : preferredSelectionOpts), [preferredSelectionOpts, selectionOpts, showAllVersions]);
|
|
54
54
|
const showAllVersionsToggle = useMemo(() => preferredSelectionOpts.length < selectionOpts.length, [preferredSelectionOpts.length, selectionOpts.length]);
|
|
55
55
|
const supportsSecureBoot = useMemo(() => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
semver.gte(
|
|
59
|
-
}, [model.deviceType.slug, model.version,
|
|
56
|
+
return (osType === 'default' &&
|
|
57
|
+
model.deviceType.slug === GENERIC_X86_SLUG &&
|
|
58
|
+
semver.gte(model.version, GENERIC_X86_MINIMUM_SUPPORTED_SECUREBOOT_VERSION));
|
|
59
|
+
}, [model.deviceType.slug, model.version, osType]);
|
|
60
60
|
const secureBootDontShowAgainKey = `${model.deviceType.slug}_secureboot_warning_do_not_show_again`;
|
|
61
61
|
const dismissSecureBootWarning = useCallback((accepted, dontShowAgain) => {
|
|
62
62
|
var _a;
|
|
@@ -5,8 +5,7 @@ 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 pickBy from '
|
|
9
|
-
import debounce from 'lodash/debounce';
|
|
8
|
+
import { pickBy, debounce } from 'es-toolkit';
|
|
10
9
|
import { OsTypesEnum } from './models';
|
|
11
10
|
import { uniq } from '../../utils/arrays';
|
|
12
11
|
import { enqueueSnackbar } from 'notistack';
|
|
@@ -83,10 +82,7 @@ const debounceDownloadSize = debounce(async (getDownloadSize, deviceType, rawVer
|
|
|
83
82
|
catch (_b) {
|
|
84
83
|
setDownloadSize(null);
|
|
85
84
|
}
|
|
86
|
-
}, 200
|
|
87
|
-
trailing: true,
|
|
88
|
-
leading: false,
|
|
89
|
-
});
|
|
85
|
+
}, 200);
|
|
90
86
|
export const DownloadImageDialog = ({ open, applicationId, releaseId, compatibleDeviceTypes, initialDeviceType, initialOsVersions, isInitialDefault, downloadUrl, onDownloadStart, getSupportedOsVersions, getSupportedOsTypes, downloadConfig, getDownloadSize, getDockerArtifact, hasEsrVersions, onClose, onFieldChange, dialogActions, authToken, }) => {
|
|
91
87
|
var _a, _b, _c, _d;
|
|
92
88
|
const formElement = useRef(null);
|
|
@@ -188,7 +184,7 @@ export const DownloadImageDialog = ({ open, applicationId, releaseId, compatible
|
|
|
188
184
|
return;
|
|
189
185
|
}
|
|
190
186
|
// Debounce as the version changes right after the devicetype does, resulting in multiple requests.
|
|
191
|
-
|
|
187
|
+
debounceDownloadSize(getDownloadSize, formModel.deviceType, formModel.version, setDownloadSize);
|
|
192
188
|
}, [formModel.deviceType, getDownloadSize, formModel.version]);
|
|
193
189
|
useEffect(() => {
|
|
194
190
|
if (!compatibleDeviceTypes || !getSupportedOsVersions) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import template from 'lodash/template';
|
|
2
1
|
import { OsTypesEnum } from './models';
|
|
3
2
|
// TODO: find a way to no release to a link but also not duplicate
|
|
4
3
|
export const FALLBACK_LOGO_UNKNOWN_DEVICE = 'https://dashboard.balena-cloud.com/img/unknown-device.svg';
|
|
@@ -8,8 +7,12 @@ export const OS_VARIANT_FULL_DISPLAY_TEXT_MAP = {
|
|
|
8
7
|
};
|
|
9
8
|
export const getExpanded = (obj) => { var _a; return (_a = (Array.isArray(obj) && obj[0])) !== null && _a !== void 0 ? _a : undefined; };
|
|
10
9
|
export const stripVersionBuild = (version) => version.replace(/(\.dev|\.prod)/, '');
|
|
11
|
-
//
|
|
12
|
-
export const interpolateMustache = (data, tpl) =>
|
|
10
|
+
// Simulate moustache templating
|
|
11
|
+
export const interpolateMustache = (data, tpl) => tpl.replace(/{{([\s\S]+?)}}/g, (_match, key) => {
|
|
12
|
+
var _a;
|
|
13
|
+
const trimmedKey = key.trim();
|
|
14
|
+
return (_a = data[trimmedKey]) !== null && _a !== void 0 ? _a : '';
|
|
15
|
+
});
|
|
13
16
|
export const getOsTypeName = (osTypeSlug) => {
|
|
14
17
|
switch (osTypeSlug) {
|
|
15
18
|
case OsTypesEnum.DEFAULT:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uniq } from '../../utils/arrays';
|
|
2
|
-
import partition from '
|
|
2
|
+
import { partition } from 'es-toolkit';
|
|
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 major && parseInt(major, 10) > LEGACY_OS_VERSION_MAJOR;
|
|
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 groupBy from '
|
|
7
|
+
import { groupBy } from 'es-toolkit';
|
|
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) => item[groupByProp]);
|
|
28
|
+
const grouped = groupBy(items, (item) => String(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,8 +1,7 @@
|
|
|
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 omit from '
|
|
5
|
-
import isEqual from 'lodash/isEqual';
|
|
4
|
+
import { omit, isEqual } from 'es-toolkit';
|
|
6
5
|
import { token } from '../../../utils/token';
|
|
7
6
|
const noneOption = {
|
|
8
7
|
disabled: false,
|
|
@@ -53,7 +52,7 @@ export const SelectWidget = ({ id, label, value, disabled, name, placeholder, on
|
|
|
53
52
|
return (
|
|
54
53
|
// eslint-disable-next-line react/jsx-key -- `key` is provided by getTagProps
|
|
55
54
|
_jsx(Chip, Object.assign({ label: option.label }, (((_a = option.schema) === null || _a === void 0 ? void 0 : _a.disabled)
|
|
56
|
-
? omit(tagProps, 'onDelete')
|
|
55
|
+
? omit(tagProps, ['onDelete'])
|
|
57
56
|
: tagProps))));
|
|
58
57
|
}), isOptionEqualToValue: (option, val) => isEqual(option, val), getOptionLabel: (option) => Array.isArray(option)
|
|
59
58
|
? option.map((o) => o.label).join(', ')
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { TypographyProps } from '@mui/material';
|
|
2
|
-
export declare const generateHexColorFromString: ((text: string) => string) &
|
|
2
|
+
export declare const generateHexColorFromString: ((text: string) => string) & {
|
|
3
|
+
cache: import("es-toolkit").MemoizeCache<any, string>;
|
|
4
|
+
};
|
|
3
5
|
export declare const isLight: (color?: string) => boolean;
|
|
4
6
|
type HighlightedNameProps = Omit<TypographyProps, 'children'> & {
|
|
5
7
|
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 memoize from '
|
|
6
|
+
import { memoize } from 'es-toolkit';
|
|
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 get from '
|
|
4
|
+
import { get } from '../../../utils/objects';
|
|
5
5
|
import { useTranslation } from '../../../hooks/useTranslations';
|
|
6
6
|
import { closeSnackbar, enqueueSnackbar } from 'notistack';
|
|
7
7
|
import { useQuery } from '@tanstack/react-query';
|
|
@@ -1,8 +1,7 @@
|
|
|
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 pick from '
|
|
5
|
-
import mapValues from 'lodash/mapValues';
|
|
4
|
+
import { pick, mapValues } from 'es-toolkit';
|
|
6
5
|
const findValueByDescription = (obj, description) => {
|
|
7
6
|
return Object.values(obj !== null && obj !== void 0 ? obj : {}).find((property) => typeof property === 'object' &&
|
|
8
7
|
'description' in property &&
|
|
@@ -88,7 +87,7 @@ const getValueForOperation = (operator, schema, value) => {
|
|
|
88
87
|
return schemaProperty
|
|
89
88
|
? typeof value === 'string'
|
|
90
89
|
? { type: 'string', [schemaProperty]: value }
|
|
91
|
-
: pick(value, schemaProperty)
|
|
90
|
+
: pick(value, [schemaProperty])
|
|
92
91
|
: value;
|
|
93
92
|
};
|
|
94
93
|
const getTitleForOperation = (operator, schema, value) => {
|
|
@@ -7,5 +7,7 @@ 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) &
|
|
10
|
+
export declare const normalizeDateTime: ((timestamp: string | number) => string | number | null) & {
|
|
11
|
+
cache: import("es-toolkit").MemoizeCache<any, string | number | null>;
|
|
12
|
+
};
|
|
11
13
|
export declare const getDataTypeSchema: (schemaField: Partial<JSONSchema>, index: number, operators: Record<string, string>, valueSchema: Partial<JSONSchema>) => JSONSchema;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { convertRefSchemeToSchemaPath, getRefSchemeTitle, getRefSchemePrefix, isJSONSchema, parseDescription, parseDescriptionProperty, } from '../schemaOps';
|
|
2
|
-
import get from '
|
|
3
|
-
import { isObjectEmpty } from '../../../utils/objects';
|
|
2
|
+
import { get, isObjectEmpty } from '../../../utils/objects';
|
|
4
3
|
const X_FOREIGN_KEY_SCHEMA_SEPARATOR = '___ref_scheme_separator_';
|
|
5
4
|
export const removeFieldsWithNoFilter = (schema) => {
|
|
6
5
|
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 isEqual from '
|
|
6
|
+
import { isEqual } from 'es-toolkit';
|
|
7
7
|
import { findInObject } from '../../utils';
|
|
8
8
|
import { isJSONSchema } from '../../schemaOps';
|
|
9
9
|
import { Tag } from '../../../Tag';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import debounce from '
|
|
3
|
+
import { debounce } from 'es-toolkit';
|
|
4
4
|
import { useUiSharedComponentsContext } from '../../../../hooks/useUiSharedComponentsContext';
|
|
5
5
|
import { ajvFilter, createFullTextSearchFilter } from './SchemaSieve';
|
|
6
6
|
import { Box, styled, Typography } from '@mui/material';
|
|
@@ -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
|
-
|
|
66
|
+
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 pickBy from '
|
|
4
|
+
import { pickBy } from 'es-toolkit';
|
|
5
5
|
import Ajv from 'ajv';
|
|
6
6
|
import { enqueueSnackbar } from 'notistack';
|
|
7
7
|
import { isObjectEmpty } from '../../../../utils/objects';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import get from '
|
|
3
|
-
import invokeMap from 'lodash/invokeMap';
|
|
2
|
+
import { get } from '../../../../../utils/objects';
|
|
4
3
|
import { UiOption, JsonTypes, widgetFactory, formatTimestamp } from '../utils';
|
|
5
4
|
import { Truncate } from '../../../../Truncate';
|
|
6
5
|
import { Typography } from '@mui/material';
|
|
@@ -11,7 +10,10 @@ const getArrayValue = (value, uiSchema) => {
|
|
|
11
10
|
if (typeof maxItems !== 'number') {
|
|
12
11
|
return '';
|
|
13
12
|
}
|
|
14
|
-
let arrayString =
|
|
13
|
+
let arrayString = value
|
|
14
|
+
.slice(0, maxItems)
|
|
15
|
+
.map((item) => item === null || item === void 0 ? void 0 : item.toString())
|
|
16
|
+
.join(', ');
|
|
15
17
|
if (maxItems && maxItems < value.length) {
|
|
16
18
|
arrayString += ` and ${value.length - maxItems} more...`;
|
|
17
19
|
}
|
|
@@ -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 isEqual from '
|
|
6
|
+
import { isEqual, pickBy } from 'es-toolkit';
|
|
7
7
|
import { Filters } from './Filters/Filters';
|
|
8
8
|
import { Tags } from './Actions/Tags';
|
|
9
9
|
import { Update } from './Actions/Update';
|
|
@@ -12,7 +12,6 @@ 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';
|
|
16
15
|
import { NoRecordsFoundView } from './NoRecordsFoundView';
|
|
17
16
|
import { Box, Link, styled } from '@mui/material';
|
|
18
17
|
import { useTranslation } from '../../hooks/useTranslations';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import pick from 'lodash/pick';
|
|
1
|
+
import { pick } from 'es-toolkit';
|
|
3
2
|
import { findInObject } from './utils';
|
|
4
|
-
import { isObjectEmpty } from '../../utils/objects';
|
|
3
|
+
import { get, isObjectEmpty, pickDeep } from '../../utils/objects';
|
|
5
4
|
export const isJson = (str) => {
|
|
6
5
|
try {
|
|
7
6
|
JSON.parse(str);
|
|
@@ -86,7 +85,7 @@ export const getRefSchemaPrefix = (propertySchema) => {
|
|
|
86
85
|
return propertySchema.type === 'array' ? `items.properties.` : `properties.`;
|
|
87
86
|
};
|
|
88
87
|
export const generateSchemaFromRefScheme = (schema, parentProperty, refScheme) => {
|
|
89
|
-
var _a, _b, _c
|
|
88
|
+
var _a, _b, _c;
|
|
90
89
|
const propertySchema = (_b = (_a = schema.properties) === null || _a === void 0 ? void 0 : _a[parentProperty]) !== null && _b !== void 0 ? _b : schema;
|
|
91
90
|
if (!refScheme) {
|
|
92
91
|
return propertySchema;
|
|
@@ -103,7 +102,7 @@ export const generateSchemaFromRefScheme = (schema, parentProperty, refScheme) =
|
|
|
103
102
|
if (ongoingIncrementalPath.length) {
|
|
104
103
|
typePaths.push(ongoingIncrementalPath);
|
|
105
104
|
}
|
|
106
|
-
return Object.assign(Object.assign(Object.assign({}, propertySchema), { description: JSON.stringify({ 'x-ref-scheme': [refScheme] }), title: (
|
|
105
|
+
return Object.assign(Object.assign(Object.assign({}, propertySchema), { description: JSON.stringify({ 'x-ref-scheme': [refScheme] }), title: (_c = get(propertySchema, convertedRefScheme).title) !== null && _c !== void 0 ? _c : propertySchema.title }), pickDeep(propertySchema, typePaths));
|
|
107
106
|
};
|
|
108
107
|
export const getRefSchema = (schema, refSchemePrefix) => {
|
|
109
108
|
var _a;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getPropertyScheme } from './schemaOps';
|
|
2
2
|
import { toArray } from '../../utils/arrays';
|
|
3
|
-
import get from '
|
|
3
|
+
import { get } from '../../utils/objects';
|
|
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,10 +4,9 @@ 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 sortBy from '
|
|
7
|
+
import { sortBy, partition } from 'es-toolkit';
|
|
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';
|
|
11
10
|
import { Button, DialogActions, DialogContent, Stack, styled, Table, TableBody, TableCell, TableHead, TableRow, TextField, Typography, } from '@mui/material';
|
|
12
11
|
import { useTranslation } from '../../hooks/useTranslations';
|
|
13
12
|
import { CollectionSummary } from '../CollectionSummary';
|
|
@@ -131,7 +130,7 @@ export const TagManagementDialog = ({ items, itemType, titleField, tagField, can
|
|
|
131
130
|
state: 'added',
|
|
132
131
|
};
|
|
133
132
|
slicedTags.push(newTag);
|
|
134
|
-
slicedTags = sortBy(slicedTags, 'tag_key');
|
|
133
|
+
slicedTags = sortBy(slicedTags, ['tag_key']);
|
|
135
134
|
}
|
|
136
135
|
setEditingTag(undefined);
|
|
137
136
|
setTags(slicedTags);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import groupBy from '
|
|
1
|
+
import { groupBy } from 'es-toolkit';
|
|
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, (item) => item.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 throttle from '
|
|
5
|
+
import { throttle } from 'es-toolkit';
|
|
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:
|
|
107
|
+
}, ListboxComponent: ListboxComponent, onInputChange: (event, input) => {
|
|
108
108
|
// input change
|
|
109
109
|
if ((event === null || event === void 0 ? void 0 : event.type) === 'change') {
|
|
110
|
-
|
|
110
|
+
debouncedInputChange(input, []);
|
|
111
111
|
}
|
|
112
112
|
}, getOptionLabel: getOptionLabel, value: value }, (loadNext === undefined ? {} : { filterOptions: (o) => o }))));
|
|
113
113
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import template from 'lodash/template';
|
|
3
2
|
import { UiSharedComponentsContextProvider } from '../contexts/UiSharedComponentsContextProvider';
|
|
4
3
|
const translationMap = {
|
|
5
4
|
// TagManagement
|
|
@@ -86,8 +85,12 @@ const getTranslation = (str, opts) => {
|
|
|
86
85
|
translation =
|
|
87
86
|
(_a = translationMap[pluralKey]) !== null && _a !== void 0 ? _a : translationMap[str];
|
|
88
87
|
}
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
return translation.replace(/{{([\s\S]+?)}}/g, (_match, key) => {
|
|
89
|
+
const trimmedKey = key.trim();
|
|
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
|
+
});
|
|
91
94
|
};
|
|
92
95
|
export const useTranslation = () => {
|
|
93
96
|
const { t: externalT } = React.useContext(UiSharedComponentsContextProvider);
|
package/dist/utils/objects.d.ts
CHANGED
|
@@ -1 +1,7 @@
|
|
|
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,3 +1,46 @@
|
|
|
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.4.1-build-
|
|
3
|
+
"version": "15.4.1-build-replace-lodash-with-es-toolkit-366e2166c19de2abc07d1f183588d670fe585847-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",
|
|
42
43
|
"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,7 +67,6 @@
|
|
|
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",
|
|
71
70
|
"@types/node": "^22.18.13",
|
|
72
71
|
"@types/qs": "^6.9.18",
|
|
73
72
|
"@types/react": "^18.0.35",
|
|
@@ -137,7 +136,7 @@
|
|
|
137
136
|
},
|
|
138
137
|
"homepage": "https://github.com/balena-io/ui-shared-components#readme",
|
|
139
138
|
"versionist": {
|
|
140
|
-
"publishedAt": "2025-12-
|
|
139
|
+
"publishedAt": "2025-12-23T22:44:14.082Z"
|
|
141
140
|
},
|
|
142
141
|
"overrides": {
|
|
143
142
|
"storybook": "$storybook",
|