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