Add components for login form and customer field

This commit is contained in:
Lance Edgar 2022-08-09 14:40:04 -05:00
parent e537d8e3a6
commit dee27b51f5
5 changed files with 328 additions and 0 deletions

View 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>

View 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

View file

@ -2,9 +2,11 @@ import ByjoveApp from './app'
import ByjoveMenu from './menu'
import ByjoveLogo from './logo'
import ByjoveFeedback from './feedback'
import ByjoveLogin from './login'
import ByjoveAutocomplete from './autocomplete'
import ByjoveModelIndex from './model-index'
import ByjoveModelCrud from './model-crud'
import ByjoveCustomerField from './customers'
import ByjoveInventory from './inventory'
import ByjoveReceiving from './receiving'
@ -13,9 +15,11 @@ export {
ByjoveMenu,
ByjoveLogo,
ByjoveFeedback,
ByjoveLogin,
ByjoveAutocomplete,
ByjoveModelIndex,
ByjoveModelCrud,
ByjoveCustomerField,
ByjoveInventory,
ByjoveReceiving,
}

View 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>

View 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