github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/fish_client/src/views/add_fish_form.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  
    18  const m = require('mithril')
    19  
    20  const api = require('../services/api')
    21  const payloads = require('../services/payloads')
    22  const transactions = require('../services/transactions')
    23  const parsing = require('../services/parsing')
    24  const {MultiSelect} = require('../components/forms')
    25  const layout = require('../components/layout')
    26  
    27  /**
    28   * Possible selection options
    29   */
    30  const authorizableProperties = [
    31    ['location', 'Location'],
    32    ['temperature', 'Temperature'],
    33    ['tilt', 'Tilt'],
    34    ['shock', 'Shock']
    35  ]
    36  
    37  /**
    38   * The Form for tracking a new fish.
    39   */
    40  const AddFishForm = {
    41    oninit (vnode) {
    42      // Initialize the empty reporters fields
    43      vnode.state.reporters = [
    44        {
    45          reporterKey: '',
    46          properties: []
    47        }
    48      ]
    49      api.get('agents')
    50        .then(agents => {
    51          const publicKey = api.getPublicKey()
    52          vnode.state.agents = agents.filter(agent => agent.key !== publicKey)
    53        })
    54    },
    55  
    56    view (vnode) {
    57      return m('.fish_form',
    58               m('form', {
    59                 onsubmit: (e) => {
    60                   e.preventDefault()
    61                   _handleSubmit(vnode.attrs.signingKey, vnode.state)
    62                 }
    63               },
    64               m('legend', 'Track New Fish'),
    65               _formGroup('Serial Number', m('input.form-control', {
    66                 type: 'text',
    67                 oninput: m.withAttr('value', (value) => {
    68                   vnode.state.serialNumber = value
    69                 }),
    70                 value: vnode.state.serialNumber
    71               })),
    72               _formGroup('Species (ASFIS 3-letter code)', m('input.form-control', {
    73                 type: 'text',
    74                 oninput: m.withAttr('value', (value) => {
    75                   vnode.state.species = value
    76                 }),
    77                 value: vnode.state.species
    78               })),
    79  
    80               layout.row([
    81                 _formGroup('Length (m)', m('input.form-control', {
    82                   type: 'number',
    83                   min: 0,
    84                   step: 'any',
    85                   oninput: m.withAttr('value', (value) => {
    86                     vnode.state.lengthInCM = value
    87                   }),
    88                   value: vnode.state.lengthInCM
    89                 })),
    90                 _formGroup('Weight (kg)', m('input.form-control', {
    91                   type: 'number',
    92                   step: 'any',
    93                   oninput: m.withAttr('value', (value) => {
    94                     vnode.state.weightInKg = value
    95                   }),
    96                   value: vnode.state.weightInKg
    97                 }))
    98               ]),
    99  
   100               layout.row([
   101                 _formGroup('Latitude', m('input.form-control', {
   102                   type: 'number',
   103                   step: 'any',
   104                   min: -90,
   105                   max: 90,
   106                   oninput: m.withAttr('value', (value) => {
   107                     vnode.state.latitude = value
   108                   }),
   109                   value: vnode.state.latitude
   110                 })),
   111                 _formGroup('Longitude', m('input.form-control', {
   112                   type: 'number',
   113                   step: 'any',
   114                   min: -180,
   115                   max: 180,
   116                   oninput: m.withAttr('value', (value) => {
   117                     vnode.state.longitude = value
   118                   }),
   119                   value: vnode.state.longitude
   120                 }))
   121               ]),
   122  
   123               m('.reporters.form-group',
   124                 m('label', 'Authorize Reporters'),
   125  
   126                 vnode.state.reporters.map((reporter, i) =>
   127                   m('.row.mb-2',
   128                     m('.col-sm-8',
   129                       m('input.form-control', {
   130                         type: 'text',
   131                         placeholder: 'Add reporter by name or public key...',
   132                         oninput: m.withAttr('value', (value) => {
   133                           // clear any previously matched values
   134                           vnode.state.reporters[i].reporterKey = null
   135                           const reporter = vnode.state.agents.find(agent => {
   136                             return agent.name === value || agent.key === value
   137                           })
   138                           if (reporter) {
   139                             vnode.state.reporters[i].reporterKey = reporter.key
   140                           }
   141                         }),
   142                         onblur: () => _updateReporters(vnode, i)
   143                       })),
   144  
   145                     m('.col-sm-4',
   146                       m(MultiSelect, {
   147                         label: 'Select Fields',
   148                         options: authorizableProperties,
   149                         selected: reporter.properties,
   150                         onchange: (selection) => {
   151                           vnode.state.reporters[i].properties = selection
   152                         }
   153                       }))))),
   154  
   155               m('.row.justify-content-end.align-items-end',
   156                 m('col-2',
   157                   m('button.btn.btn-primary',
   158                     'Create Record')))))
   159    }
   160  }
   161  
   162  /**
   163   * Update the reporter's values after a change occurs in the name of the
   164   * reporter at the given reporterIndex. If it is empty, and not the only
   165   * reporter in the list, remove it.  If it is not empty and the last item
   166   * in the list, add a new, empty reporter to the end of the list.
   167   */
   168  const _updateReporters = (vnode, reporterIndex) => {
   169    let reporterInfo = vnode.state.reporters[reporterIndex]
   170    let lastIdx = vnode.state.reporters.length - 1
   171    if (!reporterInfo.reporterKey && reporterIndex !== lastIdx) {
   172      vnode.state.reporters.splice(reporterIndex, 1)
   173    } else if (reporterInfo.reporterKey && reporterIndex === lastIdx) {
   174      vnode.state.reporters.push({
   175        reporterKey: '',
   176        properties: []
   177      })
   178    }
   179  }
   180  
   181  /**
   182   * Handle the form submission.
   183   *
   184   * Extract the appropriate values to pass to the create record transaction.
   185   */
   186  const _handleSubmit = (signingKey, state) => {
   187    const recordPayload = payloads.createRecord({
   188      recordId: state.serialNumber,
   189      recordType: 'fish',
   190      properties: [
   191        {
   192          name: 'species',
   193          stringValue: state.species,
   194          dataType: payloads.createRecord.enum.STRING
   195        },
   196        {
   197          name: 'length',
   198          numberValue: parsing.toInt(state.lengthInCM),
   199          dataType: payloads.createRecord.enum.NUMBER
   200        },
   201        {
   202          name: 'weight',
   203          numberValue: parsing.toInt(state.weightInKg),
   204          dataType: payloads.createRecord.enum.NUMBER
   205        },
   206        {
   207          name: 'location',
   208          locationValue: {
   209            latitude: parsing.toInt(state.latitude),
   210            longitude: parsing.toInt(state.longitude)
   211          },
   212          dataType: payloads.createRecord.enum.LOCATION
   213        }
   214      ]
   215    })
   216  
   217    const reporterPayloads = state.reporters
   218      .filter((reporter) => !!reporter.reporterKey)
   219      .map((reporter) => payloads.createProposal({
   220        recordId: state.serialNumber,
   221        receivingAgent: reporter.reporterKey,
   222        role: payloads.createProposal.enum.REPORTER,
   223        properties: reporter.properties
   224      }))
   225  
   226    transactions.submit([recordPayload].concat(reporterPayloads), true)
   227      .then(() => m.route.set(`/fish/${state.serialNumber}`))
   228  }
   229  
   230  /**
   231   * Create a form group (this is a styled form-group with a label).
   232   */
   233  const _formGroup = (label, formEl) =>
   234    m('.form-group',
   235      m('label', label),
   236      formEl)
   237  
   238  module.exports = AddFishForm