Fix basic problems with people profile view, per butterball

plenty more tweaks needed yet i'm sure, but page looks reasonable now
at least
This commit is contained in:
Lance Edgar 2024-05-29 20:47:10 -05:00
parent b98d651144
commit 54b75dbe1a
2 changed files with 288 additions and 149 deletions

View file

@ -115,8 +115,13 @@
Edit Name
</b-button>
</div>
<b-modal has-modal-card
:active.sync="editNameShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editNameShowDialog"
% else:
:active.sync="editNameShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -125,49 +130,52 @@
<section class="modal-card-body">
<b-field grouped>
<b-field label="First Name" expanded>
<b-input v-model.trim="editNameFirst"
:maxlength="maxLengths.person_first_name || null">
</b-input>
</b-field>
% if use_preferred_first_name:
% if use_preferred_first_name:
<b-field grouped>
<b-field label="First Name">
<b-input v-model.trim="editNameFirst"
:maxlength="maxLengths.person_first_name || null" />
</b-field>
<b-field label="Preferred First Name" expanded>
<b-input v-model.trim="editNameFirstPreferred"
:maxlength="maxLengths.person_preferred_first_name || null">
</b-input>
</b-field>
% endif
</b-field>
</b-field>
% else:
<b-field label="First Name">
<b-input v-model.trim="editNameFirst"
:maxlength="maxLengths.person_first_name || null"
expanded />
</b-field>
% endif
<b-field label="Middle Name">
<b-input v-model.trim="editNameMiddle"
:maxlength="maxLengths.person_middle_name || null">
</b-input>
:maxlength="maxLengths.person_middle_name || null"
expanded />
</b-field>
<b-field label="Last Name">
<b-input v-model.trim="editNameLast"
:maxlength="maxLengths.person_last_name || null">
</b-input>
:maxlength="maxLengths.person_last_name || null"
expanded />
</b-field>
</section>
<footer class="modal-card-foot">
<once-button type="is-primary"
@click="editNameSave()"
:disabled="editNameSaveDisabled"
icon-left="save"
text="Save">
</once-button>
<b-button type="is-primary"
@click="editNameSave()"
:disabled="editNameSaveDisabled"
icon-pack="fas"
icon-left="save">
{{ editNameSaving ? "Working, please wait..." : "Save" }}
</b-button>
<b-button @click="editNameShowDialog = false">
Cancel
</b-button>
</footer>
</div>
</b-modal>
</${b}-modal>
% endif
</div>
</div>
@ -219,8 +227,13 @@
icon-left="edit">
Edit Address
</b-button>
<b-modal has-modal-card
:active.sync="editAddressShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editAddressShowDialog"
% else:
:active.sync="editAddressShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -231,20 +244,20 @@
<b-field label="Street 1" expanded>
<b-input v-model.trim="editAddressStreet1"
:maxlength="maxLengths.address_street || null">
</b-input>
:maxlength="maxLengths.address_street || null"
expanded />
</b-field>
<b-field label="Street 2" expanded>
<b-input v-model.trim="editAddressStreet2"
:maxlength="maxLengths.address_street2 || null">
</b-input>
:maxlength="maxLengths.address_street2 || null"
expanded />
</b-field>
<b-field label="Zipcode">
<b-input v-model.trim="editAddressZipcode"
:maxlength="maxLengths.address_zipcode || null">
</b-input>
:maxlength="maxLengths.address_zipcode || null"
expanded />
</b-field>
<b-field grouped>
@ -280,7 +293,7 @@
</b-button>
</footer>
</div>
</b-modal>
</${b}-modal>
% endif
</div>
</div>
@ -312,8 +325,13 @@
Add Phone
</b-button>
</div>
<b-modal has-modal-card
:active.sync="editPhoneShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editPhoneShowDialog"
% else:
:active.sync="editPhoneShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -362,50 +380,64 @@
</b-button>
</footer>
</div>
</b-modal>
</${b}-modal>
% endif
<b-table :data="person.phones">
<${b}-table :data="person.phones">
<b-table-column field="preference"
<${b}-table-column field="preference"
label="Preferred"
v-slot="props">
{{ props.row.preferred ? "Yes" : "" }}
</b-table-column>
</${b}-table-column>
<b-table-column field="type"
<${b}-table-column field="type"
label="Type"
v-slot="props">
{{ props.row.type }}
</b-table-column>
</${b}-table-column>
<b-table-column field="number"
<${b}-table-column field="number"
label="Number"
v-slot="props">
{{ props.row.number }}
</b-table-column>
</${b}-table-column>
% if request.has_perm('people_profile.edit_person'):
<b-table-column label="Actions"
<${b}-table-column label="Actions"
v-slot="props">
<a href="#" @click.prevent="editPhoneInit(props.row)">
<i class="fas fa-edit"></i>
<a class="grid-action"
href="#" @click.prevent="editPhoneInit(props.row)">
% if request.use_oruga:
<o-icon icon="edit" />
% else:
<i class="fas fa-edit"></i>
% endif
Edit
</a>
<a href="#" @click.prevent="deletePhoneInit(props.row)"
class="has-text-danger">
<i class="fas fa-trash"></i>
<a class="grid-action has-text-danger"
href="#" @click.prevent="deletePhoneInit(props.row)">
% if request.use_oruga:
<o-icon icon="trash" />
% else:
<i class="fas fa-trash"></i>
% endif
Delete
</a>
<a href="#" @click.prevent="preferPhoneInit(props.row)"
<a class="grid-action"
href="#" @click.prevent="preferPhoneInit(props.row)"
v-if="!props.row.preferred">
<i class="fas fa-star"></i>
% if request.use_oruga:
<o-icon icon="star" />
% else:
<i class="fas fa-star"></i>
% endif
Set Preferred
</a>
</b-table-column>
</${b}-table-column>
% endif
</b-table>
</${b}-table>
</div>
</div>
@ -429,8 +461,13 @@
Add Email
</b-button>
</div>
<b-modal has-modal-card
:active.sync="editEmailShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editEmailShowDialog"
% else:
:active.sync="editEmailShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -488,56 +525,70 @@
</b-button>
</footer>
</div>
</b-modal>
</${b}-modal>
% endif
<b-table :data="person.emails">
<${b}-table :data="person.emails">
<b-table-column field="preference"
<${b}-table-column field="preference"
label="Preferred"
v-slot="props">
{{ props.row.preferred ? "Yes" : "" }}
</b-table-column>
</${b}-table-column>
<b-table-column field="type"
<${b}-table-column field="type"
label="Type"
v-slot="props">
{{ props.row.type }}
</b-table-column>
</${b}-table-column>
<b-table-column field="address"
<${b}-table-column field="address"
label="Address"
v-slot="props">
{{ props.row.address }}
</b-table-column>
</${b}-table-column>
<b-table-column field="invalid"
<${b}-table-column field="invalid"
label="Invalid?"
v-slot="props">
<span v-if="props.row.invalid" class="has-text-danger has-text-weight-bold">Invalid</span>
</b-table-column>
</${b}-table-column>
% if request.has_perm('people_profile.edit_person'):
<b-table-column label="Actions"
<${b}-table-column label="Actions"
v-slot="props">
<a href="#" @click.prevent="editEmailInit(props.row)">
<i class="fas fa-edit"></i>
<a class="grid-action"
href="#" @click.prevent="editEmailInit(props.row)">
% if request.use_oruga:
<o-icon icon="edit" />
% else:
<i class="fas fa-edit"></i>
% endif
Edit
</a>
<a href="#" @click.prevent="deleteEmailInit(props.row)"
class="has-text-danger">
<i class="fas fa-trash"></i>
<a class="grid-action has-text-danger"
href="#" @click.prevent="deleteEmailInit(props.row)">
% if request.use_oruga:
<o-icon icon="trash" />
% else:
<i class="fas fa-trash"></i>
% endif
Delete
</a>
<a href="#" @click.prevent="preferEmailInit(props.row)"
<a class="grid-action"
href="#" @click.prevent="preferEmailInit(props.row)"
v-if="!props.row.preferred">
<i class="fas fa-star"></i>
% if request.use_oruga:
<o-icon icon="star" />
% else:
<i class="fas fa-star"></i>
% endif
Set Preferred
</a>
</b-table-column>
</${b}-table-column>
% endif
</b-table>
</${b}-table>
</div>
</div>
@ -566,16 +617,22 @@
</b-button>
% endif
</div>
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else:
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% endif
</div>
</script>
</%def>
<%def name="render_personal_tab()">
<b-tab-item label="Personal"
value="personal"
icon-pack="fas"
:icon="tabchecks.personal ? 'check' : null">
<${b}-tab-item label="Personal"
value="personal"
% if not request.use_oruga:
icon-pack="fas"
% endif
:icon="tabchecks.personal ? 'check' : null">
<personal-tab ref="tab_personal"
:person="person"
@profile-changed="profileChanged"
@ -583,7 +640,7 @@
:email-type-options="emailTypeOptions"
:max-lengths="maxLengths">
</personal-tab>
</b-tab-item>
</${b}-tab-item>
</%def>
<%def name="render_member_tab_template()">
@ -692,13 +749,17 @@
</div>
% endif
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else:
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% endif
</div>
</script>
</%def>
<%def name="render_member_tab()">
<b-tab-item label="Member"
<${b}-tab-item label="Member"
value="member"
icon-pack="fas"
:icon="tabchecks.member ? 'check' : null">
@ -707,7 +768,7 @@
@profile-changed="profileChanged"
:phone-type-options="phoneTypeOptions">
</member-tab>
</b-tab-item>
</${b}-tab-item>
</%def>
<%def name="render_customer_tab_template()">
@ -814,13 +875,17 @@
<div v-if="!customers.length">
<p>{{ person.display_name }} does not have a customer account.</p>
</div>
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else:
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% endif
</div>
</script>
</%def>
<%def name="render_customer_tab()">
<b-tab-item label="Customer"
<${b}-tab-item label="Customer"
value="customer"
icon-pack="fas"
:icon="tabchecks.customer ? 'check' : null">
@ -828,7 +893,7 @@
:person="person"
@profile-changed="profileChanged">
</customer-tab>
</b-tab-item>
</${b}-tab-item>
</%def>
<%def name="render_shopper_tab_template()">
@ -890,13 +955,17 @@
<div v-if="!shoppers.length">
<p>{{ person.display_name }} is not a shopper.</p>
</div>
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else:
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% endif
</div>
</script>
</%def>
<%def name="render_shopper_tab()">
<b-tab-item label="Shopper"
<${b}-tab-item label="Shopper"
value="shopper"
icon-pack="fas"
:icon="tabchecks.shopper ? 'check' : null">
@ -904,7 +973,7 @@
:person="person"
@profile-changed="profileChanged">
</shopper-tab>
</b-tab-item>
</${b}-tab-item>
</%def>
<%def name="render_employee_tab_template()">
@ -930,8 +999,13 @@
@click="editEmployeeIdInit()">
Edit ID
</b-button>
<b-modal has-modal-card
:active.sync="editEmployeeIdShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editEmployeeIdShowDialog"
% else:
:active.sync="editEmployeeIdShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -957,7 +1031,7 @@
</b-button>
</footer>
</div>
</b-modal>
</${b}-modal>
</div>
% endif
</div>
@ -980,32 +1054,32 @@
<p><strong>Employee History</strong></p>
<br />
<b-table :data="employeeHistory">
<${b}-table :data="employeeHistory">
<b-table-column field="start_date"
<${b}-table-column field="start_date"
label="Start Date"
v-slot="props">
{{ props.row.start_date }}
</b-table-column>
</${b}-table-column>
<b-table-column field="end_date"
<${b}-table-column field="end_date"
label="End Date"
v-slot="props">
{{ props.row.end_date }}
</b-table-column>
</${b}-table-column>
% if request.has_perm('people_profile.edit_employee_history'):
<b-table-column field="actions"
<${b}-table-column field="actions"
label="Actions"
v-slot="props">
<a href="#" @click.prevent="editEmployeeHistoryInit(props.row)">
<i class="fas fa-edit"></i>
Edit
</a>
</b-table-column>
</${b}-table-column>
% endif
</b-table>
</${b}-table>
</div>
@ -1032,8 +1106,13 @@
${person} is no longer an Employee
</b-button>
<b-modal has-modal-card
:active.sync="startEmployeeShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="startEmployeeShowDialog"
% else:
:active.sync="startEmployeeShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -1060,10 +1139,15 @@
</once-button>
</footer>
</div>
</b-modal>
</${b}-modal>
<b-modal has-modal-card
:active.sync="stopEmployeeShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="stopEmployeeShowDialog"
% else:
:active.sync="stopEmployeeShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -1092,12 +1176,17 @@
</once-button>
</footer>
</div>
</b-modal>
</${b}-modal>
% endif
% if request.has_perm('people_profile.edit_employee_history'):
<b-modal has-modal-card
:active.sync="editEmployeeHistoryShowDialog">
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editEmployeeHistoryShowDialog"
% else:
:active.sync="editEmployeeHistoryShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
@ -1126,7 +1215,7 @@
</once-button>
</footer>
</div>
</b-modal>
</${b}-modal>
% endif
% if request.has_perm('employees.view'):
@ -1140,13 +1229,17 @@
</div>
</div>
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else:
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% endif
</div>
</script>
</%def>
<%def name="render_employee_tab()">
<b-tab-item label="Employee"
<${b}-tab-item label="Employee"
value="employee"
icon-pack="fas"
:icon="tabchecks.employee ? 'check' : null">
@ -1154,7 +1247,7 @@
:person="person"
@profile-changed="profileChanged">
</employee-tab>
</b-tab-item>
</${b}-tab-item>
</%def>
<%def name="render_notes_tab_template()">
@ -1171,40 +1264,40 @@
</b-button>
% endif
<b-table :data="notes">
<${b}-table :data="notes">
<b-table-column field="note_type"
<${b}-table-column field="note_type"
label="Type"
v-slot="props">
{{ props.row.note_type_display }}
</b-table-column>
</${b}-table-column>
<b-table-column field="subject"
<${b}-table-column field="subject"
label="Subject"
v-slot="props">
{{ props.row.subject }}
</b-table-column>
</${b}-table-column>
<b-table-column field="text"
<${b}-table-column field="text"
label="Text"
v-slot="props">
{{ props.row.text }}
</b-table-column>
</${b}-table-column>
<b-table-column field="created"
<${b}-table-column field="created"
label="Created"
v-slot="props">
<span v-html="props.row.created_display"></span>
</b-table-column>
</${b}-table-column>
<b-table-column field="created_by"
<${b}-table-column field="created_by"
label="Created By"
v-slot="props">
{{ props.row.created_by_display }}
</b-table-column>
</${b}-table-column>
% if request.has_any_perm('people_profile.edit_note', 'people_profile.delete_note'):
<b-table-column label="Actions"
<${b}-table-column label="Actions"
v-slot="props">
% if request.has_perm('people_profile.edit_note'):
<a href="#" @click.prevent="editNoteInit(props.row)">
@ -1219,14 +1312,19 @@
Delete
</a>
% endif
</b-table-column>
</${b}-table-column>
% endif
</b-table>
</${b}-table>
% if request.has_any_perm('people_profile.add_note', 'people_profile.edit_note', 'people_profile.delete_note'):
<b-modal :active.sync="editNoteShowDialog"
has-modal-card>
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="editNoteShowDialog"
% else:
:active.sync="editNoteShowDialog"
% endif
>
<div class="modal-card">
@ -1285,16 +1383,20 @@
</footer>
</div>
</b-modal>
</${b}-modal>
% endif
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else:
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% endif
</div>
</script>
</%def>
<%def name="render_notes_tab()">
<b-tab-item label="Notes"
<${b}-tab-item label="Notes"
value="notes"
icon-pack="fas"
:icon="tabchecks.notes ? 'check' : null">
@ -1302,7 +1404,7 @@
:person="person"
@profile-changed="profileChanged">
</notes-tab>
</b-tab-item>
</${b}-tab-item>
</%def>
<%def name="render_user_tab_template()">
@ -1355,13 +1457,17 @@
<div v-if="!users.length">
<p>{{ person.display_name }} does not have a user account.</p>
</div>
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else:
<b-loading :active.sync="refreshingTab" :is-full-page="false"></b-loading>
% endif
</div>
</script>
</%def>
<%def name="render_user_tab()">
<b-tab-item label="User"
<${b}-tab-item label="User"
value="user"
icon-pack="fas"
:icon="tabchecks.user ? 'check' : null">
@ -1369,7 +1475,7 @@
:person="person"
@profile-changed="profileChanged">
</user-tab>
</b-tab-item>
</${b}-tab-item>
</%def>
<%def name="render_profile_tabs()">
@ -1392,14 +1498,20 @@
${self.render_profile_info_extra_buttons()}
<b-tabs v-model="activeTab"
% if request.has_perm('people_profile.view_versions'):
v-show="!viewingHistory"
% endif
type="is-boxed"
@input="activeTabChanged">
<${b}-tabs v-model="activeTab"
% if request.has_perm('people_profile.view_versions'):
v-show="!viewingHistory"
% endif
% if request.use_oruga:
type="boxed"
@change="activeTabChanged"
% else:
type="is-boxed"
@input="activeTabChanged"
% endif
>
${self.render_profile_tabs()}
</b-tabs>
</${b}-tabs>
% if request.has_perm('people_profile.view_versions'):
@ -1408,7 +1520,13 @@
vshow='viewingHistory',
loading='gettingRevisions')|n}
<b-modal :active.sync="showingRevisionDialog">
<${b}-modal
% if request.use_oruga:
v-model:active="showingRevisionDialog"
% else:
:active.sync="showingRevisionDialog"
% endif
>
<div class="card">
<div class="card-content">
@ -1487,7 +1605,7 @@
</div>
</div>
</b-modal>
</${b}-modal>
% endif
</div>
@ -1522,6 +1640,7 @@
% endif
editNameMiddle: null,
editNameLast: null,
editNameSaving: false,
editAddressShowDialog: false,
editAddressStreet1: null,
@ -1562,6 +1681,9 @@
% if request.has_perm('people_profile.edit_person'):
editNameSaveDisabled: function() {
if (this.editNameSaving) {
return true
}
if (!this.editNameFirst || !this.editNameLast) {
return true
}
@ -1622,6 +1744,7 @@
},
editNameSave() {
this.editNameSaving = true
let url = '${url('people.profile_edit_name', uuid=person.uuid)}'
let params = {
first_name: this.editNameFirst,
@ -1636,6 +1759,9 @@
this.$emit('profile-changed', response.data)
this.editNameShowDialog = false
this.refreshTab()
this.editNameSaving = false
}, response => {
this.editNameSaving = false
})
},
@ -1827,6 +1953,7 @@
PersonalTab.data = function() { return PersonalTabData }
Vue.component('personal-tab', PersonalTab)
<% request.register_component('personal-tab', 'PersonalTab') %>
</script>
</%def>
@ -1872,6 +1999,7 @@
MemberTab.data = function() { return MemberTabData }
Vue.component('member-tab', MemberTab)
<% request.register_component('member-tab', 'MemberTab') %>
</script>
</%def>
@ -1908,6 +2036,7 @@
CustomerTab.data = function() { return CustomerTabData }
Vue.component('customer-tab', CustomerTab)
<% request.register_component('customer-tab', 'CustomerTab') %>
</script>
</%def>
@ -1944,6 +2073,7 @@
ShopperTab.data = function() { return ShopperTabData }
Vue.component('shopper-tab', ShopperTab)
<% request.register_component('shopper-tab', 'ShopperTab') %>
</script>
</%def>
@ -2100,6 +2230,7 @@
EmployeeTab.data = function() { return EmployeeTabData }
Vue.component('employee-tab', EmployeeTab)
<% request.register_component('employee-tab', 'EmployeeTab') %>
</script>
</%def>
@ -2220,6 +2351,7 @@
NotesTab.data = function() { return NotesTabData }
Vue.component('notes-tab', NotesTab)
<% request.register_component('notes-tab', 'NotesTab') %>
</script>
</%def>
@ -2256,6 +2388,7 @@
UserTab.data = function() { return UserTabData }
Vue.component('user-tab', UserTab)
<% request.register_component('user-tab', 'UserTab') %>
</script>
</%def>
@ -2264,7 +2397,7 @@
<script type="text/javascript">
let ProfileInfoData = {
activeTab: location.hash ? location.hash.substring(1) : undefined,
activeTab: location.hash ? location.hash.substring(1) : 'personal',
tabchecks: ${json.dumps(tabchecks)|n},
today: '${rattail_app.today()}',
profileLastChanged: Date.now(),
@ -2360,6 +2493,7 @@
ProfileInfo.data = function() { return ProfileInfoData }
Vue.component('profile-info', ProfileInfo)
<% request.register_component('profile-info', 'ProfileInfo') %>
</script>
</%def>

View file

@ -332,7 +332,8 @@
v-model="orugaValue"
@update:modelValue="val => $emit('update:modelValue', val)"
:autocomplete="autocomplete"
ref="input">
ref="input"
:expanded="expanded">
<slot />
</o-input>
</script>
@ -344,6 +345,7 @@
type: String,
autocomplete: String,
disabled: Boolean,
expanded: Boolean,
},
data() {
return {
@ -374,13 +376,16 @@
<%def name="make_b_loading_component()">
<script type="text/x-template" id="b-loading-template">
<o-loading>
<o-loading :full-page="isFullPage">
<slot />
</o-loading>
</script>
<script>
const BLoading = {
template: '#b-loading-template',
props: {
isFullPage: Boolean,
},
}
</script>
<% request.register_component('b-loading', 'BLoading') %>