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
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)
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?
Show all
workorders

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
<gz-error :errorBoxMessage="formState.errorBoxMessage"></gz-error>
<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("Address") }}</v-tab>
<v-tab>{{ $ay.t("Contacts") }}</v-tab>
@@ -631,15 +631,15 @@
<v-tab-item class="mt-4">
<v-row>
<v-col cols="12">
<!-- <v-data-table
<v-data-table
v-model="selected"
:headers="headers"
:items="obj"
:items="contactsObj"
class="elevation-1"
:disable-pagination="true"
:disable-filtering="true"
hide-default-footer
@click:row="rowClick"
@click:row="contactsRowClick"
:sort-by="['name']"
show-select
:header-props="{ sortByText: $ay.t('Sort') }"
@@ -651,7 +651,25 @@
disabled
></v-simple-checkbox>
</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-row>
</v-tab-item>
@@ -795,7 +813,15 @@ export default {
serverError: {}
},
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
@@ -1032,7 +1058,113 @@ export default {
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 window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY);
await populateSelectionLists(vm);
await cacheEnums(vm);
await createTableHeaders(vm);
}
//////////////////////////////////////////////////////////
@@ -1236,8 +1370,7 @@ async function initForm(vm) {
//
async function fetchTranslatedText(vm) {
await window.$gz.translation.cacheTranslations([
"Customer",
"Contacts",
"Customer",
"CustomerName",
"CustomerNotes",
"WebAddress",
@@ -1295,6 +1428,26 @@ async function populateSelectionLists(vm) {
await window.$gz.enums.fetchEnumList("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>
<v-container fluid>
<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-col>
<v-form ref="form">
@@ -22,9 +18,10 @@
<gz-pick-list
:ayaType="ayaTypes().Customer"
:showEditIcon="true"
:includeInactive="true"
v-model="obj.customerId"
:readonly="formState.readOnly"
:disabled="formState.readOnly"
:readonly="true"
:disabled="true"
:label="$ay.t('Customer')"
ref="customerId"
data-cy="customerId"
@@ -43,9 +40,10 @@
<gz-pick-list
:ayaType="ayaTypes().HeadOffice"
:showEditIcon="true"
:includeInactive="true"
v-model="obj.headOfficeId"
:readonly="formState.readOnly"
:disabled="formState.readOnly"
:readonly="true"
:disabled="true"
:label="$ay.t('HeadOffice')"
ref="headOfficeId"
data-cy="headOfficeId"
@@ -101,29 +99,6 @@
></v-checkbox>
</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-text-field
name="username"
@@ -277,6 +252,15 @@ export default {
await vm.getDataFromApi(vm.$route.params.recordid); //let getdata handle loading
}
} 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
}
//set initial form status
@@ -653,7 +637,7 @@ function generateMenu(vm) {
let menuOptions = {
isMain: false,
icon: "$ayiUser",
title: "User",
title: "Contact",
helpUrl: "form-adm-user",
formData: {
ayaType: window.$gz.type.User,
@@ -739,7 +723,7 @@ let JUST_DELETED = false;
async function initForm(vm) {
await fetchTranslatedText(vm);
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) {
await window.$gz.translation.cacheTranslations([
"User",
"Contact",
"Name",
"Customer",
"HeadOffice",
@@ -777,14 +761,14 @@ async function fetchTranslatedText(vm) {
]);
}
//////////////////////
//
//
async function populateSelectionLists(vm) {
//ensure the pick lists required are pre-fetched
await window.$gz.enums.fetchEnumList("outsideusertype");
vm.selectLists.usertypes = window.$gz.enums.getSelectionList(
"outsideusertype"
);
}
// //////////////////////
// //
// //
// async function populateSelectionLists(vm) {
// //ensure the pick lists required are pre-fetched
// await window.$gz.enums.fetchEnumList("outsideusertype");
// vm.selectLists.usertypes = window.$gz.enums.getSelectionList(
// "outsideusertype"
// );
// }
</script>

View File

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