@iobroker/gui-components 10.3.15 → 10.3.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.
@@ -12,9 +12,20 @@ interface SaveCloseButtonsProps {
12
12
  changed: boolean;
13
13
  error?: boolean;
14
14
  }
15
- export declare class SaveCloseButtons extends React.Component<SaveCloseButtonsProps> {
15
+ interface SaveCloseButtonsState {
16
+ /** How often the settings were saved; a check mark is drawn on the save button after each save */
17
+ savedCount: number;
18
+ showSaved: boolean;
19
+ }
20
+ export declare class SaveCloseButtons extends React.Component<SaveCloseButtonsProps, SaveCloseButtonsState> {
16
21
  private readonly isIFrame;
22
+ /** The save button was pressed and the settings are not stored yet */
23
+ private saving;
24
+ private savedTimer;
17
25
  constructor(props: SaveCloseButtonsProps);
26
+ componentDidUpdate(prevProps: Readonly<SaveCloseButtonsProps>): void;
27
+ componentWillUnmount(): void;
28
+ onSave(): void;
18
29
  render(): JSX.Element;
19
30
  }
20
31
  export {};
@@ -3,6 +3,7 @@ import React from 'react';
3
3
  import { Fab, Toolbar } from '@mui/material';
4
4
  import { Save as IconSave, Close as IconClose } from '@mui/icons-material';
5
5
  import { I18n } from '../i18n';
6
+ import { IconResult } from './AnimatedIcons/IconResult';
6
7
  const styles = {
7
8
  buttonIcon: {
8
9
  marginRight: 8,
@@ -10,6 +11,9 @@ const styles = {
10
11
  };
11
12
  export class SaveCloseButtons extends React.Component {
12
13
  isIFrame;
14
+ /** The save button was pressed and the settings are not stored yet */
15
+ saving = null;
16
+ savedTimer = null;
13
17
  constructor(props) {
14
18
  super(props);
15
19
  const newReact = props.newReact === undefined ? true : props.newReact;
@@ -24,6 +28,38 @@ export class SaveCloseButtons extends React.Component {
24
28
  this.isIFrame = !newReact;
25
29
  }
26
30
  }
31
+ this.state = { savedCount: 0, showSaved: false };
32
+ }
33
+ componentDidUpdate(prevProps) {
34
+ // the settings are stored, when nothing is changed anymore after a click on "Save"
35
+ if (this.saving && prevProps.changed && !this.props.changed) {
36
+ clearTimeout(this.saving);
37
+ this.saving = null;
38
+ if (this.savedTimer) {
39
+ clearTimeout(this.savedTimer);
40
+ }
41
+ this.savedTimer = setTimeout(() => {
42
+ this.savedTimer = null;
43
+ this.setState({ showSaved: false });
44
+ }, 2000);
45
+ this.setState({ savedCount: this.state.savedCount + 1, showSaved: true });
46
+ }
47
+ }
48
+ componentWillUnmount() {
49
+ if (this.saving) {
50
+ clearTimeout(this.saving);
51
+ }
52
+ if (this.savedTimer) {
53
+ clearTimeout(this.savedTimer);
54
+ }
55
+ }
56
+ onSave() {
57
+ if (this.saving) {
58
+ clearTimeout(this.saving);
59
+ }
60
+ // if saving fails, the settings stay changed: forget the click after a while
61
+ this.saving = setTimeout(() => (this.saving = null), 10000);
62
+ this.props.onSave(false);
27
63
  }
28
64
  render() {
29
65
  const noTextOnButtons = this.props.noTextOnButtons;
@@ -49,8 +85,8 @@ export class SaveCloseButtons extends React.Component {
49
85
  , {
50
86
  // position="absolute"
51
87
  style: style },
52
- React.createElement(Fab, { variant: "extended", "aria-label": "Save", disabled: !this.props.changed || this.props.error, onClick: () => this.props.onSave(false), style: buttonStyle },
53
- React.createElement(IconSave, { style: !noTextOnButtons ? styles.buttonIcon : undefined }),
88
+ React.createElement(Fab, { variant: "extended", "aria-label": "Save", disabled: !this.props.changed || this.props.error, onClick: () => this.onSave(), style: buttonStyle },
89
+ this.state.showSaved ? (React.createElement(IconResult, { type: "success", replay: this.state.savedCount, style: !noTextOnButtons ? styles.buttonIcon : undefined })) : (React.createElement(IconSave, { style: !noTextOnButtons ? styles.buttonIcon : undefined })),
54
90
  !noTextOnButtons && I18n.t('ra_Save')),
55
91
  React.createElement(Fab, { variant: "extended", "aria-label": "Save and close", disabled: !this.props.changed || this.props.error, onClick: () => this.props.onSave(true), style: { ...buttonStyle, ...{ marginLeft: 10 } } },
56
92
  React.createElement(IconSave, { style: !noTextOnButtons ? styles.buttonIcon : undefined }),
@@ -1 +1 @@
1
- {"version":3,"file":"SaveCloseButtons.js","sourceRoot":"./src/","sources":["Components/SaveCloseButtons.tsx"],"names":[],"mappings":"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","sourcesContent":["// please do not delete React, as without it other projects could not be compiled: ReferenceError: React is not defined\nimport React, { type JSX } from 'react';\n\nimport { Fab, Toolbar } from '@mui/material';\n\nimport { Save as IconSave, Close as IconClose } from '@mui/icons-material';\n\nimport { I18n } from '../i18n';\nimport type { IobTheme } from '../types';\n\nconst styles: Record<string, React.CSSProperties> = {\n buttonIcon: {\n marginRight: 8,\n },\n};\n\ninterface SaveCloseButtonsProps {\n /* Are the buttons without text */\n noTextOnButtons?: boolean;\n /* Theme object (from this.state.theme) */\n theme: IobTheme;\n /* bottom position 0 or 38 for iFrame */\n isIFrame?: boolean;\n /* is used in new React */\n newReact?: boolean;\n /* on Save handler */\n onSave: (close: boolean) => void;\n /* on Close handler */\n onClose: () => void;\n dense?: boolean;\n paddingLeft?: number;\n changed: boolean;\n error?: boolean;\n}\n\nexport class SaveCloseButtons extends React.Component<SaveCloseButtonsProps> {\n private readonly isIFrame: boolean;\n\n constructor(props: SaveCloseButtonsProps) {\n super(props);\n const newReact = props.newReact === undefined ? true : props.newReact;\n\n if (props.isIFrame !== undefined) {\n this.isIFrame = props.isIFrame;\n } else {\n try {\n this.isIFrame = !newReact && window.self !== window.top;\n } catch {\n this.isIFrame = !newReact;\n }\n }\n }\n\n render(): JSX.Element {\n const noTextOnButtons = this.props.noTextOnButtons;\n const buttonStyle: React.CSSProperties = {\n borderRadius: this.props.theme.saveToolbar.button.borderRadius || 3,\n height: this.props.theme.saveToolbar.button.height || 32,\n };\n\n const style: React.CSSProperties = {\n bottom: this.isIFrame ? 38 : 0,\n left: this.props.paddingLeft || 0,\n right: 0,\n position: 'absolute',\n background: this.props.theme.saveToolbar.background,\n };\n if (this.props.dense) {\n style.minHeight = 48;\n }\n\n if (this.props.error) {\n buttonStyle.border = '1px solid red';\n }\n\n return (\n <Toolbar\n // position=\"absolute\"\n style={style}\n >\n <Fab\n variant=\"extended\"\n aria-label=\"Save\"\n disabled={!this.props.changed || this.props.error}\n onClick={() => this.props.onSave(false)}\n style={buttonStyle}\n >\n <IconSave style={!noTextOnButtons ? styles.buttonIcon : undefined} />\n {!noTextOnButtons && I18n.t('ra_Save')}\n </Fab>\n <Fab\n variant=\"extended\"\n aria-label=\"Save and close\"\n disabled={!this.props.changed || this.props.error}\n onClick={() => this.props.onSave(true)}\n style={{ ...buttonStyle, ...{ marginLeft: 10 } }}\n >\n <IconSave style={!noTextOnButtons ? styles.buttonIcon : undefined} />\n {!noTextOnButtons ? I18n.t('ra_Save and close') : '+'}\n {noTextOnButtons && <IconClose />}\n </Fab>\n <div style={{ flexGrow: 1 }} />\n <Fab\n variant=\"extended\"\n aria-label=\"Close\"\n onClick={() => this.props.onClose()}\n style={buttonStyle}\n >\n <IconClose style={!noTextOnButtons ? styles.buttonIcon : undefined} />\n {!noTextOnButtons && I18n.t('ra_Close')}\n </Fab>\n </Toolbar>\n );\n }\n}\n"]}
1
+ {"version":3,"file":"SaveCloseButtons.js","sourceRoot":"./src/","sources":["Components/SaveCloseButtons.tsx"],"names":[],"mappings":"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","sourcesContent":["// please do not delete React, as without it other projects could not be compiled: ReferenceError: React is not defined\nimport React, { type JSX } from 'react';\n\nimport { Fab, Toolbar } from '@mui/material';\n\nimport { Save as IconSave, Close as IconClose } from '@mui/icons-material';\n\nimport { I18n } from '../i18n';\nimport type { IobTheme } from '../types';\nimport { IconResult } from './AnimatedIcons/IconResult';\n\nconst styles: Record<string, React.CSSProperties> = {\n buttonIcon: {\n marginRight: 8,\n },\n};\n\ninterface SaveCloseButtonsProps {\n /* Are the buttons without text */\n noTextOnButtons?: boolean;\n /* Theme object (from this.state.theme) */\n theme: IobTheme;\n /* bottom position 0 or 38 for iFrame */\n isIFrame?: boolean;\n /* is used in new React */\n newReact?: boolean;\n /* on Save handler */\n onSave: (close: boolean) => void;\n /* on Close handler */\n onClose: () => void;\n dense?: boolean;\n paddingLeft?: number;\n changed: boolean;\n error?: boolean;\n}\n\ninterface SaveCloseButtonsState {\n /** How often the settings were saved; a check mark is drawn on the save button after each save */\n savedCount: number;\n showSaved: boolean;\n}\n\nexport class SaveCloseButtons extends React.Component<SaveCloseButtonsProps, SaveCloseButtonsState> {\n private readonly isIFrame: boolean;\n\n /** The save button was pressed and the settings are not stored yet */\n private saving: ReturnType<typeof setTimeout> | null = null;\n\n private savedTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(props: SaveCloseButtonsProps) {\n super(props);\n const newReact = props.newReact === undefined ? true : props.newReact;\n\n if (props.isIFrame !== undefined) {\n this.isIFrame = props.isIFrame;\n } else {\n try {\n this.isIFrame = !newReact && window.self !== window.top;\n } catch {\n this.isIFrame = !newReact;\n }\n }\n this.state = { savedCount: 0, showSaved: false };\n }\n\n componentDidUpdate(prevProps: Readonly<SaveCloseButtonsProps>): void {\n // the settings are stored, when nothing is changed anymore after a click on \"Save\"\n if (this.saving && prevProps.changed && !this.props.changed) {\n clearTimeout(this.saving);\n this.saving = null;\n if (this.savedTimer) {\n clearTimeout(this.savedTimer);\n }\n this.savedTimer = setTimeout(() => {\n this.savedTimer = null;\n this.setState({ showSaved: false });\n }, 2000);\n this.setState({ savedCount: this.state.savedCount + 1, showSaved: true });\n }\n }\n\n componentWillUnmount(): void {\n if (this.saving) {\n clearTimeout(this.saving);\n }\n if (this.savedTimer) {\n clearTimeout(this.savedTimer);\n }\n }\n\n onSave(): void {\n if (this.saving) {\n clearTimeout(this.saving);\n }\n // if saving fails, the settings stay changed: forget the click after a while\n this.saving = setTimeout(() => (this.saving = null), 10000);\n this.props.onSave(false);\n }\n\n render(): JSX.Element {\n const noTextOnButtons = this.props.noTextOnButtons;\n const buttonStyle: React.CSSProperties = {\n borderRadius: this.props.theme.saveToolbar.button.borderRadius || 3,\n height: this.props.theme.saveToolbar.button.height || 32,\n };\n\n const style: React.CSSProperties = {\n bottom: this.isIFrame ? 38 : 0,\n left: this.props.paddingLeft || 0,\n right: 0,\n position: 'absolute',\n background: this.props.theme.saveToolbar.background,\n };\n if (this.props.dense) {\n style.minHeight = 48;\n }\n\n if (this.props.error) {\n buttonStyle.border = '1px solid red';\n }\n\n return (\n <Toolbar\n // position=\"absolute\"\n style={style}\n >\n <Fab\n variant=\"extended\"\n aria-label=\"Save\"\n disabled={!this.props.changed || this.props.error}\n onClick={() => this.onSave()}\n style={buttonStyle}\n >\n {this.state.showSaved ? (\n <IconResult\n type=\"success\"\n replay={this.state.savedCount}\n style={!noTextOnButtons ? styles.buttonIcon : undefined}\n />\n ) : (\n <IconSave style={!noTextOnButtons ? styles.buttonIcon : undefined} />\n )}\n {!noTextOnButtons && I18n.t('ra_Save')}\n </Fab>\n <Fab\n variant=\"extended\"\n aria-label=\"Save and close\"\n disabled={!this.props.changed || this.props.error}\n onClick={() => this.props.onSave(true)}\n style={{ ...buttonStyle, ...{ marginLeft: 10 } }}\n >\n <IconSave style={!noTextOnButtons ? styles.buttonIcon : undefined} />\n {!noTextOnButtons ? I18n.t('ra_Save and close') : '+'}\n {noTextOnButtons && <IconClose />}\n </Fab>\n <div style={{ flexGrow: 1 }} />\n <Fab\n variant=\"extended\"\n aria-label=\"Close\"\n onClick={() => this.props.onClose()}\n style={buttonStyle}\n >\n <IconClose style={!noTextOnButtons ? styles.buttonIcon : undefined} />\n {!noTextOnButtons && I18n.t('ra_Close')}\n </Fab>\n </Toolbar>\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iobroker/gui-components",
3
- "version": "10.3.15",
3
+ "version": "10.3.16",
4
4
  "description": "Shared React components (React 19 / MUI 9) to develop ioBroker interfaces. Successor of @iobroker/adapter-react-v5.",
5
5
  "author": {
6
6
  "name": "bluefox",