github.com/stampzilla/stampzilla-go@v2.0.0-rc9+incompatible/nodes/stampzilla-server/web/src/routes/dashboard/Device.js (about)

     1  import React, { Component } from 'react';
     2  import {
     3    mdiLightbulb,
     4    mdiPower,
     5    mdiPulse,
     6  } from '@mdi/js';
     7  import Icon from '@mdi/react';
     8  import classnames from 'classnames';
     9  
    10  import './device.scss';
    11  import { write } from '../../components/Websocket';
    12  import Trait from './Trait';
    13  
    14  export const traitPriority = [
    15    'OnOff',
    16    'Brightness',
    17    'ColorSetting',
    18  ];
    19  
    20  export const traitNames = {
    21    Brightness: 'Brightness',
    22    OnOff: 'Power',
    23    ColorSetting: 'Temperature',
    24  };
    25  
    26  export const traitStates = {
    27    Brightness: 'brightness',
    28    OnOff: 'on',
    29    ColorSetting: 'temperature',
    30  };
    31  
    32  const icons = {
    33    light: mdiLightbulb,
    34    switch: mdiPower,
    35    sensor: mdiPulse,
    36  };
    37  
    38  const guessType = (device) => {
    39    const traits = (device.get('traits') && device.get('traits').toJS()) || [];
    40  
    41    if (traits.length === 0) {
    42      return 'sensor';
    43    }
    44  
    45    if (traits.indexOf('Brightness') !== -1) {
    46      return 'light';
    47    }
    48    if (traits.indexOf('ColorSetting') !== -1) {
    49      return 'light';
    50    }
    51    if (traits.indexOf('OnOff') !== -1) {
    52      return 'switch';
    53    }
    54  
    55    return null;
    56  };
    57  
    58  class Device extends Component {
    59    onChange = (device, trait) => (value) => {
    60      const clone = device.toJS();
    61      clone.state[traitStates[trait]] = value;
    62  
    63      write({
    64        type: 'state-change',
    65        body: {
    66          [clone.id]: clone,
    67        },
    68      });
    69    }
    70  
    71    render() {
    72      const { device } = this.props;
    73  
    74      const sortedTraits = device.get('traits') && device.get('traits').sort((a, b) => {
    75        const prioA = traitPriority.findIndex(trait => trait === a);
    76        const prioB = traitPriority.findIndex(trait => trait === b);
    77        return prioA - prioB;
    78      });
    79  
    80      const primaryTrait = sortedTraits && sortedTraits.first();
    81      const secondaryTraits = sortedTraits && sortedTraits.shift();
    82  
    83      const type = device.get('type') || guessType(device);
    84      const icon = icons[type];
    85  
    86      return (
    87        <div className={classnames({
    88          'd-flex flex-column': true,
    89          offline: !device.get('online'),
    90        })}
    91        >
    92          <div className="d-flex align-items-center py-1">
    93            <div style={{ width: '1.5rem' }}>
    94              { icon &&
    95              <Icon
    96                path={icon}
    97                size={1}
    98              />
    99              }
   100            </div>
   101            <div className="flex-grow-1 mr-2">
   102              {device.get('name')}<br />
   103            </div>
   104            {primaryTrait &&
   105            <Trait
   106              trait={primaryTrait}
   107              device={device}
   108              state={traitStates[primaryTrait] && device.getIn(['state', traitStates[primaryTrait]])}
   109              onChange={this.onChange(device, primaryTrait)}
   110            />
   111            }
   112            {!primaryTrait &&
   113              <span>{JSON.stringify(device.get('state'))}</span>
   114            }
   115          </div>
   116          <div className="d-flex flex-column ml-4">
   117            {secondaryTraits && secondaryTraits.map(trait => (
   118              <div className="d-flex ml-3" key={trait}>
   119                <div className="mr-2">{traitNames[trait] || trait}</div>
   120                <div className="flex-grow-1 d-flex align-items-center">
   121                  <Trait
   122                    trait={trait}
   123                    device={device}
   124                    state={traitStates[trait] && device.getIn(['state', traitStates[trait]])}
   125                    onChange={this.onChange(device, trait)}
   126                  />
   127                </div>
   128              </div>
   129            ))}
   130          </div>
   131        </div>
   132      );
   133    }
   134  }
   135  
   136  export default Device;