@iobroker/dm-gui-components 10.0.23 → 10.1.0

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.
Files changed (46) hide show
  1. package/README.md +10 -0
  2. package/build/AnimatedIcons.d.ts +37 -0
  3. package/build/AnimatedIcons.js +108 -0
  4. package/build/AnimatedIcons.js.map +1 -0
  5. package/build/Communication.d.ts +7 -0
  6. package/build/Communication.js +43 -11
  7. package/build/Communication.js.map +1 -1
  8. package/build/DeviceCard.d.ts +25 -13
  9. package/build/DeviceCard.js +177 -282
  10. package/build/DeviceCard.js.map +1 -1
  11. package/build/DeviceControl.js +38 -26
  12. package/build/DeviceControl.js.map +1 -1
  13. package/build/DeviceImageUpload.d.ts +5 -1
  14. package/build/DeviceImageUpload.js +79 -62
  15. package/build/DeviceImageUpload.js.map +1 -1
  16. package/build/DeviceList.d.ts +8 -0
  17. package/build/DeviceList.js +74 -59
  18. package/build/DeviceList.js.map +1 -1
  19. package/build/DeviceStatus.d.ts +20 -4
  20. package/build/DeviceStatus.js +146 -191
  21. package/build/DeviceStatus.js.map +1 -1
  22. package/build/StatusIndicator.js +9 -37
  23. package/build/StatusIndicator.js.map +1 -1
  24. package/build/StatusPill.d.ts +18 -0
  25. package/build/StatusPill.js +30 -0
  26. package/build/StatusPill.js.map +1 -0
  27. package/build/Switch.d.ts +3 -0
  28. package/build/Switch.js +36 -26
  29. package/build/Switch.js.map +1 -1
  30. package/build/Utils.js +92 -60
  31. package/build/Utils.js.map +1 -1
  32. package/build/i18n/de.json +3 -0
  33. package/build/i18n/en.json +3 -0
  34. package/build/i18n/es.json +3 -0
  35. package/build/i18n/fr.json +3 -0
  36. package/build/i18n/it.json +3 -0
  37. package/build/i18n/nl.json +3 -0
  38. package/build/i18n/pl.json +3 -0
  39. package/build/i18n/pt.json +3 -0
  40. package/build/i18n/ru.json +3 -0
  41. package/build/i18n/uk.json +3 -0
  42. package/build/i18n/zh-cn.json +3 -0
  43. package/build/styles.d.ts +17 -0
  44. package/build/styles.js +226 -0
  45. package/build/styles.js.map +1 -0
  46. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceCard.js","sourceRoot":"./src/","sources":["DeviceCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { PureComponent, type JSX } from 'react';\nimport {\n Close as CloseIcon,\n VideogameAsset as ControlIcon,\n MoreVert as MoreVertIcon,\n ExpandMore,\n} from '@mui/icons-material';\nimport {\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Fab,\n IconButton,\n Paper,\n Skeleton,\n Tooltip,\n Typography,\n Accordion,\n AccordionSummary,\n AccordionDetails,\n} from '@mui/material';\n\nimport {\n DeviceTypeIcon,\n Utils,\n type Connection,\n type IobTheme,\n type ThemeName,\n type ThemeType,\n Icon,\n} from '@iobroker/gui-components';\nimport DeviceActionButton from './DeviceActionButton';\nimport DeviceControlComponent from './DeviceControl';\nimport DeviceImageUpload from './DeviceImageUpload';\nimport DeviceStatusComponent from './DeviceStatus';\nimport JsonConfig from './JsonConfig';\nimport { StatusIndicators } from './StatusIndicator';\nimport type {\n ActionBase,\n ControlBase,\n ControlState,\n DeviceDetails,\n DeviceAction,\n DeviceControl,\n DeviceInfo,\n DeviceId,\n} from './protocol/api';\n\nimport { getText, getTranslation } from './Utils';\nimport type { StateOrObjectHandler } from './StateOrObjectHandler';\nimport type { ResolvedDeviceFields } from './DeviceFields';\n\n// The type moved to `DeviceFields` together with the filtering itself. Re-exported here, because it\n// used to be exported from this module.\nexport type { DeviceFilterField } from './DeviceFields';\n\n/** Reserved action names (this is copied from https://github.com/ioBroker/dm-utils/blob/main/src/types/base.ts as we can only have type references to dm-utils) */\nconst ACTIONS = {\n /** This action will be called when the user clicks on the connection icon */\n STATUS: 'status',\n /** This action will be called when the user clicks on the enabled / disabled icon. The enabled/disabled icon will be shown only if the node status has the \"enabled\" flag set to false or true */\n ENABLE_DISABLE: 'enable/disable',\n /** This action will be called when the user clicks on the update indicator. The update indicator is shown only if `DeviceInfo.update.available` is true */\n UPDATE: 'update',\n /** This action will be called when the user clicks on the battery indicator. The battery indicator is shown only if the node status has the \"battery\" property */\n BATTERY: 'battery',\n};\n\n/**\n * Footprint of a card. The list needs it to give a not yet rendered card a placeholder of exactly\n * the same size, so that neither the layout nor the length of the scrollbar changes.\n */\nexport const CARD_WIDTH = 300;\nexport const CARD_MIN_HEIGHT = 280;\nexport const CARD_MARGIN = 10;\n\nexport const SMALL_CARD_WIDTH = 200;\nexport const SMALL_CARD_MIN_HEIGHT = 200;\nexport const SMALL_CARD_MARGIN = 5;\n\nconst cardSize: React.CSSProperties = { width: CARD_WIDTH, minHeight: CARD_MIN_HEIGHT, margin: CARD_MARGIN };\nconst smallCardSize: React.CSSProperties = {\n width: SMALL_CARD_WIDTH,\n minHeight: SMALL_CARD_MIN_HEIGHT,\n margin: SMALL_CARD_MARGIN,\n};\n/** A card that sits in a container which already has the footprint of a card */\nconst filledCardSize: React.CSSProperties = { width: '100%', margin: 0 };\n\n/**\n * Icons read from the file storage of the adapter, keyed by `<instance>/<file>`.\n *\n * A card is unmounted and mounted again while scrolling, and without this cache every one of those\n * would repeat the `readFile` round trip for an icon that is very often not there at all.\n */\nconst fileIconCache = new Map<string, string>();\n\nconst styles: Record<string, any> = {\n cardStyle: (theme: IobTheme): React.CSSProperties => ({\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: theme.palette.mode === 'dark' ? '#0b0b0b' : '#d5d5d5',\n }),\n headerStyle: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n paddingLeft: 8,\n paddingRight: 8,\n position: 'relative',\n minHeight: 60,\n color: '#000',\n },\n imgAreaStyle: {\n height: 45,\n width: 45,\n justifyContent: 'center',\n display: 'flex',\n alignItems: 'center',\n },\n imgStyle: {\n zIndex: 2,\n maxWidth: '100%',\n maxHeight: '100%',\n color: '#FFF',\n },\n titleStyle: {\n fontSize: 16,\n fontWeight: 'bold',\n // whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n detailsButtonStyle: {\n right: 20,\n bottom: -20,\n position: 'absolute',\n },\n bodyStyle: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n },\n deviceInfoStyle: {\n padding: '20px 16px 0 16px',\n },\n statusStyle: {\n padding: '15px 25px 0 15px',\n // The line may grow if the device provides custom indicators, so only the minimum is fixed\n minHeight: 41,\n },\n};\n\nfunction NoImageIcon(props: { style?: React.CSSProperties; className?: string }): JSX.Element {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n style={props.style}\n className={props.className}\n >\n <path\n fill=\"currentColor\"\n d=\"M21.9,21.9l-8.49-8.49l0,0L3.59,3.59l0,0L2.1,2.1L0.69,3.51L3,5.83V19c0,1.1,0.9,2,2,2h13.17l2.31,2.31L21.9,21.9z M5,18 l3.5-4.5l2.5,3.01L12.17,15l3,3H5z M21,18.17L5.83,3H19c1.1,0,2,0.9,2,2V18.17z\"\n />\n </svg>\n );\n}\n\ninterface DeviceCardProps {\n /* Device ID */\n id: DeviceId;\n identifierLabel: ioBroker.StringOrTranslated;\n device: DeviceInfo;\n /**\n * The device fields resolved by the list. They may be bound to a state or an object, and the\n * list resolves them centrally: a card that is not rendered cannot resolve its own name, and\n * the filter of the list needs the values of all devices, not only of the rendered ones.\n */\n fields: ResolvedDeviceFields;\n /** Handler of the whole list, so that identical states/objects are only subscribed once */\n stateOrObjectHandler: StateOrObjectHandler;\n instanceId: string;\n socket: Connection;\n /* Instance, where the images should be uploaded to */\n uploadImagesToInstance?: string;\n deviceHandler: (deviceId: DeviceId, action: ActionBase) => () => void;\n controlHandler: (\n deviceId: DeviceId,\n control: ControlBase,\n state: ControlState,\n ) => () => Promise<ioBroker.State | null>;\n controlStateHandler: (deviceId: DeviceId, control: ControlBase) => () => Promise<ioBroker.State | null>;\n smallCards?: boolean;\n /** The card is rendered inside a container that already has the footprint of a card */\n fillContainer?: boolean;\n alive: boolean;\n themeName: ThemeName;\n themeType: ThemeType;\n theme: IobTheme;\n isFloatComma: boolean;\n dateFormat: string;\n /** IDs of configurable indicators the user has switched off */\n hiddenIndicators?: string[];\n}\n\ninterface DeviceCardState {\n open: boolean;\n details: DeviceDetails | null;\n data: Record<string, any>;\n showControlDialog: boolean;\n /** Icon read from the file storage or picked by the user. Overrides `fields.icon` */\n localIcon?: string;\n}\n\n/**\n * Device Card Component.\n *\n * A `PureComponent`: the list re-renders on every loading step, on every filter change and on every\n * resolved device value. Without the shallow property comparison all cards would be re-rendered\n * every time, so all properties the list passes down are kept stable there.\n */\nexport default class DeviceCard extends PureComponent<DeviceCardProps, DeviceCardState> {\n /** True as long as the component is mounted; guards the asynchronous icon loading */\n private mounted = false;\n\n constructor(props: DeviceCardProps) {\n super(props);\n\n const cacheKey = DeviceCard.iconCacheKey(props);\n\n this.state = {\n open: false,\n details: null,\n data: {},\n showControlDialog: false,\n // Take a known icon over directly, so a card that is scrolled back into view does not flicker\n localIcon: cacheKey ? fileIconCache.get(cacheKey) : undefined,\n };\n }\n\n /**\n * Key of the icon in the file storage, or `null` if the device brings its own icon.\n *\n * The file is named after manufacturer and model, both of which may be bound to a state or an\n * object and therefore arrive only after the first render.\n */\n private static iconCacheKey(props: DeviceCardProps): string | null {\n if (props.device.icon) {\n return null;\n }\n const manufacturer = props.fields.manufacturer;\n const model = props.fields.model;\n const fileName = `${manufacturer ? `${manufacturer}_` : ''}${model || JSON.stringify(props.device.id)}`;\n return `${props.instanceId.replace('system.adapter.', '')}/${fileName}.webp`;\n }\n\n async fetchIcon(): Promise<void> {\n const cacheKey = DeviceCard.iconCacheKey(this.props);\n if (cacheKey) {\n const cached = fileIconCache.get(cacheKey);\n if (cached !== undefined) {\n if (this.state.localIcon !== cached) {\n this.setState({ localIcon: cached });\n }\n return;\n }\n\n const [adapter, ...rest] = cacheKey.split('/');\n try {\n const file = await this.props.socket.readFile(adapter, rest.join('/'), true);\n const localIcon = file ? `data:${file.mimeType};base64,${file.file}` : '';\n fileIconCache.set(cacheKey, localIcon);\n if (!this.mounted) {\n return;\n }\n this.setState({ localIcon });\n // const response = await fetch(url);\n // if (response.ok) {\n // const blob = await response.blob();\n // const reader = new FileReader();\n // reader.onloadend = () => {\n // setIcon(reader.result);\n // };\n // reader.readAsDataURL(blob);\n // } else {\n // throw new Error('Response not ok');\n // }\n } catch {\n fileIconCache.set(cacheKey, '');\n if (this.mounted && this.state.localIcon) {\n this.setState({ localIcon: '' });\n }\n }\n }\n }\n\n componentDidMount(): void {\n this.mounted = true;\n void this.fetchIcon().catch(e => console.error(e));\n }\n\n componentDidUpdate(prevProps: DeviceCardProps): void {\n // The icon is looked up in the file storage under `<manufacturer>_<model>`. Both may be bound\n // to a state or an object and therefore arrive only after the first render.\n if (\n prevProps.fields.manufacturer !== this.props.fields.manufacturer ||\n prevProps.fields.model !== this.props.fields.model ||\n prevProps.device.icon !== this.props.device.icon\n ) {\n void this.fetchIcon().catch(e => console.error(e));\n }\n }\n\n componentWillUnmount(): void {\n this.mounted = false;\n }\n\n /**\n * Load the device details\n */\n async loadDetails(): Promise<void> {\n console.log(`Loading device details for`, this.props.device.id, `... from ${this.props.instanceId}`);\n const details: DeviceDetails | null = await this.props.socket.sendTo(\n this.props.instanceId,\n 'dm:deviceDetails',\n this.props.device.id,\n );\n console.log(`Got device details for`, this.props.device.id, details);\n this.setState({ details, data: details?.data || {} });\n }\n\n /**\n * Copy the device ID to the clipboard\n */\n copyToClipboard = (): void => {\n const textToCopy = this.props.fields.identifier;\n if (!textToCopy) {\n return;\n }\n Utils.copyToClipboard(textToCopy);\n alert(`${getTranslation('copied')} ${textToCopy} ${getTranslation('toClipboard')}!`);\n };\n\n renderDialog(): JSX.Element | null {\n if (!this.state.open || !this.state.details) {\n return null;\n }\n\n return (\n <Dialog\n open={!0}\n maxWidth=\"md\"\n onClose={() => this.setState({ open: false })}\n >\n <DialogContent>\n <JsonConfig\n instanceId={this.props.instanceId}\n socket={this.props.socket}\n schema={this.state.details.schema}\n data={this.state.data}\n onChange={(data: Record<string, any> | null) => data && this.setState({ data })}\n themeName={this.props.themeName}\n themeType={this.props.themeType}\n theme={this.props.theme}\n isFloatComma={this.props.isFloatComma}\n dateFormat={this.props.dateFormat}\n />\n </DialogContent>\n <DialogActions>\n <Button\n disabled={!this.props.alive}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => this.setState({ open: false })}\n autoFocus\n >\n {getTranslation('closeButtonText')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n }\n\n renderControlItems(\n controls: DeviceControl[],\n allControls: DeviceControl[],\n colors: { primary: string; secondary: string },\n parentGroupId?: string,\n ): JSX.Element[] {\n return controls\n .filter(control => (parentGroupId ? control.group === parentGroupId : !control.group))\n .map(control => {\n if (control.type === 'group') {\n const children = allControls.filter(ctrl => ctrl.group === control.id);\n return (\n <Accordion key={control.id}>\n <AccordionSummary expandIcon={<ExpandMore />}>\n <Typography\n component=\"span\"\n style={{ display: 'flex', gap: 8, color: control.color }}\n >\n {control.icon ? <Icon src={control.icon} /> : null}\n {getTranslation(control.label!)}\n </Typography>\n </AccordionSummary>\n <AccordionDetails style={{ display: 'flex', flexDirection: 'column' }}>\n {this.renderControlItems(children, allControls, colors, control.id)}\n </AccordionDetails>\n </Accordion>\n );\n }\n return (\n <DeviceControlComponent\n disabled={false}\n key={control.id}\n control={control}\n socket={this.props.socket}\n colors={colors}\n deviceId={this.props.device.id}\n controlHandler={this.props.controlHandler}\n controlStateHandler={this.props.controlStateHandler}\n />\n );\n });\n }\n\n renderControlDialog(): JSX.Element | null {\n if (!this.state.showControlDialog || !this.props.alive) {\n return null;\n }\n const colors = { primary: '#111', secondary: '#888' };\n const allControls = this.props.device.controls || [];\n return (\n <Dialog\n open={!0}\n onClose={() => this.setState({ showControlDialog: false })}\n >\n <DialogTitle style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>\n {this.props.fields.name}\n <IconButton onClick={() => this.setState({ showControlDialog: false })}>\n <CloseIcon />\n </IconButton>\n </DialogTitle>\n <DialogContent style={{ display: 'flex', flexDirection: 'column' }}>\n {this.renderControlItems(allControls, allControls, colors)}\n </DialogContent>\n </Dialog>\n );\n }\n\n renderControls(): JSX.Element | null {\n const colors = { primary: '#111', secondary: '#888' };\n const firstControl = this.props.device.controls?.[0];\n if (\n this.props.device.controls?.length === 1 &&\n firstControl &&\n (firstControl.type === 'icon' || firstControl.type === 'switch') &&\n !firstControl.label\n ) {\n // control can be placed in the button icon\n return (\n <DeviceControlComponent\n disabled={!this.props.alive}\n control={firstControl}\n colors={colors}\n socket={this.props.socket}\n deviceId={this.props.device.id}\n controlHandler={this.props.controlHandler}\n controlStateHandler={this.props.controlStateHandler}\n />\n );\n }\n\n if (this.props.device.controls?.length) {\n // place a button and show a control dialog\n return (\n <Fab\n size=\"small\"\n style={{ width: 32, height: 32, minHeight: 32 }}\n disabled={!this.props.alive}\n onClick={() => this.setState({ showControlDialog: true })}\n >\n <ControlIcon />\n </Fab>\n );\n }\n return null;\n }\n\n /**\n * IDs of all actions that are not rendered as a normal button in the footer, because they\n * already have their place in the status line: the reserved actions, the actions with\n * `placement: 'status'` and the actions referenced by a custom indicator.\n */\n private getStatusActionIds(): Set<string> {\n const ids = new Set<string>([ACTIONS.STATUS, ACTIONS.ENABLE_DISABLE, ACTIONS.UPDATE, ACTIONS.BATTERY]);\n\n for (const indicator of this.props.device.indicators || []) {\n if (indicator.actionId) {\n ids.add(indicator.actionId);\n }\n }\n for (const action of this.props.device.actions || []) {\n if (action.placement === 'status') {\n ids.add(action.id);\n }\n }\n\n return ids;\n }\n\n /** True if at least one action is left for the button row at the bottom of the card */\n private hasFooterActions(): boolean {\n const statusActionIds = this.getStatusActionIds();\n return !!this.props.device.actions?.some(action => !statusActionIds.has(action.id));\n }\n\n /** Resolve how a custom indicator behaves on click by looking up the referenced action */\n private resolveIndicatorAction = (\n actionId: string,\n ): { onClick?: () => void; url?: string; disabled?: boolean } | undefined => {\n const action = this.props.device.actions?.find(a => a.id === actionId);\n if (!action) {\n console.warn(\n `Indicator of device ${JSON.stringify(this.props.device.id)} references the unknown action \"${actionId}\"`,\n );\n return undefined;\n }\n\n if ('url' in action && action.url) {\n return { url: getTranslation(action.url), disabled: action.disabled };\n }\n\n return {\n onClick: this.props.deviceHandler(this.props.device.id, action),\n disabled: action.disabled,\n };\n };\n\n /** Custom indicators and the actions that requested to be shown in the status line */\n renderIndicators(small?: boolean): JSX.Element | null {\n const reserved: string[] = [ACTIONS.STATUS, ACTIONS.ENABLE_DISABLE, ACTIONS.UPDATE, ACTIONS.BATTERY];\n const statusActions: DeviceAction[] =\n this.props.device.actions?.filter(a => a.placement === 'status' && !reserved.includes(a.id)) || [];\n\n // An indicator switched off by the user is not shown at all. An action referenced by it stays\n // out of the footer too, as hiding the indicator was an explicit decision of the user.\n const indicators = this.props.hiddenIndicators?.length\n ? this.props.device.indicators?.filter(indicator => !this.props.hiddenIndicators!.includes(indicator.id))\n : this.props.device.indicators;\n\n if (!indicators?.length && !statusActions.length) {\n return null;\n }\n\n return (\n <StatusIndicators\n indicators={indicators}\n theme={this.props.theme}\n stateOrObjectHandler={this.props.stateOrObjectHandler}\n disabled={!this.props.alive}\n resolveAction={this.resolveIndicatorAction}\n style={{ marginTop: small ? 2 : 4 }}\n >\n {statusActions.map(action => (\n <DeviceActionButton\n disabled={!this.props.alive}\n key={action.id}\n deviceId={this.props.device.id}\n action={action}\n deviceHandler={this.props.deviceHandler}\n />\n ))}\n </StatusIndicators>\n );\n }\n\n renderActions(): JSX.Element[] | null {\n const statusActionIds = this.getStatusActionIds();\n const actions = this.props.device.actions?.filter(a => !statusActionIds.has(a.id));\n\n return actions?.length\n ? actions.map(a => (\n <DeviceActionButton\n disabled={!this.props.alive}\n key={a.id}\n deviceId={this.props.device.id}\n action={a}\n deviceHandler={this.props.deviceHandler}\n />\n ))\n : null;\n }\n\n renderSmall(): JSX.Element {\n const status = !this.props.device.status\n ? []\n : Array.isArray(this.props.device.status)\n ? this.props.device.status\n : [this.props.device.status];\n\n const iconSrc = this.state.localIcon || this.props.fields.icon;\n const icon = iconSrc ? (\n <DeviceTypeIcon\n src={iconSrc}\n style={styles.imgStyle}\n />\n ) : (\n <NoImageIcon style={styles.imgStyle} />\n );\n const headerStyle = this.getCardHeaderStyle(this.props.theme);\n\n const title: string = this.state.details?.data?.name || this.props.device.name || '';\n\n return (\n <Paper\n style={this.props.fillContainer ? filledCardSize : smallCardSize}\n sx={styles.cardStyle}\n >\n {/* Header */}\n <Box\n sx={headerStyle}\n style={{ ...styles.headerStyle, minHeight: 48 }}\n >\n <div style={{ ...styles.imgAreaStyle, height: 32, width: 32 }}>\n {this.props.uploadImagesToInstance ? (\n <DeviceImageUpload\n uploadImagesToInstance={this.props.uploadImagesToInstance}\n deviceId={this.props.device.id}\n manufacturer={this.props.fields.manufacturer}\n model={this.props.fields.model}\n onImageSelect={(imageData: string): void => {\n if (imageData) {\n this.setState({ localIcon: imageData });\n }\n }}\n socket={this.props.socket}\n />\n ) : null}\n {icon}\n </div>\n <Box\n style={{ ...styles.titleStyle, fontSize: 14 }}\n title={title.length > 15 ? title : undefined}\n sx={theme => ({ color: headerStyle.color || theme.palette.secondary.contrastText })}\n >\n {this.state.details?.data?.name || this.props.fields.name}\n </Box>\n {this.props.fields.hasDetails ? (\n <Fab\n disabled={!this.props.alive}\n size=\"small\"\n style={styles.detailsButtonStyle}\n onClick={() => {\n if (!this.state.open) {\n this.loadDetails().catch(console.error);\n this.setState({ open: true });\n }\n }}\n color=\"primary\"\n >\n <MoreVertIcon />\n </Fab>\n ) : null}\n </Box>\n {/* Status */}\n <div style={{ ...styles.statusStyle, height: 'auto', padding: '8px 15px 0 15px' }}>\n {status.map((s, i) => (\n <DeviceStatusComponent\n key={i}\n socket={this.props.socket}\n deviceId={this.props.device.id}\n connectionType={this.props.fields.connectionType}\n status={s}\n enabled={this.props.fields.enabled}\n statusAction={this.props.device.actions?.find(a => a.id === ACTIONS.STATUS)}\n disableEnableAction={this.props.device.actions?.find(a => a.id === ACTIONS.ENABLE_DISABLE)}\n update={i === 0 ? this.props.device.update : undefined}\n updateAction={\n i === 0 ? this.props.device.actions?.find(a => a.id === ACTIONS.UPDATE) : undefined\n }\n batteryAction={this.props.device.actions?.find(a => a.id === ACTIONS.BATTERY)}\n deviceHandler={this.props.deviceHandler}\n theme={this.props.theme}\n stateOrObjectHandler={this.props.stateOrObjectHandler}\n />\n ))}\n {this.renderIndicators(true)}\n </div>\n {/* Body */}\n <div style={styles.bodyStyle}>\n <Typography\n variant=\"body2\"\n style={{ ...styles.deviceInfoStyle, padding: '10px 10px 0 10px' }}\n >\n {this.props.fields.identifier ? (\n <div\n onClick={this.copyToClipboard}\n style={{ textOverflow: 'ellipsis', overflow: 'hidden' }}\n >\n <b>{getText(this.props.identifierLabel)}:</b>\n <span style={{ marginLeft: 4 }}>{this.props.fields.identifier}</span>\n </div>\n ) : null}\n {this.props.fields.manufacturer ? (\n <Tooltip\n title={getTranslation('manufacturer')}\n slotProps={{ popper: { sx: { pointerEvents: 'none' } } }}\n >\n <div>{this.props.fields.manufacturer}</div>\n </Tooltip>\n ) : null}\n {this.props.fields.model ? (\n <Tooltip\n title={getTranslation('model')}\n slotProps={{ popper: { sx: { pointerEvents: 'none' } } }}\n >\n <div>{this.props.fields.model}</div>\n </Tooltip>\n ) : null}\n </Typography>\n {this.props.device.customInfo ? (\n // The bottom padding is not symmetry for its own sake: the footer below is\n // only rendered when the device has actions or controls, so without it the\n // last row would sit flush on the card's lower edge.\n <div style={{ padding: '0 10px 10px' }}>\n <JsonConfig\n instanceId={this.props.instanceId}\n socket={this.props.socket}\n schema={this.props.device.customInfo.schema}\n data={this.props.device.customInfo.data || {}}\n onChange={(_data: Record<string, any> | null) => {\n /* ignore */\n }}\n themeName={this.props.themeName}\n themeType={this.props.themeType}\n theme={this.props.theme}\n isFloatComma={this.props.isFloatComma}\n dateFormat={this.props.dateFormat}\n />\n </div>\n ) : null}\n {/* Footer */}\n {!!(this.hasFooterActions() || this.props.device.controls?.length) && (\n <div\n style={{\n marginTop: 'auto',\n display: 'flex',\n gap: 4,\n paddingBottom: 5,\n minHeight: 34,\n paddingLeft: 8,\n paddingRight: 8,\n }}\n >\n {this.renderActions()}\n <div style={{ flexGrow: 1 }} />\n {this.renderControls()}\n </div>\n )}\n </div>\n {this.renderDialog()}\n {this.renderControlDialog()}\n </Paper>\n );\n }\n\n getCardHeaderStyle(theme: IobTheme, maxWidth?: number): React.CSSProperties {\n const backgroundColor =\n this.props.fields.backgroundColor === 'primary'\n ? theme.palette.primary.main\n : this.props.fields.backgroundColor === 'secondary'\n ? theme.palette.secondary.main\n : this.props.fields.backgroundColor || theme.palette.secondary.main;\n\n let color;\n if (\n this.props.fields.color &&\n this.props.fields.color !== 'primary' &&\n this.props.fields.color !== 'secondary'\n ) {\n // Color was directly defined\n color = this.props.fields.color;\n } else if (this.props.fields.color === 'primary') {\n color = theme.palette.primary.main;\n } else if (this.props.fields.color === 'secondary') {\n color = theme.palette.secondary.main;\n } else {\n // Color was not defined\n if (this.props.fields.backgroundColor === 'primary') {\n color = theme.palette.primary.contrastText;\n } else if (this.props.fields.backgroundColor === 'secondary' || !this.props.fields.backgroundColor) {\n color = theme.palette.secondary.contrastText;\n } else {\n color = Utils.invertColor(backgroundColor, true);\n }\n }\n\n return {\n backgroundColor,\n color,\n maxWidth,\n };\n }\n\n renderBig(): JSX.Element {\n const status = !this.props.device.status\n ? []\n : Array.isArray(this.props.device.status)\n ? this.props.device.status\n : [this.props.device.status];\n\n const iconSrc = this.state.localIcon || this.props.fields.icon;\n const icon = iconSrc ? (\n <DeviceTypeIcon\n src={iconSrc}\n style={styles.imgStyle}\n />\n ) : (\n <NoImageIcon style={styles.imgStyle} />\n );\n const headerStyle = this.getCardHeaderStyle(this.props.theme);\n\n const title: string = this.state.details?.data?.name || this.props.device.name || '';\n\n return (\n <Paper\n style={this.props.fillContainer ? filledCardSize : cardSize}\n sx={styles.cardStyle}\n >\n {/* Header */}\n <Box\n sx={headerStyle}\n style={styles.headerStyle}\n >\n <div style={styles.imgAreaStyle}>\n {this.props.uploadImagesToInstance ? (\n <DeviceImageUpload\n uploadImagesToInstance={this.props.uploadImagesToInstance}\n deviceId={this.props.device.id}\n manufacturer={this.props.fields.manufacturer}\n model={this.props.fields.model}\n onImageSelect={(imageData: string): void => {\n if (imageData) {\n this.setState({ localIcon: imageData });\n }\n }}\n socket={this.props.socket}\n />\n ) : null}\n {icon}\n </div>\n <Box\n style={styles.titleStyle}\n title={title.length > 20 ? title : undefined}\n sx={theme => ({ color: headerStyle.color || theme.palette.secondary.contrastText })}\n >\n {this.state.details?.data?.name || this.props.fields.name}\n </Box>\n {this.props.fields.hasDetails ? (\n <Fab\n disabled={!this.props.alive}\n size=\"small\"\n style={styles.detailsButtonStyle}\n onClick={() => {\n if (!this.state.open) {\n this.loadDetails().catch(console.error);\n this.setState({ open: true });\n }\n }}\n color=\"primary\"\n >\n <MoreVertIcon />\n </Fab>\n ) : null}\n </Box>\n {/* Body */}\n <div style={styles.statusStyle}>\n {status.map((s, i) => (\n <DeviceStatusComponent\n key={i}\n socket={this.props.socket}\n deviceId={this.props.device.id}\n connectionType={this.props.fields.connectionType}\n status={s}\n enabled={this.props.fields.enabled}\n statusAction={this.props.device.actions?.find(a => a.id === ACTIONS.STATUS)}\n disableEnableAction={this.props.device.actions?.find(a => a.id === ACTIONS.ENABLE_DISABLE)}\n update={i === 0 ? this.props.device.update : undefined}\n updateAction={\n i === 0 ? this.props.device.actions?.find(a => a.id === ACTIONS.UPDATE) : undefined\n }\n batteryAction={this.props.device.actions?.find(a => a.id === ACTIONS.BATTERY)}\n deviceHandler={this.props.deviceHandler}\n theme={this.props.theme}\n stateOrObjectHandler={this.props.stateOrObjectHandler}\n />\n ))}\n {this.renderIndicators()}\n </div>\n <div style={styles.bodyStyle}>\n <Typography\n variant=\"body1\"\n style={styles.deviceInfoStyle}\n >\n {this.props.fields.identifier ? (\n <div onClick={this.copyToClipboard}>\n <b style={{ marginRight: 4 }}>{getText(this.props.identifierLabel)}:</b>\n {this.props.fields.identifier}\n </div>\n ) : null}\n {this.props.fields.manufacturer ? (\n <div>\n <b style={{ marginRight: 4 }}>{getTranslation('manufacturer')}:</b>\n {this.props.fields.manufacturer}\n </div>\n ) : null}\n {this.props.fields.model ? (\n <div>\n <b style={{ marginRight: 4 }}>{getTranslation('model')}:</b>\n {this.props.fields.model}\n </div>\n ) : null}\n </Typography>\n {this.props.device.customInfo ? (\n // See the compact card above — the footer that used to provide the gap is\n // conditional, so the padding has to be here.\n <div style={{ padding: '0 16px 16px' }}>\n <JsonConfig\n instanceId={this.props.instanceId}\n socket={this.props.socket}\n schema={this.props.device.customInfo.schema}\n data={this.props.device.customInfo.data || {}}\n onChange={(_data: Record<string, any> | null) => {\n /* ignore */\n }}\n themeName={this.props.themeName}\n themeType={this.props.themeType}\n theme={this.props.theme}\n isFloatComma={this.props.isFloatComma}\n dateFormat={this.props.dateFormat}\n />\n </div>\n ) : null}\n {/* Footer */}\n {!!(this.hasFooterActions() || this.props.device.controls?.length) && (\n <div\n style={{\n marginTop: 'auto',\n display: 'flex',\n gap: 8,\n paddingBottom: 5,\n minHeight: 34,\n paddingLeft: 10,\n paddingRight: 10,\n }}\n >\n {this.renderActions()}\n <div style={{ flexGrow: 1 }} />\n {this.renderControls()}\n </div>\n )}\n </div>\n {this.renderDialog()}\n {this.renderControlDialog()}\n </Paper>\n );\n }\n\n render(): JSX.Element {\n if (this.props.smallCards) {\n return this.renderSmall();\n }\n\n return this.renderBig();\n }\n}\n\ntype DeviceCardSkeletonProps = Pick<DeviceCardProps, 'smallCards' | 'theme'>;\n\nexport class DeviceCardSkeleton extends PureComponent<DeviceCardSkeletonProps> {\n render(): JSX.Element {\n if (this.props.smallCards) {\n return this.renderSmall();\n }\n\n return this.renderBig();\n }\n\n renderSmall(): JSX.Element {\n const headerStyle = this.getCardHeaderStyle(this.props.theme);\n\n return (\n <Paper\n sx={styles.cardStyle}\n style={smallCardSize}\n >\n <Box\n sx={headerStyle}\n style={{ ...styles.headerStyle, minHeight: 48 }}\n >\n <div style={{ ...styles.imgAreaStyle, height: 32, width: 32 }}>\n <Skeleton\n variant=\"rounded\"\n width={24}\n height={24}\n />\n </div>\n <Box\n style={{ ...styles.titleStyle, fontSize: 14, minWidth: '50%' }}\n sx={theme => ({\n color: headerStyle.color || theme.palette.secondary.contrastText,\n })}\n >\n <Skeleton />\n </Box>\n </Box>\n <div style={{ ...styles.statusStyle, height: 'auto', padding: '8px 15px 0 15px' }} />\n <div style={styles.bodyStyle}>\n <Typography\n variant=\"body2\"\n style={{ ...styles.deviceInfoStyle, padding: '10px 10px 0 10px' }}\n >\n <div>\n <Skeleton />\n </div>\n <div>\n <Skeleton />\n </div>\n <div>\n <Skeleton />\n </div>\n </Typography>\n </div>\n </Paper>\n );\n }\n\n renderBig(): JSX.Element {\n const headerStyle = this.getCardHeaderStyle(this.props.theme);\n\n return (\n <Paper\n sx={styles.cardStyle}\n style={cardSize}\n >\n <Box\n sx={headerStyle}\n style={styles.headerStyle}\n >\n <div style={styles.imgAreaStyle}>\n <Skeleton\n variant=\"rounded\"\n width={24}\n height={24}\n />\n </div>\n <Box\n style={styles.titleStyle}\n sx={theme => ({\n color: headerStyle.color || theme.palette.secondary.contrastText,\n minWidth: '50%',\n })}\n >\n <Skeleton />\n </Box>\n </Box>\n <div style={styles.statusStyle}></div>\n <div style={styles.bodyStyle}>\n <Typography\n variant=\"body1\"\n style={styles.deviceInfoStyle}\n >\n <div>\n <Skeleton />\n </div>\n <div>\n <Skeleton />\n </div>\n <div>\n <Skeleton />\n </div>\n </Typography>\n </div>\n </Paper>\n );\n }\n\n // eslint-disable-next-line class-methods-use-this\n getCardHeaderStyle(theme: IobTheme, maxWidth?: number): React.CSSProperties {\n const backgroundColor = theme.palette.secondary.main;\n const color = theme.palette.secondary.contrastText;\n\n return {\n backgroundColor,\n color,\n maxWidth,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"DeviceCard.js","sourceRoot":"./src/","sources":["DeviceCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { PureComponent, useState, type JSX } from 'react';\nimport { Close as CloseIcon, VideogameAsset as ControlIcon, MoreVert as MoreVertIcon } from '@mui/icons-material';\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n IconButton,\n Skeleton,\n Tooltip,\n Typography,\n Accordion,\n AccordionSummary,\n AccordionDetails,\n} from '@mui/material';\n\nimport {\n DeviceTypeIcon,\n Utils,\n type Connection,\n type IobTheme,\n type ThemeName,\n type ThemeType,\n Icon,\n IconCopyToClipboard,\n IconFolder,\n} from '@iobroker/gui-components';\nimport DeviceActionButton from './DeviceActionButton';\nimport DeviceControlComponent from './DeviceControl';\nimport DeviceImageUpload from './DeviceImageUpload';\nimport DeviceStatusComponent, { DeviceLed } from './DeviceStatus';\nimport JsonConfig from './JsonConfig';\nimport { StatusIndicators } from './StatusIndicator';\nimport Switch from './Switch';\nimport type {\n ActionBase,\n ControlBase,\n ControlState,\n DeviceDetails,\n DeviceAction,\n DeviceControl,\n DeviceInfo,\n DeviceId,\n DeviceStatus,\n} from './protocol/api';\n\nimport { getText, getTranslation } from './Utils';\nimport { ensureDmStyles, getThemeVars } from './styles';\nimport type { StateOrObjectHandler } from './StateOrObjectHandler';\nimport type { ResolvedDeviceFields } from './DeviceFields';\n\n// The type moved to `DeviceFields` together with the filtering itself. Re-exported here, because it\n// used to be exported from this module.\nexport type { DeviceFilterField } from './DeviceFields';\n\n/** Reserved action names (this is copied from https://github.com/ioBroker/dm-utils/blob/main/src/types/base.ts as we can only have type references to dm-utils) */\nconst ACTIONS = {\n /** This action will be called when the user clicks on the connection icon */\n STATUS: 'status',\n /** This action will be called when the user clicks on the enabled / disabled icon. The enabled/disabled icon will be shown only if the node status has the \"enabled\" flag set to false or true */\n ENABLE_DISABLE: 'enable/disable',\n /** This action will be called when the user clicks on the update indicator. The update indicator is shown only if `DeviceInfo.update.available` is true */\n UPDATE: 'update',\n /** This action will be called when the user clicks on the battery indicator. The battery indicator is shown only if the node status has the \"battery\" property */\n BATTERY: 'battery',\n};\n\n/**\n * Footprint of a card. The list needs it to give a not yet rendered card a placeholder of exactly\n * the same size, so that neither the layout nor the length of the scrollbar changes.\n */\nexport const CARD_WIDTH = 300;\nexport const CARD_MIN_HEIGHT = 250;\nexport const CARD_MARGIN = 8;\n\nexport const SMALL_CARD_WIDTH = 210;\nexport const SMALL_CARD_MIN_HEIGHT = 190;\nexport const SMALL_CARD_MARGIN = 5;\n\nconst cardSize: React.CSSProperties = { width: CARD_WIDTH, minHeight: CARD_MIN_HEIGHT, margin: CARD_MARGIN };\nconst smallCardSize: React.CSSProperties = {\n width: SMALL_CARD_WIDTH,\n minHeight: SMALL_CARD_MIN_HEIGHT,\n margin: SMALL_CARD_MARGIN,\n};\n/** A card that sits in a container which already has the footprint of a card */\nconst filledCardSize: React.CSSProperties = { width: '100%', margin: 0 };\n\nconst tooltipSlotProps = { popper: { sx: { pointerEvents: 'none' } } };\n\n/**\n * Icons read from the file storage of the adapter, keyed by `<instance>/<file>`.\n *\n * A card is unmounted and mounted again while scrolling, and without this cache every one of those\n * would repeat the `readFile` round trip for an icon that is very often not there at all.\n */\nconst fileIconCache = new Map<string, string>();\n\n/**\n * True if the icon is a picture (a photo of the device, an uploaded image). A picture keeps its own\n * colors and sits on a neutral tile; a device type or a symbol takes the color of the device.\n */\nfunction isPicture(src: string): boolean {\n if (src.startsWith('data:image/svg')) {\n return false;\n }\n return src.startsWith('data:image') || src.includes('/') || /\\.(png|jpe?g|gif|webp|ico|bmp)$/i.test(src);\n}\n\n/** The status entries of a device as a list */\nfunction getStatusList(device: DeviceInfo): DeviceStatus[] {\n if (!device.status) {\n return [];\n }\n return Array.isArray(device.status) ? device.status : [device.status];\n}\n\n/** A group of controls in the control dialog: the folder opens with the group */\nfunction ControlGroup(props: { control: DeviceControl; children: React.ReactNode }): JSX.Element {\n const [expanded, setExpanded] = useState(false);\n const { control } = props;\n return (\n <Accordion\n expanded={expanded}\n onChange={(_e, isExpanded) => setExpanded(isExpanded)}\n disableGutters\n >\n <AccordionSummary\n expandIcon={<IconFolder open={expanded} />}\n // The folder shows the state itself, it must not be turned around like the arrow\n sx={{ '& .MuiAccordionSummary-expandIconWrapper.Mui-expanded': { transform: 'none' } }}\n >\n <Typography\n component=\"span\"\n style={{ display: 'flex', alignItems: 'center', gap: 8, color: control.color }}\n >\n {control.icon ? <Icon src={control.icon} /> : null}\n {getTranslation(control.label!)}\n </Typography>\n </AccordionSummary>\n <AccordionDetails style={{ display: 'flex', flexDirection: 'column' }}>{props.children}</AccordionDetails>\n </Accordion>\n );\n}\n\ninterface DeviceCardProps {\n /* Device ID */\n id: DeviceId;\n identifierLabel: ioBroker.StringOrTranslated;\n device: DeviceInfo;\n /**\n * The device fields resolved by the list. They may be bound to a state or an object, and the\n * list resolves them centrally: a card that is not rendered cannot resolve its own name, and\n * the filter of the list needs the values of all devices, not only of the rendered ones.\n */\n fields: ResolvedDeviceFields;\n /** Handler of the whole list, so that identical states/objects are only subscribed once */\n stateOrObjectHandler: StateOrObjectHandler;\n instanceId: string;\n socket: Connection;\n /* Instance, where the images should be uploaded to */\n uploadImagesToInstance?: string;\n deviceHandler: (deviceId: DeviceId, action: ActionBase) => () => void;\n controlHandler: (\n deviceId: DeviceId,\n control: ControlBase,\n state: ControlState,\n ) => () => Promise<ioBroker.State | null>;\n controlStateHandler: (deviceId: DeviceId, control: ControlBase) => () => Promise<ioBroker.State | null>;\n smallCards?: boolean;\n /** The card is rendered inside a container that already has the footprint of a card */\n fillContainer?: boolean;\n alive: boolean;\n themeName: ThemeName;\n themeType: ThemeType;\n theme: IobTheme;\n isFloatComma: boolean;\n dateFormat: string;\n /** IDs of configurable indicators the user has switched off */\n hiddenIndicators?: string[];\n}\n\ninterface DeviceCardState {\n open: boolean;\n details: DeviceDetails | null;\n data: Record<string, any>;\n showControlDialog: boolean;\n /** Icon read from the file storage or picked by the user. Overrides `fields.icon` */\n localIcon?: string;\n}\n\n/**\n * Device Card Component.\n *\n * The card is laid out like the type plate of a device: its symbol (in the color of the device, with\n * an LED for the connection) and its name at the top, the status line below, then the facts and at\n * the bottom the actions. The status values are neutral while all is well and tinted when they need\n * attention, so that in a long list the devices with a problem stand out.\n *\n * A `PureComponent`: the list re-renders on every loading step, on every filter change and on every\n * resolved device value. Without the shallow property comparison all cards would be re-rendered\n * every time, so all properties the list passes down are kept stable there.\n */\nexport default class DeviceCard extends PureComponent<DeviceCardProps, DeviceCardState> {\n /** True as long as the component is mounted; guards the asynchronous icon loading */\n private mounted = false;\n\n constructor(props: DeviceCardProps) {\n super(props);\n ensureDmStyles();\n\n const cacheKey = DeviceCard.iconCacheKey(props);\n\n this.state = {\n open: false,\n details: null,\n data: {},\n showControlDialog: false,\n // Take a known icon over directly, so a card that is scrolled back into view does not flicker\n localIcon: cacheKey ? fileIconCache.get(cacheKey) : undefined,\n };\n }\n\n /**\n * Key of the icon in the file storage, or `null` if the device brings its own icon.\n *\n * The file is named after manufacturer and model, both of which may be bound to a state or an\n * object and therefore arrive only after the first render.\n */\n private static iconCacheKey(props: DeviceCardProps): string | null {\n if (props.device.icon) {\n return null;\n }\n const manufacturer = props.fields.manufacturer;\n const model = props.fields.model;\n const fileName = `${manufacturer ? `${manufacturer}_` : ''}${model || JSON.stringify(props.device.id)}`;\n return `${props.instanceId.replace('system.adapter.', '')}/${fileName}.webp`;\n }\n\n async fetchIcon(): Promise<void> {\n const cacheKey = DeviceCard.iconCacheKey(this.props);\n if (cacheKey) {\n const cached = fileIconCache.get(cacheKey);\n if (cached !== undefined) {\n if (this.state.localIcon !== cached) {\n this.setState({ localIcon: cached });\n }\n return;\n }\n\n const [adapter, ...rest] = cacheKey.split('/');\n try {\n const file = await this.props.socket.readFile(adapter, rest.join('/'), true);\n const localIcon = file ? `data:${file.mimeType};base64,${file.file}` : '';\n fileIconCache.set(cacheKey, localIcon);\n if (!this.mounted) {\n return;\n }\n this.setState({ localIcon });\n } catch {\n fileIconCache.set(cacheKey, '');\n if (this.mounted && this.state.localIcon) {\n this.setState({ localIcon: '' });\n }\n }\n }\n }\n\n componentDidMount(): void {\n this.mounted = true;\n void this.fetchIcon().catch(e => console.error(e));\n }\n\n componentDidUpdate(prevProps: DeviceCardProps): void {\n // The icon is looked up in the file storage under `<manufacturer>_<model>`. Both may be bound\n // to a state or an object and therefore arrive only after the first render.\n if (\n prevProps.fields.manufacturer !== this.props.fields.manufacturer ||\n prevProps.fields.model !== this.props.fields.model ||\n prevProps.device.icon !== this.props.device.icon\n ) {\n void this.fetchIcon().catch(e => console.error(e));\n }\n }\n\n componentWillUnmount(): void {\n this.mounted = false;\n }\n\n /**\n * Load the device details\n */\n async loadDetails(): Promise<void> {\n console.log(`Loading device details for`, this.props.device.id, `... from ${this.props.instanceId}`);\n const details: DeviceDetails | null = await this.props.socket.sendTo(\n this.props.instanceId,\n 'dm:deviceDetails',\n this.props.device.id,\n );\n console.log(`Got device details for`, this.props.device.id, details);\n this.setState({ details, data: details?.data || {} });\n }\n\n /**\n * Copy the device ID to the clipboard. The copy symbol shows a check mark as confirmation.\n */\n copyToClipboard = (): void => {\n const textToCopy = this.props.fields.identifier;\n if (textToCopy) {\n Utils.copyToClipboard(textToCopy);\n }\n };\n\n renderDialog(): JSX.Element | null {\n if (!this.state.open || !this.state.details) {\n return null;\n }\n\n return (\n <Dialog\n open={!0}\n maxWidth=\"md\"\n onClose={() => this.setState({ open: false })}\n >\n <DialogContent>\n <JsonConfig\n instanceId={this.props.instanceId}\n socket={this.props.socket}\n schema={this.state.details.schema}\n data={this.state.data}\n onChange={(data: Record<string, any> | null) => data && this.setState({ data })}\n themeName={this.props.themeName}\n themeType={this.props.themeType}\n theme={this.props.theme}\n isFloatComma={this.props.isFloatComma}\n dateFormat={this.props.dateFormat}\n />\n </DialogContent>\n <DialogActions>\n <Button\n disabled={!this.props.alive}\n variant=\"contained\"\n color=\"primary\"\n onClick={() => this.setState({ open: false })}\n autoFocus\n >\n {getTranslation('closeButtonText')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n }\n\n renderControlItems(\n controls: DeviceControl[],\n allControls: DeviceControl[],\n colors: { primary: string; secondary: string },\n parentGroupId?: string,\n ): JSX.Element[] {\n return controls\n .filter(control => (parentGroupId ? control.group === parentGroupId : !control.group))\n .map(control => {\n if (control.type === 'group') {\n const children = allControls.filter(ctrl => ctrl.group === control.id);\n return (\n <ControlGroup\n key={control.id}\n control={control}\n >\n {this.renderControlItems(children, allControls, colors, control.id)}\n </ControlGroup>\n );\n }\n return (\n <DeviceControlComponent\n disabled={false}\n key={control.id}\n control={control}\n socket={this.props.socket}\n colors={colors}\n deviceId={this.props.device.id}\n controlHandler={this.props.controlHandler}\n controlStateHandler={this.props.controlStateHandler}\n />\n );\n });\n }\n\n renderControlDialog(): JSX.Element | null {\n if (!this.state.showControlDialog || !this.props.alive) {\n return null;\n }\n const colors = { primary: '#111', secondary: '#888' };\n const allControls = this.props.device.controls || [];\n return (\n <Dialog\n open={!0}\n onClose={() => this.setState({ showControlDialog: false })}\n >\n <DialogTitle style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>\n {this.props.fields.name}\n <IconButton onClick={() => this.setState({ showControlDialog: false })}>\n <CloseIcon />\n </IconButton>\n </DialogTitle>\n <DialogContent style={{ display: 'flex', flexDirection: 'column' }}>\n {this.renderControlItems(allControls, allControls, colors)}\n </DialogContent>\n </Dialog>\n );\n }\n\n renderControls(): JSX.Element | null {\n const colors = { primary: '#111', secondary: '#888' };\n const firstControl = this.props.device.controls?.[0];\n if (\n this.props.device.controls?.length === 1 &&\n firstControl &&\n (firstControl.type === 'icon' || firstControl.type === 'switch') &&\n !firstControl.label\n ) {\n // control can be placed in the button icon\n return (\n <DeviceControlComponent\n disabled={!this.props.alive}\n control={firstControl}\n colors={colors}\n socket={this.props.socket}\n deviceId={this.props.device.id}\n controlHandler={this.props.controlHandler}\n controlStateHandler={this.props.controlStateHandler}\n />\n );\n }\n\n if (this.props.device.controls?.length) {\n // place a button and show a control dialog\n return (\n <IconButton\n size=\"small\"\n color=\"primary\"\n disabled={!this.props.alive}\n onClick={() => this.setState({ showControlDialog: true })}\n >\n <ControlIcon className=\"dm-ani dm-ani-tick\" />\n </IconButton>\n );\n }\n return null;\n }\n\n /**\n * IDs of all actions that are not rendered as a normal button in the footer, because they\n * already have their place in the status line: the reserved actions, the actions with\n * `placement: 'status'` and the actions referenced by a custom indicator.\n */\n private getStatusActionIds(): Set<string> {\n const ids = new Set<string>([ACTIONS.STATUS, ACTIONS.ENABLE_DISABLE, ACTIONS.UPDATE, ACTIONS.BATTERY]);\n\n for (const indicator of this.props.device.indicators || []) {\n if (indicator.actionId) {\n ids.add(indicator.actionId);\n }\n }\n for (const action of this.props.device.actions || []) {\n if (action.placement === 'status') {\n ids.add(action.id);\n }\n }\n\n return ids;\n }\n\n /** True if at least one action is left for the button row at the bottom of the card */\n private hasFooterActions(): boolean {\n const statusActionIds = this.getStatusActionIds();\n return !!this.props.device.actions?.some(action => !statusActionIds.has(action.id));\n }\n\n /** Resolve how a custom indicator behaves on click by looking up the referenced action */\n private resolveIndicatorAction = (\n actionId: string,\n ): { onClick?: () => void; url?: string; disabled?: boolean } | undefined => {\n const action = this.props.device.actions?.find(a => a.id === actionId);\n if (!action) {\n console.warn(\n `Indicator of device ${JSON.stringify(this.props.device.id)} references the unknown action \"${actionId}\"`,\n );\n return undefined;\n }\n\n if ('url' in action && action.url) {\n return { url: getTranslation(action.url), disabled: action.disabled };\n }\n\n return {\n onClick: this.props.deviceHandler(this.props.device.id, action),\n disabled: action.disabled,\n };\n };\n\n /** Custom indicators and the actions that requested to be shown in the status line */\n renderIndicators(): JSX.Element | null {\n const reserved: string[] = [ACTIONS.STATUS, ACTIONS.ENABLE_DISABLE, ACTIONS.UPDATE, ACTIONS.BATTERY];\n const statusActions: DeviceAction[] =\n this.props.device.actions?.filter(a => a.placement === 'status' && !reserved.includes(a.id)) || [];\n\n // An indicator switched off by the user is not shown at all. An action referenced by it stays\n // out of the footer too, as hiding the indicator was an explicit decision of the user.\n const indicators = this.props.hiddenIndicators?.length\n ? this.props.device.indicators?.filter(indicator => !this.props.hiddenIndicators!.includes(indicator.id))\n : this.props.device.indicators;\n\n if (!indicators?.length && !statusActions.length) {\n return null;\n }\n\n return (\n <StatusIndicators\n indicators={indicators}\n theme={this.props.theme}\n stateOrObjectHandler={this.props.stateOrObjectHandler}\n disabled={!this.props.alive}\n resolveAction={this.resolveIndicatorAction}\n // The indicators flow in the status line together with the built-in values\n style={{ display: 'contents' }}\n >\n {statusActions.map(action => (\n <DeviceActionButton\n disabled={!this.props.alive}\n key={action.id}\n deviceId={this.props.device.id}\n action={action}\n deviceHandler={this.props.deviceHandler}\n />\n ))}\n </StatusIndicators>\n );\n }\n\n renderActions(): JSX.Element[] | null {\n const statusActionIds = this.getStatusActionIds();\n const actions = this.props.device.actions?.filter(a => !statusActionIds.has(a.id));\n\n return actions?.length\n ? actions.map(a => (\n <DeviceActionButton\n disabled={!this.props.alive}\n key={a.id}\n deviceId={this.props.device.id}\n action={a}\n deviceHandler={this.props.deviceHandler}\n />\n ))\n : null;\n }\n\n /** Color of the device symbol and of the glyph on it */\n getAccent(theme: IobTheme): { background: string; color: string } {\n const backgroundColor =\n this.props.fields.backgroundColor === 'primary'\n ? theme.palette.primary.main\n : this.props.fields.backgroundColor === 'secondary'\n ? theme.palette.secondary.main\n : this.props.fields.backgroundColor || theme.palette.secondary.main;\n\n let color;\n if (\n this.props.fields.color &&\n this.props.fields.color !== 'primary' &&\n this.props.fields.color !== 'secondary'\n ) {\n // Color was directly defined\n color = this.props.fields.color;\n } else if (this.props.fields.color === 'primary') {\n color = theme.palette.primary.main;\n } else if (this.props.fields.color === 'secondary') {\n color = theme.palette.secondary.main;\n } else {\n // Color was not defined\n if (this.props.fields.backgroundColor === 'primary') {\n color = theme.palette.primary.contrastText;\n } else if (this.props.fields.backgroundColor === 'secondary' || !this.props.fields.backgroundColor) {\n color = theme.palette.secondary.contrastText;\n } else {\n color = Utils.invertColor(backgroundColor, true);\n }\n }\n\n return { background: backgroundColor, color };\n }\n\n /** The device symbol with the LED and, if allowed, the image upload */\n renderAvatar(name: string, small: boolean): JSX.Element {\n const iconSrc = this.state.localIcon || this.props.fields.icon;\n const picture = !!iconSrc && isPicture(iconSrc);\n const accent = this.getAccent(this.props.theme);\n const firstStatus = getStatusList(this.props.device)[0];\n\n let glyph: JSX.Element;\n if (iconSrc) {\n // The size is given inline, because `DeviceTypeIcon` sets an inline size of its own\n const glyphSize = small ? 20 : 26;\n glyph = (\n <DeviceTypeIcon\n src={iconSrc}\n className=\"dm-avatar-glyph\"\n style={\n picture\n ? { width: '100%', height: '100%', objectFit: 'contain' }\n : { width: glyphSize, height: glyphSize, color: accent.color }\n }\n />\n );\n } else {\n // Without an icon, the initial of the name gives each device its own symbol\n glyph = <span className=\"dm-avatar-letter\">{Array.from(name.trim())[0] || '?'}</span>;\n }\n\n return (\n <div\n className={picture ? 'dm-avatar dm-avatar-img' : 'dm-avatar'}\n style={\n picture\n ? undefined\n : ({\n '--dm-accent': accent.background,\n '--dm-accent-text': accent.color,\n } as React.CSSProperties)\n }\n >\n {glyph}\n {this.props.uploadImagesToInstance ? (\n <DeviceImageUpload\n uploadImagesToInstance={this.props.uploadImagesToInstance}\n deviceId={this.props.device.id}\n manufacturer={this.props.fields.manufacturer}\n model={this.props.fields.model}\n onImageSelect={(imageData: string): void => {\n if (imageData) {\n this.setState({ localIcon: imageData });\n }\n }}\n socket={this.props.socket}\n />\n ) : null}\n {firstStatus ? (\n <DeviceLed\n status={firstStatus}\n stateOrObjectHandler={this.props.stateOrObjectHandler}\n alive={this.props.alive}\n enabled={this.props.fields.enabled}\n />\n ) : null}\n </div>\n );\n }\n\n /** The switch that enables or disables the device */\n renderEnabled(small: boolean): JSX.Element | null {\n if (typeof this.props.fields.enabled !== 'boolean') {\n return null;\n }\n const action = this.props.device.actions?.find(a => a.id === ACTIONS.ENABLE_DISABLE);\n const tooltip = this.props.fields.enabled\n ? getTranslation('disableIconTooltip')\n : getTranslation('enableIconTooltip');\n return (\n <div className=\"dm-status-end\">\n <Tooltip\n title={tooltip}\n slotProps={tooltipSlotProps}\n >\n <div>\n <Switch\n size={small ? 'small' : undefined}\n checked={this.props.fields.enabled}\n disabled={!action || !this.props.alive}\n ariaLabel={tooltip}\n onChange={() => action && this.props.deviceHandler(this.props.device.id, action)()}\n theme={this.props.theme}\n />\n </div>\n </Tooltip>\n </div>\n );\n }\n\n /** Identifier, manufacturer and model as a table of labels and values */\n renderFacts(): JSX.Element | null {\n const { identifier, manufacturer, model } = this.props.fields;\n if (!identifier && !manufacturer && !model) {\n return null;\n }\n return (\n <div className=\"dm-facts\">\n {identifier ? (\n <>\n <span className=\"dm-fact-label\">{getText(this.props.identifierLabel)}</span>\n <span className=\"dm-fact-copy\">\n <span title={identifier}>{identifier}</span>\n <Tooltip\n title={getTranslation('ctcButtonText')}\n slotProps={tooltipSlotProps}\n >\n <IconButton\n size=\"small\"\n className=\"dm-copy-btn\"\n aria-label={getTranslation('ctcButtonText')}\n onClick={this.copyToClipboard}\n >\n {/* Listens to the click on the button and draws a check mark */}\n <IconCopyToClipboard />\n </IconButton>\n </Tooltip>\n </span>\n </>\n ) : null}\n {manufacturer ? (\n <>\n <span className=\"dm-fact-label\">{getTranslation('manufacturer')}</span>\n <span\n className=\"dm-fact-value\"\n title={manufacturer}\n >\n {manufacturer}\n </span>\n </>\n ) : null}\n {model ? (\n <>\n <span className=\"dm-fact-label\">{getTranslation('model')}</span>\n <span\n className=\"dm-fact-value\"\n title={model}\n >\n {model}\n </span>\n </>\n ) : null}\n </div>\n );\n }\n\n render(): JSX.Element {\n const small = !!this.props.smallCards;\n const status = getStatusList(this.props.device);\n const name: string = this.state.details?.data?.name || this.props.fields.name || '';\n const off = this.props.fields.enabled === false;\n\n let className = small ? 'dm-card dm-small' : 'dm-card';\n if (off) {\n className += ' dm-off';\n }\n\n const size = this.props.fillContainer ? filledCardSize : small ? smallCardSize : cardSize;\n\n return (\n <div\n className={className}\n style={{ ...getThemeVars(this.props.theme), ...size }}\n >\n <div className=\"dm-head\">\n {this.renderAvatar(name, small)}\n <div\n className=\"dm-name\"\n title={name.length > (small ? 15 : 20) ? name : undefined}\n >\n {name}\n </div>\n {this.props.fields.hasDetails ? (\n <div className=\"dm-head-end\">\n <IconButton\n size=\"small\"\n disabled={!this.props.alive}\n aria-label={getTranslation('moreInformation')}\n onClick={() => {\n if (!this.state.open) {\n this.loadDetails().catch(console.error);\n this.setState({ open: true });\n }\n }}\n >\n <MoreVertIcon className=\"dm-ani dm-ani-turn\" />\n </IconButton>\n </div>\n ) : null}\n </div>\n <div className=\"dm-status\">\n {status.map((s, i) => (\n <DeviceStatusComponent\n key={i}\n socket={this.props.socket}\n deviceId={this.props.device.id}\n connectionType={this.props.fields.connectionType}\n status={s}\n statusAction={this.props.device.actions?.find(a => a.id === ACTIONS.STATUS)}\n update={i === 0 ? this.props.device.update : undefined}\n updateAction={\n i === 0 ? this.props.device.actions?.find(a => a.id === ACTIONS.UPDATE) : undefined\n }\n batteryAction={this.props.device.actions?.find(a => a.id === ACTIONS.BATTERY)}\n deviceHandler={this.props.deviceHandler}\n theme={this.props.theme}\n stateOrObjectHandler={this.props.stateOrObjectHandler}\n />\n ))}\n {this.renderIndicators()}\n {this.renderEnabled(small)}\n </div>\n {this.renderFacts()}\n {this.props.device.customInfo ? (\n <div className=\"dm-custom\">\n <JsonConfig\n instanceId={this.props.instanceId}\n socket={this.props.socket}\n schema={this.props.device.customInfo.schema}\n data={this.props.device.customInfo.data || {}}\n onChange={(_data: Record<string, any> | null) => {\n /* ignore */\n }}\n themeName={this.props.themeName}\n themeType={this.props.themeType}\n theme={this.props.theme}\n isFloatComma={this.props.isFloatComma}\n dateFormat={this.props.dateFormat}\n />\n </div>\n ) : null}\n {this.hasFooterActions() || this.props.device.controls?.length ? (\n <div className=\"dm-foot\">\n {this.renderActions()}\n <div className=\"dm-foot-end\">{this.renderControls()}</div>\n </div>\n ) : null}\n {this.renderDialog()}\n {this.renderControlDialog()}\n </div>\n );\n }\n}\n\ntype DeviceCardSkeletonProps = Pick<DeviceCardProps, 'smallCards' | 'theme'>;\n\n/** Placeholder of a device that is not loaded yet, with the layout of the card */\nexport class DeviceCardSkeleton extends PureComponent<DeviceCardSkeletonProps> {\n constructor(props: DeviceCardSkeletonProps) {\n super(props);\n ensureDmStyles();\n }\n\n render(): JSX.Element {\n const small = !!this.props.smallCards;\n return (\n <div\n className={small ? 'dm-card dm-small dm-skeleton' : 'dm-card dm-skeleton'}\n style={{ ...getThemeVars(this.props.theme), ...(small ? smallCardSize : cardSize) }}\n >\n <div className=\"dm-head\">\n <div className=\"dm-avatar\" />\n <div className=\"dm-name\">\n <Skeleton width=\"70%\" />\n </div>\n </div>\n <div className=\"dm-status\">\n <Skeleton\n variant=\"rounded\"\n width={small ? 120 : 150}\n height={20}\n />\n </div>\n <div className=\"dm-facts\">\n {[0, 1, 2].map(i => (\n <React.Fragment key={i}>\n <Skeleton width={small ? 42 : 56} />\n <Skeleton width={`${70 - i * 12}%`} />\n </React.Fragment>\n ))}\n </div>\n <div className=\"dm-foot\">\n <Skeleton\n variant=\"rounded\"\n width={small ? 110 : 150}\n height={20}\n />\n </div>\n </div>\n );\n }\n}\n"]}
@@ -8,11 +8,41 @@ import { renderControlIcon, getTranslation } from './Utils';
8
8
  export default class DeviceControlComponent extends Component {
9
9
  constructor(props) {
10
10
  super(props);
11
+ const control = props.control;
11
12
  this.state = {
12
- value: props.control.state?.val,
13
- ts: props.control.state?.ts,
14
- unit: props.control.unit || '',
13
+ value: control.state?.val,
14
+ ts: control.state?.ts,
15
+ unit: control.unit || '',
15
16
  };
17
+ // What the definition already says is used right away. Only the rest is read from the
18
+ // object of the state, and only if the control has one (see componentDidMount).
19
+ if (control.type === 'slider' || control.type === 'number') {
20
+ if (control.min !== undefined || control.max !== undefined) {
21
+ const min = control.min ?? 0;
22
+ const max = control.max ?? 100;
23
+ this.state = { ...this.state, min, max, step: control.step ?? (max - min) / 100 };
24
+ }
25
+ else if (!control.stateId) {
26
+ // No object to read the range from. A slider cannot be shown without one.
27
+ this.state = {
28
+ ...this.state,
29
+ min: control.type === 'slider' ? 0 : undefined,
30
+ max: control.type === 'slider' ? 100 : undefined,
31
+ step: control.step ?? (control.type === 'slider' ? 1 : undefined),
32
+ };
33
+ }
34
+ }
35
+ else if (control.type === 'select' && control.options?.length) {
36
+ this.state = {
37
+ ...this.state,
38
+ options: control.options.map(item => ({
39
+ label: getTranslation(item.label),
40
+ value: item.value,
41
+ icon: item.icon,
42
+ color: item.color,
43
+ })),
44
+ };
45
+ }
16
46
  }
17
47
  async componentDidMount() {
18
48
  if (this.props.control.stateId) {
@@ -21,7 +51,7 @@ export default class DeviceControlComponent extends Component {
21
51
  await mayBePromise;
22
52
  }
23
53
  if (this.props.control.type === 'slider' || this.props.control.type === 'number') {
24
- if (this.props.control.min === undefined && this.props.control.max === undefined) {
54
+ if (this.state.min === undefined && this.state.max === undefined) {
25
55
  // read an object to get min and max
26
56
  void this.props.socket.getObject(this.props.control.stateId).then(obj => {
27
57
  if (obj?.common) {
@@ -41,19 +71,9 @@ export default class DeviceControlComponent extends Component {
41
71
  }
42
72
  });
43
73
  }
44
- else {
45
- const min = this.props.control.min ?? 0;
46
- const max = this.props.control.max ?? 100;
47
- this.setState({
48
- min,
49
- max,
50
- step: this.props.control.step === undefined ? (max - min) / 100 : this.props.control.step,
51
- unit: this.props.control.unit || '',
52
- });
53
- }
54
74
  }
55
75
  else if (this.props.control.type === 'select') {
56
- if (!this.props.control.options?.length) {
76
+ if (!this.state.options) {
57
77
  // read an object to get options
58
78
  void this.props.socket.getObject(this.props.control.stateId).then(obj => {
59
79
  if (obj?.common?.states) {
@@ -83,16 +103,6 @@ export default class DeviceControlComponent extends Component {
83
103
  }
84
104
  });
85
105
  }
86
- else {
87
- this.setState({
88
- options: this.props.control.options.map(item => ({
89
- label: getTranslation(item.label),
90
- value: item.value,
91
- icon: item.icon,
92
- color: item.color,
93
- })),
94
- });
95
- }
96
106
  }
97
107
  else if (this.props.control.type === 'info') {
98
108
  if (!this.props.control.unit) {
@@ -199,7 +209,9 @@ export default class DeviceControlComponent extends Component {
199
209
  const anyIcons = this.state.options?.some(option => !!option.icon);
200
210
  return (React.createElement(FormControl, { fullWidth: true, variant: "standard" },
201
211
  this.props.control.label ? React.createElement(InputLabel, null, getTranslation(this.props.control.label)) : null,
202
- React.createElement(Select, { variant: "standard", value: this.state.value, onChange: (e) => this.sendControl(this.props.deviceId, this.props.control, e.target.value) }, this.state.options?.map((option, i) => (React.createElement(MenuItem, { key: i.toString(), value: typeof option.value === 'boolean' ? option.value.toString() : option.value, style: { color: option.color } },
212
+ React.createElement(Select, { variant: "standard",
213
+ // Until the options are known, any value would be out of range for MUI
214
+ value: this.state.options ? (this.state.value ?? '') : '', onChange: (e) => this.sendControl(this.props.deviceId, this.props.control, e.target.value) }, this.state.options?.map((option, i) => (React.createElement(MenuItem, { key: i.toString(), value: typeof option.value === 'boolean' ? option.value.toString() : option.value, style: { color: option.color } },
203
215
  anyIcons ? (React.createElement(Icon, { src: option.icon, style: { width: 24, height: 24 } })) : null,
204
216
  option.label))))));
205
217
  }