sync
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { Dropdown, createElement, createCheckbox, createPopup, showAlert } from "../../ui";
|
||||
import { Grid, Dropdown, createElement, createCheckbox, createPopup, showAlert } from "../../ui";
|
||||
import { isEmail, nullOrEmpty, r } from "../../utility";
|
||||
|
||||
class Contact {
|
||||
@ -185,4 +185,64 @@ class Contact {
|
||||
}
|
||||
}
|
||||
|
||||
export default Contact;
|
||||
class CustomerRecordContact {
|
||||
#option;
|
||||
#grid;
|
||||
|
||||
constructor(option = {}) {
|
||||
this.#option = option;
|
||||
}
|
||||
|
||||
async show(title, parent = document.body) {
|
||||
const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3;
|
||||
|
||||
const gridContainer = createElement('div', 'selcontact-grid');
|
||||
const popup = createPopup(
|
||||
title,
|
||||
createElement('div', 'selcontact-wrapper',
|
||||
gridContainer
|
||||
),
|
||||
{
|
||||
text: r('ok', 'OK'),
|
||||
key: 'ok',
|
||||
trigger: () => {
|
||||
if (typeof this.#option.onOk === 'function') {
|
||||
return this.#option.onOk.call(this, this.#grid.source.filter(f => f.selected));
|
||||
}
|
||||
}
|
||||
},
|
||||
{ text: r('cancel', 'Cancel'), key: 'cancel' }
|
||||
);
|
||||
const result = await popup.show(parent);
|
||||
// grid
|
||||
const grid = new Grid(gridContainer);
|
||||
grid.columns = [
|
||||
{
|
||||
key: 'selected',
|
||||
type: Grid.ColumnTypes.Checkbox,
|
||||
width: 40,
|
||||
// enabled: item => !nullOrEmpty(item.ID)
|
||||
},
|
||||
{ key: 'Name', caption: r("P_CR_CONTACTNAME", "Contact Name"), width: 100 },
|
||||
{ key: 'Email', caption: r("P_CR_CONTACTEMAIL", "Contact Email"), css: { 'width': 180, 'text-align': 'left' } },
|
||||
{ key: 'MobilePhoneDisplayText', caption: r("P_CR_CONTACTMOBILE", "Contact Mobile"), width: 130 },
|
||||
{ key: 'ContactPreferenceStr', caption: r("P_CR_CONTACTPREFERENCES", "Contact Preferences"), width: 100 },
|
||||
{ key: 'OptOut', caption: r("P_CR_OPTOUT", "Opt Out"), type: Grid.ColumnTypes.Checkbox, width: 70, enabled: false, align: 'center' },
|
||||
{ key: 'Notes', caption: r("P_CR_NOTES", "Notes"), width: 120 }
|
||||
];
|
||||
grid.init();
|
||||
grid.source = this.#option.contacts.sort(function (a, b) { return ((b.Text || b.Email) ? 1 : 0) - ((a.Text || a.Email) ? 1 : 0) });
|
||||
this.#grid = grid;
|
||||
return result;
|
||||
}
|
||||
|
||||
set source(contacts) {
|
||||
this.#option.contacts = contacts;
|
||||
const grid = this.#grid;
|
||||
if (grid != null) {
|
||||
this.#grid.source = contacts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { Contact, CustomerRecordContact };
|
@ -1,7 +1,7 @@
|
||||
import { Grid, createElement, setTooltip, createIcon, createCheckbox, createRadiobox, createPopup, showAlert, showConfirm } from "../../ui";
|
||||
import { r, nullOrEmpty, formatUrl, isEmail, isPhone } from "../../utility";
|
||||
import { createBox } from "./lib";
|
||||
import Contact from "./contact";
|
||||
import { Contact, CustomerRecordContact } from "./contact";
|
||||
import Follower from "./follower";
|
||||
|
||||
class NoteCol extends Grid.GridColumn {
|
||||
@ -124,7 +124,9 @@ class CustomerCommunication {
|
||||
}
|
||||
|
||||
get contacts() {
|
||||
return [...this.#contacts.children].map(el => {
|
||||
return [...this.#contacts.children].filter(el => {
|
||||
return el.querySelector('span').dataset.notsend == "false";
|
||||
}).map(el => {
|
||||
const span = el.querySelector('span');
|
||||
return { 'Key': span.dataset.to, 'Value': span.dataset.name };
|
||||
});
|
||||
@ -132,10 +134,13 @@ class CustomerCommunication {
|
||||
set contacts(contacts) {
|
||||
this.#contacts.replaceChildren();
|
||||
if (contacts?.length > 0) {
|
||||
for (let c of contacts) {
|
||||
if (c.OptOut || c.OptOut_BC || c.selected === false) {
|
||||
continue;
|
||||
}
|
||||
var cs = contacts.sort(function (a, b) {
|
||||
if (a.Name == b.Name) return 0; return a.Name > b.Name ? 1 : -1;
|
||||
});
|
||||
for (let c of cs) {
|
||||
//if (c.OptOut || c.OptOut_BC || c.selected === false) {
|
||||
// continue;
|
||||
//}
|
||||
const mp = String(c.MobilePhoneDisplayText).trim();
|
||||
const email = String(c.Email).trim();
|
||||
const pref = String(c.ContactPreference);
|
||||
@ -146,27 +151,34 @@ class CustomerCommunication {
|
||||
const to = pref === '1' ? email : mp;
|
||||
let icon;
|
||||
let method;
|
||||
switch (pref) {
|
||||
case '0':
|
||||
icon = 'comment-lines';
|
||||
method = r('textsToColon', 'Texts to:');
|
||||
break;
|
||||
case '2':
|
||||
icon = 'mobile';
|
||||
method = r('callsToColon', 'Calls to:');
|
||||
break;
|
||||
default:
|
||||
icon = 'envelope';
|
||||
method = r('emailsToColon', 'Emails to:');
|
||||
break;
|
||||
if (c.OptOut || c.OptOut_BC || c.selected === false) {
|
||||
icon = 'times';
|
||||
method = r('optedOut', 'Opted Out:');
|
||||
}
|
||||
else {
|
||||
switch (pref) {
|
||||
case '0':
|
||||
icon = 'comment-lines';
|
||||
method = r('textsToColon', 'Texts to:');
|
||||
break;
|
||||
case '2':
|
||||
icon = 'mobile';
|
||||
method = r('callsToColon', 'Calls to:');
|
||||
break;
|
||||
default:
|
||||
icon = 'envelope';
|
||||
method = r('emailsToColon', 'Emails to:');
|
||||
break;
|
||||
}
|
||||
}
|
||||
const span = createElement('span', span => {
|
||||
span.dataset.to = to;
|
||||
span.dataset.name = c.Name;
|
||||
span.dataset.notsend = c.OptOut || c.OptOut_BC || c.selected === false;
|
||||
span.innerText = c.Name;
|
||||
});
|
||||
const item = createElement('div', 'contact-item',
|
||||
createIcon('fa-light', icon),
|
||||
createIcon('fa-light', icon, { 'fill': (c.OptOut || c.OptOut_BC || c.selected === false) ? 'red' : '' }),
|
||||
span
|
||||
);
|
||||
this.#contacts.appendChild(item);
|
||||
@ -479,6 +491,88 @@ class CustomerCommunication {
|
||||
}
|
||||
})
|
||||
),
|
||||
createElement('button', button => {
|
||||
button.style.flex = '0 0 auto';
|
||||
button.style.backgroundColor = 'rgb(1, 199, 172)';
|
||||
button.style.marginRight = '10px';
|
||||
button.className = 'roundbtn button-from-customer-record';
|
||||
if (recordReadonly) {
|
||||
button.style.display = 'none';
|
||||
}
|
||||
button.appendChild(createIcon('fa-solid', 'handshake', {
|
||||
width: '16px',
|
||||
height: '16px'
|
||||
}));
|
||||
button.addEventListener('click', () => {
|
||||
const sel = new CustomerRecordContact({
|
||||
contacts: [],
|
||||
onOk: list => {
|
||||
if (typeof this.#option.onSelectCRContacts === 'function') {
|
||||
list?.map(c => {
|
||||
delete c.selected;
|
||||
return c;
|
||||
});
|
||||
const result = this.#option.onSelectCRContacts(list);
|
||||
}
|
||||
const r = this.#data.contacts;
|
||||
this.#gridContact.source = r.filter(c => c.Id >= 0).map(c => {
|
||||
if (c.OptOut || c.OptOut_BC) {
|
||||
return c;
|
||||
}
|
||||
if (typeof c.selected === 'undefined') {
|
||||
c.selected = true;
|
||||
}
|
||||
return c;
|
||||
});
|
||||
this.#gridWo.source = r.filter(c => c.Id < 0).map(c => {
|
||||
if (c.OptOut || c.OptOut_BC) {
|
||||
return c;
|
||||
}
|
||||
if (typeof c.selected === 'undefined') {
|
||||
c.selected = true;
|
||||
}
|
||||
return c;
|
||||
});
|
||||
}
|
||||
});
|
||||
var title = r('selectFromCustomerRecord', 'Select from Customer Record');
|
||||
sel.show(title, container);
|
||||
|
||||
if (typeof this.#option.onOpenSelectCRContacts === 'function') {
|
||||
const result = this.#option.onOpenSelectCRContacts();
|
||||
if (typeof result?.then === 'function') {
|
||||
return result.then(r => {
|
||||
r.map(c => {
|
||||
for (let cc of this.#data.contacts) {
|
||||
if (c.Id === cc.Id) {
|
||||
c.selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (typeof c.selected === 'undefined') {
|
||||
c.selected = false;
|
||||
}
|
||||
return c;
|
||||
});
|
||||
this.#data.contacts.filter(c => c.Id >= 0).map(c => {
|
||||
if (c.OptOut || c.OptOut_BC) {
|
||||
return c;
|
||||
}
|
||||
if (typeof c.selected === 'undefined') {
|
||||
c.selected = true;
|
||||
}
|
||||
return c;
|
||||
});
|
||||
|
||||
sel.source = r;
|
||||
return r;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
setTooltip(button, r('selectFromCustomerRecord', 'Select from Customer Record'))
|
||||
}),
|
||||
createElement('button', button => {
|
||||
button.style.flex = '0 0 auto';
|
||||
button.style.backgroundColor = 'rgb(1, 199, 172)';
|
||||
@ -568,7 +662,7 @@ class CustomerCommunication {
|
||||
const selectedCol = This => {
|
||||
return {
|
||||
key: 'selected',
|
||||
type: TooltipCheckboxColumn,
|
||||
type: Grid.ColumnTypes.Checkbox,
|
||||
width: 50,
|
||||
enabled: item => !item.OptOut && !item.OptOut_BC,
|
||||
onchanged: function () {
|
||||
@ -576,7 +670,7 @@ class CustomerCommunication {
|
||||
option.onChanged([...This.#gridContact.source, ...This.#gridWo.source]);
|
||||
}
|
||||
},
|
||||
tooltip: item => item.OptOut ? r('optedOut', 'Opted Out') : r('optedIn', 'Opted In')
|
||||
tooltip: item => item.selected ? r('optedIn', 'Opted In') : r('optedOut', 'Opted Out')
|
||||
}
|
||||
};
|
||||
const iconCol = {
|
||||
@ -819,6 +913,33 @@ class CustomerCommunication {
|
||||
button.appendChild(createIcon('fa-solid', 'pen'));
|
||||
setTooltip(button, r('editFollower', 'Edit Followers'));
|
||||
button.addEventListener('click', () => {
|
||||
if (typeof this.#option.onInitFollower === 'function') {
|
||||
this.#option.onInitFollower(this.#data.followers).then(data => {
|
||||
if (typeof data === 'string') {
|
||||
showAlert(r('customerRecord', 'Customer Record'), data, 'warn');
|
||||
return;
|
||||
}
|
||||
const add = new Follower({
|
||||
followers: data,
|
||||
onOk: list => {
|
||||
if (typeof this.#option.onAddFollower === 'function') {
|
||||
const result = this.#option.onAddFollower(list);
|
||||
if (typeof result?.then === 'function') {
|
||||
return result.then(r => {
|
||||
//this.#gridFollower.source = r;
|
||||
return r;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
var title = this.#data.followers?.length > 0 ? r('editFollowers', 'Edit Followers') : r('addFollowers', 'Add Followers');
|
||||
add.show(title, container);
|
||||
});
|
||||
}
|
||||
return;
|
||||
|
||||
const pop = createPopup(
|
||||
createElement('div', div => {
|
||||
div.style.display = 'flex';
|
||||
|
@ -9,12 +9,12 @@ class Follower {
|
||||
this.#option = option;
|
||||
}
|
||||
|
||||
async show(parent = document.body) {
|
||||
async show(title, parent = document.body) {
|
||||
const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3;
|
||||
|
||||
const gridContainer = createElement('div', 'follower-grid');
|
||||
const popup = createPopup(
|
||||
r('addFollowers', 'Add Followers'),
|
||||
title,
|
||||
createElement('div', 'follower-wrapper',
|
||||
createElement('div', div => div.innerText = r('whoWantReceiveCustomerNotification', 'Who do you want to receive customer notifications?')),
|
||||
createElement('input', search => {
|
||||
@ -24,9 +24,10 @@ class Follower {
|
||||
search.addEventListener('input', () => {
|
||||
const key = search.value;
|
||||
if (nullOrEmpty(key)) {
|
||||
this.#grid.source = this.#option.followers;
|
||||
this.#grid.source = this.#option.followers.sort(function (a, b) { return ((b.Text || b.Email) ? 1 : 0) - ((a.Text || a.Email) ? 1 : 0) });
|
||||
} else {
|
||||
this.#grid.source = this.#option.followers.filter(f => f.Text || f.Email || contains(f.DisplayName, key, true));
|
||||
this.#grid.source = this.#option.followers.filter(f => f.Text || f.Email || contains(f.DisplayName, key, true))
|
||||
.sort(function (a, b) { return ((b.Text || b.Email) ? 1 : 0) - ((a.Text || a.Email) ? 1 : 0) });
|
||||
}
|
||||
});
|
||||
}),
|
||||
@ -66,7 +67,7 @@ class Follower {
|
||||
}
|
||||
];
|
||||
grid.init();
|
||||
grid.source = this.#option.followers;
|
||||
grid.source = this.#option.followers.sort(function (a, b) { return ((b.Text || b.Email) ? 1 : 0) - ((a.Text || a.Email) ? 1 : 0) });
|
||||
this.#grid = grid;
|
||||
return result;
|
||||
}
|
||||
|
@ -368,6 +368,8 @@
|
||||
|
||||
.contact-note {
|
||||
color: #999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -386,6 +388,16 @@
|
||||
height: 380px;
|
||||
}
|
||||
}
|
||||
|
||||
.selcontact-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 780px;
|
||||
|
||||
> .selcontact-grid {
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user