@balena/ui-shared-components 12.3.1-build-download-image-dialog-improvements-d6c61a275913e084423570c2db6e7ef02cb0dbcc-1 → 12.3.1-build-download-image-dialog-improvements-7f264c962b8e94de065c2e9dd4307dd622ad8d21-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,6 +1,6 @@
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, Checkbox, Chip, Divider, FormControl, FormControlLabel, FormLabel, InputAdornment, InputLabel, Radio, RadioGroup, TextField, Tooltip, Typography, IconButton, Autocomplete, Stack, Accordion, AccordionSummary, AccordionDetails, } from '@mui/material';
3
+ import { Avatar, Box, Checkbox, Chip, Divider, FormControl, FormControlLabel, FormLabel, InputAdornment, Radio, RadioGroup, TextField, Tooltip, Typography, IconButton, Autocomplete, Stack, Accordion, AccordionSummary, AccordionDetails, accordionSummaryClasses, } 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';
@@ -97,43 +97,47 @@ export const ImageForm = memo(function ImageForm({ compatibleDeviceTypes, osVers
97
97
  onChange('deviceType', newDeviceType);
98
98
  }, [compatibleDeviceTypes, model.deviceType.slug, onChange]);
99
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]);
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(Stack, { flex: "1", maxWidth: "100%", children: [_jsxs(InputLabel, { htmlFor: "device-type-select", sx: { display: 'flex', alignItems: 'center', mb: 2, gap: 1 }, 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" }) })] }), _jsx(Autocomplete, { fullWidth: true, id: "device-type-select", value: model.deviceType, options: compatibleDeviceTypes, getOptionLabel: (option) => option.name, renderOption: (props, option) => {
101
- var _a;
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 })] })));
103
- }, renderInput: (_a) => {
104
- var _b;
105
- var { InputProps } = _a, params = __rest(_a, ["InputProps"]);
106
- return (_jsx(TextField, Object.assign({}, params, { InputProps: Object.assign(Object.assign({}, InputProps), { startAdornment: (_jsx(Avatar, { variant: "square", src: (_b = model.deviceType.logo) !== null && _b !== void 0 ? _b : FALLBACK_LOGO_UNKNOWN_DEVICE, sx: { mr: 3, width: '20px', height: '20px' } })) }) })));
107
- }, onChange: (_event, value) => {
108
- if (!value) {
109
- return;
110
- }
111
- handleSelectedDeviceTypeChange(value);
112
- }, disableClearable: true,
113
- // TODO: consider whether there is a better solution than letting the width vary as you search
114
- componentsProps: {
115
- popper: { sx: { width: 'fit-content' } },
116
- } })] })), (!isInitialDefault || osType) &&
100
+ return (_jsxs(Stack, { action: downloadUrl, method: "post", component: "form", noValidate: true, autoComplete: "off", ref: formElement, gap: 3, 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(Stack, { direction: "row", flexWrap: "wrap", gap: 2, children: [compatibleDeviceTypes && compatibleDeviceTypes.length > 1 && (_jsx(Autocomplete, { fullWidth: true, value: model.deviceType, options: compatibleDeviceTypes, getOptionLabel: (option) => option.name, renderOption: (props, option) => {
101
+ var _a;
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 })] })));
103
+ }, renderInput: (_a) => {
104
+ var _b;
105
+ var { InputProps } = _a, params = __rest(_a, ["InputProps"]);
106
+ return (_jsx(TextField, Object.assign({}, params, { label: _jsxs(Stack, { direction: "row", alignItems: "center", gap: 1, 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' } }) })] }), slotProps: {
107
+ input: Object.assign(Object.assign({}, InputProps), { startAdornment: (_jsx(Avatar, { variant: "square", src: (_b = model.deviceType.logo) !== null && _b !== void 0 ? _b : FALLBACK_LOGO_UNKNOWN_DEVICE, sx: { mr: 3, width: '20px', height: '20px' } })) }),
108
+ } })));
109
+ }, onChange: (_event, value) => {
110
+ if (!value) {
111
+ return;
112
+ }
113
+ handleSelectedDeviceTypeChange(value);
114
+ }, disableClearable: true,
115
+ // TODO: consider whether there is a better solution than letting the width vary as you search
116
+ slotProps: {
117
+ popper: { sx: { width: 'fit-content' } },
118
+ }, sx: { flex: 1 } })), (!isInitialDefault || osType) &&
117
119
  hasEsrVersions &&
118
- model.deviceType && (_jsx(OsTypeSelector, { supportedOsTypes: osTypes, hasEsrVersions: hasEsrVersions !== null && hasEsrVersions !== void 0 ? hasEsrVersions : false, selectedOsTypeSlug: osType, onSelectedOsTypeChange: onSelectedOsTypeChange }))] }), !isInitialDefault && version && (_jsxs(Box, { display: "flex", flexWrap: "wrap", maxWidth: "100%", children: [_jsxs(Stack, { maxWidth: "100%", flex: 1, children: [_jsx(InputLabel, { sx: { mb: 2 }, htmlFor: "e2e-download-image-versions-list", children: "OS Version" }), _jsx(Autocomplete, { fullWidth: true, id: "e2e-download-image-versions-list", value: version, getOptionLabel: (option) => option.value, isOptionEqualToValue: (option, value) => option.value === value.value, options: versionSelectionOpts, onChange: (_event, ver) => {
119
- handleVersionChange(ver);
120
- }, placeholder: "Choose a version...", renderOption: (props, option) => (_jsx(Box, Object.assign({ component: "li" }, props, { children: _jsx(VersionSelectItem, { option: option, isRecommended: option.value === recommendedVersion }) }))), renderInput: (_a) => {
121
- var { InputProps } = _a, params = __rest(_a, ["InputProps"]);
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] })) }) })));
123
- }, disableClearable: true })] }), showAllVersionsToggle && (_jsx(Box, { mx: 2, display: "flex", alignItems: "center", alignSelf: "flex-end",
124
- // TODO: find a better way to center the checkbox with the input only (without label)
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) => {
126
- handleVariantChange(v ? 'dev' : 'prod');
127
- } }) })), _jsx(Divider, { variant: "fullWidth", sx: { my: 3, borderStyle: 'dashed' } }), _jsxs(Stack, { 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) => {
120
+ model.deviceType && (_jsx(OsTypeSelector, { supportedOsTypes: osTypes, hasEsrVersions: hasEsrVersions !== null && hasEsrVersions !== void 0 ? hasEsrVersions : false, selectedOsTypeSlug: osType, onSelectedOsTypeChange: onSelectedOsTypeChange }))] }), !isInitialDefault && version && (_jsxs(Stack, { direction: "row", flexWrap: "wrap", maxWidth: "100%", gap: 2, alignItems: "center", children: [_jsx(Autocomplete, { fullWidth: true, id: "e2e-download-image-versions-list", value: version, getOptionLabel: (option) => option.value, isOptionEqualToValue: (option, value) => option.value === value.value, options: versionSelectionOpts, onChange: (_event, ver) => {
121
+ handleVersionChange(ver);
122
+ }, placeholder: "Choose a version...", renderOption: (props, option) => (_jsx(Box, Object.assign({ component: "li" }, props, { children: _jsx(VersionSelectItem, { option: option, isRecommended: option.value === recommendedVersion }) }))), renderInput: (_a) => {
123
+ var { InputProps } = _a, params = __rest(_a, ["InputProps"]);
124
+ return (_jsx(TextField, Object.assign({}, params, { slotProps: {
125
+ input: 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] })) }),
126
+ }, label: "OS version" })));
127
+ }, disableClearable: true, sx: { flex: 1 } }), showAllVersionsToggle && (_jsx(FormControlLabel, { control: _jsx(Checkbox, { id: "e2e-show-all-versions-check", checked: showAllVersions, onChange: handleShowAllVersions }), label: "Show outdated versions",
128
+ // TODO: Find a better way to center the checkbox with the input only (without the label)
129
+ sx: { mt: 3 } }))] })), _jsx(Divider, { variant: "fullWidth", flexItem: true, sx: { borderStyle: 'dashed' } }), (!isInitialDefault || !variant) && (_jsx(VariantSelector, { version: version, variant: variant, onVariantChange: (v) => {
130
+ handleVariantChange(v ? 'dev' : 'prod');
131
+ } })), _jsx(Divider, { variant: "fullWidth", flexItem: true, sx: { borderStyle: 'dashed' } }), _jsxs(Stack, { 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) => {
128
132
  onChange('network', event.target.value);
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: {
133
+ }, 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(Stack, { gap: 3, children: [_jsx(TextField, { value: model.wifiSsid, id: "device-wifi-ssid", slotProps: {
130
134
  htmlInput: {
131
135
  name: 'wifiSsid',
132
136
  autoComplete: 'wifiSsid-auto-complete',
133
137
  },
134
138
  }, onChange: (event) => {
135
139
  onChange('wifiSsid', event.target.value);
136
- } }), _jsx(InputLabel, { htmlFor: "device-wifi-password", sx: { my: 2 }, children: "Wifi Passphrase" }), _jsx(TextField, { type: showPassword ? 'text' : 'password', id: "device-wifi-password", value: model.wifiKey, slotProps: {
140
+ }, label: "WiFi SSID" }), _jsx(TextField, { type: showPassword ? 'text' : 'password', id: "device-wifi-password", value: model.wifiKey, slotProps: {
137
141
  htmlInput: {
138
142
  name: 'wifiKey',
139
143
  },
@@ -147,39 +151,42 @@ export const ImageForm = memo(function ImageForm({ compatibleDeviceTypes, osVers
147
151
  },
148
152
  }, onChange: (event) => {
149
153
  onChange('wifiKey', event.target.value);
150
- } })] }))] }), _jsx(Divider, { variant: "fullWidth", sx: { my: 3, borderStyle: 'dashed' } }), _jsxs(Accordion, { disableGutters: true, elevation: 0, expanded: showAdvancedSettings, onChange: () => {
154
+ }, label: "Wifi Passphrase" })] }))] }), _jsx(Divider, { variant: "fullWidth", sx: { borderStyle: 'dashed' } }), _jsxs(Accordion, { disableGutters: true, elevation: 0, expanded: showAdvancedSettings, onChange: () => {
151
155
  setShowAdvancedSettings(!showAdvancedSettings);
152
156
  }, sx: {
153
157
  border: 'none',
154
158
  '&::before': {
155
159
  display: 'none',
156
160
  },
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: {
169
- htmlInput: {
170
- name: 'provisioningKeyName',
171
- autoComplete: 'provisioningKeyName-auto-complete',
172
- },
173
- }, onChange: (event) => {
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
- } })] }) })] })] }));
161
+ [`& .${accordionSummaryClasses.expandIconWrapper}.${accordionSummaryClasses.expanded}`]: {
162
+ transform: 'rotate(90deg)',
163
+ },
164
+ }, children: [_jsx(AccordionSummary, { expandIcon: _jsx(FontAwesomeIcon, { icon: faChevronRight }), sx: { flexDirection: 'row-reverse', gap: 2 }, children: _jsx(Typography, { variant: "titleSm", children: "Advanced settings" }) }), _jsxs(AccordionDetails, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsx(TextField, { value: model.appUpdatePollInterval, slotProps: {
165
+ htmlInput: {
166
+ name: 'appUpdatePollInterval',
167
+ autoComplete: 'appUpdatePollInterval-auto-complete',
168
+ },
169
+ }, onChange: (event) => {
170
+ onChange('appUpdatePollInterval', event.target.value);
171
+ }, label: _jsxs(Stack, { direction: "row", alignItems: "center", gap: 1, children: ["Check for updates every X minutes", ' ', _jsx(MUILinkWithTracking, { href: POLL_INTERVAL_DOCS, sx: {
172
+ display: 'flex',
173
+ alignItems: 'center',
174
+ height: '1.5rem',
175
+ }, children: _jsx(ArticleIcon, { sx: { ml: 1, fontSize: '1.15rem' } }) })] }) }), _jsx(TextField, { name: "provisioningKeyName", value: (_a = model.provisioningKeyName) !== null && _a !== void 0 ? _a : '', slotProps: {
176
+ htmlInput: {
177
+ name: 'provisioningKeyName',
178
+ autoComplete: 'provisioningKeyName-auto-complete',
179
+ },
180
+ }, onChange: (event) => {
181
+ onChange('provisioningKeyName', event.target.value);
182
+ }, label: "Provisioning Key name" }), _jsx(TextField, { type: "date", value: (_b = model.provisioningKeyExpiryDate) !== null && _b !== void 0 ? _b : '', slotProps: {
183
+ htmlInput: {
184
+ name: 'provisioningKeyExpiryDate',
185
+ autoComplete: 'provisioningKeyExpiryDate-auto-complete',
186
+ },
187
+ }, onChange: (event) => {
188
+ onChange('provisioningKeyExpiryDate', event.target.value);
189
+ }, label: "Provisioning Key expiring on" })] })] })] }));
183
190
  });
184
191
  // TODO: We need a better way than just copying the styling. Consider creating a component to export
185
192
  const VersionSelectItem = ({ option, isRecommended, }) => {
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, InputLabel, MenuItem, Select, Tooltip, Typography, } from '@mui/material';
2
+ import { Box, InputLabel, MenuItem, Select, Tooltip, Typography, Stack, } from '@mui/material';
3
3
  import { getOsTypeName } from './utils';
4
4
  import ArticleIcon from '@mui/icons-material/Article';
5
5
  import { MUILinkWithTracking } from '../MUILinkWithTracking';
@@ -30,12 +30,12 @@ export const OsTypeSelector = ({ supportedOsTypes, hasEsrVersions, selectedOsTyp
30
30
  };
31
31
  });
32
32
  const selectedOsType = selectOsTypes.find((osType) => osType.slug === selectedOsTypeSlug && osType.supportedForDeviceType);
33
- return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, children: [_jsxs(InputLabel, { htmlFor: "newAppApplicationType", sx: { display: 'flex', alignItems: 'center', mb: 2 }, children: ["Select OS type", ' ', _jsx(MUILinkWithTracking, { sx: { height: 14 }, href: "https://www.balena.io/docs/reference/OS/extended-support-release", children: _jsx(ArticleIcon, { sx: { width: 14, height: 14, marginLeft: 1 } }) })] }), _jsx(Select, { id: "newAppApplicationType", fullWidth: true, disabled: supportedOsTypes.length === 0, value: (_a = selectedOsType === null || selectedOsType === void 0 ? void 0 : selectedOsType.slug) !== null && _a !== void 0 ? _a : OsTypesEnum.DEFAULT, renderValue: (selected) => (_jsx(Box, { display: "flex", width: "100%", children: _jsx(OsTypeOption, { osType: selectOsTypes.find((osType) => selected === osType.slug) }) })), onChange: (event) => {
33
+ return (_jsxs(Stack, { flex: 1, children: [_jsx(Stack, { direction: "row", alignItems: "center", gap: 1, children: _jsxs(InputLabel, { id: "newAppApplicationType-label", sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: ["OS type", _jsx(MUILinkWithTracking, { sx: { height: 12 }, href: "https://www.balena.io/docs/reference/OS/extended-support-release", children: _jsx(ArticleIcon, { sx: { fontSize: '1rem' } }) })] }) }), _jsx(Select, { id: "newAppApplicationType", fullWidth: true, disabled: supportedOsTypes.length === 0, value: (_a = selectedOsType === null || selectedOsType === void 0 ? void 0 : selectedOsType.slug) !== null && _a !== void 0 ? _a : OsTypesEnum.DEFAULT, renderValue: (selected) => (_jsx(Box, { display: "flex", width: "100%", children: _jsx(OsTypeOption, { osType: selectOsTypes.find((osType) => selected === osType.slug) }) })), onChange: (event) => {
34
34
  const osType = selectOsTypes.find((os) => os.slug === event.target.value);
35
35
  if (!osType.disabled) {
36
36
  onSelectedOsTypeChange(osType.slug);
37
37
  }
38
- }, children: selectOsTypes.map((option) => (
38
+ }, sx: { flex: 1 }, children: selectOsTypes.map((option) => (
39
39
  // TODO: Consider adding a tooltip for the disabled options
40
40
  _jsx(MenuItem, { value: option.slug, disabled: option.disabled, children: _jsx(OsTypeOption, { osType: option }) }, option.slug))) })] }));
41
41
  };
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Box, FormControl, FormControlLabel, FormLabel, Radio, RadioGroup, Tooltip, Typography, } from '@mui/material';
2
+ import { FormControl, FormControlLabel, FormLabel, Radio, RadioGroup, Stack, Tooltip, Typography, } from '@mui/material';
3
3
  import { MUILinkWithTracking } from '../MUILinkWithTracking';
4
4
  import { getOsVariantDisplayText } from './utils';
5
5
  import { Lightbulb } from '@mui/icons-material';
@@ -7,8 +7,8 @@ import { token } from '../../utils/token';
7
7
  import { Callout } from '../Callout';
8
8
  const variantInfo = (selected) => ({
9
9
  dev: {
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"] })] })),
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." })] }))] })),
10
+ title: (_jsxs(Stack, { gap: 1, direction: "row", alignItems: "center", children: [_jsx(Typography, { children: getOsVariantDisplayText('dev') }), _jsxs(Typography, { variant: "bodySm", color: token('color.text.accent'), alignItems: "center", display: "flex", children: [_jsx(Lightbulb, { sx: { width: 14, height: 14 } }), "Recommended for first time users"] })] })),
11
+ description: (_jsxs(Stack, { gap: 1, children: [_jsxs(Typography, { 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", size: "sm", 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" }), "."] }))] })),
12
12
  },
13
13
  prod: {
14
14
  title: _jsx(Typography, { children: getOsVariantDisplayText('prod') }),
@@ -17,14 +17,14 @@ const variantInfo = (selected) => ({
17
17
  });
18
18
  const BuildVariants = ['dev', 'prod'];
19
19
  export const VariantSelector = ({ version, variant, onVariantChange, }) => {
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
+ return (_jsxs(FormControl, { children: [_jsx(FormLabel, { children: _jsx(Typography, { variant: "titleSm", children: "Edition" }) }), _jsx(RadioGroup, { "aria-labelledby": "variant-radio-buttons-group", name: "developmentMode", value: variant === 'dev', onChange: (event) => {
21
21
  onVariantChange(event.target.value === 'true');
22
- }, children: BuildVariants.map((buildVariant, index) => {
22
+ }, sx: { gap: 2 }, children: BuildVariants.map((buildVariant, index) => {
23
23
  const isDev = buildVariant === 'dev';
24
24
  const isDisabled = version == null ||
25
25
  (version.hasPrebuiltVariants && !version.rawVersions[buildVariant]);
26
26
  return (_jsx(Tooltip, { title: isDisabled
27
27
  ? 'This edition is not available for the selected version'
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));
29
- }) }, "varian")] }));
28
+ : undefined, children: _jsxs(Stack, { 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));
29
+ }) }, "variant")] }));
30
30
  };
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Avatar, Box, DialogActions, DialogContent, Divider, Grid2 as Grid, Typography, } from '@mui/material';
2
+ import { Avatar, DialogActions, DialogContent, Divider, Grid2 as Grid, Stack, Typography, } from '@mui/material';
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { FALLBACK_LOGO_UNKNOWN_DEVICE, isUrlAccessible, stripVersionBuild, } from './utils';
5
5
  import { ImageForm } from './ImageForm';
@@ -253,7 +253,7 @@ export const DownloadImageDialog = ({ open, applicationId, releaseId, compatible
253
253
  }
254
254
  setFormModel(newFormModelState);
255
255
  }, [formModel, applicationId, releaseId, onFieldChange]);
256
- return (_jsxs(DialogWithCloseButton, { title: _jsxs(Box, { display: "flex", alignItems: "center", children: [_jsx(Avatar, { variant: "square", alt: defaultDisplayName, src: (_c = (_b = formModel.deviceType) === null || _b === void 0 ? void 0 : _b.logo) !== null && _c !== void 0 ? _c : FALLBACK_LOGO_UNKNOWN_DEVICE, sx: { mr: 2 } }), _jsx(Typography, { variant: "h5", children: "Add new device" })] }), open: open, onClose: onClose, maxWidth: "lg", fullWidth: true, sx: { p: 4 }, children: [_jsx(DialogContent, { sx: { m: 0 }, children: _jsx(Spinner, { show: isValidatingUrl, children: _jsxs(Grid, { container: true, pb: 5, spacing: [0, 0, 4], children: [_jsx(Grid, { size: {
256
+ return (_jsxs(DialogWithCloseButton, { title: _jsxs(Stack, { direction: "row", alignItems: "center", gap: 2, children: [_jsx(Avatar, { variant: "square", alt: defaultDisplayName, src: (_c = (_b = formModel.deviceType) === null || _b === void 0 ? void 0 : _b.logo) !== null && _c !== void 0 ? _c : FALLBACK_LOGO_UNKNOWN_DEVICE }), _jsx(Typography, { variant: "h5", children: "Add new device" })] }), open: open, onClose: onClose, maxWidth: "lg", fullWidth: true, children: [_jsx(DialogContent, { children: _jsx(Spinner, { show: isValidatingUrl, children: _jsxs(Grid, { container: true, spacing: [0, 0, 4], children: [_jsx(Grid, { size: {
257
257
  xs: 12,
258
258
  sm: 12,
259
259
  md: 6,
@@ -277,11 +277,5 @@ export const DownloadImageDialog = ({ open, applicationId, releaseId, compatible
277
277
  : '',
278
278
  } })] }), ((_d = formModel.deviceType.imageDownloadAlerts) !== null && _d !== void 0 ? _d : []).map((alert) => {
279
279
  return (_jsx(Grid, { pt: 0, size: 12, children: _jsx(Callout, { severity: alert.type, children: alert.message }, alert.message) }, alert.message));
280
- })] }) }) }), _jsx(DialogActions, { sx: {
281
- display: 'flex',
282
- position: 'absolute',
283
- bottom: 0,
284
- right: 0,
285
- justifyContent: 'end',
286
- }, children: _jsx(DropDownButton, { className: "e2e-download-image-submit", items: actions, disabled: isValidatingUrl }) })] }));
280
+ })] }) }) }), _jsx(DialogActions, { children: _jsx(DropDownButton, { className: "e2e-download-image-submit", items: actions, disabled: isValidatingUrl }) })] }));
287
281
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@balena/ui-shared-components",
3
- "version": "12.3.1-build-download-image-dialog-improvements-d6c61a275913e084423570c2db6e7ef02cb0dbcc-1",
3
+ "version": "12.3.1-build-download-image-dialog-improvements-7f264c962b8e94de065c2e9dd4307dd622ad8d21-1",
4
4
  "main": "./dist/index.js",
5
5
  "sideEffects": false,
6
6
  "files": [
@@ -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-16T18:45:56.729Z"
141
+ "publishedAt": "2025-04-17T15:30:47.632Z"
142
142
  }
143
143
  }