Repository: empire-db Updated Branches: refs/heads/master 878e45c20 -> b2de3c7c2
EMPIREDB-271 Vue empire components Project: http://git-wip-us.apache.org/repos/asf/empire-db/repo Commit: http://git-wip-us.apache.org/repos/asf/empire-db/commit/b2de3c7c Tree: http://git-wip-us.apache.org/repos/asf/empire-db/tree/b2de3c7c Diff: http://git-wip-us.apache.org/repos/asf/empire-db/diff/b2de3c7c Branch: refs/heads/master Commit: b2de3c7c2b3433804a9826cb1eba2220660b09dd Parents: 878e45c Author: Rainer Döbele <[email protected]> Authored: Fri Sep 28 14:34:15 2018 +0200 Committer: Rainer Döbele <[email protected]> Committed: Fri Sep 28 14:34:15 2018 +0200 ---------------------------------------------------------------------- .../src/main/vue/src/components/e-control.vue | 13 ++- .../src/main/vue/src/components/e-input.vue | 101 +++++++++++++++--- .../src/main/vue/src/components/e-label.vue | 46 +++++++- .../src/main/vue/src/components/e-record.vue | 32 ++++++ .../src/main/vue/src/components/e-value.vue | 74 +++++++++++-- .../src/main/vue/src/pages/employeeDetail.vue | 55 +++++----- .../src/main/vue/src/pages/employeeList.vue | 104 ++++++++++--------- 7 files changed, 316 insertions(+), 109 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/empire-db/blob/b2de3c7c/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-control.vue ---------------------------------------------------------------------- diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-control.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-control.vue index ef816b9..f9de8f1 100644 --- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-control.vue +++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-control.vue @@ -15,8 +15,8 @@ --> <script> // import $ from 'jquery' - import Label from './e-label.vue' - import Input from './e-input.vue' + import eLabel from './e-label.vue' + import eInput from './e-input.vue' export default { functional: true, @@ -26,15 +26,18 @@ column: { required: true }, + record: { + type: Object + }, data: { - required: true + type: Object } }, render (createElement, context) { const label = createElement('td', {class: 'eCtlLabel'} - , [ createElement(Label, { props: Object.assign({column: context.props.column}) }) ]) + , [ createElement(eLabel, { props: Object.assign({column: context.props.column, forInput: true}) }) ]) const input = createElement('td', {class: 'eCtlInput'} - , [ createElement(Input, { props: context.props }) ]) + , [ createElement(eInput, { props: context.props }) ]) /* const input = createElement('td', {class: 'eCtlInput'} , [ createElement('input', { http://git-wip-us.apache.org/repos/asf/empire-db/blob/b2de3c7c/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue ---------------------------------------------------------------------- diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue index fadc680..3d6d14e 100644 --- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue +++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-input.vue @@ -15,55 +15,126 @@ --> <template> <div class="eInpWrap"> - <template v-if="column.options"> - <select :id="'CTL_' + column.name" :name="column.name" class="eInput eTypeSelect" @change="updateValue($event)"> - <template v-if="column.required === false && column.options[''] === undefined"> - <option value="" :selected="inputValue === null"></option> + <template v-if="meta.readonly"> + <e-value :column="meta" :data="_recordData"/> + </template> + <template v-else-if="meta.options"> + <select :id="'CTL_' + meta.name" :name="meta.name" class="eInput eTypeSelect" @change="updateValue($event)"> + <template v-if="meta.required === false && meta.options[''] === undefined"> + <option value="" :selected="isValueEqualTo(null)"></option> </template> - <template v-for="(value, key) in column.options"> - <option :value="key" :selected="inputValue === key">{{value}}</option> + <template v-for="(value, key) in meta.options"> + <option :value="key" :selected="isValueEqualTo(key)">{{value}}</option> </template> </select> </template> <template v-else> - <input :id="'CTL_' + column.name" :name="column.name" class="eInput eTypeText" lang="en" type="text" :maxlength="column.maxLength" :value="inputValue" @input="updateValue($event)"> + <input :id="'CTL_' + meta.name" :name="meta.name" class="eInput eTypeText" lang="en" type="text" :maxlength="meta.maxLength" :value="inputValue" @input="updateValue($event)"> </template> </div> </template> <script> import EMPAPI from '../api/emp-api' + import eValue from '../components/e-value' import $ from 'jquery' export default { name: 'e-input', + components: { + eValue + }, + props: { column: { required: true }, + record: { + type: Object + }, data: { - required: true + type: Object } }, computed: { - inputValue: function () { - return this.data[this.column.property] + _record: function () { + // find record + let record = this.record + if (record === undefined) { + let parent = this.$parent + while (parent) { + if (parent.record) { + record = parent.record + break + } + parent = parent.$parent + } + } + // check record + if (record === undefined) { + throw new TypeError('e-input: No data or record provided!') + } + if (record.meta === undefined) { + throw new TypeError('e-input: Invalid record param: no meta property!') + } + if (record.data === undefined) { + throw new TypeError('e-input: Invalid record param: no data property!') + } + return record + }, + _recordData: function () { + if (this.data === undefined) { + // get column from meta + return this._record.data + } + return this.data + }, + meta: function () { + // get column from meta + if (typeof this.column === 'string' || this.column instanceof String) { + // from record + return this._record.meta[this.column] + } + if (this.column.dataType === undefined) { + throw new TypeError('e-input: Invalid column param!') + } + return this.column + }, + inputValue: { + get: function () { + // find record + const prop = this.meta.property + return this._recordData[prop] + }, + set: function (value) { + const prop = this.meta.property + this._recordData[prop] = value + } } }, + /* created: function () { - // alert('column=' + this.column.name + ' is ' + this.data[this.column.property]) + EMPAPI.debug('Input for ' + this.meta.name + ' created!') }, + */ methods: { + isValueEqualTo (value) { + const inp = this.inputValue + if (value === '') { + value = null + } + return (inp === value) + }, updateValue (event) { - var inp = $(event.currentTarget) - var val = inp.val() + let inp = $(event.currentTarget) + let val = inp.val() // this.$emit('input', val) - this.data[this.column.property] = val + this.inputValue = val // debug - EMPAPI.debug('Value for: "' + this.column.name + '" has been set to: ' + this.data[this.column.property]) + EMPAPI.debug('Value for: "' + this.meta.name + '" has been set to: ' + val) } } } http://git-wip-us.apache.org/repos/asf/empire-db/blob/b2de3c7c/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-label.vue ---------------------------------------------------------------------- diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-label.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-label.vue index 80d3cdd..33fa16d 100644 --- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-label.vue +++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-label.vue @@ -14,22 +14,58 @@ License. --> <template> - <label class="eLabel" :for="'CTL_' + column.name">{{column.title}}:</label> + <label v-if="forInput" class="eLabel" :for="'CTL_' + meta.name">{{meta.title}}:</label> + <span v-else class="eLabel" >{{meta.title}}</span> </template> <script> - // import $ from 'jquery' - export default { name: 'e-label', props: { column: { required: true + }, + record: { + type: Object + }, + forInput: { + type: Boolean, + default: false } }, - created: function () { - // alert('column=' + this.column + ' test: ' + this.test) + computed: { + meta: function () { + // get column from meta + if (typeof this.column === 'string' || this.column instanceof String) { + // find record + let record = this.record + if (record === undefined) { + let parent = this.$parent + while (parent) { + if (parent.record) { + record = parent.record + break + } + parent = parent.$parent + } + } + // check record + if (record === undefined) { + throw new TypeError('e-label: No data or record provided!') + } + if (record.meta === undefined) { + throw new TypeError('e-label: Invalid record param: no meta property!') + } + // find in record.meta + return record.meta[this.column] + } + // column provided directly + if (this.column.dataType === undefined) { + throw new TypeError('e-label: Invalid column param!') + } + return this.column + } } } </script> http://git-wip-us.apache.org/repos/asf/empire-db/blob/b2de3c7c/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-record.vue ---------------------------------------------------------------------- diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-record.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-record.vue new file mode 100644 index 0000000..2918d14 --- /dev/null +++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-record.vue @@ -0,0 +1,32 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version + 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 Unless required by + applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. See the License for + the specific language governing permissions and limitations under the + License. + --> +<template> + <div v-if="record" class="eRecord"> + <slot></slot> + </div> +</template> +<script> + // import $ from 'jquery' + export default { + name: 'e-record', + props: { + record: { + type: Object, + required: true + } + } + } +</script> http://git-wip-us.apache.org/repos/asf/empire-db/blob/b2de3c7c/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue ---------------------------------------------------------------------- diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue index 9ecb56e..af7cb65 100644 --- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue +++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/components/e-value.vue @@ -14,7 +14,6 @@ License. --> <script> - // import $ from 'jquery' export default { functional: true, name: 'e-value', @@ -23,17 +22,78 @@ column: { required: true }, + record: { + type: Object + }, data: { - required: true + type: Object } }, + render (createElement, context) { - var value = context.props.data[context.props.column.property] - if (context.props.column.options) { - value = context.props.column.options[value] + /* + * function to get the record (if nesessary) + */ + function _record (context) { + // find record + let record = context.props.record + if (record === undefined) { + let parent = context.parent + while (parent) { + if (parent.record) { + record = parent.record + break + } + parent = parent.$parent + } + } + // check record + if (record === undefined) { + throw new TypeError('e-input: No data or record provided!') + } + if (record.meta === undefined) { + throw new TypeError('e-input: Invalid record param: no meta property!') + } + if (record.data === undefined) { + throw new TypeError('e-input: Invalid record param: no data property!') + } + return record + } + /* + * function to get the column meta data + */ + function _meta (column, context) { + // get column from meta + if (typeof column === 'string' || column instanceof String) { + // from record + return _record(context).meta[column] + } + if (column.dataType === undefined) { + throw new TypeError('e-value: Invalid column param!') + } + return column + } + /* + * function to get the raw data value + */ + function _value (prop, context) { + // find record + if (context.props.data === undefined) { + // get column from meta + return _record(context).data[prop] + } + return context.props.data[prop] + } + /* + * render implementation + */ + const meta = _meta(context.props.column, context) + let value = _value(meta.property, context) + if (meta.options) { + value = meta.options[value] } - const text = createElement('span', null, value) - return text + // create span with value + return createElement('span', {class: 'eVal'}, value) } } http://git-wip-us.apache.org/repos/asf/empire-db/blob/b2de3c7c/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue ---------------------------------------------------------------------- diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue index 616e0d2..a866ec0 100644 --- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue +++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeDetail.vue @@ -18,24 +18,26 @@ <h1>Employee-Details for {{employeeId}}</h1> - <table class="inputForm" v-if="record" style="width:400px"> - <colgroup> - <col width="120px"/> - <col/> - </colgroup> - <tr><e-control :data="record.data" :column="record.meta.salutation" /></tr> - <tr><e-control :data="record.data" :column="record.meta.firstName" /></tr> - <tr><e-control :data="record.data" :column="record.meta.lastName" /></tr> - <tr><e-control :data="record.data" :column="record.meta.dateOfBirth" format="[yyyy-MM-dd]"/></tr> - <tr><e-control :data="record.data" :column="record.meta.departmentId" /></tr> - <tr><e-control :data="record.data" :column="record.meta.gender" /> </tr> - <tr><e-control :data="record.data" :column="record.meta.phoneNumber" /></tr> - <tr><e-control :data="record.data" :column="record.meta.email" /></tr> - <tr><e-control :data="record.data" :column="record.meta.retired" /></tr> - </table> + <e-record :record="employeeRecord"> + <table class="inputForm" style="width:400px"> + <colgroup> + <col width="120px"/> + <col/> + </colgroup> + <tr><e-control column="salutation" /></tr> + <tr><e-control column="firstName" /></tr> + <tr><e-control column="lastName" /></tr> + <tr><e-control column="dateOfBirth" format="[yyyy-MM-dd]"/></tr> + <tr><e-control column="departmentId" /></tr> + <tr><e-control column="gender" /> </tr> + <tr><e-control column="phoneNumber" /></tr> + <tr><e-control column="email" /></tr> + <tr><e-control column="retired" /></tr> + </table> + </e-record> <div class="rdp-weeknavbar"> - <button class="rdp-button" @click="showList($event)">Back</button> + <button class="rdp-button" @click="returnToList($event)">Back</button> <button @click="saveChanges($event)">Save</button> </div> @@ -44,19 +46,21 @@ <script> import EMPAPI from '../api/emp-api' + import eRecord from '../components/e-record.vue' import eControl from '../components/e-control.vue' export default { name: 'details', components: { + eRecord, eControl }, data () { return { employeeId: 0, - record: {} + employeeRecord: undefined } }, @@ -70,24 +74,23 @@ loadDetails: function (event) { EMPAPI.debug('load employee record') EMPAPI.loadEmployeeRecord(this.employeeId) - .done(response => (this.record = response)) + .done(response => (this.onLoadDone(response))) /* - this.datum = this.$route.params.datum - this.bereichId = this.$route.params.bereichId - RDPAPI.loadHints(this.datum, this.bereichId) - .done(response => (this.info = response)) .fail(() => this.$router.push('/login')) */ }, saveChanges: function (event) { EMPAPI.debug('load employee record') - EMPAPI.updateEmployee(this.record.data) - .done(response => (this.setResult(response))) + EMPAPI.updateEmployee(this.employeeRecord.data) + .done(response => (this.onSaveDone(response))) }, - setResult (result) { + onLoadDone (result) { + this.employeeRecord = result + }, + onSaveDone (result) { alert('Save OK!') }, - showList: function (event) { + returnToList: function (event) { this.$router.push('/employeeList') } } http://git-wip-us.apache.org/repos/asf/empire-db/blob/b2de3c7c/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue ---------------------------------------------------------------------- diff --git a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue index 03f4098..53591b7 100644 --- a/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue +++ b/empire-db-examples/empire-db-example-vue/src/main/vue/src/pages/employeeList.vue @@ -19,41 +19,35 @@ <h1>Employee-List</h1> <div class="formPanel" v-if="filter"> - <!-- - <div style="border:1px red solid"> - <e-input :column="meta.FIRSTNAME" :data="filter"/> - </div> - --> - <table class="inputForm"> - <tr> - <e-control :column="filter.meta.firstName" :data="filter.data"/> - <e-control :column="filter.meta.lastName" :data="filter.data"/> - </tr> - <tr> - <e-control :column="filter.meta.departmentId" :data="filter.data"/> - <e-control :column="filter.meta.gender" :data="filter.data"/> - </tr> - <tr> - <td class="eCtlLabel"><label class="eLabel" for="DEPARTMENT_ID">Info:</label></td> - <td class="eCtlInput"> - firstname: {{filter.data.firstName}}, lastname: {{filter.data.lastName}} - <!-- - <e-input column="test" :value="filter.lastname"/> - <input v-model="filter.lastname"/> + <e-record :record="filter"> + <table class="inputForm"> + <tr> + <e-control column="firstName"/> + <e-control column="lastName"/> + </tr> + <tr> + <e-control column="departmentId"/> + <e-control column="gender"/> + </tr> + <!-- debug + <tr> + <td class="eCtlLabel"><label class="eLabel" for="DEPARTMENT_ID">Info:</label></td> + <td class="eCtlInput">firstname: {{filter.data.firstName}}, lastname: {{filter.data.lastName}}</td> + </tr> --> - </td> - </tr> - <tr class="formButtonRow"> - <td></td> - <td class="buttonBar" colspan="3"> - <button @click="doReset()" :disabled="!searchDone">Search reset</button> - <button @click="doSearch()">Search</button> - </td> - </tr> - </table> + <tr class="formButtonRow"> + <td></td> + <td class="buttonBar" colspan="3"> + <button @click="doReset()" :disabled="!searchDone">Search reset</button> + <button @click="doSearch()">Search</button> + </td> + </tr> + </table> + </e-record> </div> <div class="searchResult" v-if="searchDone"> + <h1>Search found {{employeeList.data.length}} Employees</h1> <table class="employeeList"> <colgroup> <col class="col-id"/> @@ -63,36 +57,35 @@ <col class="col-dateOfBirth"/> <col class="col-Retired"/> </colgroup> - + <!-- head --> <thead> <tr> <th>ID</th> - <th>{{employeeList.meta['name'].title}}</th> - <th>{{employeeList.meta['department'].title}}</th> - <th>{{employeeList.meta['gender'].title}}</th> - <th>{{employeeList.meta['dateOfBirth'].title}}</th> + <th><e-label :column="meta.name"/></th> + <th><e-label :column="meta.department"/></th> + <th><e-label :column="meta.gender"/></th> + <th><e-label :column="meta.dateOfBirth"/></th> <th>Retired</th> </tr> </thead> - + <!-- body --> <tbody> <template v-for="(item, index) in employeeList.data"> <tr v-bind:key="index" v-bind:class="[index % 2 == 0 ? 'row-even' : 'row-odd' ]"> <td>{{item.employeeId}}</td> <td> <router-link class="eLink" :to="{ path: '/employeeDetail/'+item.employeeId }"> - {{item.name}} + <e-value :column="meta.name" :data="item"/> </router-link> </td> - <td>{{item.department}}</td> - <td><e-value :column="employeeList.meta.gender" :data="item"/></td> - <td><e-value :column="employeeList.meta.dateOfBirth" :data="item"/></td> - <td><e-value :column="employeeList.meta.retired" :data="item"/></td> + <td><e-value :data="item" :column="meta.department"/></td> + <td><e-value :data="item" :column="meta.gender"/></td> + <td><e-value :data="item" :column="meta.dateOfBirth"/></td> + <td><e-value :data="item" :column="meta.retired"/></td> </tr> </template> </tbody> </table> - <h1>Employee-count is {{employeeList.data.length}}</h1> </div> @@ -117,19 +110,21 @@ <script> import EMPAPI from '../api/emp-api' + import eRecord from '../components/e-record.vue' import eControl from '../components/e-control.vue' import eInput from '../components/e-input' -// import eLabel from '../components/e-label' + import eLabel from '../components/e-label' import eValue from '../components/e-value' - import $ from 'jquery' + // import $ from 'jquery' export default { name: 'list', components: { + eRecord, eControl, eInput, -// eLabel, + eLabel, eValue }, @@ -141,6 +136,12 @@ } }, + computed: { + meta: function () { + return this.employeeList.meta + } + }, + created: function () { EMPAPI.assertLoggedIn(this) if (this.$parent.employeeFilter) { @@ -159,6 +160,7 @@ this.employeeList = undefined }, doReset: function () { + EMPAPI.debug('resetting search filter') EMPAPI.loadEmployeeFilter() .done(response => (this.initSearch(response))) this.$parent.employeeFilter = undefined @@ -172,16 +174,16 @@ setResult (result) { this.employeeList = result this.searchDone = true - this.$parent.employeeFilter = this.filter - }, - doSomething: function () { - EMPAPI.debug('list contains ' + this.employeeList.data.length + ' items') - }, + // copy filter data (do not simply assign!) + this.$parent.employeeFilter = { meta: this.filter.meta, data: Object.assign({}, this.filter.data) } + } + /* updateValue (event) { var inp = $(event.currentTarget) var val = inp.val() this.$emit('input', { val }) } + */ } } </script>
