@balena/ui-shared-components 12.3.1-build-guides-and-surveys-08fc74895a0c5c9b9cd9378c65f2608f175701c2-1 → 12.3.1-build-download-image-dialog-improvements-560b773bdbdce34c1dedc81e26a33fdc0be3e996-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.
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { Avatar, Box,
|
|
3
|
+
import { Avatar, Box, Checkbox, Chip, Divider, FormControl, FormControlLabel, FormLabel, InputAdornment, InputLabel, Radio, RadioGroup, TextField, Tooltip, Typography, IconButton, Autocomplete, Stack, Accordion, AccordionSummary, AccordionDetails, } from '@mui/material';
|
|
4
4
|
import HelpIcon from '@mui/icons-material/Help';
|
|
5
5
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
|
6
6
|
import { getPreferredVersionOpts, transformVersions } from './version';
|
|
7
7
|
import { OsTypeSelector } from './OsTypeSelector';
|
|
8
8
|
import { VariantSelector } from './VariantSelector';
|
|
9
|
-
import AddIcon from '@mui/icons-material/Add';
|
|
10
|
-
import RemoveIcon from '@mui/icons-material/Remove';
|
|
11
9
|
import ArticleIcon from '@mui/icons-material/Article';
|
|
12
10
|
import { MUILinkWithTracking } from '../MUILinkWithTracking';
|
|
13
11
|
import { Visibility, VisibilityOff } from '@mui/icons-material';
|
|
14
12
|
import { FALLBACK_LOGO_UNKNOWN_DEVICE } from './utils';
|
|
15
13
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
16
|
-
import { faTriangleExclamation } from '@fortawesome/free-solid-svg-icons';
|
|
14
|
+
import { faChevronRight, faTriangleExclamation, } from '@fortawesome/free-solid-svg-icons';
|
|
17
15
|
import { Callout } from '../Callout';
|
|
18
16
|
import { token } from '../../utils/token';
|
|
19
17
|
const POLL_INTERVAL_DOCS = 'https://www.balena.io/docs/reference/supervisor/bandwidth-reduction/#side-effects--warnings';
|
|
@@ -99,7 +97,7 @@ export const ImageForm = memo(function ImageForm({ compatibleDeviceTypes, osVers
|
|
|
99
97
|
onChange('deviceType', newDeviceType);
|
|
100
98
|
}, [compatibleDeviceTypes, model.deviceType.slug, onChange]);
|
|
101
99
|
const recommendedVersion = useMemo(() => { var _a; return (_a = versionSelectionOpts.find((v) => { var _a; return !((_a = v.knownIssueList) === null || _a === void 0 ? void 0 : _a.length); })) === null || _a === void 0 ? void 0 : _a.value; }, [versionSelectionOpts]);
|
|
102
|
-
return (_jsxs(Box, { action: downloadUrl, method: "post", component: "form", noValidate: true, autoComplete: "off", p: 2, ref: formElement, children: [_jsx("input", { type: "hidden", name: "deviceType", value: model.deviceType.slug }), _jsx("input", { type: "hidden", name: "_token", value: authToken }), _jsx("input", { type: "hidden", name: "appId", value: applicationId }), _jsx("input", { type: "hidden", name: "fileType", value: ".zip" }), _jsx("input", { type: "hidden", name: "version", value: model.version }), _jsxs(Box, { py: 3, display: "flex", flexWrap: "wrap", gap: 2, children: [compatibleDeviceTypes && compatibleDeviceTypes.length > 1 && (_jsxs(Box, { display: "flex", flexDirection: "column", flex: "1", maxWidth: "100%", children: [_jsxs(InputLabel, { htmlFor: "device-type-select", sx: { display: 'flex', alignItems: 'center', mb: 2 }, children: ["
|
|
100
|
+
return (_jsxs(Box, { action: downloadUrl, method: "post", component: "form", noValidate: true, autoComplete: "off", p: 2, ref: formElement, children: [_jsx("input", { type: "hidden", name: "deviceType", value: model.deviceType.slug }), _jsx("input", { type: "hidden", name: "_token", value: authToken }), _jsx("input", { type: "hidden", name: "appId", value: applicationId }), _jsx("input", { type: "hidden", name: "fileType", value: ".zip" }), _jsx("input", { type: "hidden", name: "version", value: model.version }), _jsxs(Box, { py: 3, display: "flex", flexWrap: "wrap", gap: 2, children: [compatibleDeviceTypes && compatibleDeviceTypes.length > 1 && (_jsxs(Box, { display: "flex", flexDirection: "column", flex: "1", maxWidth: "100%", children: [_jsxs(InputLabel, { htmlFor: "device-type-select", sx: { display: 'flex', alignItems: 'center', mb: 2 }, children: ["Device type", ' ', _jsx(Tooltip, { title: "Applications can support any devices that share the same architecture as their default device type.", children: _jsx(HelpIcon, { color: "info", sx: { fontSize: '1rem', marginLeft: 1 } }) })] }), _jsx(Autocomplete, { fullWidth: true, id: "device-type-select", value: model.deviceType, options: compatibleDeviceTypes, getOptionLabel: (option) => option.name, renderOption: (props, option) => {
|
|
103
101
|
var _a;
|
|
104
102
|
return (_jsxs(Box, Object.assign({ component: "li" }, props, { children: [_jsx(Avatar, { variant: "square", src: (_a = option.logo) !== null && _a !== void 0 ? _a : FALLBACK_LOGO_UNKNOWN_DEVICE, sx: { mr: 3, width: '20px', height: '20px' } }), _jsx(Typography, { noWrap: true, children: option.name })] })));
|
|
105
103
|
}, renderInput: (_a) => {
|
|
@@ -124,9 +122,9 @@ export const ImageForm = memo(function ImageForm({ compatibleDeviceTypes, osVers
|
|
|
124
122
|
return (_jsx(TextField, Object.assign({}, params, { InputProps: Object.assign(Object.assign({}, InputProps), { endAdornment: (_jsxs(_Fragment, { children: [version.value === recommendedVersion && (_jsx(Chip, { sx: { ml: 1 }, color: "green", label: "recommended" })), !!(version === null || version === void 0 ? void 0 : version.knownIssueList) && (_jsx(Tooltip, { title: version.knownIssueList, children: _jsx(FontAwesomeIcon, { icon: faTriangleExclamation, color: token('color.icon.warning') }) })), InputProps.endAdornment] })) }) })));
|
|
125
123
|
}, disableClearable: true })] }), showAllVersionsToggle && (_jsx(Box, { mx: 2, display: "flex", alignItems: "center", alignSelf: "flex-end",
|
|
126
124
|
// TODO: find a better way to center the checkbox with the input only (without label)
|
|
127
|
-
height: 54, children: _jsx(FormControlLabel, { control: _jsx(Checkbox, { id: "e2e-show-all-versions-check", checked: showAllVersions, onChange: handleShowAllVersions }), label: "Show outdated versions" }) }))] })), (!isInitialDefault || !variant) && (_jsx(Box, { sx: { mt: 3 }, children: _jsx(VariantSelector, { version: version, variant: variant, onVariantChange: (v) => {
|
|
125
|
+
height: 54, children: _jsx(FormControlLabel, { control: _jsx(Checkbox, { id: "e2e-show-all-versions-check", checked: showAllVersions, onChange: handleShowAllVersions }), label: "Show outdated versions" }) }))] })), _jsx(Divider, { variant: "fullWidth", sx: { my: 3, borderStyle: 'dashed' } }), (!isInitialDefault || !variant) && (_jsx(Box, { sx: { mt: 3 }, children: _jsx(VariantSelector, { version: version, variant: variant, onVariantChange: (v) => {
|
|
128
126
|
handleVariantChange(v ? 'dev' : 'prod');
|
|
129
|
-
} }) })), _jsx(Divider, { variant: "fullWidth", sx: { my: 3, borderStyle: 'dashed' } }), _jsxs(Box, { display: "flex", flexDirection: "column", children: [_jsxs(FormControl, { children: [_jsx(FormLabel, { id: "network-radio-buttons-group-label", children: "Network" }), _jsxs(RadioGroup, { "aria-labelledby": "network-radio-buttons-group-label", value: model.network, name: "network", onChange: (event) => {
|
|
127
|
+
} }) })), _jsx(Divider, { variant: "fullWidth", sx: { my: 3, borderStyle: 'dashed' } }), _jsxs(Box, { display: "flex", flexDirection: "column", children: [_jsxs(FormControl, { children: [_jsx(FormLabel, { id: "network-radio-buttons-group-label", children: _jsx(Typography, { variant: "titleSm", children: "Network" }) }), _jsxs(RadioGroup, { "aria-labelledby": "network-radio-buttons-group-label", value: model.network, name: "network", onChange: (event) => {
|
|
130
128
|
onChange('network', event.target.value);
|
|
131
129
|
}, children: [_jsx(FormControlLabel, { value: "ethernet", control: _jsx(Radio, {}), label: "Ethernet only" }), _jsx(FormControlLabel, { value: "wifi", control: _jsx(Radio, {}), label: "Wifi + Ethernet" })] })] }), model.network === 'wifi' && (_jsxs(_Fragment, { children: [_jsx(InputLabel, { htmlFor: "device-wifi-ssid", sx: { mb: 2 }, children: "WiFi SSID" }), _jsx(TextField, { value: model.wifiSsid, id: "device-wifi-ssid", slotProps: {
|
|
132
130
|
htmlInput: {
|
|
@@ -149,34 +147,39 @@ export const ImageForm = memo(function ImageForm({ compatibleDeviceTypes, osVers
|
|
|
149
147
|
},
|
|
150
148
|
}, onChange: (event) => {
|
|
151
149
|
onChange('wifiKey', event.target.value);
|
|
152
|
-
} })] }))] }), _jsx(Divider, { variant: "fullWidth", sx: { my: 3, borderStyle: 'dashed' } }), _jsxs(
|
|
150
|
+
} })] }))] }), _jsx(Divider, { variant: "fullWidth", sx: { my: 3, borderStyle: 'dashed' } }), _jsxs(Accordion, { disableGutters: true, elevation: 0, expanded: showAdvancedSettings, onChange: () => {
|
|
153
151
|
setShowAdvancedSettings(!showAdvancedSettings);
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
}, sx: {
|
|
153
|
+
border: 'none',
|
|
154
|
+
'&::before': {
|
|
155
|
+
display: 'none',
|
|
156
|
+
},
|
|
157
|
+
}, children: [_jsx(AccordionSummary, { expandIcon: _jsx(FontAwesomeIcon, { icon: faChevronRight }), sx: { flexDirection: 'row-reverse', gap: 1 }, children: _jsx(Typography, { variant: "titleSm", children: "Advanced settings" }) }), _jsx(AccordionDetails, { children: _jsxs(Stack, { children: [_jsxs(FormControl, { children: [_jsxs(FormLabel, { htmlFor: "poll-interval-label", sx: { display: 'flex' }, children: ["Check for updates every X minutes", ' ', _jsx(MUILinkWithTracking, { href: POLL_INTERVAL_DOCS, sx: {
|
|
158
|
+
display: 'flex',
|
|
159
|
+
alignItems: 'center',
|
|
160
|
+
height: '1.5rem',
|
|
161
|
+
}, children: _jsx(ArticleIcon, { sx: { ml: 1, fontSize: '1.15rem' } }) })] }), _jsx(TextField, { id: "poll-interval-label", "aria-labelledby": "poll-interval-label", value: model.appUpdatePollInterval, slotProps: {
|
|
162
|
+
htmlInput: {
|
|
163
|
+
name: 'appUpdatePollInterval',
|
|
164
|
+
autoComplete: 'appUpdatePollInterval-auto-complete',
|
|
165
|
+
},
|
|
166
|
+
}, onChange: (event) => {
|
|
167
|
+
onChange('appUpdatePollInterval', event.target.value);
|
|
168
|
+
} })] }), _jsx(InputLabel, { htmlFor: "provision-key-name", sx: { my: 2 }, children: "Provisioning Key name" }), _jsx(TextField, { name: "provisioningKeyName", id: "provision-key-name", value: (_a = model.provisioningKeyName) !== null && _a !== void 0 ? _a : '', slotProps: {
|
|
159
169
|
htmlInput: {
|
|
160
|
-
name: '
|
|
161
|
-
autoComplete: '
|
|
170
|
+
name: 'provisioningKeyName',
|
|
171
|
+
autoComplete: 'provisioningKeyName-auto-complete',
|
|
162
172
|
},
|
|
163
173
|
}, onChange: (event) => {
|
|
164
|
-
onChange('
|
|
165
|
-
} })
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
htmlInput: {
|
|
174
|
-
name: 'provisioningKeyExpiryDate',
|
|
175
|
-
autoComplete: 'provisioningKeyExpiryDate-auto-complete',
|
|
176
|
-
},
|
|
177
|
-
}, onChange: (event) => {
|
|
178
|
-
onChange('provisioningKeyExpiryDate', event.target.value);
|
|
179
|
-
} })] }) })] }));
|
|
174
|
+
onChange('provisioningKeyName', event.target.value);
|
|
175
|
+
} }), _jsx(InputLabel, { htmlFor: "provision-key-expiring", sx: { my: 2 }, children: "Provisioning Key expiring on" }), _jsx(TextField, { type: "date", id: "provision-key-expiring", value: (_b = model.provisioningKeyExpiryDate) !== null && _b !== void 0 ? _b : '', slotProps: {
|
|
176
|
+
htmlInput: {
|
|
177
|
+
name: 'provisioningKeyExpiryDate',
|
|
178
|
+
autoComplete: 'provisioningKeyExpiryDate-auto-complete',
|
|
179
|
+
},
|
|
180
|
+
}, onChange: (event) => {
|
|
181
|
+
onChange('provisioningKeyExpiryDate', event.target.value);
|
|
182
|
+
} })] }) })] })] }));
|
|
180
183
|
});
|
|
181
184
|
// TODO: We need a better way than just copying the styling. Consider creating a component to export
|
|
182
185
|
const VersionSelectItem = ({ option, isRecommended, }) => {
|
|
@@ -4,19 +4,20 @@ import { MUILinkWithTracking } from '../MUILinkWithTracking';
|
|
|
4
4
|
import { getOsVariantDisplayText } from './utils';
|
|
5
5
|
import { Lightbulb } from '@mui/icons-material';
|
|
6
6
|
import { token } from '../../utils/token';
|
|
7
|
-
|
|
7
|
+
import { Callout } from '../Callout';
|
|
8
|
+
const variantInfo = (selected) => ({
|
|
8
9
|
dev: {
|
|
9
10
|
title: (_jsxs(Box, { display: "flex", gap: 1, flexDirection: "row", alignItems: "center", children: [_jsx(Typography, { children: getOsVariantDisplayText('dev') }), _jsxs(Typography, { variant: "bodySm", color: token('color.text'), alignItems: "center", display: "flex", children: [_jsx(Lightbulb, { sx: { width: 14, height: 14 } }), "Recommended for first time users"] })] })),
|
|
10
|
-
description: (_jsxs(_Fragment, { children: ["Development images should be used when you are developing an application and want to use the fast", ' ', _jsx(MUILinkWithTracking, { href: "https://balena.io/docs/development/local-mode/", children: "local mode" }), ' ', "workflow", '
|
|
11
|
+
description: (_jsxs(_Fragment, { children: ["Development images should be used when you are developing an application and want to use the fast", ' ', _jsx(MUILinkWithTracking, { href: "https://balena.io/docs/development/local-mode/", children: "local mode" }), ' ', "workflow.", selected === 'dev' && (_jsxs(Callout, { severity: "warning", children: ["This variant should never be used in production for security reasons.", _jsx(MUILinkWithTracking, { href: "https://docs.balena.io/reference/OS/overview/#development-vs-production-mode", children: "Learn more." })] }))] })),
|
|
11
12
|
},
|
|
12
13
|
prod: {
|
|
13
14
|
title: _jsx(Typography, { children: getOsVariantDisplayText('prod') }),
|
|
14
15
|
description: (_jsx(_Fragment, { children: "Production images are ready for production deployments, but don't offer easy access for local development." })),
|
|
15
16
|
},
|
|
16
|
-
};
|
|
17
|
+
});
|
|
17
18
|
const BuildVariants = ['dev', 'prod'];
|
|
18
19
|
export const VariantSelector = ({ version, variant, onVariantChange, }) => {
|
|
19
|
-
return (_jsxs(FormControl, { children: [_jsx(FormLabel, { children: "Select edition" }), _jsx(RadioGroup, { "aria-labelledby": "variant-radio-buttons-group", name: "developmentMode", value: variant === 'dev', onChange: (event) => {
|
|
20
|
+
return (_jsxs(FormControl, { children: [_jsx(FormLabel, { children: _jsx(Typography, { variant: "titleSm", children: "Select edition" }) }), _jsx(RadioGroup, { "aria-labelledby": "variant-radio-buttons-group", name: "developmentMode", value: variant === 'dev', onChange: (event) => {
|
|
20
21
|
onVariantChange(event.target.value === 'true');
|
|
21
22
|
}, children: BuildVariants.map((buildVariant, index) => {
|
|
22
23
|
const isDev = buildVariant === 'dev';
|
|
@@ -24,6 +25,6 @@ export const VariantSelector = ({ version, variant, onVariantChange, }) => {
|
|
|
24
25
|
(version.hasPrebuiltVariants && !version.rawVersions[buildVariant]);
|
|
25
26
|
return (_jsx(Tooltip, { title: isDisabled
|
|
26
27
|
? 'This edition is not available for the selected version'
|
|
27
|
-
: undefined, children: _jsxs(Box, { display: "flex", flexDirection: "column", children: [_jsx(FormControlLabel, { sx: { opacity: isDisabled ? 0.4 : 1 }, disabled: isDisabled, value: isDev, control: _jsx(Radio, {}), label: variantInfo[buildVariant].title }), _jsx(Typography, { sx: { opacity: isDisabled ? 0.4 : 1 }, variant: "bodySm", children: variantInfo[buildVariant].description })] }) }, index));
|
|
28
|
+
: undefined, children: _jsxs(Box, { display: "flex", flexDirection: "column", children: [_jsx(FormControlLabel, { sx: { opacity: isDisabled ? 0.4 : 1 }, disabled: isDisabled, value: isDev, control: _jsx(Radio, {}), label: variantInfo(variant)[buildVariant].title }), _jsx(Typography, { sx: { opacity: isDisabled ? 0.4 : 1 }, variant: "bodySm", children: variantInfo(variant)[buildVariant].description })] }) }, index));
|
|
28
29
|
}) }, "varian")] }));
|
|
29
30
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@balena/ui-shared-components",
|
|
3
|
-
"version": "12.3.1-build-
|
|
3
|
+
"version": "12.3.1-build-download-image-dialog-improvements-560b773bdbdce34c1dedc81e26a33fdc0be3e996-1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"files": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"ajv": "^8.17.1",
|
|
33
33
|
"ajv-formats": "^3.0.1",
|
|
34
34
|
"ajv-keywords": "^5.1.0",
|
|
35
|
-
"analytics-client": "^2.
|
|
35
|
+
"analytics-client": "^2.0.1",
|
|
36
36
|
"color": "^5.0.0",
|
|
37
37
|
"color-hash": "^2.0.2",
|
|
38
38
|
"date-fns": "^4.1.0",
|
|
@@ -138,6 +138,6 @@
|
|
|
138
138
|
},
|
|
139
139
|
"homepage": "https://github.com/balena-io/ui-shared-components#readme",
|
|
140
140
|
"versionist": {
|
|
141
|
-
"publishedAt": "2025-04-
|
|
141
|
+
"publishedAt": "2025-04-16T18:00:44.588Z"
|
|
142
142
|
}
|
|
143
143
|
}
|