Initial commit
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--medium <% if (disabled) { %>is-disabled<% } %> js-<%- action %> js-action">
|
||||
<span class="CDB-Button-Text CDB-Text is-semibold u-upperCase CDB-Size-small"><%= label %></span>
|
||||
</button>
|
||||
@@ -0,0 +1,73 @@
|
||||
var Backbone = require('backbone');
|
||||
var InfoboxModel = require('./infobox-item-model');
|
||||
var _ = require('underscore');
|
||||
|
||||
/*
|
||||
* Infobox states collection
|
||||
*/
|
||||
|
||||
module.exports = Backbone.Collection.extend({
|
||||
model: InfoboxModel,
|
||||
|
||||
initialize: function () {
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
reset: function (models, options) {
|
||||
this._defaultSelected(models);
|
||||
Backbone.Collection.prototype.reset.call(this, models, options);
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.on('change:selected', this._onSelectedChange, this);
|
||||
this.on('reset', this._defaultSelected, this);
|
||||
},
|
||||
|
||||
_defaultSelected: function (models) {
|
||||
var selected = _.first(_.where(models, {selected: true}));
|
||||
if (!selected) {
|
||||
selected = _.first(models);
|
||||
if (this._isModel(selected)) {
|
||||
selected.set({selected: true}, {silent: true});
|
||||
} else {
|
||||
selected.selected = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onSelectedChange: function (changedModel, isSelected) {
|
||||
if (isSelected) {
|
||||
this.each(function (m) {
|
||||
if (m.cid !== changedModel.cid) {
|
||||
m.set({selected: false}, {silent: true});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getState: function (state) {
|
||||
return _.first(this.where({state: state}));
|
||||
},
|
||||
|
||||
getSelected: function () {
|
||||
var selected;
|
||||
selected = _.first(this.where({selected: true}));
|
||||
return selected;
|
||||
},
|
||||
|
||||
setSelected: function (state) {
|
||||
var selectedModel;
|
||||
|
||||
this.each(function (mdl) {
|
||||
if (mdl.get('state') === state) {
|
||||
mdl.set({selected: true}, {silent: true});
|
||||
selectedModel = mdl;
|
||||
} else {
|
||||
mdl.set({selected: false}, {silent: true});
|
||||
}
|
||||
});
|
||||
|
||||
return selectedModel;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
var InfoboxView = require('./infobox-item-view');
|
||||
|
||||
module.exports = {
|
||||
// Infobox with no buttons, only message
|
||||
createInfo: function (opts) {
|
||||
var closable = opts.closable === undefined ? true : opts.closable;
|
||||
return new InfoboxView({
|
||||
type: opts.type || 'default',
|
||||
title: opts.title,
|
||||
body: opts.body,
|
||||
closable: closable
|
||||
});
|
||||
},
|
||||
|
||||
createWithAction: function (opts) {
|
||||
var closable = opts.closable === undefined ? true : opts.closable;
|
||||
var options = {
|
||||
type: opts.type || 'default',
|
||||
title: opts.title,
|
||||
body: opts.body,
|
||||
closable: closable,
|
||||
klass: opts.className
|
||||
};
|
||||
|
||||
if (opts.action) {
|
||||
options.action = {
|
||||
label: opts.action.label,
|
||||
type: opts.action.type
|
||||
};
|
||||
}
|
||||
|
||||
return new InfoboxView(options);
|
||||
},
|
||||
|
||||
createLoading: function (opts) {
|
||||
return new InfoboxView({
|
||||
type: opts.type || 'default',
|
||||
title: opts.title || '',
|
||||
body: opts.body,
|
||||
loading: true
|
||||
});
|
||||
},
|
||||
|
||||
createQuota: function (opts) {
|
||||
if (opts.closable === undefined) {
|
||||
opts.closable = true;
|
||||
}
|
||||
|
||||
return new InfoboxView(opts);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
var Backbone = require('backbone');
|
||||
|
||||
/*
|
||||
* Infobox item model
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = Backbone.Model.extend({
|
||||
defaults: {
|
||||
selected: false
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,108 @@
|
||||
var CoreView = require('backbone/core-view');
|
||||
var _ = require('underscore');
|
||||
var template = require('./infobox.tpl');
|
||||
var templateButton = require('./infobox-button.tpl');
|
||||
var templateQuota = require('./infobox-quota.tpl');
|
||||
|
||||
var INFOBOX_TYPE = {
|
||||
error: 'is-error',
|
||||
alert: 'is-alert',
|
||||
code: 'is-dark',
|
||||
success: 'is-success',
|
||||
default: ''
|
||||
};
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
events: {
|
||||
'click .js-action': '_onActionClick',
|
||||
'click .js-close': '_onCloseClick'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
if (opts.title === undefined) throw new Error('Title is required');
|
||||
if (opts.body === undefined) throw new Error('Body is required');
|
||||
|
||||
this._title = opts.title;
|
||||
this._body = opts.body;
|
||||
this._loading = opts.loading;
|
||||
this._isClosable = opts.closable;
|
||||
this._klass = opts.klass;
|
||||
|
||||
if (opts.quota) {
|
||||
this._quota = opts.quota;
|
||||
}
|
||||
|
||||
if (opts.action) {
|
||||
this._actionLabel = opts.action.label;
|
||||
this._actionType = opts.action.type;
|
||||
this._actionDisabled = opts.action.disabled;
|
||||
}
|
||||
|
||||
this._type = INFOBOX_TYPE[opts.type || 'default'];
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
this.$el.empty();
|
||||
this._initViews();
|
||||
return this;
|
||||
},
|
||||
|
||||
_initViews: function () {
|
||||
var hasQuota = !_.isEmpty(this._quota);
|
||||
var isLoading = this._loading;
|
||||
|
||||
var view = template({
|
||||
className: this._klass,
|
||||
title: this._title,
|
||||
body: this._body,
|
||||
type: this._type,
|
||||
isLoading: isLoading,
|
||||
hasQuota: hasQuota,
|
||||
hasButtons: this._actionLabel || this._isClosable,
|
||||
isClosable: this._isClosable,
|
||||
closeLabel: _t('editor.messages.common.cancel')
|
||||
});
|
||||
|
||||
this.setElement(view);
|
||||
|
||||
if (this._actionLabel) {
|
||||
this.$('.js-actionPosition').html(
|
||||
templateButton({
|
||||
action: 'action',
|
||||
label: this._actionLabel,
|
||||
type: this._actionType,
|
||||
disabled: this._actionDisabled
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (hasQuota) {
|
||||
var quota = this._quota;
|
||||
var quotaPer = ((quota.usedQuota / quota.totalQuota) * 100);
|
||||
if (isNaN(quotaPer)) {
|
||||
quotaPer = 100;
|
||||
}
|
||||
var progressState = 'fine';
|
||||
if (quotaPer > 75 && quotaPer < 90) {
|
||||
progressState = 'alert';
|
||||
} else if (quotaPer >= 90) {
|
||||
progressState = 'caution';
|
||||
}
|
||||
|
||||
this.$('.js-quota').html(templateQuota({
|
||||
quotaMessage: quota.quotaMessage || '',
|
||||
progressState: progressState,
|
||||
quotaPer: quotaPer
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_onActionClick: function (e) {
|
||||
this.trigger('action:main');
|
||||
},
|
||||
|
||||
_onCloseClick: function (e) {
|
||||
this.trigger('action:close');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
var Backbone = require('backbone');
|
||||
var INFOBOX_DEFAULT_STATE = '';
|
||||
|
||||
/**
|
||||
* View model of a infobox
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = Backbone.Model.extend({
|
||||
|
||||
defaults: {
|
||||
state: INFOBOX_DEFAULT_STATE
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
<label class="CDB-Text CDB-Size CDB-Size-small u-secondaryTextColor"><%- quotaMessage %></label>
|
||||
<div class="Infobox-quotaBar Progress u-tSpace">
|
||||
<div class="Infobox-quotaBarProgress Progress-bar Progress-bar--<%- progressState %>"
|
||||
style="width: <%- quotaPer %>%"
|
||||
></div>
|
||||
</div>
|
||||
@@ -0,0 +1,71 @@
|
||||
var CoreView = require('backbone/core-view');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'infoboxModel',
|
||||
'infoboxCollection'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
this._initBinds();
|
||||
this._setSelectedModel();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
this.$el.empty();
|
||||
this._initViews();
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this._infoboxModel, 'change:state', this._onChangeState);
|
||||
this.listenTo(this._infoboxModel, 'change:visible', this.render);
|
||||
},
|
||||
|
||||
_initViews: function () {
|
||||
var createContentView;
|
||||
|
||||
if (this._selectedModel) {
|
||||
createContentView = this._selectedModel.get('createContentView');
|
||||
this.infoboxView = createContentView();
|
||||
this.$el.append(this.infoboxView.render().el);
|
||||
this.addView(this.infoboxView);
|
||||
this._initSubviewBinds();
|
||||
}
|
||||
},
|
||||
|
||||
_setSelectedModel: function () {
|
||||
var state = this._infoboxModel.get('state');
|
||||
this._selectedModel = this._infoboxCollection.setSelected(state);
|
||||
},
|
||||
|
||||
_onChangeState: function () {
|
||||
this._setSelectedModel();
|
||||
this.render();
|
||||
},
|
||||
|
||||
_initSubviewBinds: function () {
|
||||
this.listenTo(this.infoboxView, 'action:main', this._onAction);
|
||||
this.listenTo(this.infoboxView, 'action:close', this._onClose);
|
||||
},
|
||||
|
||||
_onAction: function () {
|
||||
var action = this._selectedModel.get('onAction');
|
||||
action && action();
|
||||
},
|
||||
|
||||
_onClose: function () {
|
||||
var action = this._selectedModel.get('onClose');
|
||||
if (action) {
|
||||
action();
|
||||
} else {
|
||||
// if no action associated, we still need to hide the infobox
|
||||
this._infoboxModel.set('state', null);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
<div class="Infobox <%- type %> <%- className %>">
|
||||
<div class="u-flex u-justifySpace u-bSpace--m">
|
||||
<h2 class="Infobox-title CDB-Text is-semibold CDB-Size-small u-upperCase u-bSpace--m u-rSpace--m"><%- title %></h2>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="CDB-Text CDB-Size-medium u-bSpace--xl u-flex">
|
||||
<% if (isLoading) { %>
|
||||
<div class="CDB-LoaderIcon is-dark u-rSpace--m">
|
||||
<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>
|
||||
<% } %>
|
||||
<div>
|
||||
<%= body %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="u-flex u-justifySpace u-alignCenter">
|
||||
<% if (hasQuota) { %>
|
||||
<div class="Infobox-quota js-quota"></div>
|
||||
<% } %>
|
||||
<% if (hasButtons) { %>
|
||||
<ul class="Infobox-buttons <% if (hasQuota) { %>Infobox-buttons--quota<% } %>">
|
||||
<% if (isClosable) { %>
|
||||
<li class="Infobox-button">
|
||||
<button class="Infobox-buttonLink CDB-Text is-semibold CDB-Size-small u-upperCase js-close">
|
||||
<%= closeLabel %>
|
||||
</button>
|
||||
</li>
|
||||
<% } %>
|
||||
<li class="Infobox-button Infobox-button--right js-actionPosition"></li>
|
||||
</ul>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user