ref
This commit is contained in:
@@ -26,294 +26,334 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('crm:views/meeting/modals/detail', ['views/modals/detail', 'lib!moment'], function (Dep, moment) {
|
||||
import moment from 'moment';
|
||||
import DetailModalView from 'views/modals/detail';
|
||||
|
||||
return Dep.extend({
|
||||
class MeetingModalDetailView extends DetailModalView {
|
||||
|
||||
duplicateAction: true,
|
||||
duplicateAction = true
|
||||
|
||||
setupAfterModelCreated: function () {
|
||||
Dep.prototype.setupAfterModelCreated.call(this);
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
let buttonData = this.getAcceptanceButtonData();
|
||||
this.setupStatuses();
|
||||
}
|
||||
|
||||
this.addButton({
|
||||
name: 'setAcceptanceStatus',
|
||||
html: buttonData.html,
|
||||
hidden: this.hasAcceptanceStatusButton(),
|
||||
style: buttonData.style,
|
||||
className: 'btn-text',
|
||||
pullLeft: true,
|
||||
}, 'cancel');
|
||||
setupStatuses() {
|
||||
if (this.notActualStatusList) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!~this.getAcl().getScopeForbiddenFieldList(this.model.entityType).indexOf('status')
|
||||
) {
|
||||
this.addDropdownItem({
|
||||
name: 'setHeld',
|
||||
text: this.translate('Set Held', 'labels', this.model.entityType),
|
||||
hidden: true,
|
||||
});
|
||||
this.notActualStatusList = [
|
||||
...(this.getMetadata().get(`scopes.${this.entityType}.completedStatusList`) || []),
|
||||
...(this.getMetadata().get(`scopes.${this.entityType}.canceledStatusList`) || []),
|
||||
];
|
||||
}
|
||||
|
||||
this.addDropdownItem({
|
||||
name: 'setNotHeld',
|
||||
text: this.translate('Set Not Held', 'labels', this.model.entityType),
|
||||
hidden: true,
|
||||
});
|
||||
}
|
||||
setupAfterModelCreated() {
|
||||
super.setupAfterModelCreated();
|
||||
|
||||
const buttonData = this.getAcceptanceButtonData();
|
||||
|
||||
this.addButton({
|
||||
name: 'setAcceptanceStatus',
|
||||
html: buttonData.html,
|
||||
hidden: this.hasAcceptanceStatusButton(),
|
||||
style: buttonData.style,
|
||||
className: 'btn-text',
|
||||
pullLeft: true,
|
||||
onClick: () => this.actionSetAcceptanceStatus(),
|
||||
}, 'cancel');
|
||||
|
||||
if (
|
||||
!this.getAcl().getScopeForbiddenFieldList(this.model.entityType).includes('status')
|
||||
) {
|
||||
this.addDropdownItem({
|
||||
name: 'setHeld',
|
||||
text: this.translate('Set Held', 'labels', this.model.entityType),
|
||||
hidden: true,
|
||||
});
|
||||
|
||||
this.addDropdownItem({
|
||||
name: 'sendInvitations',
|
||||
text: this.translate('Send Invitations', 'labels', 'Meeting'),
|
||||
hidden: !this.isSendInvitationsToBeDisplayed(),
|
||||
name: 'setNotHeld',
|
||||
text: this.translate('Set Not Held', 'labels', this.model.entityType),
|
||||
hidden: true,
|
||||
});
|
||||
}
|
||||
|
||||
this.addDropdownItem({
|
||||
name: 'sendInvitations',
|
||||
text: this.translate('Send Invitations', 'labels', 'Meeting'),
|
||||
hidden: !this.isSendInvitationsToBeDisplayed(),
|
||||
onClick: () => this.actionSendInvitations(),
|
||||
});
|
||||
|
||||
this.initAcceptanceStatus();
|
||||
|
||||
this.on('switch-model', (model, previousModel) => {
|
||||
this.stopListening(previousModel, 'sync');
|
||||
this.initAcceptanceStatus();
|
||||
});
|
||||
|
||||
this.on('switch-model', (model, previousModel) => {
|
||||
this.stopListening(previousModel, 'sync');
|
||||
this.initAcceptanceStatus();
|
||||
});
|
||||
|
||||
this.on('after:save', () => {
|
||||
if (this.hasAcceptanceStatusButton()) {
|
||||
this.showAcceptanceButton();
|
||||
} else {
|
||||
this.hideAcceptanceButton();
|
||||
}
|
||||
|
||||
if (this.isSendInvitationsToBeDisplayed()) {
|
||||
this.showActionItem('sendInvitations');
|
||||
} else {
|
||||
this.hideActionItem('sendInvitations');
|
||||
}
|
||||
});
|
||||
|
||||
this.listenTo(this.model, 'sync', () => {
|
||||
if (this.isSendInvitationsToBeDisplayed()) {
|
||||
this.showActionItem('sendInvitations');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.hideActionItem('sendInvitations');
|
||||
});
|
||||
|
||||
this.listenTo(this.model, 'after:save', () => {
|
||||
if (this.isSendInvitationsToBeDisplayed()) {
|
||||
this.showActionItem('sendInvitations');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.hideActionItem('sendInvitations');
|
||||
});
|
||||
},
|
||||
|
||||
controlRecordButtonsVisibility: function () {
|
||||
Dep.prototype.controlRecordButtonsVisibility.call(this);
|
||||
|
||||
this.controlStatusActionVisibility();
|
||||
},
|
||||
|
||||
controlStatusActionVisibility: function () {
|
||||
if (this.getAcl().check(this.model, 'edit') && !~['Held', 'Not Held'].indexOf(this.model.get('status'))) {
|
||||
this.showActionItem('setHeld');
|
||||
this.showActionItem('setNotHeld');
|
||||
} else {
|
||||
this.hideActionItem('setHeld');
|
||||
this.hideActionItem('setNotHeld');
|
||||
}
|
||||
},
|
||||
|
||||
hasSetStatusButton: function () {
|
||||
|
||||
},
|
||||
|
||||
initAcceptanceStatus: function () {
|
||||
this.on('after:save', () => {
|
||||
if (this.hasAcceptanceStatusButton()) {
|
||||
this.showAcceptanceButton();
|
||||
} else {
|
||||
this.hideAcceptanceButton();
|
||||
}
|
||||
|
||||
this.listenTo(this.model, 'sync', () => {
|
||||
if (this.hasAcceptanceStatusButton()) {
|
||||
this.showAcceptanceButton();
|
||||
} else {
|
||||
this.hideAcceptanceButton();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getAcceptanceButtonData: function () {
|
||||
let acceptanceStatus = this.model.getLinkMultipleColumn('users', 'status', this.getUser().id);
|
||||
|
||||
let text;
|
||||
let style = 'default';
|
||||
|
||||
let iconHtml = null;
|
||||
|
||||
if (acceptanceStatus && acceptanceStatus !== 'None') {
|
||||
text = this.getLanguage().translateOption(acceptanceStatus, 'acceptanceStatus', this.model.entityType);
|
||||
|
||||
style = this.getMetadata()
|
||||
.get(['entityDefs', this.model.entityType,
|
||||
'fields', 'acceptanceStatus', 'style', acceptanceStatus]);
|
||||
|
||||
if (style) {
|
||||
let iconClass = ({
|
||||
'success': 'fas fa-check-circle',
|
||||
'danger': 'fas fa-times-circle',
|
||||
'warning': 'fas fa-question-circle',
|
||||
})[style];
|
||||
|
||||
iconHtml = $('<span>')
|
||||
.addClass(iconClass)
|
||||
.addClass('text-' + style)
|
||||
.get(0).outerHTML;
|
||||
}
|
||||
if (this.isSendInvitationsToBeDisplayed()) {
|
||||
this.showActionItem('sendInvitations');
|
||||
} else {
|
||||
text = typeof acceptanceStatus !== 'undefined' ?
|
||||
this.translate('Acceptance', 'labels', 'Meeting') :
|
||||
' ';
|
||||
this.hideActionItem('sendInvitations');
|
||||
}
|
||||
});
|
||||
|
||||
let html = this.getHelper().escapeString(text);
|
||||
|
||||
if (iconHtml) {
|
||||
html = iconHtml + ' ' + html;
|
||||
}
|
||||
|
||||
return {
|
||||
style: style,
|
||||
text: text,
|
||||
html: html,
|
||||
};
|
||||
},
|
||||
|
||||
showAcceptanceButton: function () {
|
||||
this.showActionItem('setAcceptanceStatus');
|
||||
|
||||
if (!this.isRendered()) {
|
||||
this.once('after:render', this.showAcceptanceButton, this);
|
||||
this.listenTo(this.model, 'sync', () => {
|
||||
if (this.isSendInvitationsToBeDisplayed()) {
|
||||
this.showActionItem('sendInvitations');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let data = this.getAcceptanceButtonData();
|
||||
this.hideActionItem('sendInvitations');
|
||||
});
|
||||
|
||||
let $button = this.$el.find('.modal-footer [data-name="setAcceptanceStatus"]');
|
||||
this.listenTo(this.model, 'after:save', () => {
|
||||
if (this.isSendInvitationsToBeDisplayed()) {
|
||||
this.showActionItem('sendInvitations');
|
||||
|
||||
$button.html(data.html);
|
||||
|
||||
$button.removeClass('btn-default');
|
||||
$button.removeClass('btn-success');
|
||||
$button.removeClass('btn-warning');
|
||||
$button.removeClass('btn-info');
|
||||
$button.removeClass('btn-primary');
|
||||
$button.removeClass('btn-danger');
|
||||
$button.addClass('btn-' + data.style);
|
||||
},
|
||||
|
||||
hideAcceptanceButton: function () {
|
||||
this.hideActionItem('setAcceptanceStatus');
|
||||
},
|
||||
|
||||
hasAcceptanceStatusButton: function () {
|
||||
if (!this.model.has('status')) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.model.has('usersIds')) {
|
||||
return false;
|
||||
this.hideActionItem('sendInvitations');
|
||||
});
|
||||
}
|
||||
|
||||
controlRecordButtonsVisibility() {
|
||||
super.controlRecordButtonsVisibility();
|
||||
|
||||
this.controlStatusActionVisibility();
|
||||
}
|
||||
|
||||
controlStatusActionVisibility() {
|
||||
this.setupStatuses();
|
||||
|
||||
if (
|
||||
this.getAcl().check(this.model, 'edit') &&
|
||||
!this.notActualStatusList.includes(this.model.get('status'))
|
||||
) {
|
||||
this.showActionItem('setHeld');
|
||||
this.showActionItem('setNotHeld');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.hideActionItem('setHeld');
|
||||
this.hideActionItem('setNotHeld');
|
||||
}
|
||||
|
||||
initAcceptanceStatus() {
|
||||
if (this.hasAcceptanceStatusButton()) {
|
||||
this.showAcceptanceButton();
|
||||
} else {
|
||||
this.hideAcceptanceButton();
|
||||
}
|
||||
|
||||
this.listenTo(this.model, 'sync', () => {
|
||||
if (this.hasAcceptanceStatusButton()) {
|
||||
this.showAcceptanceButton();
|
||||
} else {
|
||||
this.hideAcceptanceButton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (~['Held', 'Not Held'].indexOf(this.model.get('status'))) {
|
||||
return false;
|
||||
/**
|
||||
*
|
||||
* @return {{
|
||||
* style: 'default'|'danger'|'success'|'warning'|'info',
|
||||
* html: string,
|
||||
* text: string,
|
||||
* }}
|
||||
*/
|
||||
getAcceptanceButtonData() {
|
||||
const acceptanceStatus = this.model.getLinkMultipleColumn('users', 'status', this.getUser().id);
|
||||
|
||||
let text;
|
||||
let style = 'default';
|
||||
|
||||
let iconHtml = null;
|
||||
|
||||
if (acceptanceStatus && acceptanceStatus !== 'None') {
|
||||
text = this.getLanguage().translateOption(acceptanceStatus, 'acceptanceStatus', this.model.entityType);
|
||||
|
||||
style = this.getMetadata()
|
||||
.get(['entityDefs', this.model.entityType,
|
||||
'fields', 'acceptanceStatus', 'style', acceptanceStatus]);
|
||||
|
||||
if (style) {
|
||||
const iconClass = ({
|
||||
'success': 'fas fa-check-circle',
|
||||
'danger': 'fas fa-times-circle',
|
||||
'warning': 'fas fa-question-circle',
|
||||
})[style];
|
||||
|
||||
iconHtml = $('<span>')
|
||||
.addClass(iconClass)
|
||||
.addClass('text-' + style)
|
||||
.get(0).outerHTML;
|
||||
}
|
||||
} else {
|
||||
text = typeof acceptanceStatus !== 'undefined' ?
|
||||
this.translate('Acceptance', 'labels', 'Meeting') :
|
||||
' ';
|
||||
}
|
||||
|
||||
if (!~this.model.getLinkMultipleIdList('users').indexOf(this.getUser().id)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
let html = this.getHelper().escapeString(text);
|
||||
|
||||
actionSetAcceptanceStatus: function () {
|
||||
this.createView('dialog', 'crm:views/meeting/modals/acceptance-status', {
|
||||
model: this.model,
|
||||
}, (view) => {
|
||||
view.render();
|
||||
if (iconHtml) {
|
||||
html = iconHtml + ' ' + html;
|
||||
}
|
||||
|
||||
this.listenTo(view, 'set-status', (status) => {
|
||||
this.hideAcceptanceButton();
|
||||
return {
|
||||
style: style,
|
||||
text: text,
|
||||
html: html,
|
||||
};
|
||||
}
|
||||
|
||||
Espo.Ajax.postRequest(this.model.entityType + '/action/setAcceptanceStatus', {
|
||||
showAcceptanceButton() {
|
||||
this.showActionItem('setAcceptanceStatus');
|
||||
|
||||
if (!this.isRendered()) {
|
||||
this.once('after:render', this.showAcceptanceButton, this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const data = this.getAcceptanceButtonData();
|
||||
|
||||
const $button = this.$el.find('.modal-footer [data-name="setAcceptanceStatus"]');
|
||||
|
||||
$button.html(data.html);
|
||||
|
||||
$button.removeClass('btn-default');
|
||||
$button.removeClass('btn-success');
|
||||
$button.removeClass('btn-warning');
|
||||
$button.removeClass('btn-info');
|
||||
$button.removeClass('btn-primary');
|
||||
$button.removeClass('btn-danger');
|
||||
$button.addClass('btn-' + data.style);
|
||||
}
|
||||
|
||||
hideAcceptanceButton() {
|
||||
this.hideActionItem('setAcceptanceStatus');
|
||||
}
|
||||
|
||||
hasAcceptanceStatusButton() {
|
||||
if (!this.model.has('status')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.model.has('usersIds')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.notActualStatusList.includes(this.model.get('status'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!~this.model.getLinkMultipleIdList('users').indexOf(this.getUser().id)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
actionSetAcceptanceStatus() {
|
||||
this.createView('dialog', 'crm:views/meeting/modals/acceptance-status', {
|
||||
model: this.model,
|
||||
}, (view) => {
|
||||
view.render();
|
||||
|
||||
this.listenTo(view, 'set-status', (status) => {
|
||||
this.hideAcceptanceButton();
|
||||
|
||||
Espo.Ui.notify(' ... ');
|
||||
|
||||
Espo.Ajax
|
||||
.postRequest(this.model.entityType + '/action/setAcceptanceStatus', {
|
||||
id: this.model.id,
|
||||
status: status,
|
||||
}).then(() => {
|
||||
})
|
||||
.then(() => {
|
||||
this.model.fetch()
|
||||
.then(() => {
|
||||
Espo.Ui.notify(false);
|
||||
|
||||
setTimeout(() => {
|
||||
this.$el.find(`button[data-name="setAcceptanceStatus"]`).focus();
|
||||
}, 50)
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
actionSetHeld: function () {
|
||||
this.model.save({status: 'Held'});
|
||||
this.trigger('after:save', this.model);
|
||||
},
|
||||
actionSetHeld() {
|
||||
this.model.save({status: 'Held'});
|
||||
|
||||
actionSetNotHeld: function () {
|
||||
this.model.save({status: 'Not Held'});
|
||||
this.trigger('after:save', this.model);
|
||||
},
|
||||
this.trigger('after:save', this.model);
|
||||
}
|
||||
|
||||
isSendInvitationsToBeDisplayed: function () {
|
||||
if (~['Held', 'Not Held'].indexOf(this.model.get('status'))) {
|
||||
return false;
|
||||
}
|
||||
actionSetNotHeld() {
|
||||
this.model.save({status: 'Not Held'});
|
||||
|
||||
let dateEnd = this.model.get('dateEnd');
|
||||
this.trigger('after:save', this.model);
|
||||
}
|
||||
|
||||
if (
|
||||
dateEnd &&
|
||||
this.getDateTime().toMoment(dateEnd).isBefore(moment.now())
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
isSendInvitationsToBeDisplayed() {
|
||||
if (this.notActualStatusList.includes(this.model.get('status'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.getAcl().checkModel(this.model, 'edit')) {
|
||||
return false;
|
||||
}
|
||||
const dateEnd = this.model.get('dateEnd');
|
||||
|
||||
let userIdList = this.model.getLinkMultipleIdList('users');
|
||||
let contactIdList = this.model.getLinkMultipleIdList('contacts');
|
||||
let leadIdList = this.model.getLinkMultipleIdList('leads');
|
||||
if (
|
||||
dateEnd &&
|
||||
this.getDateTime().toMoment(dateEnd).isBefore(moment.now())
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!contactIdList.length && !leadIdList.length && !userIdList.length) {
|
||||
return false;
|
||||
}
|
||||
if (!this.getAcl().checkModel(this.model, 'edit')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
const userIdList = this.model.getLinkMultipleIdList('users');
|
||||
const contactIdList = this.model.getLinkMultipleIdList('contacts');
|
||||
const leadIdList = this.model.getLinkMultipleIdList('leads');
|
||||
|
||||
actionSendInvitations: function () {
|
||||
Espo.Ui.notify(' ... ');
|
||||
if (!contactIdList.length && !leadIdList.length && !userIdList.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.createView('dialog', 'crm:views/meeting/modals/send-invitations', {
|
||||
model: this.model,
|
||||
}).then(view => {
|
||||
Espo.Ui.notify(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
view.render();
|
||||
actionSendInvitations() {
|
||||
Espo.Ui.notify(' ... ');
|
||||
|
||||
this.listenToOnce(view, 'sent', () => this.model.fetch());
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
this.createView('dialog', 'crm:views/meeting/modals/send-invitations', {
|
||||
model: this.model,
|
||||
}).then(view => {
|
||||
Espo.Ui.notify(false);
|
||||
|
||||
view.render();
|
||||
|
||||
this.listenToOnce(view, 'sent', () => this.model.fetch());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default MeetingModalDetailView;
|
||||
|
||||
@@ -50,7 +50,7 @@ class ModalView extends View {
|
||||
* @property {string} [html] HTML.
|
||||
* @property {boolean} [pullLeft=false] Deprecated. Use the `position` property.
|
||||
* @property {'left'|'right'} [position='left'] A position.
|
||||
* @property {'default'|'danger'|'success'|'warning'} [style='default'] A style.
|
||||
* @property {'default'|'danger'|'success'|'warning'|'info'} [style='default'] A style.
|
||||
* @property {boolean} [hidden=false] Is hidden.
|
||||
* @property {boolean} [disabled=false] Disabled.
|
||||
* @property {function(module:ui.Dialog): void} [onClick] Called on click. If not defined, then
|
||||
|
||||
Reference in New Issue
Block a user