Initial commit
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
<div class="js-dialogIconPicker">
|
||||
</div>
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
const CoreView = require('backbone/core-view');
|
||||
const checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
const OrganizationIconsView = require('../icons/organization-icons-view');
|
||||
const template = require('./icon-picker-dialog.tpl');
|
||||
|
||||
const REQUIRED_OPTS = [
|
||||
'orgId',
|
||||
'configModel'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
|
||||
className: 'Dialog Modal IconPickerDialog',
|
||||
|
||||
events: {
|
||||
'click .js-addIcon': '_onAddIconClicked'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
|
||||
this.$el.html(template());
|
||||
this.$('.content').addClass('Dialog-content--expanded');
|
||||
|
||||
this._initViews();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_initViews: function () {
|
||||
this.icon_picker = new OrganizationIconsView({
|
||||
el: this.$('.js-dialogIconPicker'),
|
||||
orgId: this._orgId,
|
||||
configModel: this._configModel
|
||||
});
|
||||
this.addView(this.icon_picker);
|
||||
|
||||
this.icon_picker.model.on('change:isProcessRunning', this._onIsProcessRunningChanged, this);
|
||||
},
|
||||
|
||||
_onIsProcessRunningChanged: function () {
|
||||
var running = this.icon_picker.model.get('isProcessRunning');
|
||||
if (running) {
|
||||
this.$el.css('pointer-events', 'none');
|
||||
} else {
|
||||
this.$el.css('pointer-events', 'auto');
|
||||
}
|
||||
},
|
||||
|
||||
_onAddIconClicked: function (event) {
|
||||
this.killEvent(event);
|
||||
|
||||
this._hideErrorMessage();
|
||||
this.$('.js-inputFile').trigger('click');
|
||||
},
|
||||
|
||||
_hideErrorMessage: function () {
|
||||
this._hide('.js-errorMessage');
|
||||
},
|
||||
|
||||
_hide: function (selector) {
|
||||
this.$(selector).addClass('is-hidden');
|
||||
}
|
||||
});
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<div class="Modal-header">
|
||||
<div class="Modal-headerContainer">
|
||||
<h2 class="CDB-Text CDB-Size-huge is-light u-bSpace">Organization icons</h2>
|
||||
<h3 class="CDB-Text CDB-Size-medium u-altTextColor"><a data-type="upload_file" href="#/upload" class="js-addIcon">Upload organization icons</a></h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="Modal-container IconModal">
|
||||
<div class="Tab-pane">
|
||||
<div class="Modal-inner">
|
||||
<div class="Dialog-body Dialog-body--expanded Dialog-body--create Dialog-body--withoutBorder">
|
||||
<div class="u-inner">
|
||||
<div class="js-dialogIconPicker"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<li class="CDB-NavMenu-item is-disabled js-your-icons<%- pane === 'your_icons' ? ' is-selected' : '' %>">
|
||||
<button data-type="your_icons" class="CDB-NavMenu-link js-item u-upperCase">Organization icons</button>
|
||||
</li>
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
const CoreView = require('backbone/core-view');
|
||||
const template = require('./delete-icons-dialog.tpl');
|
||||
const checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'modalModel',
|
||||
'onSubmit'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
events: {
|
||||
'click .js-submit': '_onSubmitClicked',
|
||||
'click .js-cancel': '_closeDialog'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||||
|
||||
this._numOfIcons = this.options.numOfIcons || 0;
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.html(template({
|
||||
numOfIcons: this._numOfIcons
|
||||
}));
|
||||
},
|
||||
|
||||
_onSubmitClicked: function () {
|
||||
this._onSubmit();
|
||||
this._closeDialog();
|
||||
},
|
||||
|
||||
_closeDialog: function () {
|
||||
this._modalModel.destroy();
|
||||
}
|
||||
});
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<div class="CDB-Text Dialog-header u-inner">
|
||||
<div class="Dialog-headerIcon Dialog-headerIcon--negative">
|
||||
<i class="CDB-IconFont CDB-IconFont-trash"></i>
|
||||
<% if (numOfIcons > 0) { %>
|
||||
<span class="Badge Badge--negative Dialog-headerIconBadge CDB-Text CDB-Size-small"><%- numOfIcons %></span>
|
||||
<% } %>
|
||||
</div>
|
||||
<h4 class="CDB-Text CDB-Size-large u-mainTextColor u-secondaryTextColor u-bSpace--m u-tSpace-xl">
|
||||
You are deleting
|
||||
<% if (numOfIcons <= 0) { %>
|
||||
icons
|
||||
<% } else if (numOfIcons === 1) { %>
|
||||
1 icon
|
||||
<% } else { %>
|
||||
<%- numOfIcons %> icons
|
||||
<% } %>
|
||||
from your organization.
|
||||
</h4>
|
||||
<p class="CDB-Text CDB-Size-medium u-altTextColor">
|
||||
Once icons are deleted they cannot be recovered. Any maps within the organization that use
|
||||
<% if (numOfIcons === 1) { %>
|
||||
this icon
|
||||
<% } else { %>
|
||||
these icons
|
||||
<% } %>
|
||||
will be adversely affected.
|
||||
</p>
|
||||
<p class="CDB-Text CDB-Size-medium u-altTextColor">Please be sure before proceeding.</p>
|
||||
</div>
|
||||
|
||||
<div class="Dialog-footer Dialog-footer--simple u-inner">
|
||||
<div class="Dialog-footerContent">
|
||||
<button class="CDB-Button CDB-Button--secondary js-cancel">
|
||||
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Cancel</span>
|
||||
</button>
|
||||
<button class="u-lSpace--xl CDB-Button CDB-Button--error js-submit">
|
||||
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Ok, delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
const Backbone = require('backbone');
|
||||
const IconModel = require('./organization-icon-model');
|
||||
const checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
const REQUIRED_OPTS = [
|
||||
'orgId',
|
||||
'configModel'
|
||||
];
|
||||
|
||||
module.exports = Backbone.Collection.extend({
|
||||
initialize: function (models, options) {
|
||||
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||||
},
|
||||
|
||||
model: function (attrs, opts) {
|
||||
const options = { ...opts, configModel: opts.collection._configModel };
|
||||
|
||||
return new IconModel(attrs, options);
|
||||
},
|
||||
|
||||
url: function (method) {
|
||||
const version = this._configModel.urlVersion('organization-assets', method);
|
||||
|
||||
return `/api/${version}/organization/${this._orgId}/assets`;
|
||||
}
|
||||
});
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
const Backbone = require('backbone');
|
||||
const _ = require('underscore');
|
||||
const checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
const REQUIRED_OPTS = [
|
||||
'configModel'
|
||||
];
|
||||
|
||||
module.exports = Backbone.Model.extend({
|
||||
defaults: {
|
||||
selected: false,
|
||||
visible: false,
|
||||
deleted: false
|
||||
},
|
||||
|
||||
fileAttribute: 'resource',
|
||||
|
||||
initialize: function (models, options) {
|
||||
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||||
},
|
||||
|
||||
save: function (attrs, options = {}) {
|
||||
attrs = attrs || _.clone(this.attributes);
|
||||
|
||||
attrs = _.omit(attrs, ['selected', 'visible', 'deleted']);
|
||||
options.data = JSON.stringify(attrs);
|
||||
|
||||
return Backbone.Model.prototype.save.call(this, attrs, options);
|
||||
}
|
||||
});
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
const _ = require('underscore');
|
||||
const CoreView = require('backbone/core-view');
|
||||
const template = require('./organization-icon.tpl');
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
tagName: 'li',
|
||||
|
||||
className: 'IconList-item IconList-item--small',
|
||||
|
||||
events: {
|
||||
'click': '_onClick'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
if (_.isUndefined(options.model)) {
|
||||
throw new Error('An organization icon model is mandatory.');
|
||||
}
|
||||
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.html(template({
|
||||
url: this.model.get('public_url')
|
||||
}));
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this.model, 'change:selected', this._onSelectedChanged);
|
||||
this.listenTo(this.model, 'change:deleted', this._onDeletedChanged);
|
||||
},
|
||||
|
||||
_onClick: function () {
|
||||
this.model.set('selected', !this.model.get('selected'));
|
||||
},
|
||||
|
||||
_onSelectedChanged: function () {
|
||||
this.$el.toggleClass('is-selected', this.model.get('selected'));
|
||||
},
|
||||
|
||||
_onDeletedChanged: function () {
|
||||
if (this.model.get('deleted')) {
|
||||
this.$el.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<div class="IconItem-icon js-asset">
|
||||
<img height="24" src="<%- url %>" alt="icon" crossorigin="anonymous" />
|
||||
</div>
|
||||
+349
@@ -0,0 +1,349 @@
|
||||
const Backbone = require('backbone');
|
||||
const CoreView = require('backbone/core-view');
|
||||
const _ = require('underscore');
|
||||
const IconCollection = require('./organization-icon-collection');
|
||||
const IconView = require('./organization-icon-view');
|
||||
const DeleteIconsDialog = require('./delete-icons-dialog-view');
|
||||
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
|
||||
const template = require('./organization-icons.tpl');
|
||||
const checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
const REQUIRED_OPTS = [
|
||||
'orgId',
|
||||
'configModel'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
|
||||
events: {
|
||||
'click .js-addIcon': '_onAddIconClicked',
|
||||
'click .js-selectAllIcons': '_onSelectAllIconsClicked',
|
||||
'click .js-deselectAllIcons': '_onDeselectAllIconsClicked',
|
||||
'click .js-deleteIcons': '_onDeleteIconsClicked',
|
||||
'change .js-inputFile': '_onFileSelected'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||||
|
||||
this._modals = new ModalsServiceModel();
|
||||
this.model = new Backbone.Model({
|
||||
isProcessRunning: false
|
||||
});
|
||||
this._iconCollection = new IconCollection(null, {
|
||||
orgId: this._orgId,
|
||||
configModel: this._configModel
|
||||
});
|
||||
this._numOfUploadingProcesses = 0;
|
||||
this._numOfDeletingProcesses = 0;
|
||||
this._fetchErrorMessage = 'Error fetching organization icons. Please refresh the page.';
|
||||
this._runningMessage = '';
|
||||
|
||||
this.render();
|
||||
this._fetchAllIcons();
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.html(template());
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this._iconCollection, 'change:selected', this._refreshActions);
|
||||
this.listenTo(this.model, 'change:isProcessRunning', this._onProcessRunningChanged);
|
||||
},
|
||||
|
||||
_fetchAllIcons: function () {
|
||||
this._iconCollection.fetch({
|
||||
success: this._renderAllIcons.bind(this),
|
||||
error: this._onFetchIconsError.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
_renderAllIcons: function () {
|
||||
_.each(this._iconCollection.models, this._addIconElement, this);
|
||||
},
|
||||
|
||||
_onFetchIconsError: function () {
|
||||
this._showErrorMessage(this._fetchErrorMessage);
|
||||
},
|
||||
|
||||
_renderIcon: function (iconModel) {
|
||||
var iconView = new IconView({
|
||||
model: iconModel
|
||||
});
|
||||
iconView.render();
|
||||
iconModel.set('visible', true);
|
||||
this.$('.js-items').append(iconView.$el);
|
||||
},
|
||||
|
||||
_addIconElement: function (iconModel) {
|
||||
this._renderIcon(iconModel);
|
||||
},
|
||||
|
||||
_onAddIconClicked: function (event) {
|
||||
this.killEvent(event);
|
||||
|
||||
this._hideErrorMessage();
|
||||
this.$('.js-inputFile').trigger('click');
|
||||
},
|
||||
|
||||
_parseResponseText: function (response) {
|
||||
if (response && response.responseText) {
|
||||
try {
|
||||
var text = JSON.parse(response.responseText);
|
||||
if (text && text.errors && typeof text.errors === 'string') {
|
||||
return text.errors;
|
||||
}
|
||||
} catch (exc) {
|
||||
// Swallow
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
_getSelectedFiles: function () {
|
||||
return this.$('.js-inputFile').prop('files');
|
||||
},
|
||||
|
||||
_onFileSelected: function () {
|
||||
var files = this._getSelectedFiles();
|
||||
|
||||
_.each(files, function (file) {
|
||||
this._iconCollection.create({
|
||||
kind: 'organization_asset',
|
||||
resource: file
|
||||
}, {
|
||||
beforeSend: this._beforeIconUpload.bind(this),
|
||||
success: this._onIconUploaded.bind(this),
|
||||
error: this._onIconUploadError.bind(this),
|
||||
complete: this._onIconUploadComplete.bind(this)
|
||||
});
|
||||
}, this);
|
||||
},
|
||||
|
||||
_beforeIconUpload: function () {
|
||||
this._numOfUploadingProcesses++;
|
||||
if (this._numOfUploadingProcesses > 0) {
|
||||
this._runningMessage = 'Uploading icons...';
|
||||
this.model.set('isProcessRunning', true);
|
||||
}
|
||||
},
|
||||
|
||||
_onIconUploaded: function (iconModel) {
|
||||
this._resetFileSelection();
|
||||
this._addIconElement(iconModel);
|
||||
},
|
||||
|
||||
_onIconUploadError: function (model, response) {
|
||||
var errorText = this._parseResponseText(response);
|
||||
this._resetFileSelection();
|
||||
this._showErrorMessage(this._uploadErrorMessage(errorText));
|
||||
},
|
||||
|
||||
_onIconUploadComplete: function () {
|
||||
this._numOfUploadingProcesses--;
|
||||
if (this._numOfUploadingProcesses <= 0) {
|
||||
this.model.set('isProcessRunning', false);
|
||||
}
|
||||
},
|
||||
|
||||
_resetFileSelection: function () {
|
||||
this.$('.js-inputFile').val('');
|
||||
},
|
||||
|
||||
_show: function (selector) {
|
||||
this.$(selector).removeClass('is-hidden');
|
||||
},
|
||||
|
||||
_hide: function (selector) {
|
||||
this.$(selector).addClass('is-hidden');
|
||||
},
|
||||
|
||||
_refreshActions: function () {
|
||||
if (this.model.get('isProcessRunning')) {
|
||||
return;
|
||||
}
|
||||
var limit = Math.min(this._iconCollection.length);
|
||||
var numOfSelectedIcons = this._getNumberOfSelectedIcons();
|
||||
var iconText = (numOfSelectedIcons === 1 ? '1 icon selected' : '' + numOfSelectedIcons + ' icons selected');
|
||||
this.$('.js-iconMainLabel').text(iconText);
|
||||
|
||||
if (numOfSelectedIcons === 0) {
|
||||
this.$('.js-iconMainLabel').text('');
|
||||
this._hide('.js-iconMainLabel, .js-selectAllIcons, .js-deselectAllIcons, .js-deleteIcons');
|
||||
this._show('.js-iconsInfo');
|
||||
} else if (numOfSelectedIcons < limit) {
|
||||
this._show('.js-iconMainLabel, .js-selectAllIcons, .js-deleteIcons');
|
||||
this._hide('.js-deselectAllIcons, .js-iconsInfo');
|
||||
} else {
|
||||
this._show('.js-iconMainLabel, .js-deselectAllIcons, .js-deleteIcons');
|
||||
this._hide('.js-selectAllIcons, .js-iconsInfo');
|
||||
}
|
||||
|
||||
if (numOfSelectedIcons > 1) {
|
||||
this.$('.js-deleteIcons a').text('Delete icons...');
|
||||
} else if (numOfSelectedIcons === 1) {
|
||||
this.$('.js-deleteIcons a').text('Delete icon...');
|
||||
}
|
||||
},
|
||||
|
||||
_hideActions: function () {
|
||||
this._hide('.js-selectAllIcons, .js-deselectAllIcons, .js-deleteIcons, .js-iconsInfo');
|
||||
},
|
||||
|
||||
_onDeselectAllIconsClicked: function (event) {
|
||||
event.preventDefault();
|
||||
this._iconCollection.each(function (icon) {
|
||||
icon.set('selected', false);
|
||||
});
|
||||
},
|
||||
|
||||
_onSelectAllIconsClicked: function (event) {
|
||||
event.preventDefault();
|
||||
this._iconCollection.each(function (icon) {
|
||||
if (icon.get('visible')) {
|
||||
icon.set('selected', true);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_onDeleteIconsClicked: function (event) {
|
||||
event.preventDefault();
|
||||
this._openDeleteIconsDialog();
|
||||
},
|
||||
|
||||
_openDeleteIconsDialog: function (event) {
|
||||
this.killEvent(event);
|
||||
|
||||
this._modals.create(modalModel =>
|
||||
new DeleteIconsDialog({
|
||||
modalModel,
|
||||
numOfIcons: this._getNumberOfSelectedIcons(),
|
||||
onSubmit: this._deleteIcons.bind(this)
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
_deleteIcons: function () {
|
||||
this._hideErrorMessage();
|
||||
var iconsToDelete = this._iconCollection.where({ selected: true });
|
||||
|
||||
_.each(iconsToDelete, function (icon) {
|
||||
icon.destroy({
|
||||
beforeSend: this._beforeIconDelete.bind(this),
|
||||
success: this._onIconDeleted.bind(this),
|
||||
error: this._onIconDeleteError.bind(this),
|
||||
complete: this._onIconDeleteComplete.bind(this)
|
||||
});
|
||||
}, this);
|
||||
},
|
||||
|
||||
_getNumberOfSelectedIcons: function () {
|
||||
return this._iconCollection.where({ selected: true }).length;
|
||||
},
|
||||
|
||||
_beforeIconDelete: function () {
|
||||
this._numOfDeletingProcesses++;
|
||||
if (this._numOfDeletingProcesses > 0) {
|
||||
this._runningMessage = 'Deleting icons...';
|
||||
this.model.set('isProcessRunning', true);
|
||||
}
|
||||
},
|
||||
|
||||
_onIconDeleted: function (icon) {
|
||||
icon.set('deleted', true);
|
||||
this._addExtraIcon();
|
||||
},
|
||||
|
||||
_onIconDeleteError: function (icon, response) {
|
||||
var errorText = this._parseResponseText(response);
|
||||
// Even if API throws error the icon has been already removed from the collection.
|
||||
// We must add it again
|
||||
this._iconCollection.add(icon);
|
||||
this._resetSelection();
|
||||
this._showErrorMessage(this._deleteErrorMessage(errorText));
|
||||
},
|
||||
|
||||
_onIconDeleteComplete: function () {
|
||||
this._numOfDeletingProcesses--;
|
||||
if (this._numOfDeletingProcesses <= 0) {
|
||||
this.model.set('isProcessRunning', false);
|
||||
}
|
||||
},
|
||||
|
||||
_showSpinner: function (enable) {
|
||||
if (enable) {
|
||||
this._hide('.js-plusSign');
|
||||
this._show('.js-spinner');
|
||||
} else {
|
||||
this._show('.js-plusSign');
|
||||
this._hide('.js-spinner');
|
||||
}
|
||||
},
|
||||
|
||||
_showErrorMessage: function (message) {
|
||||
this.$('.js-errorMessage label').text(message);
|
||||
this._show('.js-errorMessage');
|
||||
},
|
||||
|
||||
_hideErrorMessage: function () {
|
||||
this._hide('.js-errorMessage');
|
||||
},
|
||||
|
||||
_resetSelection: function () {
|
||||
this._iconCollection.each(function (icon) {
|
||||
icon.set('selected', false);
|
||||
});
|
||||
this._refreshActions();
|
||||
},
|
||||
|
||||
_addExtraIcon: function () {
|
||||
var iconAdded = false;
|
||||
this._iconCollection.each(function (icon) {
|
||||
if (!icon.get('visible') && !iconAdded) {
|
||||
this._addIconElement(icon);
|
||||
iconAdded = true;
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_onProcessRunningChanged: function () {
|
||||
var running = this.model.get('isProcessRunning');
|
||||
this._showSpinner(running);
|
||||
if (running) {
|
||||
this.$el.css('pointer-events', 'none');
|
||||
this._hideActions();
|
||||
this.$('.js-runningInfo').text(this._runningMessage);
|
||||
this._show('.js-runningInfo');
|
||||
} else {
|
||||
this.$('.js-runningInfo').text('');
|
||||
this._hide('.js-runningInfo');
|
||||
this._refreshActions();
|
||||
this._iconCollection.trigger('refreshCollection', { cid: this.cid });
|
||||
this.$el.css('pointer-events', 'auto');
|
||||
}
|
||||
},
|
||||
|
||||
_uploadErrorMessage: function (errorText) {
|
||||
var message = 'Error uploading your image. ';
|
||||
if (errorText) {
|
||||
message += '[ ' + errorText + ' ]. ';
|
||||
}
|
||||
message += 'Please try again.';
|
||||
|
||||
return message;
|
||||
},
|
||||
|
||||
_deleteErrorMessage: function (errorText) {
|
||||
var message = 'Error deleting your image. ';
|
||||
if (errorText) {
|
||||
message += '[ ' + errorText + ' ]. ';
|
||||
}
|
||||
message += 'Please try again.';
|
||||
|
||||
return message;
|
||||
}
|
||||
});
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<div class="FormAccount-rowLabel IconActions">
|
||||
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor u-rSpace--xl js-iconMainLabel is-hidden"></label>
|
||||
<label class="CDB-Text CDB-Size-small u-rSpace--xl u-altTextColor js-iconsInfo">These icons can be used as markers.</label>
|
||||
<label class="CDB-Text CDB-Size-small u-rSpace--xl u-altTextColor js-runningInfo is-hidden"></label>
|
||||
<label class="CDB-Text CDB-Size-medium u-rSpace--xl js-selectAllIcons is-hidden"><a href="#/select_all">Select all</a></label>
|
||||
<label class="CDB-Text CDB-Size-medium u-rSpace--xl js-deselectAllIcons is-hidden"><a href="#/deselect_all">Deselect all</a></label>
|
||||
<label class="CDB-Text CDB-Size-medium js-deleteIcons is-hidden"><a class="IconText is--critical" href="#/delete_icons">Delete icons...</a></label>
|
||||
</div>
|
||||
<div class="FormAccount-rowData js-asset-icons">
|
||||
<ul class="IconList js-items">
|
||||
|
||||
<li class="IconList-item IconList-item--small IconList-item--dashed js-addIcon">
|
||||
<div class="IconItem-icon js-plusSign">
|
||||
<svg width="11px" height="11px" viewBox="15 15 11 11" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<polygon id="Mas" stroke="none" fill="#1785FB" fill-rule="evenodd" points="15 20 15 21 20 21 20 26 21 26 21 21 26 21 26 20 21 20 21 15 20 15 20 20"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="CDB-LoaderIcon is-blue js-spinner is-hidden">
|
||||
<svg class="CDB-LoaderIcon-spinner" viewBox="0 0 50 50">
|
||||
<circle class="CDB-LoaderIcon-path" cx="25" cy="25" r="20" fill="none"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="FormAccount-rowData js-errorMessage is-hidden">
|
||||
<label class="CDB-Text CDB-Size-medium IconText is--critical"></label>
|
||||
</div>
|
||||
<input id="iconfile" class="js-inputFile" type="file" value="Choose icon" accept="image/jpeg,image/jpg,image/gif,image/png,image/svg+xml" tabindex="-1" style="position: absolute; clip: rect(0px 0px 0px 0px); opacity: 0;" multiple>
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
const Backbone = require('backbone');
|
||||
const IconPickerView = require('./icons/organization-icons-view');
|
||||
const OrganizationIconCollection = require('./icons/organization-icon-collection');
|
||||
const IconView = require('./icons/organization-icon-view');
|
||||
const IconPickerDialog = require('./icon-picker-dialog/icon-picker-dialog-view');
|
||||
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
|
||||
const template = require('./organization-icon-picker.tpl');
|
||||
const checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
const REQUIRED_OPTS = [
|
||||
'orgId',
|
||||
'configModel'
|
||||
];
|
||||
|
||||
module.exports = IconPickerView.extend({
|
||||
|
||||
events: IconPickerView.extendEvents({
|
||||
'click .js-viewAllIcons': '_onViewAllIconsClicked'
|
||||
}),
|
||||
|
||||
initialize: function (options) {
|
||||
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||||
|
||||
this._maxIcons = 23;
|
||||
this._modals = new ModalsServiceModel();
|
||||
this.model = new Backbone.Model({
|
||||
isProcessRunning: false
|
||||
});
|
||||
this._iconCollection = new OrganizationIconCollection(null, {
|
||||
orgId: this._orgId,
|
||||
configModel: this._configModel
|
||||
});
|
||||
this._numOfUploadingProcesses = 0;
|
||||
this._numOfDeletingProcesses = 0;
|
||||
this._fetchErrorMessage = 'Error fetching organization icons. Please refresh the page.';
|
||||
this._runningMessage = '';
|
||||
this.teplate = template;
|
||||
|
||||
this.render();
|
||||
this._fetchAllIcons();
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.html(template());
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this._iconCollection, 'change:selected', this._refreshActions);
|
||||
this.listenTo(this._iconCollection, 'refreshCollection', this._refreshCollection);
|
||||
this.listenTo(this.model, 'change:isProcessRunning', this._onProcessRunningChanged);
|
||||
},
|
||||
|
||||
_refreshCollection: function (data) {
|
||||
if (data.cid && this.cid !== data.cid) {
|
||||
this.render();
|
||||
this._fetchAllIcons();
|
||||
}
|
||||
},
|
||||
|
||||
_renderIcon: function (iconModel) {
|
||||
if (iconModel.get('index') < this._maxIcons) {
|
||||
var iconView = new IconView({
|
||||
model: iconModel
|
||||
});
|
||||
iconView.render();
|
||||
iconModel.set('visible', true);
|
||||
this.$('.js-items').append(iconView.$el);
|
||||
}
|
||||
},
|
||||
|
||||
_addIconElement: function (iconModel) {
|
||||
iconModel.set('index', this._getIconIndex(iconModel));
|
||||
this._renderIcon(iconModel);
|
||||
this._refreshActions();
|
||||
},
|
||||
|
||||
_refreshActions: function () {
|
||||
if (this.model.get('isProcessRunning')) {
|
||||
return;
|
||||
}
|
||||
var limit = Math.min(this._maxIcons, this._iconCollection.length);
|
||||
var numOfSelectedIcons = this._getNumberOfSelectedIcons();
|
||||
var iconText = (numOfSelectedIcons === 1 ? '1 icon selected' : '' + numOfSelectedIcons + ' icons selected');
|
||||
this.$('.js-iconMainLabel').text(iconText);
|
||||
|
||||
if (numOfSelectedIcons === 0) {
|
||||
this.$('.js-iconMainLabel').text('Icons');
|
||||
this._hide('.js-selectAllIcons, .js-deselectAllIcons, .js-deleteIcons');
|
||||
this._show('.js-iconsInfo');
|
||||
} else if (numOfSelectedIcons < limit) {
|
||||
this._show('.js-selectAllIcons, .js-deleteIcons');
|
||||
this._hide('.js-deselectAllIcons, .js-iconsInfo');
|
||||
} else {
|
||||
this._hide('.js-selectAllIcons, .js-iconsInfo');
|
||||
this._show('.js-deselectAllIcons, .js-deleteIcons');
|
||||
}
|
||||
|
||||
if (numOfSelectedIcons > 1) {
|
||||
this.$('.js-deleteIcons a').text('Delete icons...');
|
||||
} else if (numOfSelectedIcons === 1) {
|
||||
this.$('.js-deleteIcons a').text('Delete icon...');
|
||||
}
|
||||
|
||||
if (this._iconCollection.length > this._maxIcons) {
|
||||
this._show('.js-viewAllIcons');
|
||||
} else {
|
||||
this._hide('.js-viewAllIcons');
|
||||
}
|
||||
},
|
||||
|
||||
_hideActions: function () {
|
||||
this._hide('.js-selectAllIcons, .js-deselectAllIcons, .js-deleteIcons, .js-iconsInfo, .js-viewAllIcons');
|
||||
},
|
||||
|
||||
_getIconIndex: function (icon) {
|
||||
return this._iconCollection.indexOf(icon);
|
||||
},
|
||||
|
||||
_addExtraIcon: function () {
|
||||
var iconAdded = false;
|
||||
this._iconCollection.each(function (icon) {
|
||||
var index = this._getIconIndex(icon);
|
||||
if (index < this._maxIcons && !icon.get('visible') && !iconAdded) {
|
||||
this._addIconElement(icon);
|
||||
iconAdded = true;
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
_onViewAllIconsClicked: function (event) {
|
||||
this.killEvent(event);
|
||||
|
||||
this._modals.create(modalModel =>
|
||||
new IconPickerDialog({
|
||||
orgId: this._orgId,
|
||||
configModel: this._configModel
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<div class="FormAccount-rowLabel">
|
||||
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor u-rSpace--xl js-iconMainLabel">Icons</label>
|
||||
<label class="CDB-Text CDB-Size-medium u-rSpace--xl js-viewAllIcons is-hidden"><a href="#/view_icons">View all icons</a></label>
|
||||
<label class="CDB-Text CDB-Size-small u-rSpace--xl u-altTextColor js-iconsInfo">These icons can be used as markers.</label>
|
||||
<label class="CDB-Text CDB-Size-small u-rSpace--xl u-altTextColor js-runningInfo is-hidden"></label>
|
||||
<label class="CDB-Text CDB-Size-medium u-rSpace--xl js-selectAllIcons is-hidden"><a href="#/select_all">Select all</a></label>
|
||||
<label class="CDB-Text CDB-Size-medium u-rSpace--xl js-deselectAllIcons is-hidden"><a href="#/deselect_all">Deselect all</a></label>
|
||||
<label class="CDB-Text CDB-Size-medium js-deleteIcons is-hidden"><a class="IconText is--critical" href="#/delete_icons">Delete icons...</a></label>
|
||||
</div>
|
||||
<div class="FormAccount-rowData js-asset-icons">
|
||||
<ul class="IconList js-items">
|
||||
|
||||
<li class="IconList-item IconList-item--small IconList-item--dashed js-addIcon">
|
||||
<div class="IconItem-icon js-plusSign">
|
||||
<svg width="11px" height="11px" viewBox="15 15 11 11" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<polygon id="Mas" stroke="none" fill="#1785FB" fill-rule="evenodd" points="15 20 15 21 20 21 20 26 21 26 21 21 26 21 26 20 21 20 21 15 20 15 20 20"></polygon>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="CDB-LoaderIcon is-blue js-spinner is-hidden">
|
||||
<svg class="CDB-LoaderIcon-spinner" viewBox="0 0 50 50">
|
||||
<circle class="CDB-LoaderIcon-path" cx="25" cy="25" r="20" fill="none"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="FormAccount-rowData js-errorMessage is-hidden">
|
||||
<label class="CDB-Text CDB-Size-medium IconText is--critical"></label>
|
||||
</div>
|
||||
<input id="iconfile" class="js-inputFile" type="file" value="Choose icon" accept="image/jpeg,image/jpg,image/gif,image/png,image/svg+xml" tabindex="-1" style="position: absolute; clip: rect(0px 0px 0px 0px); opacity: 0;" multiple>
|
||||
Reference in New Issue
Block a user