sync
This commit is contained in:
		| @@ -71,7 +71,7 @@ export default class CustomerRecordComment { | ||||
|             createElement('div', null, | ||||
|                 createElement('div', div => { | ||||
|                     div.className = 'title-module'; | ||||
|                     div.innerText = r('P_CR_COMMENTS', 'Comments'); | ||||
|                     div.innerText = r('FLTL_00584', 'Comments'); | ||||
|                 }, | ||||
|                     createHideMessageTitleButton(this, 'showCommentHidden') | ||||
|                 ) | ||||
| @@ -97,7 +97,7 @@ export default class CustomerRecordComment { | ||||
|         ); | ||||
|         // enter box | ||||
|         const enter = createElement('textarea', 'ui-text'); | ||||
|         enter.placeholder = r('P_CU_ENTERCOMMENTHERE', 'Enter Comment Here'); | ||||
|         enter.placeholder = r('FLTL_01154', 'Enter Comment Here'); | ||||
|         enter.maxLength = this._var.option.maxLength ??= 3000; | ||||
|         enter.addEventListener('input', () => { | ||||
|             const val = this.text; | ||||
| @@ -120,8 +120,8 @@ export default class CustomerRecordComment { | ||||
|                             button.style.display = 'none'; | ||||
|                         } | ||||
|                         button.appendChild(createIcon('fa-solid', 'paper-plane')); | ||||
|                         // setTooltip(button, r('P_M3_SENDMESSAGE', 'Send Message')); | ||||
|                         setTooltip(button, r('P_CU_POSTNOTE', 'Post Note')); | ||||
|                         // setTooltip(button, r('FLTL_02692', 'Send Message')); | ||||
|                         setTooltip(button, r('FLTL_02301', 'Post Note')); | ||||
|                         button.addEventListener('click', () => { | ||||
|                             if (typeof this._var.option.onAddComment === 'function') { | ||||
|                                 this._var.option.onAddComment(this.text); | ||||
| @@ -151,7 +151,7 @@ export default class CustomerRecordComment { | ||||
|                     } | ||||
|                 } | ||||
|                 // if (sendto !== '') { | ||||
|                 //     sendto = r('P_CU_SENDTO_COLON', 'Sent To :') + `\n${sendto}`; | ||||
|                 //     sendto = r('FLTL_02716', 'Sent To :') + `\n${sendto}`; | ||||
|                 // } | ||||
|                 div.appendChild(createElement('div', div => { | ||||
|                     div.className = 'item-poster'; | ||||
|   | ||||
| @@ -29,9 +29,9 @@ export class Contact { | ||||
|         }); | ||||
|         const preferences = new Dropdown({ tabIndex: tabIndex + 2 }); | ||||
|         preferences.source = [ | ||||
|             { value: '0', text: r('P_CR_TEXT', 'Text') }, | ||||
|             { value: '1', text: r('P_CR_EMAIL', 'Email') }, | ||||
|             { value: '2', text: r('P_CR_PHONE', 'Phone') } | ||||
|             { value: '0', text: r('FLTL_02915', 'Text') }, | ||||
|             { value: '1', text: r('FLTL_01089', 'Email') }, | ||||
|             { value: '2', text: r('FLTL_02194', 'Phone') } | ||||
|         ]; | ||||
|         const contactEmail = createElement('input', input => { | ||||
|             input.type = 'email'; | ||||
| @@ -57,7 +57,7 @@ export class Contact { | ||||
|         const buttons = []; | ||||
|         if (this._var.option.company) { | ||||
|             buttons.push({ | ||||
|                 text: c == null ? r('P_WO_ADDCONTACTRECORD', 'Add Contact Record') : r('P_WO_EDITCONTACTRECORD', 'Edit Contact Record'), | ||||
|                 text: c == null ? r('FLTL_00100', 'Add Contact Record') : r('FLTL_01042', 'Edit Contact Record'), | ||||
|                 // tabIndex: tabIndex + 7, | ||||
|                 trigger: () => { | ||||
|                     const item = this.prepare(); | ||||
| @@ -73,7 +73,7 @@ export class Contact { | ||||
|         } | ||||
|         buttons.push( | ||||
|             { | ||||
|                 text: r('P_WO_WORKORDERONLY', 'Work Order Only'), | ||||
|                 text: r('FLTL_03348', 'Work Order Only'), | ||||
|                 // tabIndex: tabIndex + 8, | ||||
|                 trigger: () => { | ||||
|                     const item = this.prepare(); | ||||
| @@ -88,39 +88,39 @@ export class Contact { | ||||
|                 } | ||||
|             }, | ||||
|             { | ||||
|                 text: r('P_WO_CANCEL', 'Cancel'), | ||||
|                 text: r('FLTL_00499', 'Cancel'), | ||||
|                 // tabIndex: tabIndex + 9 | ||||
|             } | ||||
|         ); | ||||
|         const popup = new Popup({ | ||||
|             onMasking: this._var.option.onMasking, | ||||
|             title: c == null ? r('P_CR_ADDCONTACT', 'Add Contact') : r('P_CR_EDITCONTACT', 'Edit Contact'), | ||||
|             title: c == null ? r('FLTL_00099', 'Add Contact') : r('FLTL_01041', 'Edit Contact'), | ||||
|             content: createElement('div', wrapper => { | ||||
|                 wrapper.className = 'setting-wrapper'; | ||||
|                 wrapper.style.width = '500px'; | ||||
|             }, | ||||
|                 createElement('div', 'setting-item', | ||||
|                     createElement('span', 'setting-label setting-required', r('P_CR_CONTACTNAME_COLON', 'Contact Name:')), | ||||
|                     createElement('span', 'setting-label setting-required', r('FLTL_00640', 'Contact Name:')), | ||||
|                     contactName | ||||
|                 ), | ||||
|                 createElement('div', 'setting-item', | ||||
|                     createElement('span', 'setting-label', r('P_CR_CONTACTPREFERENCES_COLON', 'Contact Preferences:')), | ||||
|                     createElement('span', 'setting-label', r('FLTL_00643', 'Contact Preferences:')), | ||||
|                     preferences.create() | ||||
|                 ), | ||||
|                 createElement('div', 'setting-item', | ||||
|                     createElement('span', 'setting-label', r('P_CR_EMAILADDRESS_COLON', 'Email Address:')), | ||||
|                     createElement('span', 'setting-label', r('FLTL_01092', 'Email Address:')), | ||||
|                     contactEmail | ||||
|                 ), | ||||
|                 createElement('div', 'setting-item', | ||||
|                     createElement('span', 'setting-label', r('P_WO_MOBILE_COLON', 'Mobile:')), | ||||
|                     createElement('span', 'setting-label', r('FLTL_01932', 'Mobile:')), | ||||
|                     contactMobile | ||||
|                 ), | ||||
|                 createElement('div', 'setting-item', | ||||
|                     createElement('span', 'setting-label', r('P_CR_OPTOUT_COLON', 'Opt Out:')), | ||||
|                     createElement('span', 'setting-label', r('FLTL_02089', 'Opt Out:')), | ||||
|                     checkOpt | ||||
|                 ), | ||||
|                 createElement('div', 'setting-item', | ||||
|                     createElement('span', 'setting-label', r('P_CR_NOTES_COLON', 'Notes:')), | ||||
|                     createElement('span', 'setting-label', r('FLTL_02017', 'Notes:')), | ||||
|                     contactNotes | ||||
|                 ) | ||||
|             ), | ||||
| @@ -156,24 +156,24 @@ export class Contact { | ||||
|         const phone = this._var.refs.contactMobile.value; | ||||
|         const opt = this._var.refs.checkOpt.querySelector('input').checked; | ||||
|         const notes = this._var.refs.contactNotes.value; | ||||
|         const title = this._var.option.contact == null ? r('P_CR_ADDCONTACT', 'Add Contact') : r('P_CR_EDITCONTACT', 'Edit Contact'); | ||||
|         const title = this._var.option.contact == null ? r('FLTL_00099', 'Add Contact') : r('FLTL_01041', 'Edit Contact'); | ||||
|         if (nullOrEmpty(name)) { | ||||
|             showAlert(title, r('P_CR_CONTACTNAMECANNOTBEEMPTY', 'Contact Name cannot be empty.'), 'warn') | ||||
|             showAlert(title, r('FLTL_00639', 'Contact Name cannot be empty.'), 'warn') | ||||
|                 .then(() => this._var.refs.contactName.focus()); | ||||
|             return null; | ||||
|         } | ||||
|         if ((pref == 0 || pref == 2) && nullOrEmpty(phone)) { | ||||
|             showAlert(title, r('P_CR_MOBILECANNOTBEEMPTY', 'Mobile cannot be empty.'), 'warn') | ||||
|             showAlert(title, r('FLTL_01929', 'Mobile cannot be empty.'), 'warn') | ||||
|                 .then(() => this._var.refs.contactMobile.focus()); | ||||
|             return null; | ||||
|         } | ||||
|         if (pref == 1 && nullOrEmpty(email)) { | ||||
|             showAlert(title, r('P_CU_EMAILCANNOTBEEMPTY', 'Email cannot be empty.'), 'warn') | ||||
|             showAlert(title, r('FLTL_01094', 'Email cannot be empty.'), 'warn') | ||||
|                 .then(() => this._var.refs.contactEmail.focus()); | ||||
|             return null; | ||||
|         } | ||||
|         if (!nullOrEmpty(email) && !isEmail(email)) { | ||||
|             showAlert(title, r('P_CR_EMAILISNOTAVALIDEMAILADDRESS', 'The email address is invalid.'), 'warn') | ||||
|             showAlert(title, r('FLTL_02952', 'The email address is invalid.'), 'warn') | ||||
|                 .then(() => this._var.refs.contactEmail.focus()); | ||||
|             return null; | ||||
|         } | ||||
| @@ -223,7 +223,7 @@ export class CustomerRecordContact { | ||||
|             ), | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: r('P_WO_OK', 'OK'), | ||||
|                     text: r('FLTL_02057', 'OK'), | ||||
|                     key: 'ok', | ||||
|                     trigger: () => { | ||||
|                         if (typeof this._var.option.onOk === 'function') { | ||||
| @@ -231,7 +231,7 @@ export class CustomerRecordContact { | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { text: r('P_WO_CANCEL', 'Cancel'), key: 'cancel' } | ||||
|                 { text: r('FLTL_00499', 'Cancel'), key: 'cancel' } | ||||
|             ] | ||||
|         }); | ||||
|         const result = await popup.show(parent); | ||||
| @@ -244,12 +244,12 @@ export class CustomerRecordContact { | ||||
|                 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 } | ||||
|             { key: 'Name', caption: r('FLTL_00637', 'Contact Name'), width: 100 }, | ||||
|             { key: 'Email', caption: r('FLTL_00633', 'Contact Email'), css: { 'width': 180, 'text-align': 'left' } }, | ||||
|             { key: 'MobilePhoneDisplayText', caption: r('FLTL_00636', 'Contact Mobile'), width: 130 }, | ||||
|             { key: 'ContactPreferenceStr', caption: r('FLTL_00642', 'Contact Preferences'), width: 100 }, | ||||
|             { key: 'OptOut', caption: r('FLTL_02084', 'Opt Out'), type: Grid.ColumnTypes.Checkbox, width: 70, enabled: false, align: 'center' }, | ||||
|             { key: 'Notes', caption: r('FLTL_02012', 'Notes'), width: 120 } | ||||
|         ]; | ||||
|         grid.init(); | ||||
|         grid.source = this._var.option.contacts.sort(function (a, b) { return ((b.Text || b.Email) ? 1 : 0) - ((a.Text || a.Email) ? 1 : 0) }); | ||||
|   | ||||
| @@ -215,7 +215,7 @@ export default class CustomerCommunication { | ||||
|                 let tipstr; | ||||
|                 if (c.OptOut || c.OptOut_BC || c.selected === false) { | ||||
|                     icon = 'times'; | ||||
|                     tipstr = r('P_CU_OPTEDOUT_PROMPT', 'User has opted out of messages'); | ||||
|                     tipstr = r('FLTL_03200', 'User has opted out of messages'); | ||||
|                 } | ||||
|                 else { | ||||
|                     switch (pref) { | ||||
| @@ -224,20 +224,20 @@ export default class CustomerCommunication { | ||||
|                                 icon = 'times'; | ||||
|                                 if (c.MobilePhoneStatus === 412) { | ||||
|                                     // landline | ||||
|                                     tipstr = r('P_CU_LANDLINE', 'Landline'); | ||||
|                                     tipstr = r('FLTL_01707', 'Landline'); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 icon = 'comment-lines'; | ||||
|                             } | ||||
|                             method = r('P_CU_TEXTSTO_COLON', 'Texts to:'); | ||||
|                             method = r('FLTL_02924', 'Texts to:'); | ||||
|                             break; | ||||
|                         case '2': | ||||
|                             icon = 'phone'; | ||||
|                             tipstr = r('P_CU_NOMESSAGE', 'No Messages Sent'); | ||||
|                             tipstr = r('FLTL_01991', 'No Messages Sent'); | ||||
|                             break; | ||||
|                         default: | ||||
|                             icon = 'envelope'; | ||||
|                             method = r('P_CU_EMAILSTO_COLON', 'Emails to:'); | ||||
|                             method = r('FLTL_01109', 'Emails to:'); | ||||
|                             break; | ||||
|                     } | ||||
|                 } | ||||
| @@ -254,7 +254,7 @@ export default class CustomerCommunication { | ||||
|                 this._var.contacts.appendChild(item); | ||||
|                 let tip = tipstr || `${method} ${to}`; | ||||
|                 if (span.scrollWidth > span.offsetWidth) { | ||||
|                     tip = r('P_WO_NAME_COLON', 'Name:') + ` ${c.Name}\n${tip}`; | ||||
|                     tip = r('FLTL_01970', 'Name:') + ` ${c.Name}\n${tip}`; | ||||
|                 } | ||||
|                 setTooltip(span, tip); | ||||
|             } | ||||
| @@ -315,8 +315,8 @@ export default class CustomerCommunication { | ||||
|                 if (this._var.option.customerReadonly === true) { | ||||
|                     div.style.display = 'none'; | ||||
|                 } else { | ||||
|                     div.querySelector('.title-company-name').innerText = r('P_WO_NOCUSTOMERASSIGNED', 'No Customer Assigned'); | ||||
|                     companyCode.innerText = ' /\n' + r('P_WO_SELECTCUSTOMER', 'Select Customer'); | ||||
|                     div.querySelector('.title-company-name').innerText = r('FLTL_01985', 'No Customer Assigned'); | ||||
|                     companyCode.innerText = ' /\n' + r('FLTL_02654', 'Select Customer'); | ||||
|                     companyCode.style.display = ''; | ||||
|                 } | ||||
|             } else { | ||||
| @@ -337,8 +337,8 @@ export default class CustomerCommunication { | ||||
|         const companyCode = div.querySelector('.title-company-code'); | ||||
|         if (companyCode != null) { | ||||
|             if (nullOrEmpty(option.companyName)) { | ||||
|                 div.querySelector('.title-company-name').innerText = r('P_WO_NOCUSTOMERASSIGNED', 'No Customer Assigned'); | ||||
|                 companyCode.innerText = ' /\n' + r('P_WO_SELECTCUSTOMER', 'Select Customer'); | ||||
|                 div.querySelector('.title-company-name').innerText = r('FLTL_01985', 'No Customer Assigned'); | ||||
|                 companyCode.innerText = ' /\n' + r('FLTL_02654', 'Select Customer'); | ||||
|                 companyCode.style.display = ''; | ||||
|             } else { | ||||
|                 div.querySelector('.title-company-name').innerText = option.companyName; | ||||
| @@ -364,7 +364,7 @@ export default class CustomerCommunication { | ||||
|         this._var.followers.replaceChildren(); | ||||
|         if (followers?.length > 0) { | ||||
|             this._var.container.querySelector('.follower-bar').style.display = ''; | ||||
|             setTooltip(this._var.buttonFollower, r('P_CU_EDITFOLLOWERS', 'Edit Followers')); | ||||
|             setTooltip(this._var.buttonFollower, r('FLTL_01054', 'Edit Followers')); | ||||
|             this._var.container.querySelector('.follower-bar>.bar-list').appendChild(this._var.buttonFollower); | ||||
|             for (let f of followers) { | ||||
|                 if (f.OptOut) { | ||||
| @@ -375,10 +375,10 @@ export default class CustomerCommunication { | ||||
|                 const email = String(f.Email).trim(); | ||||
|                 const tips = []; | ||||
|                 if (f.SendEmail) { | ||||
|                     tips.push(r('P_CU_EMAILSTO_COLON', 'Emails to:') + ` ${email}`); | ||||
|                     tips.push(r('FLTL_01109', 'Emails to:') + ` ${email}`); | ||||
|                 } | ||||
|                 if (f.SendText) { | ||||
|                     tips.push(r('P_CU_TEXTSTO_COLON', 'Texts to:') + ` ${mpDisplay}`); | ||||
|                     tips.push(r('FLTL_02924', 'Texts to:') + ` ${mpDisplay}`); | ||||
|                 } | ||||
|                 let icon; | ||||
|                 if (f.SendText && f.SendEmail) { | ||||
| @@ -402,13 +402,13 @@ export default class CustomerCommunication { | ||||
|                 ); | ||||
|                 this._var.followers.appendChild(item); | ||||
|                 if (span.scrollWidth > span.offsetWidth) { | ||||
|                     tips.splice(0, 0, r('P_WO_NAME_COLON', 'Name:') + ` ${f.Name}`); | ||||
|                     tips.splice(0, 0, r('FLTL_01970', 'Name:') + ` ${f.Name}`); | ||||
|                 } | ||||
|                 setTooltip(span, tips.join('\n')); | ||||
|             } | ||||
|         } else { | ||||
|             this._var.container.querySelector('.follower-bar').style.display = 'none'; | ||||
|             setTooltip(this._var.buttonFollower, r('P_CR_ADDFOLLOWERS', 'Add Followers')); | ||||
|             setTooltip(this._var.buttonFollower, r('FLTL_00116', 'Add Followers')); | ||||
|             this._var.container.querySelector('.button-edit-contacts').insertAdjacentElement('beforebegin', this._var.buttonFollower) | ||||
|         } | ||||
|         this._var.message.scrollTop = this._var.message.scrollHeight | ||||
| @@ -429,8 +429,8 @@ export default class CustomerCommunication { | ||||
|             uncheckedNode: createIcon('fa-regular', 'ban'), | ||||
|             onchange: function () { | ||||
|                 setTooltip(checkAutoUpdate, this.checked ? | ||||
|                     r('P_CU_AUTOUPDATESENABLED', 'Auto Updates Enabled') : | ||||
|                     r('P_CU_AUTOUPDATESDISABLED', 'Auto Updates Disabled')); | ||||
|                     r('FLTL_00420', 'Auto Updates Enabled') : | ||||
|                     r('FLTL_00419', 'Auto Updates Disabled')); | ||||
|             } | ||||
|         }); | ||||
|         if (option.autoUpdatesVisible === false) { | ||||
| @@ -445,8 +445,8 @@ export default class CustomerCommunication { | ||||
|             uncheckedNode: createIcon('fa-regular', 'unlink'), | ||||
|             onchange: function () { | ||||
|                 setTooltip(checkLink, this.checked ? | ||||
|                     r('P_WO_STATUSLINKINCLUDED', 'Status Link Included') : | ||||
|                     r('P_WO_STATUSLINKEXCLUDED', 'Status Link Excluded')); | ||||
|                     r('FLTL_02830', 'Status Link Included') : | ||||
|                     r('FLTL_02829', 'Status Link Excluded')); | ||||
|                 if (typeof option.onStatusLinkChanged === 'function') { | ||||
|                     option.onStatusLinkChanged.call(This, this.checked); | ||||
|                 } | ||||
| @@ -460,7 +460,7 @@ export default class CustomerCommunication { | ||||
|             createElement('div', null, | ||||
|                 createElement('div', div => { | ||||
|                     div.className = 'title-module'; | ||||
|                     div.innerText = option.title ?? r('P_WO_CUSTOMERCOMMUNICATION', 'Customer Communication'); | ||||
|                     div.innerText = option.title ?? r('FLTL_00732', 'Customer Communication'); | ||||
|                 }, | ||||
|                     createHideMessageTitleButton(this, 'showMessageHidden') | ||||
|                 ), | ||||
| @@ -472,7 +472,7 @@ export default class CustomerCommunication { | ||||
|                     createElement('span', span => { | ||||
|                         span.className = 'title-company-name'; | ||||
|                         if (nullOrEmpty(option.companyName)) { | ||||
|                             span.innerText = r('P_WO_NOCUSTOMERASSIGNED', 'No Customer Assigned'); | ||||
|                             span.innerText = r('FLTL_01985', 'No Customer Assigned'); | ||||
|                         } else { | ||||
|                             span.innerText = option.companyName; | ||||
|                         } | ||||
| @@ -482,7 +482,7 @@ export default class CustomerCommunication { | ||||
|                         if (option.customerReadonly === true) { | ||||
|                             span.style.display = 'none'; | ||||
|                         } else if (nullOrEmpty(option.companyName)) { | ||||
|                             span.innerText = ' /\n' + r('P_WO_SELECTCUSTOMER', 'Select Customer'); | ||||
|                             span.innerText = ' /\n' + r('FLTL_02654', 'Select Customer'); | ||||
|                         } else if (!nullOrEmpty(option.companyCode)) { | ||||
|                             span.innerText = ' / ' + option.companyCode; | ||||
|                         } else { | ||||
| @@ -494,7 +494,7 @@ export default class CustomerCommunication { | ||||
|                         if (option.recordReadonly) { | ||||
|                             span.style.display = 'none'; | ||||
|                         } | ||||
|                         setTooltip(span, r('P_WO_SELECTCUSTOMER', 'Select Customer')); | ||||
|                         setTooltip(span, r('FLTL_02654', 'Select Customer')); | ||||
|                         if (typeof option.onAddCompany === 'function') { | ||||
|                             span.addEventListener('click', () => option.onAddCompany.call(this)); | ||||
|                         } | ||||
| @@ -504,8 +504,8 @@ export default class CustomerCommunication { | ||||
|                 ) | ||||
|             ), | ||||
|             [ | ||||
|                 setTooltip(checkAutoUpdate, r('P_CU_AUTOUPDATESENABLED', 'Auto Updates Enabled')), | ||||
|                 setTooltip(checkLink, r('P_WO_STATUSLINKEXCLUDED', 'Status Link Excluded')) | ||||
|                 setTooltip(checkAutoUpdate, r('FLTL_00420', 'Auto Updates Enabled')), | ||||
|                 setTooltip(checkLink, r('FLTL_02829', 'Status Link Excluded')) | ||||
|             ] | ||||
|         ); | ||||
|         // contacts | ||||
| @@ -514,7 +514,7 @@ export default class CustomerCommunication { | ||||
|         this._var.followers = this._createFollowers(container, option); | ||||
|         // enter box | ||||
|         const enter = createElement('textarea', 'ui-text'); | ||||
|         enter.placeholder = r('P_CU_ENTERMESSAGEHERE', 'Enter Message Here'); | ||||
|         enter.placeholder = r('FLTL_01157', 'Enter Message Here'); | ||||
|         option.maxLength ??= 3000; | ||||
|         enter.maxLength = option.maxLength; | ||||
|         // if (readonly === true) { | ||||
| @@ -586,7 +586,7 @@ export default class CustomerCommunication { | ||||
|                                 div.style.display = 'none'; | ||||
|                             } | ||||
|                         }, | ||||
|                             createElement('span', span => span.innerText = r('P_WO_NAME_COLON', 'Name:')), | ||||
|                             createElement('span', span => span.innerText = r('FLTL_01970', 'Name:')), | ||||
|                             createElement('input', input => { | ||||
|                                 input.type = 'text'; | ||||
|                                 input.className = 'ui-input'; | ||||
| @@ -631,11 +631,11 @@ export default class CustomerCommunication { | ||||
|                         //     button.style.display = 'none'; | ||||
|                         // } | ||||
|                         button.appendChild(createIcon('fa-solid', 'paper-plane')); | ||||
|                         setTooltip(button, r('P_M3_SENDMESSAGE', 'Send Message')); | ||||
|                         setTooltip(button, r('FLTL_02692', 'Send Message')); | ||||
|                         button.addEventListener('click', () => { | ||||
|                             const val = this.text; | ||||
|                             if (nullOrEmpty(val?.trim())) { | ||||
|                                 const p = showAlert(r('P_WO_ERROR', 'Error'), r('P_WO_PLEASEINPUTTHEMESSAGE', 'Please input the message.'), 'warn'); | ||||
|                                 const p = showAlert(r('FLTL_01165', 'Error'), r('FLTL_02233', 'Please input the message.'), 'warn'); | ||||
|                                 if (typeof option.onMasking === 'function') { | ||||
|                                     option.onMasking(true); | ||||
|                                     p.then(() => option.onMasking(false)); | ||||
| @@ -678,7 +678,7 @@ export default class CustomerCommunication { | ||||
|                             button.style.display = 'none'; | ||||
|                         } | ||||
|                         button.appendChild(createIcon('fa-solid', 'user-edit')); | ||||
|                         setTooltip(button, r('P_CU_EDITCONTACTS', 'Edit Contacts')); | ||||
|                         setTooltip(button, r('FLTL_01043', 'Edit Contacts')); | ||||
|                         button.addEventListener('click', () => { | ||||
|                             const editContacts = () => { | ||||
|                                 const pop = new Popup({ | ||||
| @@ -692,7 +692,7 @@ export default class CustomerCommunication { | ||||
|                                                 div.className = 'ui-popup-move'; | ||||
|                                                 div.style.flex = '1 1 auto'; | ||||
|                                             }, | ||||
|                                                 createElement('div', div => div.innerText = r('P_CU_EDITCONTACTS', 'Edit Contacts')), | ||||
|                                                 createElement('div', div => div.innerText = r('FLTL_01043', 'Edit Contacts')), | ||||
|                                                 createElement('div', div => { | ||||
|                                                     div.className = 'title-company'; | ||||
|                                                     div.style.maxWidth = '540px'; | ||||
| @@ -760,7 +760,7 @@ export default class CustomerCommunication { | ||||
|                                                             }); | ||||
|                                                         } | ||||
|                                                     }); | ||||
|                                                     var title = r('P_CU_SELECTFROMCUSTOMERRECORD', 'Select from Customer Record'); | ||||
|                                                     var title = r('FLTL_02657', 'Select from Customer Record'); | ||||
|                                                     sel.show(title, container); | ||||
|  | ||||
|                                                     if (typeof option.onOpenSelectCRContacts === 'function') { | ||||
| @@ -796,7 +796,7 @@ export default class CustomerCommunication { | ||||
|                                                         return false; | ||||
|                                                     } | ||||
|                                                 }); | ||||
|                                                 setTooltip(button, r('P_CU_SELECTFROMCUSTOMERRECORD', 'Select from Customer Record')) | ||||
|                                                 setTooltip(button, r('FLTL_02657', 'Select from Customer Record')) | ||||
|                                             }), | ||||
|                                             createElement('button', button => { | ||||
|                                                 button.style.flex = '0 0 auto'; | ||||
| @@ -818,7 +818,7 @@ export default class CustomerCommunication { | ||||
|                                                         onSave: item => { | ||||
|                                                             const exists = this._var.gridContact.source.some(s => s.Name === item.Name && s.MobilePhone === item.MobilePhone); | ||||
|                                                             if (exists) { | ||||
|                                                                 showAlert(r('P_CR_ADDCONTACT', 'Add Contact'), r('P_WO_CONTACTNAMEANDMOBILEUNIQUECOMBINATION', 'Contact name and contact mobile must be a unique combination.'), 'warn'); | ||||
|                                                                 showAlert(r('FLTL_00099', 'Add Contact'), r('FLTL_00638', 'Contact name and contact mobile must be a unique combination.'), 'warn'); | ||||
|                                                                 return false; | ||||
|                                                             } | ||||
|                                                             if (typeof option.onSave === 'function') { | ||||
| @@ -852,7 +852,7 @@ export default class CustomerCommunication { | ||||
|                                                     }); | ||||
|                                                     add.show(container); | ||||
|                                                 }); | ||||
|                                                 setTooltip(button, r('P_CR_ADDCONTACT', 'Add Contact')) | ||||
|                                                 setTooltip(button, r('FLTL_00099', 'Add Contact')) | ||||
|                                             }) | ||||
|                                         ) | ||||
|                                     }), | ||||
| @@ -862,7 +862,7 @@ export default class CustomerCommunication { | ||||
|                                                 div.style.display = 'none'; | ||||
|                                             } | ||||
|                                             div.style.fontWeight = 'bold'; | ||||
|                                             div.innerText = r('P_CU_CONTACTSFROMCUSTOMERRECORD', 'Contacts from Customer Record'); | ||||
|                                             div.innerText = r('FLTL_00657', 'Contacts from Customer Record'); | ||||
|                                         }), | ||||
|                                         createElement('div', div => { | ||||
|                                             if (nullOrEmpty(option.companyName)) { | ||||
| @@ -875,7 +875,7 @@ export default class CustomerCommunication { | ||||
|                                         }), | ||||
|                                         createElement('div', div => { | ||||
|                                             div.style.fontWeight = 'bold'; | ||||
|                                             div.innerText = r('P_CU_CONTACTSNOTCUSTOMERRECORD', 'Contacts not on Customer Record'); | ||||
|                                             div.innerText = r('FLTL_00659', 'Contacts not on Customer Record'); | ||||
|                                         }), | ||||
|                                         createElement('div', div => { | ||||
|                                             div.className = 'contacts-wo'; | ||||
| @@ -897,7 +897,7 @@ export default class CustomerCommunication { | ||||
|                                                     option.onChanged([...This._var.gridContact.source, ...This._var.gridWo.source]); | ||||
|                                                 } | ||||
|                                             }, | ||||
|                                             tooltip: item => item.selected ? r('P_CU_OPTEDIN', 'Opted In') : r('P_CU_OPTEDOUT', 'Opted Out') | ||||
|                                             tooltip: item => item.selected ? r('FLTL_02090', 'Opted In') : r('FLTL_02091', 'Opted Out') | ||||
|                                         } | ||||
|                                     }; | ||||
|                                     const iconCol = { | ||||
| @@ -927,7 +927,7 @@ export default class CustomerCommunication { | ||||
|                                             key: 'edit', | ||||
|                                             ...buttonCol, | ||||
|                                             text: 'edit', | ||||
|                                             tooltip: r('P_WO_EDIT', 'Edit'), | ||||
|                                             tooltip: r('FLTL_01032', 'Edit'), | ||||
|                                             events: { | ||||
|                                                 onclick: function () { | ||||
|                                                     const edit = new Contact({ | ||||
| @@ -940,7 +940,7 @@ export default class CustomerCommunication { | ||||
|                                                                 This._var.gridContact.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone) || | ||||
|                                                                 This._var.gridWo.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone); | ||||
|                                                             if (exists) { | ||||
|                                                                 showAlert(r('P_CR_EDITCONTACT', 'Edit Contact'), r('P_WO_CONTACTNAMEANDMOBILEUNIQUECOMBINATION', 'Contact name and contact mobile must be a unique combination.'), 'warn'); | ||||
|                                                                 showAlert(r('FLTL_01041', 'Edit Contact'), r('FLTL_00638', 'Contact name and contact mobile must be a unique combination.'), 'warn'); | ||||
|                                                                 return false; | ||||
|                                                             } | ||||
|                                                             if (typeof option.onSave === 'function') { | ||||
| @@ -993,15 +993,15 @@ export default class CustomerCommunication { | ||||
|                                             key: 'delete', | ||||
|                                             ...buttonCol, | ||||
|                                             text: 'times', | ||||
|                                             tooltip: r('P_WO_DELETE', 'Delete'), | ||||
|                                             tooltip: r('FLTL_00791', 'Delete'), | ||||
|                                             events: { | ||||
|                                                 onclick: function () { | ||||
|                                                     showConfirm( | ||||
|                                                         r('P_CU_REMOVECONTACT', 'Remove Contact'), | ||||
|                                                         r('FLTL_02417', 'Remove Contact'), | ||||
|                                                         createElement('div', null, | ||||
|                                                             createElement('div', div => { | ||||
|                                                                 div.style.paddingLeft = '16px'; | ||||
|                                                                 div.innerText = r('P_CU_REMOVEFROM', 'Remove {name} from').replace('{name}', this.Name); | ||||
|                                                                 div.innerText = r('FLTL_02412', 'Remove {name} from').replace('{name}', this.Name); | ||||
|                                                             }), | ||||
|                                                             createElement('div', div => { | ||||
|                                                                 div.style.display = 'flex'; | ||||
| @@ -1010,19 +1010,19 @@ export default class CustomerCommunication { | ||||
|                                                             }, | ||||
|                                                                 createRadiobox({ | ||||
|                                                                     name: 'remove-type', | ||||
|                                                                     label: r('P_CUSTOMERRECORD', 'Customer Record'), | ||||
|                                                                     label: r('FLTL_00747', 'Customer Record'), | ||||
|                                                                     checked: true, | ||||
|                                                                     className: 'radio-customer-record' | ||||
|                                                                 }), | ||||
|                                                                 createRadiobox({ | ||||
|                                                                     name: 'remove-type', | ||||
|                                                                     label: r('P_WORKORDER', 'Work Order') | ||||
|                                                                     label: r('FLTL_03317', 'Work Order') | ||||
|                                                                 }) | ||||
|                                                             ) | ||||
|                                                         ), | ||||
|                                                         [ | ||||
|                                                             { key: 'ok', text: r('P_WO_OK', 'OK') }, | ||||
|                                                             { key: 'cancel', text: r('P_WO_CANCEL', 'Cancel') } | ||||
|                                                             { key: 'ok', text: r('FLTL_02057', 'OK') }, | ||||
|                                                             { key: 'cancel', text: r('FLTL_00499', 'Cancel') } | ||||
|                                                         ] | ||||
|                                                     ).then(r => { | ||||
|                                                         if (r.result === 'ok') { | ||||
| @@ -1078,12 +1078,12 @@ export default class CustomerCommunication { | ||||
|                                             key: 'delete', | ||||
|                                             ...buttonCol, | ||||
|                                             text: 'times', | ||||
|                                             tooltip: r('P_WO_DELETE', 'Delete'), | ||||
|                                             tooltip: r('FLTL_00791', 'Delete'), | ||||
|                                             events: { | ||||
|                                                 onclick: function () { | ||||
|                                                     showConfirm(r('P_CU_REMOVECONTACT', 'Remove Contact'), r('P_CU_REMOVEFROMWORKORDER', 'You are removing {name} from work order.\n\nDo you want to Continue?').replace('{name}', this.Name), [ | ||||
|                                                         { key: 'continue', text: r('P_JS_CONTINUE', 'Continue') }, | ||||
|                                                         { key: 'cancel', text: r('P_WO_CANCEL', 'Cancel') } | ||||
|                                                     showConfirm(r('FLTL_02417', 'Remove Contact'), r('FLTL_03382', 'You are removing {name} from work order.\n\nDo you want to Continue?').replace('{name}', this.Name), [ | ||||
|                                                         { key: 'continue', text: r('FLTL_00661', 'Continue') }, | ||||
|                                                         { key: 'cancel', text: r('FLTL_00499', 'Cancel') } | ||||
|                                                     ]).then(r => { | ||||
|                                                         if (r.result === 'continue') { | ||||
|                                                             if (typeof option.onDelete === 'function') { | ||||
| @@ -1124,18 +1124,18 @@ export default class CustomerCommunication { | ||||
|                             }; | ||||
|                             if (nullOrEmpty(option.companyName)) { | ||||
|                                 showConfirm( | ||||
|                                     r('P_CU_EDITCONTACTS', 'Edit Contacts'), | ||||
|                                     r('P_CUSTOMER_ADDCOMPANYPROMPT', 'There is no company associated with this work order. Would you like to add one?\n\nIf no company is indicated, contacts must be added as "Work Order Only".'), | ||||
|                                     r('FLTL_01043', 'Edit Contacts'), | ||||
|                                     r('FLTL_03008', 'There is no company associated with this work order. Would you like to add one?\n\nIf no company is indicated, contacts must be added as "Work Order Only".'), | ||||
|                                     [ | ||||
|                                         { key: 'add', text: r('P_CUSTOMER_ADDCOMPANY', 'Add Company') }, | ||||
|                                         { key: 'skip', text: r('P_CUSTOMER_SKIPTHISSTEP', 'Skip This Step') } | ||||
|                                         { key: 'add', text: r('FLTL_00098', 'Add Company') }, | ||||
|                                         { key: 'skip', text: r('FLTL_02777', 'Skip This Step') } | ||||
|                                     ] | ||||
|                                 ).then(r => { | ||||
|                                     if (r.result === 'add') { | ||||
|                                         if (typeof option.onAddCompany === 'function') { | ||||
|                                             option.onAddCompany.call(this); | ||||
|                                         } | ||||
|                                     } else if (r.key === 'skip') { | ||||
|                                     } else if (r.result === 'skip') { | ||||
|                                         editContacts(); | ||||
|                                     } | ||||
|                                 }); | ||||
| @@ -1147,7 +1147,7 @@ export default class CustomerCommunication { | ||||
|                 ), | ||||
|                 createElement('div', div => { | ||||
|                     div.className = 'bar-info'; | ||||
|                     div.innerText = r('P_CR_CONTACTINFORMATION', 'Contact Information'); | ||||
|                     div.innerText = r('FLTL_00635', 'Contact Information'); | ||||
|                 }), | ||||
|                 createElement('div', div => { | ||||
|                     if (option.contactCollapserVisible === false) { | ||||
| @@ -1191,12 +1191,12 @@ export default class CustomerCommunication { | ||||
|                 button.style.display = 'none'; | ||||
|             } | ||||
|             button.appendChild(createIcon('fa-solid', 'pen')); | ||||
|             setTooltip(button, r('P_CU_EDITFOLLOWERS', 'Edit Followers')); | ||||
|             setTooltip(button, r('FLTL_01054', 'Edit Followers')); | ||||
|             button.addEventListener('click', () => { | ||||
|                 if (typeof option.onInitFollower === 'function') { | ||||
|                     option.onInitFollower(this._var.data.followers).then(data => { | ||||
|                         if (typeof data === 'string') { | ||||
|                             showAlert(r('P_CUSTOMERRECORD', 'Customer Record'), data, 'warn'); | ||||
|                             showAlert(r('FLTL_00747', 'Customer Record'), data, 'warn'); | ||||
|                             return; | ||||
|                         } | ||||
|                         const add = new Follower({ | ||||
| @@ -1216,7 +1216,7 @@ export default class CustomerCommunication { | ||||
|                                 } | ||||
|                             } | ||||
|                         }); | ||||
|                         var title = this._var.data.followers?.length > 0 ? r('P_CU_EDITFOLLOWERS', 'Edit Followers') : r('P_CR_ADDFOLLOWERS', 'Add Followers'); | ||||
|                         var title = this._var.data.followers?.length > 0 ? r('FLTL_01054', 'Edit Followers') : r('FLTL_00116', 'Add Followers'); | ||||
|                         add.show(title, container); | ||||
|                     }); | ||||
|                 } | ||||
| @@ -1236,7 +1236,7 @@ export default class CustomerCommunication { | ||||
|                         'border-radius': '15px', | ||||
|                         'padding': '4px' | ||||
|                     }) | ||||
|                 ), r('P_CU_COPIED', 'Copied')), | ||||
|                 ), r('FLTL_00667', 'Copied')), | ||||
|                 createElement('div', 'bar-list', | ||||
|                     followers, | ||||
|                     buttonEditFollower | ||||
|   | ||||
| @@ -24,7 +24,7 @@ export default class Follower { | ||||
|             onMasking: this._var.option.onMasking, | ||||
|             title, | ||||
|             content: createElement('div', 'follower-wrapper', | ||||
|                 createElement('div', div => div.innerText = r('P_CR_WHODOYOUWANTTORECEIVECUSTOMERNOTIFICATIONS', 'Who do you want to receive customer notifications?')), | ||||
|                 createElement('div', div => div.innerText = r('FLTL_03300', 'Who do you want to receive customer notifications?')), | ||||
|                 createElement('input', search => { | ||||
|                     search.type = 'text'; | ||||
|                     search.tabIndex = tabIndex + 3; | ||||
| @@ -43,7 +43,7 @@ export default class Follower { | ||||
|             ), | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: r('P_WO_OK', 'OK'), | ||||
|                     text: r('FLTL_02057', 'OK'), | ||||
|                     key: 'ok', | ||||
|                     trigger: () => { | ||||
|                         if (typeof this._var.option.onOk === 'function') { | ||||
| @@ -51,7 +51,7 @@ export default class Follower { | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { text: r('P_WO_CANCEL', 'Cancel'), key: 'cancel' } | ||||
|                 { text: r('FLTL_00499', 'Cancel'), key: 'cancel' } | ||||
|             ] | ||||
|         }); | ||||
|         const result = await popup.show(parent); | ||||
| @@ -59,18 +59,18 @@ export default class Follower { | ||||
|         // grid | ||||
|         const grid = new Grid(gridContainer); | ||||
|         grid.columns = [ | ||||
|             { key: 'DisplayName', caption: r('P_WO_CONTACTNAME', 'Contact Name'), width: 240 }, | ||||
|             { key: 'ContactTypeName', caption: r('P_WO_CONTACTTYPE', 'Contact Type'), width: 120 }, | ||||
|             { key: 'DisplayName', caption: r('FLTL_00637', 'Contact Name'), width: 240 }, | ||||
|             { key: 'ContactTypeName', caption: r('FLTL_00644', 'Contact Type'), width: 120 }, | ||||
|             { | ||||
|                 key: 'Text', | ||||
|                 caption: r('P_CR_TEXT', 'Text'), | ||||
|                 caption: r('FLTL_02915', 'Text'), | ||||
|                 type: Grid.ColumnTypes.Checkbox, | ||||
|                 width: 60, | ||||
|                 enabled: item => !nullOrEmpty(item.Mobile) | ||||
|             }, | ||||
|             { | ||||
|                 key: 'Email', | ||||
|                 caption: r('P_CR_EMAIL', 'Email'), | ||||
|                 caption: r('FLTL_01089', 'Email'), | ||||
|                 type: Grid.ColumnTypes.Checkbox, | ||||
|                 width: 70, | ||||
|                 // enabled: item => !nullOrEmpty(item.ID) | ||||
|   | ||||
| @@ -138,7 +138,7 @@ export default class InternalComment { | ||||
|             createElement('div', null, | ||||
|                 createElement('div', div => { | ||||
|                     div.className = 'title-module'; | ||||
|                     div.innerText = r('P_WO_INTERNALCOMMENTS', 'Internal Comments'); | ||||
|                     div.innerText = r('FLTL_01613', 'Internal Comments'); | ||||
|                 }, | ||||
|                     createHideMessageTitleButton(this, 'showMessageHidden') | ||||
|                 ) | ||||
| @@ -147,7 +147,7 @@ export default class InternalComment { | ||||
|         const readonly = option.readonly; | ||||
|         // enter box | ||||
|         const enter = createElement('textarea', 'ui-text'); | ||||
|         enter.placeholder = r('P_CU_ENTERCOMMENTHERE', 'Enter Comment Here'); | ||||
|         enter.placeholder = r('FLTL_01154', 'Enter Comment Here'); | ||||
|         enter.maxLength = option.maxLength ??= 3000; | ||||
|         enter.addEventListener('input', () => { | ||||
|             const val = this.text; | ||||
| @@ -237,7 +237,7 @@ export default class InternalComment { | ||||
|                         if (readonly === true || option.noCallLog === true) { | ||||
|                             button.style.display = 'none'; | ||||
|                         } | ||||
|                         setTooltip(button, r('P_WO_CALLLOG', 'Call Log')); | ||||
|                         setTooltip(button, r('FLTL_00491', 'Call Log')); | ||||
|                         button.addEventListener('click', () => { | ||||
|                             if (typeof option.onAddCallLog === 'function') { | ||||
|                                 this.loading = true; | ||||
| @@ -252,7 +252,7 @@ export default class InternalComment { | ||||
|                             button.style.display = 'none'; | ||||
|                         } | ||||
|                         button.appendChild(createIcon('fa-solid', 'paper-plane')); | ||||
|                         setTooltip(button, r('P_M3_SENDMESSAGE', 'Send Message')); | ||||
|                         setTooltip(button, r('FLTL_02692', 'Send Message')); | ||||
|                         button.addEventListener('click', () => { | ||||
|                             const val = this.text; | ||||
|                             if (nullOrEmpty(val?.trim())) { | ||||
| @@ -272,7 +272,7 @@ export default class InternalComment { | ||||
|                             button.style.display = 'none'; | ||||
|                         } | ||||
|                         button.appendChild(createIcon('fa-solid', 'comment-alt-lines')); | ||||
|                         setTooltip(button, r('P_CU_POSTNOTE', 'Post Note')); | ||||
|                         setTooltip(button, r('FLTL_02301', 'Post Note')); | ||||
|                         button.addEventListener('click', () => { | ||||
|                             const val = this.text; | ||||
|                             if (nullOrEmpty(val?.trim())) { | ||||
| @@ -339,10 +339,10 @@ export default class InternalComment { | ||||
|                 } | ||||
|                 // if (comment.FollowUp?.length > 0) { | ||||
|                 //     div.classList.add('item-sent'); | ||||
|                 //     const sendto = r('P_CU_SENDTO_COLON', 'Sent To :') + '\r\n' + comment.FollowUp.split(';').join('\r\n'); | ||||
|                 //     const sendto = r('FLTL_02716', 'Sent To :') + '\r\n' + comment.FollowUp.split(';').join('\r\n'); | ||||
|                 //     content.appendChild(createElement('div', div => { | ||||
|                 //         div.className = 'item-status'; | ||||
|                 //         div.innerText = r('P_WO_SENT', 'Sent'); | ||||
|                 //         div.innerText = r('FLTL_02711', 'Sent'); | ||||
|                 //         setTooltip(div, sendto); | ||||
|                 //     })); | ||||
|                 // } | ||||
|   | ||||
| @@ -155,12 +155,12 @@ export function insertFile(container, file, r) { | ||||
|             type = type.substring(type.lastIndexOf('.')); | ||||
|         } | ||||
|         if (fileSupported.indexOf(type) < 0) { | ||||
|             showAlert(r('P_WO_ERROR', 'Error'), r('P_CU_TYPENOTSUPPORTED', 'File type "{type}" is now not supported.').replace('{type}', type)); | ||||
|             showAlert(r('FLTL_01165', 'Error'), r('FLTL_01385', 'File type "{type}" is now not supported.').replace('{type}', type)); | ||||
|             return; | ||||
|         } | ||||
|         const isImage = /^image\//.test(type); | ||||
|         if (!isImage && file.size > MaxAttachmentSize.limit) { | ||||
|             showAlert(r('P_WO_ERROR', 'Error'), r('P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS', `Attachment size exceeds the maximum allowed to be sent (${MaxAttachmentSize.text})`), 'warn'); | ||||
|             showAlert(r('FLTL_01165', 'Error'), r('FLTL_00407', `Attachment size exceeds the maximum allowed to be sent (${MaxAttachmentSize.text})`), 'warn'); | ||||
|             return; | ||||
|         } | ||||
|         const fn = file.name; | ||||
| @@ -202,12 +202,12 @@ function getStatusText(status, dict) { | ||||
|  | ||||
| export function getMessageStatus(comm, r, _var) { | ||||
|     const messageStatus = { | ||||
|         0: r('P_CU_PENDING', 'Pending'), | ||||
|         1: r('P_WO_SENT', 'Sent'), | ||||
|         5: r('P_CU_DELIVERYCONFIRMED', 'Delivery Confirmed'), | ||||
|         6: r('P_CU_RESENT', 'Resent'), | ||||
|         9: r('P_MA_FAILED', 'Failed'), | ||||
|         9999: r('P_CU_UNKNOWN', 'Unknown') | ||||
|         0: r('FLTL_02186', 'Pending'), | ||||
|         1: r('FLTL_02711', 'Sent'), | ||||
|         5: r('FLTL_00864', 'Delivery Confirmed'), | ||||
|         6: r('FLTL_02478', 'Resent'), | ||||
|         9: r('FLTL_01224', 'Failed'), | ||||
|         9999: r('FLTL_03152', 'Unknown') | ||||
|     }; | ||||
|     const knownStatus = [0, 1, 5, 6, 9, 10, 412]; | ||||
|     const okStatus = [1, 5, 6]; | ||||
| @@ -269,7 +269,7 @@ export function getMessageStatus(comm, r, _var) { | ||||
|             if (statusUpdatable !== false) { | ||||
|                 tip.appendChild(createElement('div', b => { | ||||
|                     b.className = 'tip-function-button'; | ||||
|                     // setTooltip(b, r('P_CU_UPDATESTATUS', 'Update Status')); | ||||
|                     // setTooltip(b, r('FLTL_03174', 'Update Status')); | ||||
|                     b.addEventListener('click', async () => { | ||||
|                         for (let p of comm.Participator) { | ||||
|                             switch (p.Status) { | ||||
| @@ -292,7 +292,7 @@ export function getMessageStatus(comm, r, _var) { | ||||
|                         const gridContainer = createElement('div', 'status-grid'); | ||||
|                         const popup = new Popup({ | ||||
|                             onMasking: _var.option.onMasking, | ||||
|                             title: r('P_CU_UPDATESTATUS', 'Update Status'), | ||||
|                             title: r('FLTL_03174', 'Update Status'), | ||||
|                             content: createElement('div', wrapper => { | ||||
|                                 wrapper.className = 'update-status-wrapper'; | ||||
|                                 wrapper.style.width = '500px'; | ||||
| @@ -301,7 +301,7 @@ export function getMessageStatus(comm, r, _var) { | ||||
|                             ), | ||||
|                             buttons: [ | ||||
|                                 { | ||||
|                                     text: r('P_WO_OK', 'OK'), | ||||
|                                     text: r('FLTL_02057', 'OK'), | ||||
|                                     key: 'ok', | ||||
|                                     trigger: () => { | ||||
|                                         const changed = msgs.filter(m => { | ||||
| @@ -329,7 +329,7 @@ export function getMessageStatus(comm, r, _var) { | ||||
|                                     } | ||||
|                                 }, | ||||
|                                 { | ||||
|                                     text: r('P_WO_CANCEL', 'Cancel'), | ||||
|                                     text: r('FLTL_00499', 'Cancel'), | ||||
|                                     key: 'cancel' | ||||
|                                 } | ||||
|                             ] | ||||
| @@ -341,22 +341,22 @@ export function getMessageStatus(comm, r, _var) { | ||||
|                         grid.columns = [ | ||||
|                             { | ||||
|                                 key: 'CustomerNumber', | ||||
|                                 caption: r('P_JS_NUMBER', 'Number'), | ||||
|                                 caption: r('FLTL_02026', 'Number'), | ||||
|                                 width: 150 | ||||
|                             }, | ||||
|                             /*{ | ||||
|                                 key: 'customerName', | ||||
|                                 caption: r('P_WOS_CUSTOMERNAME', 'Customer Name'), | ||||
|                                 caption: r('FLTL_00742', 'Customer Name'), | ||||
|                                 width: 120 | ||||
|                             },*/ | ||||
|                             { | ||||
|                                 key: 'statusText', | ||||
|                                 caption: r('P_CU_CURRENTSTATUS', 'Current Status'), | ||||
|                                 caption: r('FLTL_00725', 'Current Status'), | ||||
|                                 width: 155 | ||||
|                             }, | ||||
|                             { | ||||
|                                 key: 'statusChanged', | ||||
|                                 caption: r('P_CU_REVISEDSTATUS', 'Revised Status'), | ||||
|                                 caption: r('FLTL_02511', 'Revised Status'), | ||||
|                                 width: 155, | ||||
|                                 type: Grid.ColumnTypes.Dropdown, | ||||
|                                 source: [ | ||||
| @@ -404,7 +404,7 @@ export function getMessageSendTo(comm, contacts, followers, r) { | ||||
|         } | ||||
|     } | ||||
|     if (sendto !== '') { | ||||
|         sendto = r('P_CU_SENDTO_COLON', 'Sent to :') + `\n${sendto}`; | ||||
|         sendto = r('FLTL_02716', 'Sent to :') + `\n${sendto}`; | ||||
|     } | ||||
|     return sendto; | ||||
| } | ||||
| @@ -432,7 +432,7 @@ export function createHideMessageTitleButton(This, optionName) { | ||||
|                 span.className = 'msgadminsetting sbutton iconnotview'; | ||||
|             } | ||||
|             span.style.padding = '0px 0px 0px 5px'; | ||||
|             setTooltip(span, option?.getText('P_WO_MESSAGEHISTORY_MANAGE', 'Manage Messages')); | ||||
|             setTooltip(span, option?.getText('FLTL_01860', 'Manage Messages')); | ||||
|             span.addEventListener('click', function () { | ||||
|                 const container = This._var.container; | ||||
|                 if (!option[optionName]) { | ||||
| @@ -457,8 +457,8 @@ export function createHideMessageTitleButton(This, optionName) { | ||||
|  | ||||
| export function createHideMessageCommentTail(This, optionName, comment, commentTime, func, hisFunc) { | ||||
|     const option = This._var.option; | ||||
|     const showTooltip = option?.getText('P_WO_MESSAGEHISTORY_VISIBLE', 'Visible'); | ||||
|     const notShowTooltip = option?.getText('P_WO_MESSAGEHISTORY_NOTVISIBLE', 'Not Visible'); | ||||
|     const showTooltip = option?.getText('FLTL_03267', 'Visible'); | ||||
|     const notShowTooltip = option?.getText('FLTL_02006', 'Not Visible'); | ||||
|     return createElement('div', div => { | ||||
|         div.className = 'item-time'; | ||||
|         div.style.display = 'flex'; | ||||
| @@ -498,7 +498,7 @@ export function createHideMessageCommentTail(This, optionName, comment, commentT | ||||
|             span.className = 'msgHistory history-span-' + comment.Id; | ||||
|             span.setAttribute('ModifyCount', comment.ModifyCount ?? 0); | ||||
|             span.style.display = (option[optionName] && comment.ModifyCount > 0) ? '' : 'none'; | ||||
|             setTooltip(span, option?.getText('P_WO_MESSAGEHISTORY_HEADER', 'Hidden History')); | ||||
|             setTooltip(span, option?.getText('FLTL_01508', 'Hidden History')); | ||||
|             const icon = createIcon('fa-light', 'wave-sine'); | ||||
|             icon.style.height = '12px'; | ||||
|             icon.style.width = '12px'; | ||||
|   | ||||
| @@ -205,7 +205,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|     } | ||||
|  | ||||
|     async getItem() { | ||||
|         const title = this.r('P_WO_OPENWORKORDER', 'Open Work Order'); | ||||
|         const title = this.r('FLTL_02078', 'Open Work Order'); | ||||
|         const el = this._var.el; | ||||
|         let status = el.dropStatus.selected; | ||||
|         if (status != null) { | ||||
| @@ -223,7 +223,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|         } | ||||
|         let machine = this._var.asset; | ||||
|         if (machine == null) { | ||||
|             showAlert(title, this.r('P_WO_ASSETNOTEMPTY', 'Asset cannot be empty.')).then(() => this._var.container.querySelector('.wo-asset>svg')?.focus()); | ||||
|             showAlert(title, this.r('FLTL_00311', 'Asset cannot be empty.')).then(() => this._var.container.querySelector('.wo-asset>svg')?.focus()); | ||||
|             return null; | ||||
|         } | ||||
|         const item = { | ||||
| @@ -256,24 +256,24 @@ export default class AddWorkOrder extends OptionBase { | ||||
|         item.Contacts = this._var.contacts ?? []; | ||||
|         item.Followers = this._var.followers ?? []; | ||||
|         if (nullOrEmpty(el.textComplaint?.value)) { | ||||
|             showAlert(title, this.r('P_WO_COMPLAINTREQUIRED', 'Complaint is required.')).then(() => el.textComplaint.focus()); | ||||
|             showAlert(title, this.r('FLTL_00602', 'Complaint is required.')).then(() => el.textComplaint.focus()); | ||||
|             return null; | ||||
|         } | ||||
|         if (el.dropStatus.selected?.Completed) { | ||||
|             if (!el.dateCompleted.element.validity.valid) { | ||||
|                 showAlert(title, this.r('P_WO_COMPLETEDDATECANNOTBEEMPTY', 'Completed Date cannot be empty.')).then(() => el.dateCompleted.element.focus()); | ||||
|                 showAlert(title, this.r('FLTL_00613', 'Completed Date cannot be empty.')).then(() => el.dateCompleted.element.focus()); | ||||
|                 return null; | ||||
|             } | ||||
|             if (machine.OnRoad) { | ||||
|                 item.MeterType = 'Odometer'; | ||||
|                 if (nullOrEmpty(item.Odometer) || isNaN(item.Odometer) || item.Odometer < 0) { | ||||
|                     showAlert(title, this.r('P_WO_ODOMETERFORMATERROR', 'Odometer format error.')).then(() => el.inputOdometer.focus()); | ||||
|                     showAlert(title, this.r('FLTL_02044', 'Odometer format error.')).then(() => el.inputOdometer.focus()); | ||||
|                     return null; | ||||
|                 } | ||||
|             } else { | ||||
|                 item.MeterType = 'HourMeter'; | ||||
|                 if (nullOrEmpty(item.HourMeter) || isNaN(item.HourMeter) || item.HourMeter < 0) { | ||||
|                     showAlert(title, this.r('P_WO_HOURMETERFORMATERROR', 'Hour Meter format error.')).then(() => el.inputHours.focus()); | ||||
|                     showAlert(title, this.r('FLTL_01516', 'Hour Meter format error.')).then(() => el.inputHours.focus()); | ||||
|                     return null; | ||||
|                 } | ||||
|             } | ||||
| @@ -284,12 +284,12 @@ export default class AddWorkOrder extends OptionBase { | ||||
|     async show() { | ||||
|         const option = this._option; | ||||
|         const allowCustomer = option.allowCustomer === true; | ||||
|         const title = this.r('P_WO_OPENWORKORDER', 'Open Work Order'); | ||||
|         const title = this.r('FLTL_02078', 'Open Work Order'); | ||||
|         const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3; | ||||
|         const textComplaint = createElement('textarea', textarea => { | ||||
|             textarea.tabIndex = tabIndex + 2; | ||||
|             textarea.className = 'ui-text wo-complaint'; | ||||
|             textarea.placeholder = this.r('P_WO_ENTERCOMPLAINT', 'Enter Complaint'); | ||||
|             textarea.placeholder = this.r('FLTL_01155', 'Enter Complaint'); | ||||
|         }); | ||||
|         const baseOption = { | ||||
|             search: true, | ||||
| @@ -330,8 +330,8 @@ export default class AddWorkOrder extends OptionBase { | ||||
|             selected: 'Mile' | ||||
|         }); | ||||
|         dropOdometerUnit.source = [ | ||||
|             { value: 'Mile', text: GetTextByKey('P_WO_MILE', 'Mile') }, | ||||
|             { value: 'Kilometre', text: GetTextByKey('P_WO_KILOMETER', 'Kilometer') } | ||||
|             { value: 'Mile', text: this.r('FLTL_01922', 'Mile') }, | ||||
|             { value: 'Kilometre', text: this.r('FLTL_01694', 'Kilometer') } | ||||
|         ] | ||||
|         const dropAssignedTo = new Dropdown({ | ||||
|             tabIndex: tabIndex + 10, | ||||
| @@ -385,7 +385,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 createElement('div', 'wo-combined wo-asset', | ||||
|                     createElement('span', span => { | ||||
|                         span.className = 'wo-title wo-title-required'; | ||||
|                         span.innerText = this.r('P_WO_ASSET_COLON', 'Asset:'); | ||||
|                         span.innerText = this.r('FLTL_00361', 'Asset:'); | ||||
|                     }), | ||||
|                     createIcon('fa-light', 'search', svg => { | ||||
|                         svg.tabIndex = tabIndex + 1; | ||||
| @@ -430,16 +430,16 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                                     } | ||||
|                                 }; | ||||
|                                 popup = new Popup({ | ||||
|                                     title: this.r('P_MA_SELECTASSET', 'Select Asset'), | ||||
|                                     title: this.r('FLTL_02645', 'Select Asset'), | ||||
|                                     content: selector.create(), | ||||
|                                     persistent: true, | ||||
|                                     buttons: [ | ||||
|                                         { | ||||
|                                             key: 'ok', | ||||
|                                             text: this.r('P_GRID_OK', 'OK'), | ||||
|                                             text: this.r('FLTL_02057', 'OK'), | ||||
|                                             trigger: () => selector.select() | ||||
|                                         }, | ||||
|                                         { text: this.r('P_WO_CANCEL', 'Cancel') } | ||||
|                                         { text: this.r('FLTL_00499', 'Cancel') } | ||||
|                                     ] | ||||
|                                 }); | ||||
|                                 this._var.assetSelectorPopup = popup; | ||||
| @@ -458,7 +458,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 createElement('div', 'wo-line wo-combined', | ||||
|                     createElement('span', span => { | ||||
|                         span.className = 'wo-title wo-title-required'; | ||||
|                         span.innerText = this.r('P_WO_COMPLAINTCOLON', 'Complaint:'); | ||||
|                         span.innerText = this.r('FLTL_00603', 'Complaint:'); | ||||
|                     }) | ||||
|                 ), | ||||
|                 createElement('div', div => { | ||||
| @@ -470,7 +470,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 ), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title'; | ||||
|                     span.innerText = this.r('P_WO_WORKORDERTYPE_COLON', 'Work Order Type:'); | ||||
|                     span.innerText = this.r('FLTL_03359', 'Work Order Type:'); | ||||
|                 }), | ||||
|                 dropWorkOrderType.create(), | ||||
|                 createElement('div', div => { | ||||
| @@ -481,7 +481,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 }, | ||||
|                     createElement('span', span => { | ||||
|                         span.className = 'wo-title'; | ||||
|                         span.innerText = this.r('P_WO_COMPANYNAME_COLON', 'Company Name:'); | ||||
|                         span.innerText = this.r('FLTL_00598', 'Company Name:'); | ||||
|                     }), | ||||
|                     createIcon('fa-light', 'search', svg => { | ||||
|                         svg.tabIndex = tabIndex + 4; | ||||
| @@ -507,18 +507,18 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 displayElement(createElement('span', 'wo-company-name'), allowCustomer), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title'; | ||||
|                     span.innerText = this.r('P_WO_STATUS_COLON', 'Status:'); | ||||
|                     span.innerText = this.r('FLTL_02834', 'Status:'); | ||||
|                 }), | ||||
|                 dropStatus.create(), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title wo-title-required wo-sub-line wo-status-closed'; | ||||
|                     span.innerText = this.r('P_WO_COMPLETEDDATE_COLON', 'Completed Date:'); | ||||
|                     span.innerText = this.r('FLTL_00617', 'Completed Date:'); | ||||
|                     displayElement(span, false); | ||||
|                 }), | ||||
|                 displayElement(dateCompleted.create(), false), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title wo-title-required wo-sub-line wo-hours'; | ||||
|                     span.innerText = this.r('P_WO_HOURS_COLON', 'Hours:'); | ||||
|                     span.innerText = this.r('FLTL_01530', 'Hours:'); | ||||
|                     displayElement(span, false); | ||||
|                 }), | ||||
|                 displayElement( | ||||
| @@ -527,7 +527,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 ), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title wo-title-required wo-sub-line wo-odometer'; | ||||
|                     span.innerText = this.r('P_WO_ODOMETER_COLON', 'Odometer:'); | ||||
|                     span.innerText = this.r('FLTL_02054', 'Odometer:'); | ||||
|                     displayElement(span, false); | ||||
|                 }), | ||||
|                 createElement('div', div => { | ||||
| @@ -539,12 +539,12 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 ), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title'; | ||||
|                     span.innerText = this.r('P_WO_ASSIGNEDTO_COLON', 'Assigned Tech:'); | ||||
|                     span.innerText = this.r('FLTL_00382', 'Assigned Tech:'); | ||||
|                 }), | ||||
|                 dropAssignedTo.create(), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title wo-customer-record'; | ||||
|                     span.innerText = this.r('P_WO_ADVISOR_COLON', 'Advisor:'); | ||||
|                     span.innerText = this.r('FLTL_00199', 'Advisor:'); | ||||
|                     if (!allowCustomer) { | ||||
|                         displayElement(span, false); | ||||
|                     } | ||||
| @@ -552,7 +552,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 displayElement(dropAdvisor.create(), allowCustomer), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title wo-customer-record'; | ||||
|                     span.innerText = this.r('P_WO_LOCATION_COLON', 'Location:'); | ||||
|                     span.innerText = this.r('FLTL_01796', 'Location:'); | ||||
|                     if (!allowCustomer) { | ||||
|                         displayElement(span, false); | ||||
|                     } | ||||
| @@ -560,7 +560,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                 displayElement(dropLocation.create(), allowCustomer), | ||||
|                 createElement('span', span => { | ||||
|                     span.className = 'wo-title wo-customer-record'; | ||||
|                     span.innerText = this.r('P_WO_DEPARTMENT_COLON', 'Department:'); | ||||
|                     span.innerText = this.r('FLTL_00869', 'Department:'); | ||||
|                     if (!allowCustomer) { | ||||
|                         displayElement(span, false); | ||||
|                     } | ||||
| @@ -616,12 +616,12 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                             } | ||||
|                             if (this._var.asset.Hide) { | ||||
|                                 if (!option.assetFullcontrol) { | ||||
|                                     await showAlert(title, this.r('P_WO_HIDDENCANNOTCREATE', 'The selected asset is hidden and a work order cannot be created.') + '\n\n' + this.r('P_WO_CONTACTTOUNHIDE', 'Please contact your Fleet Manager to Unhide the asset if you require a work order.')); | ||||
|                                     await showAlert(title, this.r('FLTL_02992', 'The selected asset is hidden and a work order cannot be created.') + '\n\n' + this.r('FLTL_02213', 'Please contact your Fleet Manager to Unhide the asset if you require a work order.')); | ||||
|                                     return false; | ||||
|                                 } | ||||
|                                 const next = await showConfirm(title, this.r('P_WO_HIDDENCANNOTCREATE', 'The selected asset is hidden and a work order cannot be created.') + '\n\n' + this.r('P_WO_PROMPTUNHIDE', 'Do you wish to "Un-Hide" the asset?'), [ | ||||
|                                     { key: 'unhide', text: this.r('P_WO_UNHIDE', 'Unhide') }, | ||||
|                                     { key: 'cancel', text: this.r('P_WO_CANCELWO', 'Cancel Work Order') } | ||||
|                                 const next = await showConfirm(title, this.r('FLTL_02992', 'The selected asset is hidden and a work order cannot be created.') + '\n\n' + this.r('FLTL_00999', 'Do you wish to "Un-Hide" the asset?'), [ | ||||
|                                     { key: 'unhide', text: this.r('FLTL_03136', 'Unhide') }, | ||||
|                                     { key: 'cancel', text: this.r('FLTL_00502', 'Cancel Work Order') } | ||||
|                                 ]); | ||||
|                                 if (next.result !== 'unhide') { | ||||
|                                     return false; | ||||
| @@ -642,21 +642,21 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                                         const popWorkorders = new Popup({ | ||||
|                                             title, | ||||
|                                             content: createElement('div', 'wo-opened-workorder', | ||||
|                                                 createElement('header', header => header.innerText = this.r('P_WO_ASSETOPENEDWORKORDER', 'The selected asset has the following open work orders:')), | ||||
|                                                 createElement('header', header => header.innerText = this.r('FLTL_02991', 'The selected asset has the following open work orders:')), | ||||
|                                                 createElement('div', 'wo-grid-opened') | ||||
|                                             ), | ||||
|                                             resolve, | ||||
|                                             buttons: [ | ||||
|                                                 { key: 'create', text: this.r('P_WO_CREATEWO', 'Create Work Order'), trigger: () => resolve('create') }, | ||||
|                                                 { key: 'cancel', text: this.r('P_WO_CANCELWO', 'Cancel Work Order'), trigger: () => resolve('cancel') } | ||||
|                                                 { key: 'create', text: this.r('FLTL_00700', 'Create Work Order'), trigger: () => resolve('create') }, | ||||
|                                                 { key: 'cancel', text: this.r('FLTL_00502', 'Cancel Work Order'), trigger: () => resolve('cancel') } | ||||
|                                             ] | ||||
|                                         }); | ||||
|                                         popWorkorders.show().then(mask => { | ||||
|                                             const grid = new Grid(mask.querySelector('.wo-grid-opened'), this.r); | ||||
|                                             grid.columns = [ | ||||
|                                                 { key: 'WorkOrderNumber', caption: 'WO #', width: 100 }, | ||||
|                                                 { key: 'CreateDateStr', caption: this.r('P_WO_CREATEDDATE', 'Created Date'), width: 120 }, | ||||
|                                                 { key: 'Description', caption: this.r('P_WO_COMPLAINT', 'Complaint'), width: 360 } | ||||
|                                                 { key: 'CreateDateStr', caption: this.r('FLTL_00703', 'Created Date'), width: 120 }, | ||||
|                                                 { key: 'Description', caption: this.r('FLTL_00600', 'Complaint'), width: 360 } | ||||
|                                             ]; | ||||
|                                             grid.init(); | ||||
|                                             grid.source = wos.map(w => ({ | ||||
| @@ -682,7 +682,7 @@ export default class AddWorkOrder extends OptionBase { | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { text: this.r('P_WO_CANCEL', 'Cancel') } | ||||
|                 { text: this.r('FLTL_00499', 'Cancel') } | ||||
|             ] | ||||
|         }); | ||||
|         popup.create(); | ||||
|   | ||||
| @@ -80,7 +80,7 @@ export default class AssetSelector extends OptionBase { | ||||
|         super(opt); | ||||
|     } | ||||
|  | ||||
|     get title() { return this.r('P_MA_SELECTASSET', 'Select Asset') } | ||||
|     get title() { return this.r('FLTL_02645', 'Select Asset') } | ||||
|  | ||||
|     get currentAsset() { return this._var.el.grid.currentItem } | ||||
|  | ||||
| @@ -126,7 +126,7 @@ export default class AssetSelector extends OptionBase { | ||||
|         const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3; | ||||
|         const inputSearch = createElement('input', input => { | ||||
|             input.type = 'text'; | ||||
|             input.placeholder = this.r('P_SELECTASSETS_SEARCH', 'Search'); | ||||
|             input.placeholder = this.r('FLTL_02606', 'Search'); | ||||
|             input.tabIndex = tabIndex + 2; | ||||
|             input.className = 'ui-input'; | ||||
|             input.addEventListener('keypress', e => { | ||||
| @@ -137,7 +137,7 @@ export default class AssetSelector extends OptionBase { | ||||
|         }); | ||||
|         const checkHidden = createCheckbox({ | ||||
|             tabIndex: tabIndex + 3, | ||||
|             label: this.r('P_SELECTASSETS_SHOWHIDDEN', 'Show Hidden'), | ||||
|             label: this.r('FLTL_02768', 'Show Hidden'), | ||||
|             onchange: () => this.refresh() | ||||
|         }); | ||||
|         if (option.ignoreHidden) { | ||||
| @@ -168,14 +168,14 @@ export default class AssetSelector extends OptionBase { | ||||
|         }); | ||||
|         const grid = new Grid(gridContent, this.r); | ||||
|         grid.columns = [ | ||||
|             { key: 'VIN', caption: this.r('P_SELECTASSETS_VIN', 'VIN'), width: 170 }, | ||||
|             { key: 'DisplayName', caption: this.r('P_SELECTASSETS_NAME', 'Name'), width: 190 }, | ||||
|             { key: 'MakeName', caption: this.r('P_SELECTASSETS_MAKE', 'Make'), width: 110, allowFilter: true }, | ||||
|             { key: 'ModelName', caption: this.r('P_SELECTASSETS_MODEL', 'Model'), width: 110, allowFilter: true }, | ||||
|             { key: 'TypeName', caption: this.r('P_SELECTASSETS_TYPE', 'Type'), width: 110, allowFilter: true }, | ||||
|             { key: 'AcquisitionType', caption: this.r('P_MA_ACQUISITIONTYPE', 'Acquisition Type'), width: 130, allowFilter: true }, | ||||
|             { key: 'AssetGroups', caption: this.r('P_MA_ASSETGROUP', 'Asset Group'), width: 150 }, | ||||
|             { key: 'Jobsites', caption: this.r('P_SELECTASSETS_JOBSITE', 'Jobsite'), width: 180, filter: it => it.Jobsites?.map(s => s.Key) } | ||||
|             { key: 'VIN', caption: this.r('FLTL_03260', 'VIN'), width: 170 }, | ||||
|             { key: 'DisplayName', caption: this.r('FLTL_01966', 'Name'), width: 190 }, | ||||
|             { key: 'MakeName', caption: this.r('FLTL_01832', 'Make'), width: 110, allowFilter: true }, | ||||
|             { key: 'ModelName', caption: this.r('FLTL_01933', 'Model'), width: 110, allowFilter: true }, | ||||
|             { key: 'TypeName', caption: this.r('FLTL_03112', 'Type'), width: 110, allowFilter: true }, | ||||
|             { key: 'AcquisitionType', caption: this.r('FLTL_00072', 'Acquisition Type'), width: 130, allowFilter: true }, | ||||
|             { key: 'AssetGroups', caption: this.r('FLTL_00318', 'Asset Group'), width: 150 }, | ||||
|             { key: 'Jobsites', caption: this.r('FLTL_01666', 'Jobsite'), width: 180, filter: it => it.Jobsites?.map(s => s.Key) } | ||||
|         ]; | ||||
|         grid.onRowDblClicked = index => { | ||||
|             const item = grid.source[index]; | ||||
| @@ -202,7 +202,7 @@ export default class AssetSelector extends OptionBase { | ||||
|                 option.assetFullcontrol ? createElement('button', button => { | ||||
|                     button.className = 'ui-popup-button'; | ||||
|                     button.tabIndex = tabIndex + 1; | ||||
|                     button.innerText = this.r('P_MA_ADDASSET', 'Add Asset'); | ||||
|                     button.innerText = this.r('FLTL_00091', 'Add Asset'); | ||||
|                     button.addEventListener('click', async () => { | ||||
|                         if (typeof option.requestAddAsset === 'function') { | ||||
|                             this.loading(true); | ||||
| @@ -228,11 +228,11 @@ export default class AssetSelector extends OptionBase { | ||||
|                     ) | ||||
|                 ), | ||||
|                 checkHidden, | ||||
|                 createElement('span', span => span.innerText = this.r('P_WO_ASSETGROUP', 'Asset Group')), | ||||
|                 createElement('span', span => span.innerText = this.r('FLTL_00318', 'Asset Group')), | ||||
|                 dropAssetGroup.create(), | ||||
|                 createElement('span', span => span.innerText = this.r('P_WO_JOBSITE', 'Jobsite')), | ||||
|                 createElement('span', span => span.innerText = this.r('FLTL_01666', 'Jobsite')), | ||||
|                 dropJobsite.create(), | ||||
|                 createElement('span', span => span.innerText = this.r('P_SELECTASSETS_JOBSITECODE', 'Jobsite Code')), | ||||
|                 createElement('span', span => span.innerText = this.r('FLTL_01669', 'Jobsite Code')), | ||||
|                 dropJobsiteCode.create() | ||||
|             ), | ||||
|             gridContent | ||||
|   | ||||
| @@ -85,23 +85,23 @@ export default class InspectionWizard extends OptionBase { | ||||
|             templateSelector.create() | ||||
|         ]; | ||||
|         const popup = new Popup({ | ||||
|             title: this.r('ADDINSPECTION', 'Add Inspection'), | ||||
|             title: this.r('FLTL_00121', 'Add Inspection'), | ||||
|             content: createElement('div', null, ...this._var.containers), | ||||
|             persistent: true, | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: this.r('BACK', 'Back'), | ||||
|                     text: this.r('FLTL_00447', 'Back'), | ||||
|                     trigger: () => { | ||||
|                         this._changePage(0); | ||||
|                         return false; | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: this.r('NEXT', 'Next'), | ||||
|                     text: this.r('FLTL_01973', 'Next'), | ||||
|                     trigger: () => { | ||||
|                         const asset = assetSelector.currentAsset; | ||||
|                         if (asset == null) { | ||||
|                             showAlert(assetSelector.title, this.r('P_SELECTASSETS_SELECTASSET', 'Please select an Asset.')); | ||||
|                             showAlert(assetSelector.title, this.r('FLTL_02269', 'Please select an Asset.')); | ||||
|                             return false; | ||||
|                         } | ||||
|                         this._var.asset = asset; | ||||
| @@ -112,18 +112,18 @@ export default class InspectionWizard extends OptionBase { | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: this.r('P_GRID_OK', 'OK'), | ||||
|                     text: this.r('FLTL_02057', 'OK'), | ||||
|                     trigger: () => { | ||||
|                         const template = templateSelector.currentTemplate; | ||||
|                         if (template == null) { | ||||
|                             showAlert(templateSelector.title, this.r('P_WO_PLEASESELECTATEMPLATE', 'Please select a template.')); | ||||
|                             showAlert(templateSelector.title, this.r('FLTL_02261', 'Please select a template.')); | ||||
|                             return false; | ||||
|                         } | ||||
|                         this._var.template = template; | ||||
|                         this._select(); | ||||
|                     } | ||||
|                 }, | ||||
|                 { text: this.r('P_WO_CANCEL', 'Cancel') } | ||||
|                 { text: this.r('FLTL_00499', 'Cancel') } | ||||
|             ] | ||||
|         }); | ||||
|         this._var.popup = popup; | ||||
|   | ||||
| @@ -161,7 +161,7 @@ export default class ScheduleItem extends OptionBase { | ||||
|                     }), | ||||
|                     validation( | ||||
|                         createElement('input', i => { i.type = 'text', i.className = 'ui-input schedule-id-occur-once', i.maxLength = 5 }), | ||||
|                         /^([01][0-9]|[2][0-3]):[0-5][0-9]$/ | ||||
|                         /^([1-9]|[01][0-9]|[2][0-3]):([1-9]|[0-5][0-9])$/ | ||||
|                     ) | ||||
|                 ), | ||||
|                 createElement('div', 'schedule-item-line schedule-item-line-occur-every', | ||||
| @@ -182,14 +182,14 @@ export default class ScheduleItem extends OptionBase { | ||||
|                             createElement('span', span => span.innerText = 'Starting at'), | ||||
|                             validation( | ||||
|                                 createElement('input', i => { i.type = 'text', i.className = 'ui-input schedule-id-occur-starting', i.maxLength = 5 }), | ||||
|                                 /^([01][0-9]|[2][0-3]):[0-5][0-9]$/ | ||||
|                                 /^([1-9]|[01][0-9]|[2][0-3]):([1-9]|[0-5][0-9])$/ | ||||
|                             ) | ||||
|                         ), | ||||
|                         createElement('div', 'scheldule-item-line', | ||||
|                             createElement('span', span => span.innerText = 'Ending at'), | ||||
|                             validation( | ||||
|                                 createElement('input', i => { i.type = 'text', i.className = 'ui-input schedule-id-occur-ending', i.maxLength = 5 }), | ||||
|                                 /^([01][0-9]|[2][0-3]):[0-5][0-9]$/ | ||||
|                                 /^([1-9]|[01][0-9]|[2][0-3]):([1-9]|[0-5][0-9])$/ | ||||
|                             ) | ||||
|                         ) | ||||
|                     ) | ||||
|   | ||||
| @@ -37,7 +37,7 @@ export default class Signature extends OptionBase { | ||||
|  | ||||
|     async show() { | ||||
|         const popup = new Popup({ | ||||
|             title: this.r('P_IPT_SIGNATURE', 'Signature'), | ||||
|             title: this.r('FLTL_02770', 'Signature'), | ||||
|             content: this._var.canvas = createElement('canvas', canvas => { | ||||
|                 canvas.style.width = '100%'; | ||||
|                 canvas.style.height = '100%'; | ||||
| @@ -56,7 +56,7 @@ export default class Signature extends OptionBase { | ||||
|             }, | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: this.r('P_GRID_OK', 'OK'), | ||||
|                     text: this.r('FLTL_02057', 'OK'), | ||||
|                     trigger: () => { | ||||
|                         if (this._var.allPoints.length === 0) { | ||||
|                             return false; | ||||
| @@ -65,14 +65,14 @@ export default class Signature extends OptionBase { | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: this.r('P_GRID_RESET', 'Reset'), | ||||
|                     text: this.r('FLTL_02479', 'Reset'), | ||||
|                     trigger: () => { | ||||
|                         const ctx = this._var.canvas.getContext('2d'); | ||||
|                         ctx.clearRect(0, 0, this._var.canvas.width, this._var.canvas.height); | ||||
|                         return false | ||||
|                     } | ||||
|                 }, | ||||
|                 { text: this.r('P_WO_CANCEL', 'Cancel') } | ||||
|                 { text: this.r('FLTL_00499', 'Cancel') } | ||||
|             ] | ||||
|         }); | ||||
|         this._var.popup = popup; | ||||
|   | ||||
| @@ -50,7 +50,7 @@ export default class TemplateSelector extends OptionBase { | ||||
|         this.refresh(); | ||||
|     } | ||||
|  | ||||
|     get title() { return this.r('P_MODULE_INSPECTIONTEMPLATES', 'Inspection Templates') } | ||||
|     get title() { return this.r('FLTL_01604', 'Inspection Templates') } | ||||
|  | ||||
|     get currentTemplate() { return this._var.el.grid.currentItem } | ||||
|  | ||||
| @@ -83,7 +83,7 @@ export default class TemplateSelector extends OptionBase { | ||||
|         const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3; | ||||
|         const inputSearch = createElement('input', input => { | ||||
|             input.type = 'text'; | ||||
|             input.placeholder = this.r('P_SELECTASSETS_SEARCH', 'Search'); | ||||
|             input.placeholder = this.r('FLTL_02606', 'Search'); | ||||
|             input.tabIndex = tabIndex + 1; | ||||
|             input.className = 'ui-input'; | ||||
|             input.addEventListener('keypress', e => e.key === 'Enter' && this.refresh()); | ||||
| @@ -102,8 +102,8 @@ export default class TemplateSelector extends OptionBase { | ||||
|                 resizable: false, | ||||
|                 filter: it => nullOrEmpty(it.IssueId) ? '' : 'cubes' | ||||
|             }, | ||||
|             { key: 'Name', caption: this.r('P_IPT_NAME', 'Name'), width: 390 }, | ||||
|             { key: 'Notes', caption: this.r('P_IPT_NOTES', 'Notes'), width: 630 } | ||||
|             { key: 'Name', caption: this.r('FLTL_01966', 'Name'), width: 390 }, | ||||
|             { key: 'Notes', caption: this.r('FLTL_02012', 'Notes'), width: 630 } | ||||
|         ]; | ||||
|         grid.onRowDblClicked = index => { | ||||
|             const item = grid.source[index]; | ||||
| @@ -122,7 +122,7 @@ export default class TemplateSelector extends OptionBase { | ||||
|         // content | ||||
|         const container = createElement('div', 'popup-selector', | ||||
|             createElement('div', 'popup-selector-header', | ||||
|                 createElement('h3', h3 => h3.innerText = this.r('P_WO_PLEASESELECTATEMPLATE', 'Please select a template.')) | ||||
|                 createElement('h3', h3 => h3.innerText = this.r('FLTL_02261', 'Please select a template.')) | ||||
|             ), | ||||
|             createElement('div', 'popup-selector-function', | ||||
|                 createElement('div', 'search-box', | ||||
|   | ||||
| @@ -3,6 +3,10 @@ import { createElement } from "../functions"; | ||||
| import { createIcon } from "./icon"; | ||||
|  | ||||
| function fillCheckbox(container, type = 'fa-regular', label, tabindex = -1, charactor = 'check', title) { | ||||
|     const checkIcon = createIcon(type, charactor); | ||||
|     checkIcon.classList.add('ui-check-icon'); | ||||
|     const indeterminateIcon = createIcon(type, 'grip-lines'); | ||||
|     indeterminateIcon.classList.add('ui-indeterminate-icon') | ||||
|     container.appendChild( | ||||
|         createElement('layer', layer => { | ||||
|             layer.className = 'ui-check-inner'; | ||||
| @@ -18,7 +22,7 @@ function fillCheckbox(container, type = 'fa-regular', label, tabindex = -1, char | ||||
|             if (tabindex >= 0) { | ||||
|                 layer.tabIndex = tabindex; | ||||
|             } | ||||
|         }, createIcon(type, charactor)) | ||||
|         }, checkIcon, indeterminateIcon) | ||||
|     ); | ||||
|     if (label instanceof Element) { | ||||
|         container.appendChild(label); | ||||
| @@ -68,6 +72,9 @@ export function createCheckbox(opts = {}) { | ||||
|             if (opts.checked === true) { | ||||
|                 input.checked = true; | ||||
|             } | ||||
|             if (opts.indeterminate === true) { | ||||
|                 input.indeterminate = true; | ||||
|             } | ||||
|             if (opts.enabled === false) { | ||||
|                 input.disabled = true; | ||||
|             } | ||||
|   | ||||
| @@ -185,9 +185,20 @@ $listMaxHeight: 210px; | ||||
|                 background-color: var(--hover-bg-color); | ||||
|             } | ||||
|  | ||||
|             >.ui-check-wrapper { | ||||
|                 height: $dropItemHeight; | ||||
|             >.li-wrapper { | ||||
|                 display: flex; | ||||
|                 align-items: center; | ||||
|  | ||||
|                 >.ui-expandor { | ||||
|                     width: 12px; | ||||
|                     height: 12px; | ||||
|                     display: flex; | ||||
|                 } | ||||
|  | ||||
|                 >.ui-check-wrapper { | ||||
|                     height: $dropItemHeight; | ||||
|                     display: flex; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -92,7 +92,22 @@ | ||||
|             border-color: var(--link-color); | ||||
|             background-color: var(--link-color); | ||||
|  | ||||
|             >svg { | ||||
|             >.ui-check-icon { | ||||
|                 transform: scale(1); | ||||
|                 opacity: 1; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         &:indeterminate+.ui-check-inner { | ||||
|             border-color: var(--secondary-color); | ||||
|             background-color: var(--secondary-color); | ||||
|  | ||||
|             >.ui-check-icon { | ||||
|                 transform: scale(0); | ||||
|                 opacity: 0; | ||||
|             } | ||||
|  | ||||
|             >.ui-indeterminate-icon { | ||||
|                 transform: scale(1); | ||||
|                 opacity: 1; | ||||
|             } | ||||
|   | ||||
| @@ -178,6 +178,7 @@ export function getFormatter(date, utc) { | ||||
|  * @param {Date | number | string} date - 需要格式化的日期值,支持的格式如下: | ||||
|  *  | ||||
|  * * `"2024-01-26"` | ||||
|  * * `"2024/1/26"` | ||||
|  * * `"2024-01-26T00:00:00"` | ||||
|  * * `"1/26/2024"` | ||||
|  * * `"638418240000000000"` | ||||
| @@ -214,7 +215,7 @@ export function formatDate(date, formatter) { | ||||
|     if (isNaN(date)) { | ||||
|         let e = /^(\d{4})-(\d{2})-(\d{2})/.exec(date); | ||||
|         if (e == null) { | ||||
|             e = /^(\d{4})\/(\d{2})\/(\d{2})/.exec(date); | ||||
|             e = /^(\d{4})\/(\d{1,2})\/(\d{1,2})/.exec(date); | ||||
|         } | ||||
|         if (e != null) { | ||||
|             date = new Date(e[1], parseInt(e[2]) - 1, e[3]); | ||||
|   | ||||
| @@ -302,7 +302,14 @@ export class Dropdown { | ||||
|         if (!Array.isArray(list)) { | ||||
|             return; | ||||
|         } | ||||
|         this._var.source = list; | ||||
|         const valuekey = this._var.options.valueKey; | ||||
|         function reduceItems(list, id, level = 0) { | ||||
|             if (!Array.isArray(list)) { | ||||
|                 return []; | ||||
|             } | ||||
|             return list.reduce((array, item) => [...array, { __p: id, __level: level, ...item }, ...reduceItems(item.children, item[valuekey], level + 1)], []); | ||||
|         } | ||||
|         this._var.source = reduceItems(list); | ||||
|         if (this._expanded) { | ||||
|             setTimeout(() => this._dropdown(), 120); | ||||
|         } | ||||
| @@ -422,6 +429,7 @@ export class Dropdown { | ||||
|                 const search = createElement('div', 'ui-drop-search'); | ||||
|                 const input = createElement('input'); | ||||
|                 input.type = 'text'; | ||||
|                 input.className = 'ui-input'; | ||||
|                 isPositive(options.tabIndex) && input.setAttribute('tabindex', options.tabIndex); | ||||
|                 !nullOrEmpty(options.searchPlaceholder) && input.setAttribute('placeholder', options.searchPlaceholder); | ||||
|                 input.addEventListener('input', e => { | ||||
| @@ -579,7 +587,14 @@ export class Dropdown { | ||||
|             } | ||||
|             if (multiselect) { | ||||
|                 const selected = selectedlist.some(s => String(getValue(s, valuekey, textkey)) === val); | ||||
|                 item.__checked = allchecked || selected; | ||||
|                 if (allchecked || selected) { | ||||
|                     item.__checked = 1; | ||||
|                 } else { | ||||
|                     const indeterminate = selectedlist.some(s => this._contains(String(getValue(s, valuekey, textkey)), item, valuekey, textkey)); | ||||
|                     if (indeterminate) { | ||||
|                         item.__checked = 2; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         if (source.length > 20) { | ||||
| @@ -592,6 +607,20 @@ export class Dropdown { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _contains(it, item, valuekey, textkey) { | ||||
|         if (item.children?.length > 0) { | ||||
|             for (let t of item.children) { | ||||
|                 if (it === getValue(t, valuekey, textkey)) { | ||||
|                     return true; | ||||
|                 } | ||||
|                 if (this._contains(it, t, valuekey, textkey)) { | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     _dofilllist(content, array) { | ||||
|         const multiselect = this.multiSelect; | ||||
|         const valuekey = this._var.options.valueKey; | ||||
| @@ -608,6 +637,18 @@ export class Dropdown { | ||||
|             const li = createElement('li'); | ||||
|             li.dataset.value = val; | ||||
|             li.title = item[textkey]; | ||||
|             if (item.__level > 0) { | ||||
|                 li.style.marginLeft = `${item.__level * 24}px`; | ||||
|             } | ||||
|             const wrapper = createElement('span', 'li-wrapper', | ||||
|                 createElement('span', span => { | ||||
|                     // events | ||||
|                     span.className = 'ui-expandor'; | ||||
|                 }, | ||||
|                     createIcon('fa-light', 'caret-down') | ||||
|                 ) | ||||
|             ); | ||||
|             li.appendChild(wrapper); | ||||
|             let label; | ||||
|             let html; | ||||
|             if (typeof template === 'function') { | ||||
| @@ -628,20 +669,21 @@ export class Dropdown { | ||||
|                 } | ||||
|                 const box = createCheckbox({ | ||||
|                     label, | ||||
|                     checked: item.__checked, | ||||
|                     checked: item.__checked === 1, | ||||
|                     indeterminate: item.__checked === 2, | ||||
|                     customAttributes: { | ||||
|                         'class': 'dataitem', | ||||
|                         'data-value': val | ||||
|                     }, | ||||
|                     onchange: e => this._triggerselect(e.target, item) | ||||
|                 }); | ||||
|                 li.appendChild(box); | ||||
|                 wrapper.appendChild(box); | ||||
|             } else { | ||||
|                 if (label == null) { | ||||
|                     li.innerText = item[textkey]; | ||||
|                 } else { | ||||
|                     li.appendChild(label); | ||||
|                     label = createElement('span'); | ||||
|                     label.innerHTML = item[textkey]; | ||||
|                 } | ||||
|                 wrapper.appendChild(label); | ||||
|                 if (selected != null && String(selected[valuekey]) === val) { | ||||
|                     scrolled = DropdownItemHeight * i; | ||||
|                     li.classList.add('selected'); | ||||
| @@ -664,7 +706,7 @@ export class Dropdown { | ||||
|             boxes.forEach(box => box.checked = allchecked); | ||||
|             list = []; | ||||
|         } else { | ||||
|             item.__checked = checkbox.checked; | ||||
|             item.__checked = checkbox.indeterminate ? 2 : checkbox.checked ? 1 : 0; | ||||
|             const all = this._var.container.querySelector('input[isall="1"]'); | ||||
|             if (checkbox.checked) { | ||||
|                 const source = this.source; | ||||
|   | ||||
| @@ -1431,12 +1431,21 @@ export class Grid { | ||||
|                 e.stopPropagation(); | ||||
|             } | ||||
|         }); | ||||
|         grid.addEventListener('mousedown', e => { | ||||
|         grid.addEventListener('mousedown', async e => { | ||||
|             if (e.target === this._var.el) { | ||||
|                 if (e.offsetX < 0 || e.offsetX > e.target.clientWidth || e.offsetY < 0 || e.offsetY > e.target.clientHeight) { | ||||
|                     // except scroll bars | ||||
|                     return; | ||||
|                 } | ||||
|                 if (typeof this.willSelect === 'function') { | ||||
|                     let result = this.willSelect(-1, -1); | ||||
|                     if (result instanceof Promise) { | ||||
|                         result = await result; | ||||
|                     } | ||||
|                     if (!result) { | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|                 // cancel selections | ||||
|                 const selectedIndexes = this._var.selectedIndexes; | ||||
|                 if (selectedIndexes?.length > 0) { | ||||
| @@ -1525,7 +1534,7 @@ export class Grid { | ||||
|                     holder.classList.remove('active'); | ||||
|                     this._clearHolder(holder); | ||||
|                 } | ||||
|                 return this._onRowClicked(e, row, col); | ||||
|                 this._onRowClicked(e, row, col); | ||||
|             }); | ||||
|             holder.addEventListener('dblclick', e => this._onRowDblClicked(e)); | ||||
|             wrapper.appendChild(holder); | ||||
| @@ -2107,6 +2116,7 @@ export class Grid { | ||||
|         // FIXME: 清除缓存会导致选中状态下动态数据源下拉列表显示为空 | ||||
|         // delete it.source; | ||||
|         it.values = item; | ||||
|         this._var.colAttrs.__filtered = false; | ||||
|         if (this.sortArray?.length > 0) { | ||||
|             this.sort(); | ||||
|         } else if (this.sortIndex >= 0) { | ||||
| @@ -2148,6 +2158,7 @@ export class Grid { | ||||
|                 this._var.source.push(newIt); | ||||
|             } | ||||
|         } | ||||
|         this._var.colAttrs.__filtered = false; | ||||
|         if (this.sortArray?.length > 0) { | ||||
|             this.sort(true); | ||||
|         } else if (this.sortIndex >= 0) { | ||||
| @@ -2195,6 +2206,7 @@ export class Grid { | ||||
|                 this._var.source.push(...items); | ||||
|             } | ||||
|         } | ||||
|         this._var.colAttrs.__filtered = false; | ||||
|         if (this.sortArray?.length > 0) { | ||||
|             this.sort(true); | ||||
|         } else if (this.sortIndex >= 0) { | ||||
| @@ -3926,6 +3938,8 @@ export class Grid { | ||||
|                     return String(displayValue).toLowerCase().includes(key); | ||||
|                 }); | ||||
|                 this._fillFilterList(col, itemlist, items, itemall); | ||||
|                 this._set(col.key, 'filterTop', -1); | ||||
|                 itemlist.dispatchEvent(new Event('scroll')); | ||||
|             }); | ||||
|         } | ||||
|         // function | ||||
| @@ -4405,12 +4419,9 @@ export class Grid { | ||||
|      * @param {number} index  | ||||
|      * @param {number} colIndex  | ||||
|      */ | ||||
|     _onRowClicked(e, index, colIndex) { | ||||
|     _afterRowChanged(e, index, colIndex) { | ||||
|         const startIndex = this._var.startIndex; | ||||
|         const selectedIndex = startIndex + index; | ||||
|         if (typeof this.willSelect === 'function' && !this.willSelect(selectedIndex, colIndex)) { | ||||
|             return; | ||||
|         } | ||||
|         // multi-select | ||||
|         let flag = false; | ||||
|         const selectedIndexes = this._var.selectedIndexes; | ||||
| @@ -4471,6 +4482,26 @@ export class Grid { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {MouseEvent} e  | ||||
|      * @param {number} index  | ||||
|      * @param {number} colIndex  | ||||
|      */ | ||||
|     async _onRowClicked(e, index, colIndex) { | ||||
|         if (typeof this.willSelect === 'function') { | ||||
|             const selectedIndex = this._var.startIndex + index; | ||||
|             let result = this.willSelect(selectedIndex, colIndex); | ||||
|             if (result instanceof Promise) { | ||||
|                 result = await result; | ||||
|             } | ||||
|             if (!result) { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         this._afterRowChanged(e, index, colIndex); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      * @param {MouseEvent} e  | ||||
|   | ||||
| @@ -53,19 +53,24 @@ function isPhone(text) { | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| function verifyPassword(password, min) { | ||||
| function getPasswordStrength(password) { | ||||
|     if (password == null || typeof password !== 'string') { | ||||
|         return false; | ||||
|         return 0; | ||||
|     } | ||||
|     if (password.length < 8) { | ||||
|         return false; | ||||
|         return 0; | ||||
|     } | ||||
|     min ??= 3; | ||||
|     let secure = 0; | ||||
|     if (/[0-9]/.test(password)) { secure++ } | ||||
|     if (/[a-z]/.test(password)) { secure++ } | ||||
|     if (/[A-Z]/.test(password)) { secure++ } | ||||
|     if (/[^0-9a-zA-Z]/.test(password)) { secure++ } | ||||
|     return secure; | ||||
| } | ||||
|  | ||||
| function verifyPassword(password, min) { | ||||
|     min ??= 3; | ||||
|     const secure = getPasswordStrength(password); | ||||
|     return secure >= min; | ||||
| } | ||||
|  | ||||
| @@ -100,6 +105,7 @@ export { | ||||
|     truncate, | ||||
|     isEmail, | ||||
|     isPhone, | ||||
|     getPasswordStrength, | ||||
|     verifyPassword, | ||||
|     domLoad | ||||
| } | ||||
		Reference in New Issue
	
	Block a user