github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/asset_client/src/views/agent_detail.js (about)

     1  /**
     2   * Copyright 2017 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * ----------------------------------------------------------------------------
    16   */
    17  'use strict'
    18  
    19  const m = require('mithril')
    20  const _ = require('lodash')
    21  
    22  const api = require('../services/api')
    23  const transactions = require('../services/transactions')
    24  const layout = require('../components/layout')
    25  const forms = require('../components/forms')
    26  
    27  // Returns a string of bullets
    28  const bullets = count => _.fill(Array(count), '•').join('')
    29  
    30  // Basis for info fields with headers
    31  const labeledField = (header, field) => {
    32    return m('.field-group.mt-5', header, field)
    33  }
    34  
    35  const fieldHeader = (label, ...additions) => {
    36    return m('.field-header', [
    37      m('span.h5.mr-3', label),
    38      additions
    39    ])
    40  }
    41  
    42  // Simple info field with a label
    43  const staticField = (label, info) => labeledField(fieldHeader(label), info)
    44  
    45  const toggledInfo = (isToggled, initialView, toggledView) => {
    46    return m('.field-info', isToggled ? toggledView : initialView)
    47  }
    48  
    49  // An in-line form for updating a single field
    50  const infoForm = (state, key, onSubmit, opts) => {
    51    return m('form.form-inline', {
    52      onsubmit: () => onSubmit().then(() => { state.toggled[key] = false })
    53    }, [
    54      m('input.form-control-sm.mr-1', _.assign({
    55        oninput: m.withAttr('value', value => { state.update[key] = value })
    56      }, opts)),
    57      m('button.btn.btn-secondary.btn-sm.mr-1', {
    58        onclick: () => { state.toggled[key] = false }
    59      }, 'Cancel'),
    60      m('button.btn.btn-primary.btn-sm.mr-1', { type: 'submit' }, 'Update')
    61    ])
    62  }
    63  
    64  const privateKeyField = state => {
    65    return labeledField(
    66      fieldHeader('Private Key',
    67        forms.clickIcon('eye', () => {
    68          if (state.toggled.privateKey) {
    69            state.toggled.privateKey = false
    70            return
    71          }
    72          return transactions.getPrivateKey()
    73            .then(privateKey => {
    74              state.toggled.privateKey = privateKey
    75              m.redraw()
    76            })
    77        }),
    78        forms.clickIcon('cloud-download', () => {
    79          return transactions.getPrivateKey()
    80            .then(privateKey => {
    81              forms.triggerDownload(`${state.agent.username}.priv`, privateKey)
    82            })
    83        })),
    84      toggledInfo(
    85        state.toggled.privateKey,
    86        bullets(64),
    87        state.toggled.privateKey))
    88  }
    89  
    90  // Pencil icon that simply toggles visibility
    91  const editIcon = (obj, key) => {
    92    return forms.clickIcon('pencil', () => { obj[key] = !obj[key] })
    93  }
    94  
    95  // Edits a field in state
    96  const editField = (state, label, key) => {
    97    const currentInfo = _.get(state, ['agent', key], '')
    98    const onSubmit = () => {
    99      return api.patch('users', _.pick(state.update, key))
   100        .then(() => { state.agent[key] = state.update[key] })
   101    }
   102  
   103    return labeledField(
   104      fieldHeader(label, editIcon(state.toggled, key)),
   105      toggledInfo(
   106        state.toggled[key],
   107        currentInfo,
   108        infoForm(state, key, onSubmit, {placeholder: currentInfo})))
   109  }
   110  
   111  const passwordField = state => {
   112    const onSubmit = () => {
   113      return transactions.changePassword(state.update.password)
   114        .then(encryptedKey => {
   115          return api.patch('users', {
   116            encryptedKey,
   117            password: state.update.password
   118          })
   119        })
   120        .then(() => m.redraw())
   121    }
   122  
   123    return labeledField(
   124      fieldHeader('Password', editIcon(state.toggled, 'password')),
   125      toggledInfo(
   126        state.toggled.password,
   127        bullets(16),
   128        infoForm(state, 'password', onSubmit, { type: 'password' })))
   129  }
   130  
   131  /**
   132   * Displays information for a particular Agent.
   133   * The information can be edited if the user themself.
   134   */
   135  const AgentDetailPage = {
   136    oninit (vnode) {
   137      vnode.state.toggled = {}
   138      vnode.state.update = {}
   139      api.get(`agents/${vnode.attrs.publicKey}`)
   140        .then(agent => { vnode.state.agent = agent })
   141    },
   142  
   143    view (vnode) {
   144      const publicKey = _.get(vnode.state, 'agent.publicKey', '')
   145  
   146      const profileContent = [
   147        layout.row(privateKeyField(vnode.state)),
   148        layout.row([
   149          editField(vnode.state, 'Username', 'username'),
   150          passwordField(vnode.state)
   151        ]),
   152        layout.row(editField(vnode.state, 'Email', 'email'))
   153      ]
   154  
   155      return [
   156        layout.title(_.get(vnode.state, 'agent.name', '')),
   157        m('.container',
   158          layout.row(staticField('Public Key', publicKey)),
   159          publicKey === api.getPublicKey() ? profileContent : null)
   160      ]
   161    }
   162  }
   163  
   164  module.exports = AgentDetailPage