/*
* Copyright 2022 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class is a singleton to handle actions on signup invitations
*/
Ext.define('Ametys.plugins.web.tempusers.InvitationActions', {
singleton: true,
/**
* Open a dialog box to send an invitation to signup
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
sendInvitation: function(controller)
{
if (!this._sendInvitationDialog)
{
this._sendInvitationDialog = this._sendInvitationDialogBox(controller, controller.getInitialConfig());
}
var form = this._sendInvitationDialog.items.getAt(0).getForm();
form.reset();
form.findField('userDirectory').setValue(controller.getInitialConfig().defaultUserDirectory);
this._sendInvitationDialog.show();
},
/**
* @private
*/
_sendInvitationDialogBox: function(controller, config)
{
var formPanel = Ext.create('Ext.form.Panel', {
border: false,
scrollable: false,
defaults: {
cls: 'ametys',
labelSeparator: '',
labelAlign: 'top',
anchor: "100%",
msgTarget: 'side'
},
items: [
{
xtype: 'component',
html: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_HINT}}",
cls: 'text',
style: {
marginBottom: '10px'
}
},
{
xtype: 'edition.userdirectory',
itemId: 'userDirectory',
name: 'userDirectory',
fieldLabel: "* {{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_USER_DIRECTORY_LABEL}}",
ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_USER_DIRECTORY_DESC}}",
allowBlank: false,
onlyModifiable: true,
userPopulationOnly: config.userPopulationOnly || false
},
{
xtype: 'textfield',
itemId: 'email',
name: 'email',
fieldLabel: "* {{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_EMAIL_LABEL}}",
ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_EMAIL_DESC}}",
allowBlank: false,
regex: new RegExp('^.+@.+$'),
regexText: "{{i18n plugin.core:PLUGINS_CORE_REGEXP_INVALID_MAIL}}"
},
{
xtype: 'textfield',
itemId: 'lastname',
name: 'lastname',
fieldLabel: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_LASTNAME_LABEL}}",
ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_LASTNAME_DESC}}"
},
{
xtype: 'textfield',
itemId: 'firstname',
name: 'firstname',
fieldLabel: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_FIRSTNAME_LABEL}}",
ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_FIRSTNAME_DESC}}"
}
]
});
return Ext.create('Ametys.window.DialogBox', {
title: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_TITLE}}",
iconCls: 'ametysicon-desktop-envelope-invitation',
layout: {
type: 'vbox',
align : 'stretch',
pack : 'start'
},
width: 470,
items: [formPanel],
buttons: [{
text: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_OK}}",
handler: Ext.bind(this._ok, this, [controller], false),
scope: this
}, {
text: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_CANCEL}}",
handler: this._cancel,
scope: this
}]
});
},
/**
* @private
*/
_ok: function(controller)
{
var form = this._sendInvitationDialog.items.getAt(0).getForm();
if (form.isValid())
{
var values = form.getValues();
controller.serverCall('sendInvitation', [Ametys.getAppParameter("siteName"), values.userDirectory, values.email, values.lastname, values.firstname], Ext.bind(this._sendCb, this), {
errorMessage: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_MSG}}",
waitMessage: true
});
}
},
/**
* @private
*/
_sendCb: function(result)
{
if (!result.success)
{
var msg = "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_MSG}}";
msg += result.message || "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_UNKNOWN}}";
Ametys.Msg.show({
title: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_TITLE}}",
msg: msg,
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
}
else
{
this._sendInvitationDialog.hide();
Ametys.Msg.show({
title: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_SUCCESS_TITLE}}",
msg: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_SUCCESS_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.CREATED,
targets: {
id: Ametys.message.MessageTarget.TEMP_USER,
parameters: {
email: result.email
}
}
});
}
},
/**
* @private
*/
_cancel: function(button, event)
{
this._sendInvitationDialog.hide();
},
/**
* Open a dialog box to import invitations from a CSV file
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
sendInvitationsFromCSV: function(controller)
{
if (!this._importDialog)
{
this._importDialog = this._createImportDialogBox(controller.getInitialConfig());
}
var form = this._importDialog.items.getAt(0).getForm();
form.findField('userDirectory').setValue(controller.getInitialConfig().defaultUserDirectory);
form.findField('resendInvitations').setValue(false);
form.findField('file').reset();
this._importDialog.show();
},
/**
* @private
*/
_createImportDialogBox: function(config)
{
var existingInvitationOpts = Ext.create('Ext.data.Store', {
fields: ['value', 'label'],
data : [
{"value": false, "label":"{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_IGNORE}}"},
{"value": true, "label":"{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_RESEND}}"}
]
});
var formPanel = Ext.create('Ext.form.Panel', {
border: false,
scrollable: false,
defaults: {
cls: 'ametys',
labelSeparator: '',
labelAlign: 'top',
anchor: "100%"
},
items: [
{
xtype: 'component',
html: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_HINT}}",
cls: 'text',
style: {
marginBottom: '10px'
}
},
{
xtype: 'fileuploadfield',
itemId: 'file',
name: 'file',
fieldLabel: "* {{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_DESC}}",
allowBlank: false,
emptyText: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_EMPTY_TEXT}}",
buttonText: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_BUTTON}}"
},
{
xtype: 'edition.userdirectory',
itemId: 'userDirectory',
name: 'userDirectory',
fieldLabel: "* {{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_USER_DIRECTORY_LABEL}}",
ametysDescription: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_USER_DIRECTORY_DESC}}",
allowBlank: false,
onlyModifiable: true,
userPopulationOnly: config.userPopulationOnly || false
},
{
xtype: 'combobox',
itemId: 'resendInvitations',
name: 'resendInvitations',
store: existingInvitationOpts,
queryMode: 'local',
displayField: 'label',
valueField: 'value',
allowBlank: false,
fieldLabel: "* {{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_LABEL}}",
ametysDescription: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_DESC}}"
}
]
});
return Ext.create('Ametys.window.DialogBox', {
title: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_TITLE}}",
iconCls: 'ametysicon-desktop-envelope-invitation',
layout: {
type: 'vbox',
align : 'stretch',
pack : 'start'
},
width: 500,
items: [formPanel],
buttons: [{
text: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_OK}}",
handler: this._validateImport,
scope: this
}, {
text: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_CANCEL}}",
handler: this._cancelImport,
scope: this
}]
});
},
/**
* @private
*/
_validateImport: function(button, event)
{
var form = this._importDialog.items.getAt(0).getForm();
if (form.isValid())
{
Ametys.Msg.confirm("{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_CONFIRM_TITLE}}",
"{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_CONFIRM}}",
function(answer) {
if (answer == 'yes')
{
this._doImport(form);
}
},
this
);
}
},
/**
* @private
*/
_doImport: function(form)
{
var formValues = form.getFieldValues();
var resendInvitations = formValues["resendInvitations"] == "true";
var parameters = [formValues["userDirectory"], resendInvitations, form.findField('file').getFiles()[0]];
Ametys.data.ServerComm.callMethod({
role: 'org.ametys.web.usermanagement.ImportInvitations',
methodName: 'doImport',
parameters: parameters,
priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST,
callback: {
handler: this._doImportCb,
scope: this,
},
errorMessage: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_MSG}}",
progressMessage: {
title: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_WAIT_TITLE}}",
msg: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_WAIT_MSG}}"
}
});
},
/**
* @private
* This function is called after the resources have tried to be imported
* @param {Object} result The results
*/
_doImportCb: function(result)
{
if (result.success)
{
this._success(result);
}
else
{
this._failure(result);
}
},
/**
* @private
*/
_success: function(result)
{
this._importDialog.hide();
},
/**
* @private
*/
_failure: function(result)
{
var message = '';
var error = result.error;
if (error == 'invalid-extension')
{
message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_INVALID_FILE}}";
}
else if (error == 'rejected-file')
{
message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_REJECTED_FILE}}";
}
else if (error == 'file-error')
{
message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_FILE_ERROR}}";
}
else if (error == 'schedule-error')
{
message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_SCHEDULE_ERROR}}";
}
else
{
message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR}}";
}
Ametys.Msg.show({
title: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_TITLE}}",
msg: message,
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
},
/**
* @private
*/
_cancelImport: function(button, event)
{
this._importDialog.hide();
},
/**
* Resend an existing invitation to signup
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
resendInvitation: function(controller)
{
var targets = controller.getMatchingTargets();
if (targets.length == 0)
{
return;
}
Ametys.Msg.confirm("{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_CONFIRM_TITLE}}",
"{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_CONFIRM_MSG}}",
function(answer) {
if (answer == 'yes')
{
this._doResendInvitation(targets[0], controller);
}
},
this
);
},
/**
* @private
*/
_doResendInvitation: function(target, controller)
{
var params = target.getParameters();
controller.serverCall('resendInvitation', [Ametys.getAppParameter("siteName"), params.email, params.population, params.userDirectory], Ext.bind(this._resendInvitationCb, this), {
errorMessage: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_MSG}}",
waitMessage: true
});
},
/**
* @private
* Callback function invoke after resend of invitation
* @param {Object} result the result map
*/
_resendInvitationCb: function(result)
{
if (!result.success)
{
var msg = "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_MSG}}";
msg += result.message || "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_UNKNOWN}}";
Ametys.Msg.show({
title: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_TITLE}}",
msg: msg,
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
}
else
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_SUCCESS_TITLE}}",
msg: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_SUCCESS_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
Ametys.plugins.web.tempusers.TempUsersDAO.localUpdate(result.email, {
subscriptionDate: result.subscriptionDate,
expired: false
});
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.MODIFIED,
targets: [{
id: Ametys.message.MessageTarget.TEMP_USER,
parameters: {
email: result.email
}
}]
});
}
},
/**
* Resend an existing invitation to signup
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
removeInvitation: function(controller)
{
var targets = controller.getMatchingTargets();
if (targets.length == 0)
{
return;
}
var emails = controller.getAllRightEmails();
var confirmMsg = Ext.String.format("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_CONFIRM_MSG}}", emails.join(", "));
Ametys.Msg.confirm("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_CONFIRM_TITLE}}",
confirmMsg,
function(answer) {
if (answer == 'yes')
{
this._doRemoveInvitation(targets, controller);
}
},
this
);
},
/**
* @private
*/
_doRemoveInvitation: function (targets, controller)
{
var emails = controller.getAllRightEmails();
controller.serverCall('removeInvitation', [Ametys.getAppParameter("siteName"), emails], Ext.bind(this._removeInvitationCb, this, [targets], 1), {
errorMessage: "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_MSG}}",
waitMessage: true
});
},
/**
* @private
* Callback function invoke after resend of invitation
* @param {Object} result the result map
* @param {Ametys.message.MessageTarget} target the initial targets
*/
_removeInvitationCb: function(result, initialTargets)
{
if (!result.success)
{
var msg = "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_MSG}}";
msg += result.message || "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_UNKNOWN}}";
Ametys.Msg.show({
title: "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_TITLE}}",
msg: msg,
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
}
else
{
var deletedInvitations = result['deleted-invitations'];
var deletedTargets = Ext.Array.filter (initialTargets, function (target) {
return Ext.Array.contains(deletedInvitations, target.getParameters().email);
});
if (deletedTargets.length > 0)
{
Ext.create('Ametys.message.Message', {
type: Ametys.message.Message.DELETED,
targets: deletedTargets
});
}
var noRightInvitations = result['noright-invitations'];
var noInvitations = result['no-invitations'];
var errorMsg = "";
if (noRightInvitations.length > 0)
{
errorMsg += Ext.String.format("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_NORIGHT}}", noRightInvitations.join(", "));
}
if (noInvitations.length > 0)
{
errorMsg += Ext.String.format("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_UNREMOVABLE_SIGNUP_REQUEST}}", noInvitations.join(", "));
}
if (errorMsg != '')
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_TITLE}}",
msg: errorMsg,
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
}
}
}
});