Skip to content

Commit

Permalink
Working on device manager
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Nov 18, 2024
1 parent f11e6a5 commit 8c25c8a
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 52 deletions.
108 changes: 68 additions & 40 deletions packages/dm-gui-components/src/Communication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,17 @@ interface CommunicationForm {
title?: ioBroker.StringOrTranslated | null | undefined;
label?: ioBroker.StringOrTranslated | null | undefined; // same as title
noTranslation?: boolean; // Do not translate title/label
schema?: JsonFormSchema;
schema: JsonFormSchema;
data?: Record<string, any>;
buttons?: (ActionButton | 'apply' | 'cancel')[];
}

interface CommunicationFormInState extends CommunicationForm {
handleClose?: (data?: Record<string, any>) => void;
originalData: string;
changed: boolean;
}

interface InputAction extends ActionBase {
/** If it is a device action */
deviceId?: string;
Expand All @@ -98,7 +104,7 @@ export type CommunicationState = {
message: string;
handleClose: (confirmation?: boolean) => void;
} | null;
form: (CommunicationForm & { handleClose?: (data?: Record<string, any>) => void }) | null;
form: CommunicationFormInState | null;
progress: {
open: boolean;
progress: number;
Expand Down Expand Up @@ -314,9 +320,22 @@ class Communication<P extends CommunicationProps, S extends CommunicationState>
case 'form':
console.log('Form received');
if (response.form) {
const data: Record<string, any> | undefined = response.form.data;
const originalData: Record<string, any> = {};
if (data) {
Object.keys(data).forEach(key => {
if (data[key] !== undefined) {
originalData[key] = data[key];
}
});
}
response.form.data = JSON.parse(JSON.stringify(originalData)) as Record<string, any>;

this.setState({
form: {
...response.form,
changed: false,
originalData: JSON.stringify(originalData),
handleClose: (data: any) =>
this.setState({ form: null }, () => {
console.log(`Form ${JSON.stringify(data)}`);
Expand Down Expand Up @@ -506,6 +525,7 @@ class Communication<P extends CommunicationProps, S extends CommunicationState>
return (
<Button
key="apply"
disabled={!this.state.form?.changed}
variant={button?.variant || 'contained'}
color={button?.color || 'primary'}
onClick={() => this.state.form?.handleClose && this.state.form.handleClose(this.state.form?.data)}
Expand Down Expand Up @@ -572,11 +592,12 @@ class Communication<P extends CommunicationProps, S extends CommunicationState>
socket={this.props.socket as AdminConnection}
onChange={(data: Record<string, any>) => {
console.log('handleFormChange', { data });
const form: CommunicationForm & { handleClose?: (data?: Record<string, any>) => void } = {
...this.state.form,
const form: CommunicationFormInState = {
...(this.state.form as CommunicationFormInState),
};
if (form) {
form.data = data;
form.changed = JSON.stringify(data) !== form.originalData;
this.setState({ form });
}
}}
Expand Down Expand Up @@ -686,6 +707,42 @@ class Communication<P extends CommunicationProps, S extends CommunicationState>
);
}

onShowInputOk(): void {
if (!this.state.showInput) {
return;
}

const showInput = this.state.showInput;
this.setState({ showInput: null }, () => {
if (showInput.deviceId) {
this.sendActionToInstance(
'dm:deviceAction',
{
actionId: showInput.id,
deviceId: showInput.deviceId,
value:
showInput.inputBefore?.type === 'checkbox'
? !!this.state.inputValue
: showInput.inputBefore?.type === 'number'
? parseFloat(this.state.inputValue as string) || 0
: this.state.inputValue,
},
showInput.refresh,
);
} else {
this.sendActionToInstance('dm:instanceAction', {
actionId: showInput.id,
value:
showInput.inputBefore?.type === 'checkbox'
? !!this.state.inputValue
: showInput.inputBefore?.type === 'number'
? parseFloat(this.state.inputValue as string) || 0
: this.state.inputValue,
});
}
});
}

renderInputDialog(): React.JSX.Element | null {
if (!this.state.showInput || !this.state.showInput.inputBefore) {
return null;
Expand Down Expand Up @@ -745,6 +802,11 @@ class Communication<P extends CommunicationProps, S extends CommunicationState>
fullWidth
value={this.state.inputValue}
onChange={e => this.setState({ inputValue: e.target.value })}
onKeyUp={(e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
this.onShowInputOk();
}
}}
/>
) : null}
{this.state.showInput.inputBefore.type === 'checkbox' ? (
Expand Down Expand Up @@ -791,7 +853,7 @@ class Communication<P extends CommunicationProps, S extends CommunicationState>
<Grid2>
<Slider
value={typeof this.state.inputValue === 'number' ? this.state.inputValue : 0}
onChange={(event: Event, newValue: number) =>
onChange={(_event: Event, newValue: number) =>
this.setState({ inputValue: newValue })
}
/>
Expand Down Expand Up @@ -848,41 +910,7 @@ class Communication<P extends CommunicationProps, S extends CommunicationState>
variant="contained"
disabled={okDisabled}
color="primary"
onClick={() => {
if (!this.state.showInput) {
return;
}

const showInput = this.state.showInput;
this.setState({ showInput: null }, () => {
if (showInput.deviceId) {
this.sendActionToInstance(
'dm:deviceAction',
{
actionId: showInput.id,
deviceId: showInput.deviceId,
value:
showInput.inputBefore?.type === 'checkbox'
? !!this.state.inputValue
: showInput.inputBefore?.type === 'number'
? parseFloat(this.state.inputValue as string) || 0
: this.state.inputValue,
},
showInput.refresh,
);
} else {
this.sendActionToInstance('dm:instanceAction', {
actionId: showInput.id,
value:
showInput.inputBefore?.type === 'checkbox'
? !!this.state.inputValue
: showInput.inputBefore?.type === 'number'
? parseFloat(this.state.inputValue as string) || 0
: this.state.inputValue,
});
}
});
}}
onClick={() => this.onShowInputOk()}
startIcon={<Check />}
>
{getTranslation('yesButtonText')}
Expand Down
72 changes: 60 additions & 12 deletions packages/dm-gui-components/src/Utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { ControlBase } from '@iobroker/dm-utils/build/types/base';
import type { ActionBase } from '@iobroker/dm-utils/build/types/api';
import {
Add,
Article,
Bluetooth,
BluetoothDisabled,
Delete,
Expand Down Expand Up @@ -36,6 +37,30 @@ import {

import { I18n, Icon } from '@iobroker/adapter-react-v5';

/**
* Get Icon by font-awesome name. Do not use these name, use names from getIconByName
*
* @param icon font-awesome icon name
* Only following font-awesome icons are supported:
* - fa-trash-can, fa-trash
* - fa-pen
* - fa-redo-alt
* - fa-plus
* - fa-qrcode, qrcode
* - fa-wifi
* - fa-wifi-slash
* - fa-bluetooth
* - fa-bluetooth-slash
* - fa-eye
* - fa-search
* - fa-unlink
* - fa-link
* - fa-search-location
* - fa-play
* - fa-stop
* - fa-pause
* @param color color of the icon
*/
function getFaIcon(icon: string, color?: string): React.JSX.Element | null {
const iconStyle = icon
.split(' ')
Expand Down Expand Up @@ -93,21 +118,41 @@ function getFaIcon(icon: string, color?: string): React.JSX.Element | null {
if (iconStyle.includes('fa-pause')) {
return <Pause style={{ color }} />;
}
if (iconStyle.includes('forward')) {
return <FastForward style={{ color }} />;
}
if (iconStyle.includes('rewind')) {
return <FastRewind style={{ color }} />;
}
if (iconStyle.includes('users') || iconStyle.includes('group')) {
return <Group style={{ color }} />;
}
if (iconStyle.includes('user')) {
return <Person style={{ color }} />;
}
return <QuestionMark style={{ color }} />;
}

/**
* Get Icon by name or by action
*
* @param name action name
* possible action or icon names are
* - edit, rename
* - delete
* - refresh
* - newDevice, new, add
* - discover, search
* - unpairDevice, unpair
* - pairDevice, pair
* - identify
* - play
* - stop
* - pause
* - forward, next
* - rewind, previous
* - lamp, light
* - backlight
* - dimmer
* - socket
* - settings
* - users, group
* - user
* - qrcode
* - identify
* - info
* - lines
* @param altName icon name
* @param color color of the icon
*/
function getIconByName(name: string, altName?: string, color?: string): React.JSX.Element | null {
if (name === 'edit' || name === 'rename' || altName === 'edit' || altName === 'rename') {
return <Edit style={{ color }} />;
Expand Down Expand Up @@ -185,6 +230,9 @@ function getIconByName(name: string, altName?: string, color?: string): React.JS
if (name === 'info' || altName === 'info') {
return <Info style={{ color }} />;
}
if (name === 'lines' || altName === 'lines') {
return <Article style={{ color }} />;
}
return <QuestionMark style={{ color }} />;
}

Expand Down

0 comments on commit 8c25c8a

Please sign in to comment.