/** * map settings dialogs */ define([ 'jquery', 'app/init', 'app/util', 'app/render', 'bootbox', 'app/map/util', 'app/module_map' ], ($, Init, Util, Render, bootbox, MapUtil, ModuleMap) => { 'use strict'; let config = { // map dialog newMapDialogId: 'pf-map-dialog', // id for map settings dialog dialogMapNewContainerId: 'pf-map-dialog-new', // id for the "new map" container dialogMapEditContainerId: 'pf-map-dialog-edit', // id for the "edit" container dialogMapSettingsContainerId: 'pf-map-dialog-settings', // id for the "settings" container dialogMapDownloadContainerId: 'pf-map-dialog-download', // id for the "download" container // new map form newIconSelectId: 'pf-map-dialog-new-icon-select', // id for "icon" select newScopeSelectId: 'pf-map-dialog-new-scope-select', // id for "scope" select newTypeSelectId: 'pf-map-dialog-new-type-select', // id for "type" select // edit map form editIconSelectId: 'pf-map-dialog-edit-icon-select', // id for "icon" select editScopeSelectId: 'pf-map-dialog-edit-scope-select', // id for "scope" select editTypeSelectId: 'pf-map-dialog-edit-type-select', // id for "type" select // settings map form deleteExpiredConnectionsId: 'pf-map-dialog-delete-connections-expired', // id for "deleteExpiredConnections" checkbox deleteEolConnectionsId: 'pf-map-dialog-delete-connections-eol', // id for "deleteEOLConnections" checkbox persistentAliasesId: 'pf-map-dialog-persistent-aliases', // id for "persistentAliases" checkbox persistentSignaturesId: 'pf-map-dialog-persistent-signatures', // id for "persistentSignatures" checkbox logHistoryId: 'pf-map-dialog-history', // id for "history logging" checkbox logActivityId: 'pf-map-dialog-activity', // id for "activity" checkbox slackWebHookURLId: 'pf-map-dialog-slack-url', // id for Slack "webHookUrl" slackUsernameId: 'pf-map-dialog-slack-username', // id for Slack "username" slackIconId: 'pf-map-dialog-slack-icon', // id for Slack "icon" slackChannelHistoryId: 'pf-map-dialog-slack-channel-history', // id for Slack channel "history" slackChannelRallyId: 'pf-map-dialog-slack-channel-rally', // id for Slack channel "rally" discordUsernameId: 'pf-map-dialog-discord-username', // id for Discord "username" discordWebHookURLRallyId: 'pf-map-dialog-discord-url-rally', // id for Discord "rally" webHookUrl discordWebHookURLHistoryId: 'pf-map-dialog-discord-url-history', // id for Discord "history" webHookUrl characterSelectId: 'pf-map-dialog-character-select', // id for "character" select corporationSelectId: 'pf-map-dialog-corporation-select', // id for "corporation" select allianceSelectId: 'pf-map-dialog-alliance-select', // id for "alliance" select dialogMapExportFormId: 'pf-map-dialog-form-export', // id for "export" form dialogMapImportFormId: 'pf-map-dialog-form-import', // id for "import" form buttonExportId: 'pf-map-dialog-button-export', // id for "export" button buttonImportId: 'pf-map-dialog-button-import', // id for "import" button fieldExportId: 'pf-map-filename-export', // id for "export" filename field fieldImportId: 'pf-map-filename-import', // id for "import" filename field dialogMapImportInfoId: 'pf-map-import-container', // id for "info" container dragDropElementClass: 'pf-form-dropzone' // class for "drag&drop" zone }; /** * format a given string into a valid filename * @param filename * @returns {string} */ let formatFilename = function(filename){ filename = filename.replace(/[^a-zA-Z0-9]/g,'_'); let nowDate = new Date(); let filenameDate = nowDate.toISOString().slice(0,10).replace(/-/g, '_'); return (filename + '_' + filenameDate).replace(/__/g,'_'); }; /** * shows the add/edit map dialog * @param mapData * @param options */ $.fn.showMapSettingsDialog = function(mapData, options){ // check if dialog is already open let mapInfoDialogElement = $('#' + config.newMapDialogId); if(!mapInfoDialogElement.is(':visible')){ requirejs([ 'text!templates/dialog/map.html', 'text!templates/form/map.html', 'mustache' ], (templateMapDialog, templateMapForm, Mustache) => { let dialogTitle = 'Map settings'; // if there are no maps -> hide settings tab let hideSettingsTab = false; let hideEditTab = false; let hideDownloadTab = false; let hasRightMapCreate = true; let hasRightMapUpdate = true; let hasRightMapExport = true; let hasRightMapImport = true; if(mapData === false){ hideSettingsTab = true; hideEditTab = true; hideDownloadTab = true; }else{ hasRightMapUpdate = MapUtil.checkRight('map_update', mapData.config); hasRightMapExport = MapUtil.checkRight('map_export', mapData.config); hasRightMapImport = MapUtil.checkRight('map_import', mapData.config); } // available map "types" for a new or existing map let mapTypes = MapUtil.getMapTypes(true); let mapFormData = { select2Class: Util.config.select2Class, scope: MapUtil.getMapScopes(), type: mapTypes, icon: MapUtil.getMapIcons(), formErrorContainerClass: Util.config.formErrorContainerClass, formWarningContainerClass: Util.config.formWarningContainerClass, formInfoContainerClass: Util.config.formInfoContainerClass }; // render "new map" tab content ----------------------------------------------------------------------- let mapFormDataNew = $.extend({}, mapFormData, { hasRightMapForm: hasRightMapCreate, iconSelectId: config.newIconSelectId, scopeSelectId: config.newScopeSelectId, typeSelectId: config.newTypeSelectId }); let contentNewMap = Mustache.render(templateMapForm, mapFormDataNew); // render "edit map" tab content ---------------------------------------------------------------------- let mapFormDataEdit = $.extend({}, mapFormData, { hasRightMapForm: hasRightMapUpdate, iconSelectId: config.editIconSelectId, scopeSelectId: config.editScopeSelectId, typeSelectId: config.editTypeSelectId }); let contentEditMap = Mustache.render(templateMapForm, mapFormDataEdit); contentEditMap = $(contentEditMap); // current map access info let accessCharacter = []; let accessCorporation = []; let accessAlliance = []; let deleteExpiredConnections = true; let deleteEolConnections = true; let persistentAliases = true; let persistentSignatures = true; let logActivity = true; let logHistory = true; let slackWebHookURL = ''; let slackUsername = ''; let slackIcon = ''; let slackChannelHistory = ''; let slackChannelRally = ''; let slackEnabled = false; let slackHistoryEnabled = false; let slackRallyEnabled = false; let slackSectionShow = false; let discordUsername = ''; let discordWebHookURLRally = ''; let discordWebHookURLHistory = ''; let discordEnabled = false; let discordRallyEnabled = false; let discordHistoryEnabled = false; let discordSectionShow = false; if(mapData !== false){ // set current map information contentEditMap.find('input[name="id"]').val( mapData.config.id ); contentEditMap.find('select[name="icon"]').val( mapData.config.icon ); contentEditMap.find('input[name="name"]').val( mapData.config.name ); contentEditMap.find('select[name="scopeId"]').val( mapData.config.scope.id ); contentEditMap.find('select[name="typeId"]').val( mapData.config.type.id ); accessCharacter = mapData.config.access.character; accessCorporation = mapData.config.access.corporation; accessAlliance = mapData.config.access.alliance; deleteExpiredConnections = mapData.config.deleteExpiredConnections; deleteEolConnections = mapData.config.deleteEolConnections; persistentAliases = mapData.config.persistentAliases; persistentSignatures = mapData.config.persistentSignatures; logActivity = mapData.config.logging.activity; logHistory = mapData.config.logging.history; slackWebHookURL = mapData.config.logging.slackWebHookURL; slackUsername = mapData.config.logging.slackUsername; slackIcon = mapData.config.logging.slackIcon; slackChannelHistory = mapData.config.logging.slackChannelHistory; slackChannelRally = mapData.config.logging.slackChannelRally; slackEnabled = Boolean(Util.getObjVal(Init, 'slack.status')); slackHistoryEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_slack_enabled')); slackRallyEnabled = slackEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_slack_enabled')); slackSectionShow = (slackEnabled && slackWebHookURL.length > 0); discordUsername = Util.getObjVal(mapData, 'config.logging.discordUsername'); discordWebHookURLRally = Util.getObjVal(mapData, 'config.logging.discordWebHookURLRally'); discordWebHookURLHistory = Util.getObjVal(mapData, 'config.logging.discordWebHookURLHistory'); discordEnabled = Boolean(Util.getObjVal(Init, 'discord.status')); discordRallyEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_rally_discord_enabled')); discordHistoryEnabled = discordEnabled && Boolean(Util.getObjVal(Init.mapTypes, mapData.config.type.name + '.defaultConfig.send_history_discord_enabled')); discordSectionShow = (discordEnabled && (discordWebHookURLRally.length > 0 || discordWebHookURLHistory.length > 0)); // remove "#" from Slack channels slackChannelHistory = slackChannelHistory.indexOf('#') === 0 ? slackChannelHistory.substr(1) : slackChannelHistory; slackChannelRally = slackChannelRally.indexOf('#') === 0 ? slackChannelRally.substr(1) : slackChannelRally; } // render main dialog --------------------------------------------------------------------------------- let mapDialogData = { id: config.newMapDialogId, mapData: mapData, type: mapTypes, // message container formErrorContainerClass: Util.config.formErrorContainerClass, formWarningContainerClass: Util.config.formWarningContainerClass, formInfoContainerClass: Util.config.formInfoContainerClass, // default open tab ---------- openTabNew: options.tab === 'new', openTabEdit: options.tab === 'edit', openTabSettings: options.tab === 'settings', openTabDownload: options.tab === 'download', dialogMapNewContainerId: config.dialogMapNewContainerId, dialogMapEditContainerId: config.dialogMapEditContainerId, dialogMapSettingsContainerId: config.dialogMapSettingsContainerId, dialogMapDownloadContainerId: config.dialogMapDownloadContainerId, hideEditTab: hideEditTab, hideSettingsTab: hideSettingsTab, hideDownloadTab: hideDownloadTab, // settings tab -------------- deleteExpiredConnectionsId : config.deleteExpiredConnectionsId, deleteEolConnectionsId : config.deleteEolConnectionsId, persistentAliasesId : config.persistentAliasesId, persistentSignaturesId : config.persistentSignaturesId, deleteExpiredConnections: deleteExpiredConnections, deleteEolConnections: deleteEolConnections, persistentAliases: persistentAliases, persistentSignatures: persistentSignatures, logHistoryId: config.logHistoryId, logActivityId: config.logActivityId, logActivity: logActivity, logHistory: logHistory, slackWebHookURLId: config.slackWebHookURLId, slackUsernameId: config.slackUsernameId, slackIconId: config.slackIconId, slackChannelHistoryId: config.slackChannelHistoryId, slackChannelRallyId: config.slackChannelRallyId, slackWebHookURL: slackWebHookURL, slackUsername: slackUsername, slackIcon: slackIcon, slackChannelHistory: slackChannelHistory, slackChannelRally: slackChannelRally, slackEnabled: slackEnabled, slackHistoryEnabled: slackHistoryEnabled, slackRallyEnabled: slackRallyEnabled, slackSectionShow: slackSectionShow, discordUsernameId: config.discordUsernameId, discordWebHookURLRallyId: config.discordWebHookURLRallyId, discordWebHookURLHistoryId: config.discordWebHookURLHistoryId, discordUsername: discordUsername, discordWebHookURLRally: discordWebHookURLRally, discordWebHookURLHistory: discordWebHookURLHistory, discordEnabled: discordEnabled, discordRallyEnabled: discordRallyEnabled, discordHistoryEnabled: discordHistoryEnabled, discordSectionShow: discordSectionShow, characterSelectId: config.characterSelectId, corporationSelectId: config.corporationSelectId, allianceSelectId: config.allianceSelectId, // map access objects -------- accessCharacter: accessCharacter, accessCorporation: accessCorporation, accessAlliance: accessAlliance, // access limitations -------- maxCharacter: Init.mapTypes.private.defaultConfig.max_shared, maxCorporation: Init.mapTypes.corporation.defaultConfig.max_shared, maxAlliance: Init.mapTypes.alliance.defaultConfig.max_shared, // download tab -------------- dialogMapExportFormId: config.dialogMapExportFormId, dialogMapImportFormId: config.dialogMapImportFormId, buttonExportId: config.buttonExportId, buttonImportId: config.buttonImportId, fieldExportId: config.fieldExportId, fieldImportId: config.fieldImportId, dialogMapImportInfoId: config.dialogMapImportInfoId, hasRightMapUpdate: hasRightMapUpdate, hasRightMapExport: hasRightMapExport, hasRightMapImport: hasRightMapImport, formatFilename: function(){ // format filename from "map name" (initial) return function(mapName, render){ let filename = render(mapName); return formatFilename(filename); }; } }; let contentDialog = Mustache.render(templateMapDialog, mapDialogData); contentDialog = $(contentDialog); // set tab content $('#' + config.dialogMapNewContainerId, contentDialog).html(contentNewMap); $('#' + config.dialogMapEditContainerId, contentDialog).html(contentEditMap); let mapInfoDialog = bootbox.dialog({ title: dialogTitle, message: contentDialog, buttons: { close: { label: 'cancel', className: 'btn-default' }, success: { label: ' save', className: 'btn-success', callback: function(){ // get the current active form let form = $('#' + config.newMapDialogId).find('form').filter(':visible'); // validate form form.validator('validate'); // validate select2 fields (settings tab) form.find('select').each(function(){ let selectField = $(this); let selectValues = selectField.val(); if(selectValues && selectValues.length > 0){ selectField.parents('.form-group').removeClass('has-error'); }else{ selectField.parents('.form-group').addClass('has-error'); } }); // check whether the form is valid let formValid = form.isValidForm(); if(formValid === true){ // lock dialog let dialogContent = mapInfoDialog.find('.modal-content'); dialogContent.showLoadingAnimation(); // get form data let formData = form.getFormValues(); // add value prefixes (Slack channels) let tmpVal; if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelHistory')) === 'string' && tmpVal.length){ formData.slackChannelHistory = '#' + tmpVal; } if(typeof (tmpVal = Util.getObjVal(formData, 'slackChannelRally')) === 'string' && tmpVal.length){ formData.slackChannelRally = '#' + tmpVal; } // checkbox fix -> settings tab if( form.find('#' + config.deleteExpiredConnectionsId).length ){ formData.deleteExpiredConnections = formData.hasOwnProperty('deleteExpiredConnections') ? parseInt( formData.deleteExpiredConnections ) : 0; } if( form.find('#' + config.deleteEolConnectionsId).length ){ formData.deleteEolConnections = formData.hasOwnProperty('deleteEolConnections') ? parseInt( formData.deleteEolConnections ) : 0; } if( form.find('#' + config.persistentAliasesId).length ){ formData.persistentAliases = formData.hasOwnProperty('persistentAliases') ? parseInt( formData.persistentAliases ) : 0; } if( form.find('#' + config.persistentSignaturesId).length ){ formData.persistentSignatures = formData.hasOwnProperty('persistentSignatures') ? parseInt( formData.persistentSignatures ) : 0; } if( form.find('#' + config.logHistoryId).length ){ formData.logHistory = formData.hasOwnProperty('logHistory') ? parseInt( formData.logHistory ) : 0; } if( form.find('#' + config.logActivityId).length ){ formData.logActivity = formData.hasOwnProperty('logActivity') ? parseInt( formData.logActivity ) : 0; } let requestData = {formData: formData}; $.ajax({ type: 'POST', url: Init.path.saveMap, data: requestData, dataType: 'json' }).done(function(responseData){ if(responseData.error.length){ form.showFormMessage(responseData.error); }else{ // success Util.showNotify({title: dialogTitle, text: 'Map: ' + responseData.mapData.mapData.name, type: 'success'}); // update map-tab Element let tabLinkElement = Util.getMapModule().getMapTabElements(responseData.mapData.mapData.id); if(tabLinkElement.length === 1){ ModuleMap.updateTabData(tabLinkElement, responseData.mapData.mapData); } $(mapInfoDialog).modal('hide'); Util.triggerMenuAction(document, 'Close'); } }).fail(function(jqXHR, status, error){ let reason = status + ' ' + error; Util.showNotify({title: jqXHR.status + ': saveMap', text: reason, type: 'warning'}); $(document).setProgramStatus('problem'); }).always(function(){ dialogContent.hideLoadingAnimation(); }); } return false; } } } }); // after modal is shown =============================================================================== mapInfoDialog.on('shown.bs.modal', function(e){ mapInfoDialog.initTooltips(); // manually trigger the "show" event for the initial active tab (not triggered by default...) mapInfoDialog.find('.navbar li.active a[data-toggle=tab]').trigger('shown.bs.tab'); // prevent "disabled" tabs from being clicked... "bootstrap" bugFix... mapInfoDialog.find('.navbar a[data-toggle=tab]').on('click', function(e){ if($(this).hasClass('disabled')){ e.preventDefault(); return false; } }); // make