This commit is contained in:
2020-11-17 00:52:44 +00:00
parent 54a8fbd2ec
commit ebb7590c57
6 changed files with 202 additions and 57 deletions

View File

@@ -70,8 +70,15 @@ todo: TESTING After customer form is made
OUTSTANDING WITH CUSTOMER OUTSTANDING WITH CUSTOMER
contacts contacts
make list of users in grid, shows all contact info
can open to cust-user edit form
Change cust-user edit form (and other user edit form) and add tabs and user options section so that it can all be set there as well
Add button to email the user their creds and login and invite them to change the password once they login
Customer User (contacts) UI for this client (generate, view) Customer User (contacts) UI for this client (generate, view)
case for this and notes, sb very simple way to create and send creds for user case for this and notes, sb very simple way to create and send creds for user
Customer User / User(s)
Label as Contact / Contacts
Show customer / head office in generic contacts grid view
Copy address to clipboard? Copy address to clipboard?
Show all Show all
workorders workorders

View File

@@ -277,7 +277,7 @@ function initNavPanel() {
//Customer / Headoffice Users subitem //Customer / Headoffice Users subitem
sub.push({ sub.push({
title: "UserList", title: "Contacts",
icon: "$ayiUsers", icon: "$ayiUsers",
route: "/cust-users", route: "/cust-users",
key: key++ key: key++

View File

@@ -123,6 +123,7 @@ export default {
"Service", "Service",
"CustomerList", "CustomerList",
"HeadOfficeList", "HeadOfficeList",
"Contacts",
"WorkOrderList", "WorkOrderList",
"WorkOrderServiceTemplate", "WorkOrderServiceTemplate",
"QuoteList", "QuoteList",

View File

@@ -6,7 +6,7 @@
<gz-error :errorBoxMessage="formState.errorBoxMessage"></gz-error> <gz-error :errorBoxMessage="formState.errorBoxMessage"></gz-error>
<v-form ref="form"> <v-form ref="form">
<v-tabs mobile-breakpoint="100" v-model="tab"> <v-tabs mobile-breakpoint="100" v-model="tab" @change="tabChanged">
<v-tab>{{ $ay.t("Customer") }}</v-tab> <v-tab>{{ $ay.t("Customer") }}</v-tab>
<v-tab>{{ $ay.t("Address") }}</v-tab> <v-tab>{{ $ay.t("Address") }}</v-tab>
<v-tab>{{ $ay.t("Contacts") }}</v-tab> <v-tab>{{ $ay.t("Contacts") }}</v-tab>
@@ -631,15 +631,15 @@
<v-tab-item class="mt-4"> <v-tab-item class="mt-4">
<v-row> <v-row>
<v-col cols="12"> <v-col cols="12">
<!-- <v-data-table <v-data-table
v-model="selected" v-model="selected"
:headers="headers" :headers="headers"
:items="obj" :items="contactsObj"
class="elevation-1" class="elevation-1"
:disable-pagination="true" :disable-pagination="true"
:disable-filtering="true" :disable-filtering="true"
hide-default-footer hide-default-footer
@click:row="rowClick" @click:row="contactsRowClick"
:sort-by="['name']" :sort-by="['name']"
show-select show-select
:header-props="{ sortByText: $ay.t('Sort') }" :header-props="{ sortByText: $ay.t('Sort') }"
@@ -651,7 +651,25 @@
disabled disabled
></v-simple-checkbox> ></v-simple-checkbox>
</template> </template>
</v-data-table> -->
<template v-slot:top>
<div>
<v-btn
@click="contactsGetDataFromApi"
:disabled="obj.id == 0"
>
<v-icon data-cy="refresh">$ayiSync</v-icon>
</v-btn>
<v-btn
class="ml-12"
@click="addContact"
:disabled="obj.id == 0"
>
<v-icon data-cy="add">$ayiPlus</v-icon>
</v-btn>
</div>
</template>
</v-data-table>
</v-col> </v-col>
</v-row> </v-row>
</v-tab-item> </v-tab-item>
@@ -795,7 +813,15 @@ export default {
serverError: {} serverError: {}
}, },
rights: window.$gz.role.defaultRightsObject(), rights: window.$gz.role.defaultRightsObject(),
ayaType: window.$gz.type.Customer ayaType: window.$gz.type.Customer,
contactsObj: [],
hasFetchedContacts: false,
headers: [],
selected: [],
availableRoles: [],
timeZoneName: window.$gz.locale.getBrowserTimeZoneName(),
languageName: window.$gz.locale.getBrowserLanguages(),
hour12: window.$gz.locale.getHour12()
}; };
}, },
//WATCHERS //WATCHERS
@@ -1032,7 +1058,113 @@ export default {
loading: false loading: false
}); });
} }
},
tabChanged: async function(tab) {
if (tab == 2) {
//contacts tab, load contacts if not done already
if (!this.hasFetchedContacts) {
await this.contactsGetDataFromApi();
}
}
// let vm = this;
// if (vm[tabIndexToRoute(vm.tab)].isnew) {
// vm.getDataFromApi();
// }
},
addContact() {
if (this.obj.id == 0) {
return;
}
this.$router.push({
name: "cust-user",
params: { recordid: 0, customerid: this.obj.id }
});
},
contactsRowClick(item) {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.User,
id: item.id,
inside: false
});
},
rolesDisplayFromRoles(roles) {
let roleNames = [];
if (roles != null && roles != 0) {
for (let i = 0; i < this.availableRoles.length; i++) {
let role = this.availableRoles[i];
if (!!(roles & role.id)) {
roleNames.push(role.name);
}
}
}
return roleNames.join(", ");
},
async contactsGetDataFromApi() {
let vm = this;
vm.formState.loading = true;
window.$gz.form.deleteAllErrorBoxErrors(vm);
try {
let res = await window.$gz.api.get(
`user/customer-contacts/${vm.obj.id}`
);
vm.hasFetchedContacts = true;
if (res.error) {
if (res.error.code == "2010") {
window.$gz.form.handleObjectNotFound(vm);
}
vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm);
} else {
if (res.data) {
/* Id = z.Id,
Active = z.Active,
Name = z.Name,
UserType = z.UserType,
LastLogin = z.LastLogin */
let ret = [];
for (let i = 0; i < res.data.length; i++) {
let o = res.data[i];
ret.push({
id: o.id,
name: o.name,
active: o.active,
userType: window.$gz.enums.get("outsideusertype", o.userType),
lastLogin: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
o.lastLogin,
this.timeZoneName,
this.languageName,
this.hour12
),
roles: this.rolesDisplayFromRoles(o.roles)
});
}
vm.contactsObj = ret;
} else {
vm.rawObj = [];
vm.contactsObj = [];
}
window.$gz.form.setFormState({
vm: vm,
dirty: false,
valid: true,
loading: false
});
generateMenu(vm);
}
} catch (error) {
window.$gz.form.setFormState({
vm: vm,
loading: false
});
window.$gz.errorHandler.handleFormError(error, vm);
}
} }
//end methods
} }
}; };
@@ -1228,6 +1360,8 @@ async function initForm(vm) {
await fetchTranslatedText(vm); await fetchTranslatedText(vm);
await window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY); await window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY);
await populateSelectionLists(vm); await populateSelectionLists(vm);
await cacheEnums(vm);
await createTableHeaders(vm);
} }
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
@@ -1236,8 +1370,7 @@ async function initForm(vm) {
// //
async function fetchTranslatedText(vm) { async function fetchTranslatedText(vm) {
await window.$gz.translation.cacheTranslations([ await window.$gz.translation.cacheTranslations([
"Customer", "Customer",
"Contacts",
"CustomerName", "CustomerName",
"CustomerNotes", "CustomerNotes",
"WebAddress", "WebAddress",
@@ -1295,6 +1428,26 @@ async function populateSelectionLists(vm) {
await window.$gz.enums.fetchEnumList("usertype"); await window.$gz.enums.fetchEnumList("usertype");
vm.selectLists.usertypes = window.$gz.enums.getSelectionList("usertype"); vm.selectLists.usertypes = window.$gz.enums.getSelectionList("usertype");
} }
</script>
<style></style> //////////////////////
//
//
async function cacheEnums(vm) {
//ensure the enum values required are pre-fetched
await window.$gz.enums.fetchEnumList("outsideusertype");
await window.$gz.enums.fetchEnumList("AuthorizationRoles");
vm.availableRoles = window.$gz.enums.getSelectionList("AuthorizationRoles");
}
//////////////////////
//
//
async function createTableHeaders(vm) {
vm.headers = [
{ text: vm.$ay.t("User"), value: "name" },
{ text: vm.$ay.t("Active"), value: "active" },
{ text: vm.$ay.t("UserType"), value: "userType" },
{ text: vm.$ay.t("LastLogin"), value: "lastLogin" }
];
}
</script>

View File

@@ -1,11 +1,7 @@
<template> <template>
<v-container fluid> <v-container fluid>
<gz-report-selector ref="reportSelector"></gz-report-selector> <gz-report-selector ref="reportSelector"></gz-report-selector>
<h2 class="red--text" v-if="$ay.dev">
todo: revisit after add customer, ho, to support usertypes
customer,headoffice TEST SAVE for both types and make sure wont' allow
without customer / ho chosen and make sure if not error is clear
</h2>
<v-row v-if="formState.ready"> <v-row v-if="formState.ready">
<v-col> <v-col>
<v-form ref="form"> <v-form ref="form">
@@ -22,9 +18,10 @@
<gz-pick-list <gz-pick-list
:ayaType="ayaTypes().Customer" :ayaType="ayaTypes().Customer"
:showEditIcon="true" :showEditIcon="true"
:includeInactive="true"
v-model="obj.customerId" v-model="obj.customerId"
:readonly="formState.readOnly" :readonly="true"
:disabled="formState.readOnly" :disabled="true"
:label="$ay.t('Customer')" :label="$ay.t('Customer')"
ref="customerId" ref="customerId"
data-cy="customerId" data-cy="customerId"
@@ -43,9 +40,10 @@
<gz-pick-list <gz-pick-list
:ayaType="ayaTypes().HeadOffice" :ayaType="ayaTypes().HeadOffice"
:showEditIcon="true" :showEditIcon="true"
:includeInactive="true"
v-model="obj.headOfficeId" v-model="obj.headOfficeId"
:readonly="formState.readOnly" :readonly="true"
:disabled="formState.readOnly" :disabled="true"
:label="$ay.t('HeadOffice')" :label="$ay.t('HeadOffice')"
ref="headOfficeId" ref="headOfficeId"
data-cy="headOfficeId" data-cy="headOfficeId"
@@ -101,29 +99,6 @@
></v-checkbox> ></v-checkbox>
</v-col> </v-col>
<v-col
v-if="form().showMe(this, 'UserType')"
cols="12"
sm="6"
lg="4"
xl="3"
>
<v-select
v-model="obj.userType"
:items="selectLists.usertypes"
item-text="name"
item-value="id"
:readonly="formState.readOnly"
:disabled="formState.readOnly"
:label="$ay.t('UserType')"
ref="usertype"
data-cy="usertype"
:rules="[form().integerValid(this, 'usertype')]"
:error-messages="form().serverErrors(this, 'usertype')"
@input="fieldValueChanged('usertype')"
></v-select>
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3"> <v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field <v-text-field
name="username" name="username"
@@ -277,6 +252,15 @@ export default {
await vm.getDataFromApi(vm.$route.params.recordid); //let getdata handle loading await vm.getDataFromApi(vm.$route.params.recordid); //let getdata handle loading
} }
} else { } else {
/* Customer = 3,
HeadOffice = 4, */
if (vm.$route.params.customerid != 0) {
vm.obj.customerId = vm.$route.params.customerid;
vm.obj.userType = 3;
} else if (vm.$route.params.headofficeid != 0) {
vm.obj.headOfficeId = vm.$route.params.headofficeid;
vm.obj.userType = 4;
}
vm.formState.loading = false; //here we handle it immediately vm.formState.loading = false; //here we handle it immediately
} }
//set initial form status //set initial form status
@@ -653,7 +637,7 @@ function generateMenu(vm) {
let menuOptions = { let menuOptions = {
isMain: false, isMain: false,
icon: "$ayiUser", icon: "$ayiUser",
title: "User", title: "Contact",
helpUrl: "form-adm-user", helpUrl: "form-adm-user",
formData: { formData: {
ayaType: window.$gz.type.User, ayaType: window.$gz.type.User,
@@ -739,7 +723,7 @@ let JUST_DELETED = false;
async function initForm(vm) { async function initForm(vm) {
await fetchTranslatedText(vm); await fetchTranslatedText(vm);
await window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY); await window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY);
await populateSelectionLists(vm); //await populateSelectionLists(vm);
} }
////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////
@@ -748,7 +732,7 @@ async function initForm(vm) {
// //
async function fetchTranslatedText(vm) { async function fetchTranslatedText(vm) {
await window.$gz.translation.cacheTranslations([ await window.$gz.translation.cacheTranslations([
"User", "Contact",
"Name", "Name",
"Customer", "Customer",
"HeadOffice", "HeadOffice",
@@ -777,14 +761,14 @@ async function fetchTranslatedText(vm) {
]); ]);
} }
////////////////////// // //////////////////////
// // //
// // //
async function populateSelectionLists(vm) { // async function populateSelectionLists(vm) {
//ensure the pick lists required are pre-fetched // //ensure the pick lists required are pre-fetched
await window.$gz.enums.fetchEnumList("outsideusertype"); // await window.$gz.enums.fetchEnumList("outsideusertype");
vm.selectLists.usertypes = window.$gz.enums.getSelectionList( // vm.selectLists.usertypes = window.$gz.enums.getSelectionList(
"outsideusertype" // "outsideusertype"
); // );
} // }
</script> </script>

View File

@@ -196,7 +196,7 @@ function generateMenu(vm) {
let menuOptions = { let menuOptions = {
isMain: true, isMain: true,
icon: "$ayiUsers", icon: "$ayiUsers",
title: "UserList", title: "Contacts",
helpUrl: "form-cust-users", helpUrl: "form-cust-users",
menuItems: [] menuItems: []
}; };