Add components for login form and customer field
This commit is contained in:
parent
e537d8e3a6
commit
dee27b51f5
154
src/components/customers/ByjoveCustomerField.vue
Normal file
154
src/components/customers/ByjoveCustomerField.vue
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
<template>
|
||||||
|
<b-field :label="label" expanded
|
||||||
|
:type="fieldType">
|
||||||
|
|
||||||
|
<byjove-autocomplete v-if="!readonly && !useDropdown"
|
||||||
|
v-model="customerUUID"
|
||||||
|
:service-url="autocompleteUrl"
|
||||||
|
@input="customerChanged">
|
||||||
|
</byjove-autocomplete>
|
||||||
|
|
||||||
|
<b-select v-if="!readonly && useDropdown"
|
||||||
|
v-model="customerUUID"
|
||||||
|
@input="customerChanged">
|
||||||
|
|
||||||
|
<option v-for="customer in customers"
|
||||||
|
:key="customer.uuid"
|
||||||
|
:value="customer.uuid">
|
||||||
|
{{ customer.name }}
|
||||||
|
</option>
|
||||||
|
|
||||||
|
</b-select>
|
||||||
|
|
||||||
|
<router-link v-if="readonly"
|
||||||
|
:to="`/customers/${value}`">
|
||||||
|
{{ readonlyDisplay || value }}
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
</b-field>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ByjoveAutocomplete from '../autocomplete'
|
||||||
|
export default {
|
||||||
|
name: 'ByjoveCustomerField',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
ByjoveAutocomplete,
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: "Customer",
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
readonlyDisplay: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
dropdown: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
autocompleteUrl: {
|
||||||
|
type: String,
|
||||||
|
// TODO: should not hard-code the "full" api endpoint url here
|
||||||
|
default: '/api/customers/autocomplete',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
inited: false,
|
||||||
|
customerUUID: null,
|
||||||
|
customers: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
fieldType() {
|
||||||
|
if (this.required && !this.customerUUID) {
|
||||||
|
return 'is-danger'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
useDropdown() {
|
||||||
|
|
||||||
|
// use whatever caller specified, if they did so
|
||||||
|
if (this.dropdown !== null) {
|
||||||
|
return this.dropdown
|
||||||
|
}
|
||||||
|
|
||||||
|
// use setting, provided session is loaded
|
||||||
|
if (this.$store.state.session_established) {
|
||||||
|
return this.$store.state.settings['customer_field_dropdown']
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise assume false by default
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
'$store.state.session_established': 'init',
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
init() {
|
||||||
|
// only need to init once
|
||||||
|
if (this.inited) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// cannot init until session is established
|
||||||
|
if (!this.$store.state.session_established) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inited = true
|
||||||
|
|
||||||
|
// fetch any needed data
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchData() {
|
||||||
|
|
||||||
|
// nothing to fetch if not using dropdown
|
||||||
|
if (!this.useDropdown) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all customers for dropdown
|
||||||
|
this.$http.get('/api/customers?sort=name|asc').then(response => {
|
||||||
|
this.customers = response.data.customers
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
customerChanged(value) {
|
||||||
|
this.$emit('input', value)
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
27
src/components/customers/index.js
Normal file
27
src/components/customers/index.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import ByjoveCustomerField from './ByjoveCustomerField.vue'
|
||||||
|
|
||||||
|
// Declare install function executed by Vue.use()
|
||||||
|
export function install(Vue) {
|
||||||
|
if (install.installed) return;
|
||||||
|
install.installed = true;
|
||||||
|
Vue.component('ByjoveCustomerField', ByjoveCustomerField);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create module definition for Vue.use()
|
||||||
|
const plugin = {
|
||||||
|
install,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Auto-install when vue is found (eg. in browser via <script> tag)
|
||||||
|
let GlobalVue = null;
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
GlobalVue = window.Vue;
|
||||||
|
} else if (typeof global !== 'undefined') {
|
||||||
|
GlobalVue = global.Vue;
|
||||||
|
}
|
||||||
|
if (GlobalVue) {
|
||||||
|
GlobalVue.use(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To allow use as module (npm/webpack/etc.) export component
|
||||||
|
export default ByjoveCustomerField
|
|
@ -2,9 +2,11 @@ import ByjoveApp from './app'
|
||||||
import ByjoveMenu from './menu'
|
import ByjoveMenu from './menu'
|
||||||
import ByjoveLogo from './logo'
|
import ByjoveLogo from './logo'
|
||||||
import ByjoveFeedback from './feedback'
|
import ByjoveFeedback from './feedback'
|
||||||
|
import ByjoveLogin from './login'
|
||||||
import ByjoveAutocomplete from './autocomplete'
|
import ByjoveAutocomplete from './autocomplete'
|
||||||
import ByjoveModelIndex from './model-index'
|
import ByjoveModelIndex from './model-index'
|
||||||
import ByjoveModelCrud from './model-crud'
|
import ByjoveModelCrud from './model-crud'
|
||||||
|
import ByjoveCustomerField from './customers'
|
||||||
import ByjoveInventory from './inventory'
|
import ByjoveInventory from './inventory'
|
||||||
import ByjoveReceiving from './receiving'
|
import ByjoveReceiving from './receiving'
|
||||||
|
|
||||||
|
@ -13,9 +15,11 @@ export {
|
||||||
ByjoveMenu,
|
ByjoveMenu,
|
||||||
ByjoveLogo,
|
ByjoveLogo,
|
||||||
ByjoveFeedback,
|
ByjoveFeedback,
|
||||||
|
ByjoveLogin,
|
||||||
ByjoveAutocomplete,
|
ByjoveAutocomplete,
|
||||||
ByjoveModelIndex,
|
ByjoveModelIndex,
|
||||||
ByjoveModelCrud,
|
ByjoveModelCrud,
|
||||||
|
ByjoveCustomerField,
|
||||||
ByjoveInventory,
|
ByjoveInventory,
|
||||||
ByjoveReceiving,
|
ByjoveReceiving,
|
||||||
}
|
}
|
||||||
|
|
116
src/components/login/ByjoveLogin.vue
Normal file
116
src/components/login/ByjoveLogin.vue
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
<template>
|
||||||
|
<div class="byjove-login">
|
||||||
|
<form>
|
||||||
|
|
||||||
|
<byjove-logo centered :appsettings="appsettings">
|
||||||
|
</byjove-logo>
|
||||||
|
|
||||||
|
<b-field label="Username">
|
||||||
|
<b-input v-model="username" />
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field label="Password">
|
||||||
|
<b-input v-model="password" type="password" />
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<div v-if="loginError" style="color: red;">
|
||||||
|
{{ loginError }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
<b-button type="is-primary"
|
||||||
|
@click="attemptLogin()"
|
||||||
|
:disabled="loginFormDisabled"
|
||||||
|
expanded>
|
||||||
|
Login
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ByjoveLogo from '../logo'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ByjoveLogin',
|
||||||
|
components: {
|
||||||
|
ByjoveLogo,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
appsettings: Object,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
inited: false,
|
||||||
|
username: null,
|
||||||
|
password: null,
|
||||||
|
loginError: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
|
||||||
|
loginFormDisabled: function() {
|
||||||
|
if (!this.username) {
|
||||||
|
return true
|
||||||
|
} else if (!this.password) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.session_established': 'init',
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
init() {
|
||||||
|
if (this.inited) return
|
||||||
|
|
||||||
|
// cannot init until session is established
|
||||||
|
if (!this.$store.state.session_established) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inited = true
|
||||||
|
|
||||||
|
// send logged-in users to "home" page
|
||||||
|
if (this.$store.state.user) {
|
||||||
|
this.$router.push('/')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
attemptLogin() {
|
||||||
|
|
||||||
|
// clear any previous login error
|
||||||
|
this.loginError = null
|
||||||
|
|
||||||
|
// post credentials to login API
|
||||||
|
let creds = {
|
||||||
|
username: this.username,
|
||||||
|
password: this.password,
|
||||||
|
}
|
||||||
|
this.$http.post('/api/login', creds).then(response => {
|
||||||
|
if (response.data.ok) {
|
||||||
|
|
||||||
|
// login successful; let the app know
|
||||||
|
this.$loginUser(response.data.user)
|
||||||
|
|
||||||
|
// send user to "home" page
|
||||||
|
this.$router.push('/')
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// login failed
|
||||||
|
this.loginError = response.data.error;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
27
src/components/login/index.js
Normal file
27
src/components/login/index.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import ByjoveLogin from './ByjoveLogin.vue'
|
||||||
|
|
||||||
|
// Declare install function executed by Vue.use()
|
||||||
|
export function install(Vue) {
|
||||||
|
if (install.installed) return;
|
||||||
|
install.installed = true;
|
||||||
|
Vue.component('ByjoveLogin', ByjoveLogin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create module definition for Vue.use()
|
||||||
|
const plugin = {
|
||||||
|
install,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Auto-install when vue is found (eg. in browser via <script> tag)
|
||||||
|
let GlobalVue = null;
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
GlobalVue = window.Vue;
|
||||||
|
} else if (typeof global !== 'undefined') {
|
||||||
|
GlobalVue = global.Vue;
|
||||||
|
}
|
||||||
|
if (GlobalVue) {
|
||||||
|
GlobalVue.use(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To allow use as module (npm/webpack/etc.) export component
|
||||||
|
export default ByjoveLogin
|
Loading…
Reference in a new issue