@iobroker/json-config 8.2.14 → 8.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/build/JsonConfigComponent/ConfigOAuth2.js +3 -3
- package/build/JsonConfigComponent/ConfigOAuth2.js.map +1 -1
- package/build/JsonConfigComponent/ConfigStaticImage.d.ts +6 -2
- package/build/JsonConfigComponent/ConfigStaticImage.js +28 -4
- package/build/JsonConfigComponent/ConfigStaticImage.js.map +1 -1
- package/build/types.d.ts +6 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -732,10 +732,13 @@ exactly one of `label` or `text` must be specified - not both
|
|
|
732
732
|
|
|
733
733
|
### `staticImage`
|
|
734
734
|
|
|
735
|
-
| Property
|
|
736
|
-
|
|
737
|
-
| `href`
|
|
738
|
-
| `src`
|
|
735
|
+
| Property | Description |
|
|
736
|
+
|----------------------------|----------------------------------------------------------------------------------------------|
|
|
737
|
+
| `href` | optional HTTP link |
|
|
738
|
+
| `src` | name of picture (from admin directory) |
|
|
739
|
+
| `showInDialog` | if true, a small thumbnail is shown and clicking it opens a dialog with the full-size image |
|
|
740
|
+
| `showInDialogButtonLabel` | if `showInDialog`, an optional label for a button that also opens the dialog |
|
|
741
|
+
| `showInDialogSmallSize` | if `showInDialog`, the height of the small thumbnail in pixels (default 100) |
|
|
739
742
|
|
|
740
743
|
### `table`
|
|
741
744
|
|
|
@@ -1749,8 +1752,9 @@ The schema is used here: https://github.com/SchemaStore/schemastore/blob/6da29cd
|
|
|
1749
1752
|
### **WORK IN PROGRESS**
|
|
1750
1753
|
-->
|
|
1751
1754
|
## Changelog
|
|
1752
|
-
### 8.2.
|
|
1755
|
+
### 8.2.16 (2026-03-24)
|
|
1753
1756
|
- (@GermanBluefox) Added the possibility to use own Client ID for oauth authentication
|
|
1757
|
+
- (@GermanBluefox) Added the possibility show small image and open it in full size by click on it
|
|
1754
1758
|
|
|
1755
1759
|
### 8.2.11 (2026-03-20)
|
|
1756
1760
|
- (@GermanBluefox) Correcting unit in schema
|
|
@@ -88,7 +88,7 @@ export default class ConfigOAuth2 extends ConfigGeneric {
|
|
|
88
88
|
// Give 10 seconds to user to copy the token
|
|
89
89
|
accessTokensParsed.access_token_expires_on ||= new Date(Date.now() + accessTokensParsed.expires_in * 1000).toISOString();
|
|
90
90
|
if (this.props.schema.ownClientId) {
|
|
91
|
-
accessTokensParsed.client_id = ConfigGeneric.getValue(this.props.data, this.props.schema.
|
|
91
|
+
accessTokensParsed.client_id = ConfigGeneric.getValue(this.props.data, this.props.schema.ownClientId);
|
|
92
92
|
}
|
|
93
93
|
this.props.oContext.socket
|
|
94
94
|
.setState(this.oid, JSON.stringify(accessTokensParsed), true)
|
|
@@ -156,7 +156,7 @@ export default class ConfigOAuth2 extends ConfigGeneric {
|
|
|
156
156
|
this.props.schema.ownClientId ? (React.createElement(TextField, { value: this.state.clientId, onChange: e => {
|
|
157
157
|
const value = e.target.value;
|
|
158
158
|
this.setState({ clientId: value }, () => this.onChange(this.props.schema.ownClientId, value));
|
|
159
|
-
}, variant: "standard", fullWidth: true, error: !this.state.clientId, disabled: !!disabled, label: I18n.t('ra_OAuth Client ID'), slotProps: {
|
|
159
|
+
}, style: { marginBottom: 8 }, variant: "standard", fullWidth: true, error: !this.state.clientId, disabled: !!disabled, label: I18n.t('ra_OAuth Client ID'), slotProps: {
|
|
160
160
|
input: {
|
|
161
161
|
endAdornment: this.state.clientId ? (React.createElement(IconButton, { size: "small", tabIndex: -1, onClick: () => this.setState({ clientId: '' }, () => this.onChange(this.props.schema.ownClientId, '')) },
|
|
162
162
|
React.createElement(CloseIcon, null))) : null,
|
|
@@ -165,7 +165,7 @@ export default class ConfigOAuth2 extends ConfigGeneric {
|
|
|
165
165
|
this.props.schema.ownClientSecret ? (React.createElement(TextField, { value: this.state.clientSecret, onChange: e => {
|
|
166
166
|
const value = e.target.value;
|
|
167
167
|
this.setState({ clientSecret: value }, () => this.onChange(this.props.schema.ownClientSecret, value));
|
|
168
|
-
}, variant: "standard", fullWidth: true, error: !this.state.clientSecret, disabled: !!disabled, label: I18n.t('ra_OAuth Client secret'), slotProps: {
|
|
168
|
+
}, style: { marginBottom: 8 }, variant: "standard", fullWidth: true, error: !this.state.clientSecret, disabled: !!disabled, label: I18n.t('ra_OAuth Client secret'), slotProps: {
|
|
169
169
|
input: {
|
|
170
170
|
endAdornment: this.state.clientSecret ? (React.createElement(IconButton, { size: "small", tabIndex: -1, onClick: () => this.setState({ clientSecret: '' }, () => this.onChange(this.props.schema.ownClientSecret, '')) },
|
|
171
171
|
React.createElement(CloseIcon, null))) : null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigOAuth2.js","sourceRoot":"./src/","sources":["JsonConfigComponent/ConfigOAuth2.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport { Button, IconButton, TextField } from '@mui/material';\nimport { Close as CloseIcon, CloudUpload } from '@mui/icons-material';\n\nimport { I18n } from '@iobroker/adapter-react-v5';\n\nimport ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';\nimport type { ConfigItemOAuth2 } from '../types';\n\ndeclare global {\n interface Window {\n attachEvent: Window['addEventListener'];\n detachEvent: Window['removeEventListener'];\n }\n}\n\ninterface ConfigOAuth2Props extends ConfigGenericProps {\n schema: ConfigItemOAuth2;\n}\n\nexport interface AccessTokens {\n access_token: string;\n expires_in: number;\n access_token_expires_on: string;\n ext_expires_in: number;\n token_type: 'Bearer';\n scope: string;\n refresh_token: string;\n client_id: string;\n}\n\ninterface ConfigOAuth2State extends ConfigGenericState {\n accessTokens: string;\n success: boolean;\n blocked: boolean;\n running: boolean;\n pressed: boolean;\n clientId: string;\n clientSecret: string;\n}\n\nexport default class ConfigOAuth2 extends ConfigGeneric<ConfigOAuth2Props, ConfigOAuth2State> {\n private authWindow?: WindowProxy | null;\n private readonly oid: string;\n private readonly url: string;\n\n constructor(props: ConfigOAuth2Props) {\n super(props);\n\n this.state = {\n ...this.state,\n accessTokens: '',\n success: false,\n blocked: false,\n running: false,\n pressed: false,\n clientId: '',\n clientSecret: '',\n };\n\n this.url = `https://oauth2.iobroker.in/${props.schema.identifier}?redirect=true`;\n if (props.schema.scope) {\n this.url += `&scope=${encodeURIComponent(props.schema.scope)}`;\n }\n\n this.oid = `${this.props.oContext.adapterName}.${this.props.oContext.instance}.${this.props.schema.saveTokenIn || 'oauth2Tokens'}`;\n }\n\n async componentDidMount(): Promise<void> {\n super.componentDidMount();\n if (window.addEventListener) {\n window.addEventListener('message', this.onMessage as any, false);\n } else {\n window.attachEvent('onmessage', this.onMessage as any, false);\n }\n\n await this.props.oContext.socket.subscribeState(this.oid, this.onTokensUpdated);\n\n let state: Partial<ConfigOAuth2State> | undefined;\n if (this.props.schema.ownClientId) {\n state = { clientId: ConfigGeneric.getValue(this.props.data, this.props.schema.ownClientId) };\n }\n if (this.props.schema.ownClientId) {\n state ||= {};\n state.clientSecret = ConfigGeneric.getValue(this.props.data, this.props.schema.ownClientSecret);\n }\n\n // read tokens\n const tokens = await this.props.oContext.socket.getState(this.oid);\n if (tokens) {\n const accessTokens: AccessTokens = JSON.parse(tokens.val as string);\n if (new Date(accessTokens.access_token_expires_on).getTime() > Date.now()) {\n state ||= {};\n state.accessTokens = tokens.val as string;\n }\n }\n if (state) {\n this.setState(state as ConfigOAuth2State);\n }\n }\n\n onTokensUpdated = (_id: string, state: ioBroker.State | null | undefined): void => {\n if (state?.val) {\n const accessTokens: AccessTokens = JSON.parse(state.val as string);\n if (new Date(accessTokens.access_token_expires_on).getTime() > Date.now()) {\n if (this.state.accessTokens !== state.val) {\n this.setState({ accessTokens: state.val as string });\n }\n return;\n }\n }\n this.setState({ accessTokens: '' });\n };\n\n componentWillUnmount(): void {\n super.componentWillUnmount();\n if (window.removeEventListener) {\n window.removeEventListener('message', this.onMessage as any, false);\n } else {\n window.detachEvent('onmessage', this.onMessage as any, false);\n }\n this.props.oContext.socket.unsubscribeState(this.oid, this.onTokensUpdated);\n }\n\n saveToken(accessTokens: string): void {\n try {\n if (accessTokens && !accessTokens.startsWith('{')) {\n // convert base64 to string\n accessTokens = atob(accessTokens);\n }\n\n const accessTokensParsed: AccessTokens = JSON.parse(accessTokens);\n if (accessTokensParsed.access_token && accessTokensParsed.refresh_token && accessTokensParsed.expires_in) {\n // Give 10 seconds to user to copy the token\n accessTokensParsed.access_token_expires_on ||= new Date(\n Date.now() + accessTokensParsed.expires_in * 1000,\n ).toISOString();\n if (this.props.schema.ownClientId) {\n accessTokensParsed.client_id = ConfigGeneric.getValue(\n this.props.data,\n this.props.schema.ownClientSecret,\n );\n }\n\n this.props.oContext.socket\n .setState(this.oid, JSON.stringify(accessTokensParsed), true)\n .catch((e: Error) => console.log(`Error occurred: ${e.toString()}`));\n }\n } catch (e) {\n // ignore\n console.warn(e);\n }\n }\n\n onMessage = (event: MessageEvent): void => {\n if (event.origin !== 'https://oauth2.iobroker.in') {\n return;\n }\n if (\n (typeof event.data === 'string' &&\n event.data.startsWith(`${this.props.schema.identifier}-authentication:`)) ||\n (typeof (event as any).message === 'string' &&\n (event as any).message.startsWith(`${this.props.schema.identifier}-authentication:`))\n ) {\n const parts = (event.data || (event as any).message).split(':');\n if (parts[1] === 'success') {\n this.setState({ accessTokens: parts[2], success: true, pressed: false }, () =>\n this.saveToken(this.state.accessTokens),\n );\n\n // send message to auth window to close it\n this.authWindow?.postMessage('close', event.origin);\n this.authWindow = null;\n } else {\n this.props.onError?.(parts[2]);\n }\n }\n };\n\n onOpenUrl(): void {\n this.authWindow = window.open(\n this.url + (this.props.schema.ownClientId ? `&clientId=${encodeURIComponent(this.state.clientId)}` : ''),\n this.props.schema.identifier,\n );\n if (!this.authWindow || this.authWindow.closed || typeof this.authWindow.closed === 'undefined') {\n this.setState({ blocked: true });\n } else {\n this.setState({ pressed: true });\n }\n }\n\n renderItem(_error?: boolean, disabled?: boolean): React.JSX.Element {\n let validTill = '';\n if (this.state.accessTokens) {\n try {\n const accessTokensParsed: AccessTokens = JSON.parse(this.state.accessTokens);\n validTill = new Date(accessTokensParsed.access_token_expires_on).toLocaleString();\n } catch {\n // ignore\n }\n }\n\n let label: string;\n if (this.state.accessTokens) {\n label = this.props.schema.refreshLabel\n ? this.getText(this.props.schema.refreshLabel)\n : I18n.t(\n 'ra_Renew %s access',\n this.props.schema.identifier[0].toUpperCase() + this.props.schema.identifier.slice(1),\n );\n } else {\n label = this.props.schema.label\n ? this.getText(this.props.schema.label)\n : I18n.t(\n 'ra_Get %s access',\n this.props.schema.identifier[0].toUpperCase() + this.props.schema.identifier.slice(1),\n );\n }\n const icon = this.getIcon();\n\n return (\n <div style={{ width: '100%', margin: '0 0 1rem 0' }}>\n {this.props.schema.ownClientId ? (\n <TextField\n value={this.state.clientId}\n onChange={e => {\n const value = e.target.value;\n\n this.setState({ clientId: value }, () =>\n this.onChange(this.props.schema.ownClientId, value),\n );\n }}\n variant=\"standard\"\n fullWidth\n error={!this.state.clientId}\n disabled={!!disabled}\n label={I18n.t('ra_OAuth Client ID')}\n slotProps={{\n input: {\n endAdornment: this.state.clientId ? (\n <IconButton\n size=\"small\"\n tabIndex={-1}\n onClick={() =>\n this.setState({ clientId: '' }, () =>\n this.onChange(this.props.schema.ownClientId, ''),\n )\n }\n >\n <CloseIcon />\n </IconButton>\n ) : null,\n },\n }}\n />\n ) : null}\n {this.props.schema.ownClientSecret ? (\n <TextField\n value={this.state.clientSecret}\n onChange={e => {\n const value = e.target.value;\n\n this.setState({ clientSecret: value }, () =>\n this.onChange(this.props.schema.ownClientSecret, value),\n );\n }}\n variant=\"standard\"\n fullWidth\n error={!this.state.clientSecret}\n disabled={!!disabled}\n label={I18n.t('ra_OAuth Client secret')}\n slotProps={{\n input: {\n endAdornment: this.state.clientSecret ? (\n <IconButton\n size=\"small\"\n tabIndex={-1}\n onClick={() =>\n this.setState({ clientSecret: '' }, () =>\n this.onChange(this.props.schema.ownClientSecret, ''),\n )\n }\n >\n <CloseIcon />\n </IconButton>\n ) : null,\n },\n }}\n />\n ) : null}\n <Button\n disabled={\n this.state.running ||\n (this.props.schema.ownClientSecret && !this.state.clientSecret) ||\n (this.props.schema.ownClientId && !this.state.clientId)\n }\n endIcon={icon || <CloudUpload />}\n variant=\"contained\"\n onClick={() => this.onOpenUrl()}\n >\n {label}\n </Button>\n {this.state.blocked ? (\n <div style={{ color: 'red', fontSize: 16, marginTop: 20 }}>\n {I18n.t('ra_Please allow popups in your browser for this page!')}\n </div>\n ) : null}\n {this.state.accessTokens ? (\n <div style={{ color: 'green', fontSize: 16, marginTop: 20 }}>\n {this.props.alive\n ? I18n.t(\n 'ra_Successfully authorized. Token valid till %s and will be automatically renewed.',\n validTill,\n )\n : I18n.t(\n 'ra_Successfully authorized. Token valid till %s but it can expire as the instance is not running.',\n validTill,\n )}\n </div>\n ) : null}\n {this.state.pressed ? (\n <>\n <div style={{ width: '100%', margin: '1rem 0 1rem 0' }}>\n <span style={{ marginRight: 4 }}>\n {`${I18n.t('ra_If the button above does not work, you can authorize manually this app by visiting this url')}`}\n :\n </span>\n <br />\n <a\n target={this.props.schema.identifier}\n href={this.url}\n rel=\"noreferrer\"\n >\n {this.url}\n </a>\n </div>\n <TextField\n value={this.state.accessTokens}\n label={I18n.t('ra_Enter the code from that page here')}\n variant=\"standard\"\n onChange={e => {\n let accessTokens = e.target.value;\n if (accessTokens && !accessTokens.startsWith('{')) {\n // convert base64 to string\n accessTokens = atob(accessTokens);\n }\n try {\n const accessTokensParsed: AccessTokens = JSON.parse(accessTokens);\n if (accessTokensParsed.access_token) {\n accessTokensParsed.access_token_expires_on = new Date(\n Date.now() + (accessTokensParsed.expires_in - 10) * 1000,\n ).toISOString();\n this.setState({ accessTokens: JSON.stringify(accessTokensParsed) }, () =>\n this.saveToken(this.state.accessTokens),\n );\n }\n } catch {\n // ignore\n }\n }}\n fullWidth\n />\n </>\n ) : null}\n </div>\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ConfigOAuth2.js","sourceRoot":"./src/","sources":["JsonConfigComponent/ConfigOAuth2.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport { Button, IconButton, TextField } from '@mui/material';\nimport { Close as CloseIcon, CloudUpload } from '@mui/icons-material';\n\nimport { I18n } from '@iobroker/adapter-react-v5';\n\nimport ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';\nimport type { ConfigItemOAuth2 } from '../types';\n\ndeclare global {\n interface Window {\n attachEvent: Window['addEventListener'];\n detachEvent: Window['removeEventListener'];\n }\n}\n\ninterface ConfigOAuth2Props extends ConfigGenericProps {\n schema: ConfigItemOAuth2;\n}\n\nexport interface AccessTokens {\n access_token: string;\n expires_in: number;\n access_token_expires_on: string;\n ext_expires_in: number;\n token_type: 'Bearer';\n scope: string;\n refresh_token: string;\n client_id: string;\n}\n\ninterface ConfigOAuth2State extends ConfigGenericState {\n accessTokens: string;\n success: boolean;\n blocked: boolean;\n running: boolean;\n pressed: boolean;\n clientId: string;\n clientSecret: string;\n}\n\nexport default class ConfigOAuth2 extends ConfigGeneric<ConfigOAuth2Props, ConfigOAuth2State> {\n private authWindow?: WindowProxy | null;\n private readonly oid: string;\n private readonly url: string;\n\n constructor(props: ConfigOAuth2Props) {\n super(props);\n\n this.state = {\n ...this.state,\n accessTokens: '',\n success: false,\n blocked: false,\n running: false,\n pressed: false,\n clientId: '',\n clientSecret: '',\n };\n\n this.url = `https://oauth2.iobroker.in/${props.schema.identifier}?redirect=true`;\n if (props.schema.scope) {\n this.url += `&scope=${encodeURIComponent(props.schema.scope)}`;\n }\n\n this.oid = `${this.props.oContext.adapterName}.${this.props.oContext.instance}.${this.props.schema.saveTokenIn || 'oauth2Tokens'}`;\n }\n\n async componentDidMount(): Promise<void> {\n super.componentDidMount();\n if (window.addEventListener) {\n window.addEventListener('message', this.onMessage as any, false);\n } else {\n window.attachEvent('onmessage', this.onMessage as any, false);\n }\n\n await this.props.oContext.socket.subscribeState(this.oid, this.onTokensUpdated);\n\n let state: Partial<ConfigOAuth2State> | undefined;\n if (this.props.schema.ownClientId) {\n state = { clientId: ConfigGeneric.getValue(this.props.data, this.props.schema.ownClientId) };\n }\n if (this.props.schema.ownClientId) {\n state ||= {};\n state.clientSecret = ConfigGeneric.getValue(this.props.data, this.props.schema.ownClientSecret);\n }\n\n // read tokens\n const tokens = await this.props.oContext.socket.getState(this.oid);\n if (tokens) {\n const accessTokens: AccessTokens = JSON.parse(tokens.val as string);\n if (new Date(accessTokens.access_token_expires_on).getTime() > Date.now()) {\n state ||= {};\n state.accessTokens = tokens.val as string;\n }\n }\n if (state) {\n this.setState(state as ConfigOAuth2State);\n }\n }\n\n onTokensUpdated = (_id: string, state: ioBroker.State | null | undefined): void => {\n if (state?.val) {\n const accessTokens: AccessTokens = JSON.parse(state.val as string);\n if (new Date(accessTokens.access_token_expires_on).getTime() > Date.now()) {\n if (this.state.accessTokens !== state.val) {\n this.setState({ accessTokens: state.val as string });\n }\n return;\n }\n }\n this.setState({ accessTokens: '' });\n };\n\n componentWillUnmount(): void {\n super.componentWillUnmount();\n if (window.removeEventListener) {\n window.removeEventListener('message', this.onMessage as any, false);\n } else {\n window.detachEvent('onmessage', this.onMessage as any, false);\n }\n this.props.oContext.socket.unsubscribeState(this.oid, this.onTokensUpdated);\n }\n\n saveToken(accessTokens: string): void {\n try {\n if (accessTokens && !accessTokens.startsWith('{')) {\n // convert base64 to string\n accessTokens = atob(accessTokens);\n }\n\n const accessTokensParsed: AccessTokens = JSON.parse(accessTokens);\n if (accessTokensParsed.access_token && accessTokensParsed.refresh_token && accessTokensParsed.expires_in) {\n // Give 10 seconds to user to copy the token\n accessTokensParsed.access_token_expires_on ||= new Date(\n Date.now() + accessTokensParsed.expires_in * 1000,\n ).toISOString();\n if (this.props.schema.ownClientId) {\n accessTokensParsed.client_id = ConfigGeneric.getValue(\n this.props.data,\n this.props.schema.ownClientId,\n );\n }\n\n this.props.oContext.socket\n .setState(this.oid, JSON.stringify(accessTokensParsed), true)\n .catch((e: Error) => console.log(`Error occurred: ${e.toString()}`));\n }\n } catch (e) {\n // ignore\n console.warn(e);\n }\n }\n\n onMessage = (event: MessageEvent): void => {\n if (event.origin !== 'https://oauth2.iobroker.in') {\n return;\n }\n if (\n (typeof event.data === 'string' &&\n event.data.startsWith(`${this.props.schema.identifier}-authentication:`)) ||\n (typeof (event as any).message === 'string' &&\n (event as any).message.startsWith(`${this.props.schema.identifier}-authentication:`))\n ) {\n const parts = (event.data || (event as any).message).split(':');\n if (parts[1] === 'success') {\n this.setState({ accessTokens: parts[2], success: true, pressed: false }, () =>\n this.saveToken(this.state.accessTokens),\n );\n\n // send message to auth window to close it\n this.authWindow?.postMessage('close', event.origin);\n this.authWindow = null;\n } else {\n this.props.onError?.(parts[2]);\n }\n }\n };\n\n onOpenUrl(): void {\n this.authWindow = window.open(\n this.url + (this.props.schema.ownClientId ? `&clientId=${encodeURIComponent(this.state.clientId)}` : ''),\n this.props.schema.identifier,\n );\n if (!this.authWindow || this.authWindow.closed || typeof this.authWindow.closed === 'undefined') {\n this.setState({ blocked: true });\n } else {\n this.setState({ pressed: true });\n }\n }\n\n renderItem(_error?: boolean, disabled?: boolean): React.JSX.Element {\n let validTill = '';\n if (this.state.accessTokens) {\n try {\n const accessTokensParsed: AccessTokens = JSON.parse(this.state.accessTokens);\n validTill = new Date(accessTokensParsed.access_token_expires_on).toLocaleString();\n } catch {\n // ignore\n }\n }\n\n let label: string;\n if (this.state.accessTokens) {\n label = this.props.schema.refreshLabel\n ? this.getText(this.props.schema.refreshLabel)\n : I18n.t(\n 'ra_Renew %s access',\n this.props.schema.identifier[0].toUpperCase() + this.props.schema.identifier.slice(1),\n );\n } else {\n label = this.props.schema.label\n ? this.getText(this.props.schema.label)\n : I18n.t(\n 'ra_Get %s access',\n this.props.schema.identifier[0].toUpperCase() + this.props.schema.identifier.slice(1),\n );\n }\n const icon = this.getIcon();\n\n return (\n <div style={{ width: '100%', margin: '0 0 1rem 0' }}>\n {this.props.schema.ownClientId ? (\n <TextField\n value={this.state.clientId}\n onChange={e => {\n const value = e.target.value;\n\n this.setState({ clientId: value }, () =>\n this.onChange(this.props.schema.ownClientId, value),\n );\n }}\n style={{ marginBottom: 8 }}\n variant=\"standard\"\n fullWidth\n error={!this.state.clientId}\n disabled={!!disabled}\n label={I18n.t('ra_OAuth Client ID')}\n slotProps={{\n input: {\n endAdornment: this.state.clientId ? (\n <IconButton\n size=\"small\"\n tabIndex={-1}\n onClick={() =>\n this.setState({ clientId: '' }, () =>\n this.onChange(this.props.schema.ownClientId, ''),\n )\n }\n >\n <CloseIcon />\n </IconButton>\n ) : null,\n },\n }}\n />\n ) : null}\n {this.props.schema.ownClientSecret ? (\n <TextField\n value={this.state.clientSecret}\n onChange={e => {\n const value = e.target.value;\n\n this.setState({ clientSecret: value }, () =>\n this.onChange(this.props.schema.ownClientSecret, value),\n );\n }}\n style={{ marginBottom: 8 }}\n variant=\"standard\"\n fullWidth\n error={!this.state.clientSecret}\n disabled={!!disabled}\n label={I18n.t('ra_OAuth Client secret')}\n slotProps={{\n input: {\n endAdornment: this.state.clientSecret ? (\n <IconButton\n size=\"small\"\n tabIndex={-1}\n onClick={() =>\n this.setState({ clientSecret: '' }, () =>\n this.onChange(this.props.schema.ownClientSecret, ''),\n )\n }\n >\n <CloseIcon />\n </IconButton>\n ) : null,\n },\n }}\n />\n ) : null}\n <Button\n disabled={\n this.state.running ||\n (this.props.schema.ownClientSecret && !this.state.clientSecret) ||\n (this.props.schema.ownClientId && !this.state.clientId)\n }\n endIcon={icon || <CloudUpload />}\n variant=\"contained\"\n onClick={() => this.onOpenUrl()}\n >\n {label}\n </Button>\n {this.state.blocked ? (\n <div style={{ color: 'red', fontSize: 16, marginTop: 20 }}>\n {I18n.t('ra_Please allow popups in your browser for this page!')}\n </div>\n ) : null}\n {this.state.accessTokens ? (\n <div style={{ color: 'green', fontSize: 16, marginTop: 20 }}>\n {this.props.alive\n ? I18n.t(\n 'ra_Successfully authorized. Token valid till %s and will be automatically renewed.',\n validTill,\n )\n : I18n.t(\n 'ra_Successfully authorized. Token valid till %s but it can expire as the instance is not running.',\n validTill,\n )}\n </div>\n ) : null}\n {this.state.pressed ? (\n <>\n <div style={{ width: '100%', margin: '1rem 0 1rem 0' }}>\n <span style={{ marginRight: 4 }}>\n {`${I18n.t('ra_If the button above does not work, you can authorize manually this app by visiting this url')}`}\n :\n </span>\n <br />\n <a\n target={this.props.schema.identifier}\n href={this.url}\n rel=\"noreferrer\"\n >\n {this.url}\n </a>\n </div>\n <TextField\n value={this.state.accessTokens}\n label={I18n.t('ra_Enter the code from that page here')}\n variant=\"standard\"\n onChange={e => {\n let accessTokens = e.target.value;\n if (accessTokens && !accessTokens.startsWith('{')) {\n // convert base64 to string\n accessTokens = atob(accessTokens);\n }\n try {\n const accessTokensParsed: AccessTokens = JSON.parse(accessTokens);\n if (accessTokensParsed.access_token) {\n accessTokensParsed.access_token_expires_on = new Date(\n Date.now() + (accessTokensParsed.expires_in - 10) * 1000,\n ).toISOString();\n this.setState({ accessTokens: JSON.stringify(accessTokensParsed) }, () =>\n this.saveToken(this.state.accessTokens),\n );\n }\n } catch {\n // ignore\n }\n }}\n fullWidth\n />\n </>\n ) : null}\n </div>\n );\n }\n}\n"]}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { type JSX } from 'react';
|
|
2
2
|
import type { ConfigItemStaticImage } from '../types';
|
|
3
3
|
import ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';
|
|
4
|
-
interface
|
|
4
|
+
interface ConfigStaticImageProps extends ConfigGenericProps {
|
|
5
5
|
schema: ConfigItemStaticImage;
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
interface ConfigStaticImageState extends ConfigGenericState {
|
|
8
|
+
showDialog?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare class ConfigStaticImage extends ConfigGeneric<ConfigStaticImageProps, ConfigStaticImageState> {
|
|
11
|
+
private getSrc;
|
|
8
12
|
renderItem(): JSX.Element;
|
|
9
13
|
}
|
|
10
14
|
export default ConfigStaticImage;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { Button, Dialog, DialogActions, DialogContent, Tooltip } from '@mui/material';
|
|
3
|
+
import { I18n } from '@iobroker/adapter-react-v5';
|
|
2
4
|
import ConfigGeneric from './ConfigGeneric';
|
|
3
5
|
class ConfigStaticImage extends ConfigGeneric {
|
|
4
|
-
|
|
6
|
+
getSrc() {
|
|
5
7
|
let src = this.props.schema.src;
|
|
6
8
|
if (src &&
|
|
7
9
|
!src.startsWith('.') &&
|
|
@@ -10,9 +12,31 @@ class ConfigStaticImage extends ConfigGeneric {
|
|
|
10
12
|
!src.startsWith(`./adapter/${this.props.oContext.adapterName}/`)) {
|
|
11
13
|
src = `adapter/${this.props.oContext.adapterName}/${src}`;
|
|
12
14
|
}
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
return src;
|
|
16
|
+
}
|
|
17
|
+
renderItem( /* error: string, disabled: boolean, defaultValue */) {
|
|
18
|
+
const { schema } = this.props;
|
|
19
|
+
const src = this.getSrc();
|
|
20
|
+
if (schema.showInDialog) {
|
|
21
|
+
const smallSize = schema.showInDialogSmallSize || 100;
|
|
22
|
+
const buttonLabel = schema.showInDialogButtonLabel ? this.getText(schema.showInDialogButtonLabel) : '';
|
|
23
|
+
return (React.createElement(React.Fragment, null,
|
|
24
|
+
React.createElement(Tooltip, { title: I18n.t('ra_Click to see in full size') },
|
|
25
|
+
React.createElement("img", { src: src, style: {
|
|
26
|
+
cursor: 'pointer',
|
|
27
|
+
width: 'auto',
|
|
28
|
+
height: smallSize,
|
|
29
|
+
objectFit: 'contain',
|
|
30
|
+
}, onClick: () => this.setState({ showDialog: true }), alt: "" })),
|
|
31
|
+
' ',
|
|
32
|
+
buttonLabel ? (React.createElement(Button, { variant: "outlined", color: "grey", onClick: () => this.setState({ showDialog: true }) }, buttonLabel)) : null,
|
|
33
|
+
this.state.showDialog ? (React.createElement(Dialog, { open: !0, onClose: () => this.setState({ showDialog: false }), maxWidth: "lg" },
|
|
34
|
+
React.createElement(DialogContent, null,
|
|
35
|
+
React.createElement("img", { src: src, style: { width: '100%', height: '100%', objectFit: 'contain' }, alt: "" })),
|
|
36
|
+
React.createElement(DialogActions, null,
|
|
37
|
+
React.createElement(Button, { variant: "contained", onClick: () => this.setState({ showDialog: false }), color: "primary" }, I18n.t('ra_Close'))))) : null));
|
|
38
|
+
}
|
|
39
|
+
return (React.createElement("img", { src: src, style: { cursor: schema.href ? 'pointer' : undefined, width: '100%', height: '100%' }, onClick: schema.href ? () => schema.href && window.open(schema.href, '_blank') : null, alt: "" }));
|
|
16
40
|
}
|
|
17
41
|
}
|
|
18
42
|
export default ConfigStaticImage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigStaticImage.js","sourceRoot":"./src/","sources":["JsonConfigComponent/ConfigStaticImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ConfigStaticImage.js","sourceRoot":"./src/","sources":["JsonConfigComponent/ConfigStaticImage.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { type JSX } from 'react';\n\nimport { Button, Dialog, DialogActions, DialogContent, Tooltip } from '@mui/material';\n\nimport { I18n } from '@iobroker/adapter-react-v5';\n\nimport type { ConfigItemStaticImage } from '../types';\nimport ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';\n\ninterface ConfigStaticImageProps extends ConfigGenericProps {\n schema: ConfigItemStaticImage;\n}\n\ninterface ConfigStaticImageState extends ConfigGenericState {\n showDialog?: boolean;\n}\n\nclass ConfigStaticImage extends ConfigGeneric<ConfigStaticImageProps, ConfigStaticImageState> {\n private getSrc(): string {\n let src = this.props.schema.src;\n if (\n src &&\n !src.startsWith('.') &&\n !src.startsWith('http') &&\n !src.startsWith(`adapter/${this.props.oContext.adapterName}/`) &&\n !src.startsWith(`./adapter/${this.props.oContext.adapterName}/`)\n ) {\n src = `adapter/${this.props.oContext.adapterName}/${src}`;\n }\n return src;\n }\n\n renderItem(/* error: string, disabled: boolean, defaultValue */): JSX.Element {\n const { schema } = this.props;\n const src = this.getSrc();\n\n if (schema.showInDialog) {\n const smallSize = schema.showInDialogSmallSize || 100;\n const buttonLabel = schema.showInDialogButtonLabel ? this.getText(schema.showInDialogButtonLabel) : '';\n\n return (\n <>\n <Tooltip title={I18n.t('ra_Click to see in full size')}>\n <img\n src={src}\n style={{\n cursor: 'pointer',\n width: 'auto',\n height: smallSize,\n objectFit: 'contain',\n }}\n onClick={() => this.setState({ showDialog: true })}\n alt=\"\"\n />\n </Tooltip>{' '}\n {buttonLabel ? (\n <Button\n variant=\"outlined\"\n color=\"grey\"\n onClick={() => this.setState({ showDialog: true })}\n >\n {buttonLabel}\n </Button>\n ) : null}\n {this.state.showDialog ? (\n <Dialog\n open={!0}\n onClose={() => this.setState({ showDialog: false })}\n maxWidth=\"lg\"\n >\n <DialogContent>\n <img\n src={src}\n style={{ width: '100%', height: '100%', objectFit: 'contain' }}\n alt=\"\"\n />\n </DialogContent>\n <DialogActions>\n <Button\n variant=\"contained\"\n onClick={() => this.setState({ showDialog: false })}\n color=\"primary\"\n >\n {I18n.t('ra_Close')}\n </Button>\n </DialogActions>\n </Dialog>\n ) : null}\n </>\n );\n }\n\n return (\n <img\n src={src}\n style={{ cursor: schema.href ? 'pointer' : undefined, width: '100%', height: '100%' }}\n onClick={schema.href ? () => schema.href && window.open(schema.href, '_blank') : null}\n alt=\"\"\n />\n );\n }\n}\n\nexport default ConfigStaticImage;\n"]}
|
package/build/types.d.ts
CHANGED
|
@@ -500,6 +500,12 @@ export interface ConfigItemStaticImage extends ConfigItem {
|
|
|
500
500
|
src: string;
|
|
501
501
|
/** optional HTTP link */
|
|
502
502
|
href?: string;
|
|
503
|
+
/** It will be shown small image 100px, and by click on it the dialog will be opened with bigger image */
|
|
504
|
+
showInDialog?: boolean;
|
|
505
|
+
/** If showInDialog, the label for the button */
|
|
506
|
+
showInDialogButtonLabel?: ioBroker.StringOrTranslated;
|
|
507
|
+
/** If showInDialog, the size of small image (default 100px) */
|
|
508
|
+
showInDialogSmallSize?: number;
|
|
503
509
|
}
|
|
504
510
|
|
|
505
511
|
export interface ConfigItemStaticText extends Omit<ConfigItem, 'button'> {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iobroker/json-config",
|
|
3
3
|
"description": "This package contains the ioBroker JSON config UI components",
|
|
4
|
-
"version": "8.2.
|
|
4
|
+
"version": "8.2.16",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "bluefox",
|
|
7
7
|
"email": "dogafox@gmail.com"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@iobroker/adapter-react-v5": "^8.1.
|
|
38
|
+
"@iobroker/adapter-react-v5": "^8.1.6",
|
|
39
39
|
"@module-federation/runtime": "^2.1.0",
|
|
40
40
|
"@mui/x-date-pickers": "^7.29.4",
|
|
41
41
|
"crypto-js": "^4.2.0",
|