upgrade ember version to 3.28

This commit is contained in:
Donghuang 2022-06-05 16:44:46 +08:00
parent 799a5f6b1f
commit 7c87aa0fd9
161 changed files with 2495 additions and 10916 deletions

View File

@ -2,6 +2,7 @@ import Ember from 'ember';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
import $ from 'jquery';
let App;
@ -14,7 +15,7 @@ App = Ember.Application.extend({
});
if (config.environment === 'production') {
Ember.$.ajaxSetup({
$.ajaxSetup({
beforeSend(jqXHR, opt) {
opt.url = '/crm-api/' + opt.url;
}

View File

@ -1,4 +1,5 @@
import Ember from 'ember';
import $ from 'jquery';
export default Ember.Component.extend({
classNames: ['container-fluid'],
@ -24,10 +25,10 @@ export default Ember.Component.extend({
didInsertElement() {
let me = this;
me._super(...arguments);
Ember.$('body').removeClass().addClass('login-layout blur-login');
$('body').removeClass().addClass('login-layout blur-login');
},
willDestroy() {
Ember.$('body').removeClass('login-layout blur-login').addClass('no-skin');
$('body').removeClass('login-layout blur-login').addClass('no-skin');
},
actions: {
login() {
@ -35,14 +36,14 @@ export default Ember.Component.extend({
me.validate() || me.get('onLogin')(me.get('model'));
},
loginIdInsertNewline(loginId) {
Ember.Logger.info('Login Id Insert Newline', loginId);
console.info('Login Id Insert Newline', loginId);
this.send('login');
},
loginIdKeyPress(loginId) {
loginId && this.set('errors.loginId', null);
},
passwordInsertNewline(password) {
// Ember.Logger.info('Password Insert Newline', password);
// console.info('Password Insert Newline', password);
this.send('login');
},
passwordKeyPress(password) {

View File

@ -0,0 +1,61 @@
import Component from '@ember/component';
import { getOwner } from '@ember/application';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
export default Component.extend({
toolService: service('tool-service'),
routeName: alias('router.currentRouteName'),
'trim-index': true,
route: computed('routeName', function() {
let me = this;
let routeName = me.get('routeName');
return me.getRoute(me.get('trim-index') ?
routeName.replace(/\.index$/, '') : routeName);
}),
service: computed('routeName', function() {
return this.getService();
}),
params: computed('router.location.lastSetURL', function() {
const me = this;
const routeName = me.get('routeName');
return me.getRouteParams(me.get('trim-index') ?
routeName.replace(/\.index$/, '') : routeName);
}),
getRouteParams(routeName) {
return this.get('route').paramsFor(routeName ||
this.get('trim-index') ?
this.get('routeName').replace(/\.index$/, '')
: this.get('routeName'));
},
getRoute(routeName) {
return getOwner(this).lookup(
'route:' + (routeName || this.get('routeName')));
},
getParentRouteName(routeName) {
return routeName.replace(/\.[^.]+$/, '');
},
getService(name) {
const me = this;
return name ? me.get('toolService').getServiceByRouteName(name) :
me.getRoute().get('service') ||
me.get('toolService').getServiceByRouteName(me.get('routeName'));
},
didReceiveAttrs() {
const me = this;
me._super(...arguments);
me.get('model') ||
me.set('model', me.get('route.controller.model'));
},
getVal() {
const me = this;
const name = me.get('name');
return me.get(name ? 'model.' + name : '__value__');
},
setVal(val) {
const me = this;
const name = me.get('name');
me.set(name ? 'model.' + name : '__value__', val);
}
});

View File

@ -15,7 +15,7 @@ export default Ember.Component.extend(BaseComponentMixin, {
}
}
}
Ember.Logger.info('Breadcrumbs: ', breadcrumbs);
console.info('Breadcrumbs: ', breadcrumbs);
return breadcrumbs;
}),
tabName: 'ul',

View File

@ -1,5 +1,6 @@
import Ember from 'ember';
import BaseComponent from './base-component';
import $ from 'jquery';
export default BaseComponent.extend({
'allow-blank': true,
@ -10,17 +11,17 @@ export default BaseComponent.extend({
'on-updated': false,
actions: {
doEdit() {
var me = this;
const me = this;
me.set('oldValue', me.getFieldValue());
me.set('isEditing', true)
Ember.run.later(() => {
Ember.$('input[type="text"][name="' + me.get('model.id') + '"]').focus();
$('input[type="text"][name="' + me.get('model.id') + '"]', me.element).focus();
}, 320);
},
doUpdate() {
let me = this;
if (me.get('isUpdating')) {
Ember.Logger.info('Cell Is Updating, Ignore.');
console.info('Cell Is Updating, Ignore.');
return;
}
me.set('isUpdating', true);
@ -49,7 +50,7 @@ export default BaseComponent.extend({
}
}
else {
Ember.Logger.info('Editable cell field value not changed.')
console.info('Editable cell field value not changed.')
me.set('isUpdating', false);
}
me.set('isEditing', false);

View File

@ -1,6 +1,7 @@
import Ember from 'ember';
import Component from '@ember/component';
import { computed } from '@ember/object';
import $ from 'jquery'
export default Component.extend({
file: {},
@ -15,7 +16,7 @@ export default Component.extend({
let me = this;
me._super(...arguments);
me.$('input[type=file]').ace_file_input({
$('input[type=file]', me.element).ace_file_input({
no_file: me.get('no-file'),
btn_choose: me.get('btn-choose'),
btn_change: null,
@ -28,17 +29,16 @@ export default Component.extend({
// allowMime: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'],
before_change: function() {
let filename = me.$(this).val();
const filename = $(this).val();
me.set('value', filename);
return true;
},
before_remove: function() {
let filename = me.$(this).val();
me.set('value', null);
return true;
}
}).on('file.error.ace', function(e, info) {
if (me.$(this)[0] === e.target) {
if ($(this)[0] === e.target) {
if (info.error_count['ext'] > 0 || info.error_count['mime'] > 0) {
me.get('message').warn('Invalid file');
}

View File

@ -0,0 +1,17 @@
import BasicComponent from './basic-component';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
export default BasicComponent.extend({
'col-width': 6,
classNames: ['form-group'],
classNameBindings: ['has-error:has-error'],
errors: alias('route.controller.errors'),
'has-error': computed('errors', function() {
return this.get('errors.' + this.get('name'));
}),
hasError: alias('has-error'),
'error-msg': true,
'label-class': 'col-xs-12 col-sm-3 col-md-3',
'input-class': 'col-xs-12 col-sm-5 col-md-5'
});

View File

@ -2,6 +2,7 @@ import Ember from 'ember';
import BaseComponent from './base-component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import $ from 'jquery'
export default BaseComponent.extend({
classNames: ['wizard-actions'],
@ -60,7 +61,7 @@ export default BaseComponent.extend({
if (!me.validate()) {
me.dialog.confirm('Are you sure to submit?', () => {
me.postData().then((m) => {
Ember.Logger.info('Post Model Result: ', m);
console.info('Post Model Result: ', m);
// write back
Ember.setProperties(me.getModel(), m);
me.alertMessage();
@ -83,7 +84,7 @@ export default BaseComponent.extend({
postData() {
let me = this;
let data = me.get('form') ?
new FormData(me.$().closest('form')[0]) :
new FormData($(me.element).closest('form')[0]) :
me.getModel();
let postUrl = me.get('postUrl');
if (postUrl) {

View File

@ -1,5 +1,6 @@
import Ember from 'ember';
import BaseFormInput from './base-form-input';
import $ from 'jquery'
export default BaseFormInput.extend({
classNames: ['form-group'],
@ -41,7 +42,7 @@ export default BaseFormInput.extend({
if (hexColor && (hexColor = hexColor.trim())) {
let rgb = me.hexToRgb(hexColor);
if (rgb) {
Ember.Logger.info('Hex Color Changed.', rgb);
console.info('Hex Color Changed.', rgb);
me.set('lockColor', true);
me.set(me.getFieldPath(), `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 1)`);
me.set('lockColor', false);
@ -53,7 +54,7 @@ export default BaseFormInput.extend({
return 'model.' + this.get('name');
},
getInputEl() {
return this.$('.colorpicker-component');
return $('.colorpicker-component', this.element);
},
rgbaRegex: /\s*rgba\s*\(\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*,\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\s*,\s*(0(?:\.\d+)?|1(?:\.0+)?)\s*\)\s*/i,
rgbaStr2hex(rgba) {

View File

@ -1,13 +1,25 @@
import Ember from 'ember';
import BaseFormInput from './base-form-input';
import BaseFormInput from './form-field';
import { computed } from '@ember/object';
export default BaseFormInput.extend({
classNames: ['form-group'],
classNameBindings: ['hasError:has-error'],
actions: {
onOptionChanged(val) {
let me = this;
me.setVal(val);
options: [],
'value-field': 'value',
'text-field': 'text',
'enabled-field': null,
'hidden-input': true,
loose: true,
'fire-init-change': true,
'values-as-string': true,
'values-splitter': ',',
'col-width': computed('multiple', {
get() {
if (this._col_width) {
return this._col_width;
}
return this.get('multiple') ? 12 : 7;
},
set(key, value) {
return this._col_width = value;
}
}
})
});

View File

@ -1,107 +0,0 @@
import BaseFormInput from './base-form-input';
import { set, observer } from '@ember/object'
import { isNone } from '@ember/utils'
import { uniqBy } from '@ember/object/computed';
import { isArray } from '@ember/array';
export default BaseFormInput.extend({
classNames: ['form-group'],
classNameBindings: ['hasError:has-error'],
uniqueSelected: uniqBy('options', 'selected'),
'value-field': 'value',
'text-field': 'text',
onSelectionChanged: observer('options.@each.selected', function() {
const me = this;
const options = me.get('options');
me.setVal(me.getSelected());
const onChange = me.get('on-change');
onChange && onChange(me.getVal(), options);
}),
didReceiveAttrs() {
const me = this;
me._super(...arguments);
isNone(me.get('options')) && me.set('options', []);
},
didInsertElement() {
const me = this;
me._super(...arguments);
me.prependEmpty();
me.initSelect();
me.$('select.select2').select2({
allowClear: me.get('nullable'),
placeholder: me.get('placeholder') || me.get('label') || 'Please select...'
}).on('change', function(e) {
console.log('select2 change: ', e);
if (e.removed) {
me.unselect(me.findOption(e.removed.id));
}
if (e.added) {
me.select(me.findOption(e.added.id));
}
});
},
didUpdate() {
const me = this;
me._super(...arguments);
me.prependEmpty();
me.$('select.select2').select2('val', me.getSelected());
},
prependEmpty() {
const me = this;
// prepend empty object for nullable
if (me.get('nullable')) {
const firstObject = me.get('options.firstObject');
if (firstObject
&& firstObject[me.get('value-field')]
&& firstObject[me.get('text-field')]) {
me.get('options').unshiftObject({});
}
}
},
initSelect() {
const me = this;
// init select
if (me.get('multiple')) {
const vals = me.getVal();
if (isArray(vals)) {
vals.forEach(v => me.select(me.findOption(v)));
}
else {
me.setVal(me.getSelected());
}
}
else {
const val = me.getVal();
if (!isNone(val)) {
me.select(me.findOption(val));
}
else {
const selected = me.get('options').find(o => o.selected);
if (selected) {
me.setVal(selected[me.get('value-field')]);
}
else {
me.select(me.get('options.firstObject'))
}
}
}
},
findOption(val) {
const me = this;
// val may empty of nullable option
return val ? me.get('options').find(op => op[me.get('value-field')] == val)
: me.get('options.firstObject');
},
select(op) {
op && set(op, 'selected', true);
},
unselect(op) {
op && set(op, 'selected', false);
},
getSelected() {
const me = this;
const selected = me.get('options').filter(o => o.selected).mapBy(me.get('value-field'));
return selected.length > 1 ? selected : selected.length == 1 ? selected[0] : null;
}
});

View File

@ -1,5 +1,5 @@
import Ember from 'ember';
import BaseFormInput from './base-form-input';
import $ from 'jquery'
export default BaseFormInput.extend({
classNames: ['form-group'],
@ -12,7 +12,7 @@ export default BaseFormInput.extend({
},
didInsertElement() {
let me = this;
me.$('input[type=text]').ace_spinner({
$('input[type=text]', me.element).ace_spinner({
value: me.getVal(),
min: me.get('min'),
max: me.get('max'),
@ -21,7 +21,7 @@ export default BaseFormInput.extend({
btn_down_class: 'btn-info'})
.closest('.ace-spinner')
.on('changed.fu.spinbox', function() {
me.setVal(me.$('input[type=text]').val());
me.setVal($('input[type=text]', me.element).val());
});
}
});

View File

@ -1,5 +1,6 @@
import Ember from 'ember';
import BaseFormInput from './base-form-input';
import $ from 'jquery';
export default BaseFormInput.extend({
classNames: ['form-group'],
@ -27,20 +28,20 @@ export default BaseFormInput.extend({
let me = this;
me._super(...arguments);
me.get('type') === 'file' &&
me.$('input[type=file]').ace_file_input({
$('input[type=file]', me.element).ace_file_input({
no_file: 'No File Choosed...',
btn_choose: 'Choose',
btn_change: 'Change',
droppable: true,
before_change: function() {
let filename = Ember.$(this).val();
Ember.Logger.info('Before File [' + filename + '] Changed.');
const filename = $(this.element).val();
console.info('Before File [' + filename + '] Changed.');
me.setFilename(filename);
return true;
},
before_remove: function() {
let filename = Ember.$(this).val();
Ember.Logger.info('Before File [' + filename + '] Removed.');
const filename = $(this.element).val();
console.info('Before File [' + filename + '] Removed.');
me.setFilename(null);
return true;
},

View File

@ -1,11 +1,12 @@
import Ember from 'ember';
import $ from 'jquery';
export default Ember.Component.extend({
classNames: ['page-content', 'no-padding', 'desktop'],
init() {
let me = this;
me._super(...arguments);
Ember.$(window).on('resize', Ember.run.bind(me, me.onWindowResize));
$(window).on('resize', Ember.run.bind(me, me.onWindowResize));
},
didInsertElement() {
let me = this;
@ -13,6 +14,6 @@ export default Ember.Component.extend({
me.onWindowResize();
},
onWindowResize() {
this.$().height(Ember.$(window).height() - 86 - 60);
$(this.element).height($(window).height() - 86 - 60);
}
});

View File

@ -1,6 +1,6 @@
import Ember from 'ember';
import Component from '@ember/component';
import { computed } from '@ember/object';
import $ from 'jquery'
export default Component.extend({
image: {},
@ -13,7 +13,7 @@ export default Component.extend({
let me = this;
me._super(...arguments);
me.$('input[type=file]').ace_file_input({
$('input[type=file]', me.element).ace_file_input({
no_file: 'Choose Image',
btn_choose: 'Choose Image',
btn_change: null,
@ -26,19 +26,19 @@ export default Component.extend({
allowMime: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'],
before_change: function() {
let filename = me.$(this).val();
Ember.Logger.info('Before image [' + filename + '] changed.');
let filename = $(this).val();
console.info('Before image [' + filename + '] changed.');
me.set('value', filename);
return true;
},
before_remove: function() {
let filename = me.$(this).val();
Ember.Logger.info('Before image [' + filename + '] removed.');
let filename = $(this).val();
console.info('Before image [' + filename + '] removed.');
me.set('value', null);
return true;
}
}).on('file.error.ace', function(e, info) {
if (me.$(this)[0] === e.target) {
if ($(this)[0] === e.target) {
if (info.error_count['ext'] > 0 || info.error_count['mime'] > 0) {
me.get('message').warn('Invalid image');
}

View File

@ -15,7 +15,7 @@ export default Component.extend({
didReceiveAttrs() {
let me = this;
let images = me.get('images');
if (Ember.$.type(images) === 'string') {
if ($.type(images) === 'string') {
let sep = me.get('separator');
me.set('images', sep ? images.split(sep) : [images]);
}
@ -26,7 +26,7 @@ export default Component.extend({
let rel = me.get('elementId') + '_preview';
let $overflow = '';
me.$('a[data-rel="' + rel + '"]').colorbox({
$('a[data-rel="' + rel + '"]', me.element).colorbox({
rel: rel,
reposition: true,
// scalePhotos: true,
@ -46,7 +46,7 @@ export default Component.extend({
document.body.style.overflow = $overflow;
},
onComplete: function() {
Ember.$.colorbox.resize();
$.colorbox.resize();
}
});

View File

@ -0,0 +1,150 @@
import BasicComponent from './basic-component';
import { observer } from '@ember/object';
import { A } from '@ember/array';
import $ from 'jquery';
export default BasicComponent.extend({
tagName: 'x-fake-el',
options: [],
'value-field': 'value',
'text-field': 'text',
'enabled-field': null,
'hidden-input': true,
loose: true,
'fire-init-change': true,
'values-as-string': true,
'values-splitter': ',',
didReceiveAttrs() {
const me = this;
me._super(...arguments);
// select first
if (!me.get('multiple') &&
!me.get('nullable')) {
const options = me.get('options');
if (options && options.length) {
const val = me._getVal();
// no val or val not in options
if (!val || !options.any(o => me.opEq(o, val))) {
me._setVal(me.getOpVal(options[0]));
}
}
}
},
didInsertElement() {
const me = this;
me._super(...arguments);
$(me.element).children('select.select2').select2({
multiple: me.get('multiple'),
disabled: me.get('readonly'),
allowClear: me.get('nullable'),
placeholder: me.get('placeholder') ||
me.get('label') || 'Please select...',
templateResult: me.get('tplResult'),
templateSelection: me.get('tplSelection')
}).on('change', function(e) {
console.log('selection change: ', e);
const selected = $(this).select2('data');
if (me.get('multiple')) {
me._setVal(selected ? selected.map(o => o.id) : []);
}
else {
const o = selected ? selected[0] : null;
me._setVal(o ? o.id : null);
}
me.notifyChange();
})
// init val, trigger change required
.val(me._getVal()).trigger('change');
if (me.get('fire-init-change')) {
me.notifyChange();
}
},
optionsChanged: observer('options', function() {
const me = this;
me.set('optionsUpdated', true);
}),
didUpdate() {
const me = this;
me._super(...arguments);
if (me.get('optionsUpdated')) {
me.set('optionsUpdated', false);
const options = me.get('options');
const jqEl = $(me.element).children('select.select2');
if (me.get('multiple')) {
me._setVal([]);
// clear selection
jqEl.val(null).trigger('change');
}
else {
const val = me._getVal();
// reset old val
if (val && me.findOption(val)) {
jqEl.val(val).trigger('change');
}
else {
const firstOption = options[0];
if (firstOption && !me.get('nullable')) {
me._setVal(me.getOptVal(firstOption));
jqEl.val(val).trigger('change');
}
else {
me._setVal(null);
jqEl.val(null).trigger('change');
}
}
}
}
},
findOption(val) {
const me = this;
return me.get('options').find(op => me.opEq(op, val));
},
notifyChange() {
const me = this;
const options = me.get('options');
const onChange = me.get('on-change');
onChange && onChange(me._getVal(), options);
},
_getVal() {
const me = this;
const val = me.getVal();
if (me.get('multiple')
&& typeof val === 'string'
&& me.get('values-as-string')) {
return A(val ? val.split(me.get('values-splitter')) : []);
}
return val;
},
_setVal(val) {
const me = this;
me.setVal(me.get('multiple')
&& me.get('values-as-string') ?
(val.length ? val.join(me.get('values-splitter')) : null) :
val);
},
isPlainVal(val) {
return typeof val === 'string' ||
typeof val === 'number' ||
typeof val === 'boolean' ||
(
(!!val && typeof val === 'object') &&
['[object String]',
'[object Number]',
'[object Boolean]'
].includes(Object.prototype.toString.call(val))
)
},
getOpVal(op) {
const me = this;
return me.isPlainVal(op) ? op : op[me.get('value-field')];
},
opEq(op, val) {
const me = this;
let opv = me.getOpVal(op);
return me.get('loose') ? opv == val : opv === val;
}
});

View File

@ -9,7 +9,7 @@ export default Ember.Component.extend({
let me = this;
let max = me.get('max');
if (!Ember.isNone(max) && me.get('value') == max) {
Ember.Logger.info('Spinner increase to max: ', max);
console.info('Spinner increase to max: ', max);
return;
}
this.incrementProperty('value');
@ -18,7 +18,7 @@ export default Ember.Component.extend({
let me = this;
let min = me.get('min');
if (!Ember.isNone(min) && me.get('value') == min) {
Ember.Logger.info('Spinner decrease to min: ', min);
console.info('Spinner decrease to min: ', min);
return;
}
this.decrementProperty('value');

View File

@ -1,18 +1,19 @@
import Ember from 'ember';
import Component from '@ember/component';
import $ from 'jquery'
export default Ember.Component.extend({
export default Component.extend({
classNames: ['issue-cell'],
didReceiveAttrs() {
let me = this;
const me = this;
me._super(...arguments);
const issue = me.get('issue').replace(/\r?\n/g, '<br />');
me.set('issuePopover', issue);
me.set('issueHtml', Ember.String.htmlSafe(issue));
},
didInsertElement() {
let me = this;
const me = this;
me._super(...arguments);
me.$('[data-rel=popover]').popover({
$('[data-rel=popover]', me.element).popover({
html: true,
trigger: 'hover',
delay: { show: 300, hide: 100 }

View File

@ -1,13 +1,14 @@
import Ember from 'ember';
import Component from '@ember/component';
import $ from 'jquery'
export default Ember.Component.extend({
export default Component.extend({
elementId: 'main-container',
classNames: ['main-container'],
sidebarCollapsed: false,
didInsertElement() {
let me = this;
me._super(...arguments);
// Ember.$('body').removeClass().addClass('login-layout blur-login');
// $('body').removeClass().addClass('login-layout blur-login');
(function($) {
basics();
enableSidebar();
@ -427,6 +428,6 @@ export default Ember.Component.extend({
}
}
})(Ember.$); //jQuery document ready
})($); //jQuery document ready
},
});

View File

@ -1,5 +1,6 @@
import Component from '@ember/component'
import BaseComponentMixin from '../mixins/components/base-component';
import $ from 'jquery'
export default Component.extend(BaseComponentMixin, {
classNames: ['modal', 'fade'],
@ -12,11 +13,11 @@ export default Component.extend(BaseComponentMixin, {
let me = this;
me._super(...arguments);
if (me.get('init-modal')) {
me.$().modal({
$(me.element).modal({
backdrop: me.get('backdrop'),
keyboard: me.get('keyboard')
}).on('hidden.bs.modal', ()=> {
me.$() && me.get('close-to-parent') &&
$(me.element) && me.get('close-to-parent') &&
me.get('router').transitionTo(
me.get('parentRouteName') ||
me.get('routeName').replace(/\.[^.]+$/, ''));
@ -29,6 +30,6 @@ export default Component.extend(BaseComponentMixin, {
}
},
willDestroyElement() {
this.$().modal('hide');
$(this.element).modal('hide');
}
});

View File

@ -16,7 +16,7 @@ export default BaseComponent.extend({
currPage: computed('params.page', function() {
let me = this;
let currPage = parseInt(me.get('params.page'));
Ember.Logger.info('Get current page [' + currPage + ']');
console.info('Get current page [' + currPage + ']');
return currPage;
}),
pages: computed('total', function() {
@ -77,7 +77,7 @@ export default BaseComponent.extend({
let me = this;
let router = me.get('router');
let params = me.get('params');
Ember.Logger.info('Go to page [' + page + '], params: ', params);
console.info('Go to page [' + page + '], params: ', params);
router.transitionTo(me.get('routeName'), page, {queryParams: params});
}
}

View File

@ -1,6 +1,7 @@
import Ember from 'ember';
import Component from '@ember/component';
import $ from 'jquery'
export default Ember.Component.extend({
export default Component.extend({
classNames: ['btn-group'],
didReceiveAttrs() {
let me = this;
@ -13,7 +14,7 @@ export default Ember.Component.extend({
}
// let label = me.get('label');
let label = null;
me.set('qrConfigMerged', Ember.$.extend({
me.set('qrConfigMerged', $.extend({
// render method: 'canvas', 'image' or 'div'
render: 'canvas',
@ -74,6 +75,6 @@ export default Ember.Component.extend({
}
},
renderQrCode() {
this.$('.qr-code').qrcode(this.get('qrConfigMerged'));
$('.qr-code', this.element).qrcode(this.get('qrConfigMerged'));
}
});

View File

@ -22,7 +22,7 @@ export default Ember.Component.extend({
remove() {
let me = this;
let criterion = me.get('criterion');
Ember.Logger.info('Remove Criterion: ', criterion);
console.info('Remove Criterion: ', criterion);
let removeAction = me.get('removeCriterion');
removeAction && removeAction(criterion);
},

View File

@ -1,13 +1,14 @@
import Ember from 'ember';
import Component from '@ember/component';
import $ from 'jquery'
export default Ember.Component.extend({
export default Component.extend({
tagName: 'ul',
classNames: ['item-list'],
didInsertElement() {
let me = this;
me._super(...arguments);
me.set('prevIds', me.get('model').mapBy('id'));
me.$().sortable({
$(me.element).sortable({
opacity: 0.8,
revert: true,
forceHelperSize: true,
@ -21,8 +22,8 @@ export default Ember.Component.extend({
if (me.get('onSortStopped')) {
let prevIds = me.get('prevIds');
let changed = false;
let ids = Array.prototype.map.call(me.$('li'), (li, i) => {
let id = Ember.$(li).data('item-id');
let ids = Array.prototype.map.call($('li', me.element), (li, i) => {
let id = $(li).data('item-id');
if (id !== prevIds[i] && !changed) {
changed = true;
}

View File

@ -1,25 +1,30 @@
import Ember from 'ember';
import { set, computed } from '@ember/object';
import BaseComponentMixin from '../mixins/components/base-component';
import BaseComponent from './basic-component';
export default Ember.Component.extend(BaseComponentMixin, {
export default BaseComponent.extend({
tagName: 'span',
classNames: ['cursor-pointer'],
'dialog-title': 'Data Filter',
'dialog-title': null,
'full-width': false,
'value-field': 'value',
'text-field': 'text',
filtered: computed('options.@each.selected', function() {
const options = this.get('options');
return options && options.filterBy('selected', 'selected').length > 0;
}),
'values-as-string': false,
loose: true,
filtered: [],
didReceiveAttrs() {
let me = this;
let filters = me.getFilters()[me.get('name')];
const me = this;
me._super(...arguments);
const filters = me.getFilters()[me.get('name')];
if (filters && filters.length) {
const valField = me.get('value-field');
me.get('options').forEach(option => {
filters.find(val => val == option[valField]) && set(option, 'selected', 'selected');
me.setProperties({
filtered: filters,
hasFilter: true
});
}
else {
me.setProperties({
filtered: [],
hasFilter: false
});
}
},
@ -41,13 +46,16 @@ export default Ember.Component.extend(BaseComponentMixin, {
me.set('showModal', false);
},
onModalSubmit() {
let me = this;
const me = this;
me.set('showModal', false);
let filters = me.getFilters();
const valField = me.get('value-field');
filters[me.get('name')] = me.get('options').filter(f => f.selected).map(f => f[valField]);
me.set('route.controller.filters', JSON.stringify(filters));
me.get('router').transitionTo(me.get('routeName'), 1);
const filters = me.getFilters();
const filtered = me.get('filtered');
filters[me.get('name')] = filtered;
me.set('hasFilter', !!filtered.length);
me.get('route.controller').setProperties({
page: 1,
filters: JSON.stringify(filters)
});
}
}
});

View File

@ -2,14 +2,14 @@ import Ember from 'ember';
import BaseComponent from './base-component';
export default BaseComponent.extend({
elementId: 'navbar',
// elementId: 'navbar',
classNames: ['navbar', 'navbar-default', 'navbar-collapse'],
user: Ember.computed.alias('ajax.user'),
didReceiveAttrs() {
let me = this;
let user = me.get('user');
if (!user) {
Ember.Logger.info('No User Found In Session Storage, Try To Load From Cloud');
console.info('No User Found In Session Storage, Try To Load From Cloud');
me.ajax.doGet(false, 'auth/info', (u) => {
me.set('user', u);
});

View File

@ -1,14 +1,12 @@
import Ember from 'ember';
import Component from '@ember/component';
import $ from 'jquery'
export default Ember.Component.extend({
export default Component.extend({
classNames: ['widget-box', 'widget-color-blue2'],
didReceiveAttrs() {
let me = this;
},
didInsertElement() {
let me = this;
const me = this;
me._super(...arguments);
me.$('div.widget-main > div').treeview({
$('div.widget-main > div', me.element).treeview({
data: me.get('data')
});
}

View File

@ -1,12 +1,12 @@
import Ember from 'ember';
import BaseFormInput from './base-form-input';
import $ from 'jquery'
export default BaseFormInput.extend({
didInsertElement() {
const me = this;
me._super(...arguments);
//intialize wysiwyg editor
me.$('.wysiwyg-editor').ace_wysiwyg({
$('.wysiwyg-editor', me.element).ace_wysiwyg({
toolbar: [
'font',
null,
@ -38,7 +38,7 @@ export default BaseFormInput.extend({
'redo'
]
}).on('DOMSubtreeModified propertychange', function() {
me.setVal(Ember.$(this).html());
me.setVal($(this).html());
}).html(me.getVal()).prev().addClass('wysiwyg-style2');
}
});

View File

@ -1,7 +1,7 @@
import Ember from 'ember';
export function array(params/*, hash*/) {
Ember.Logger.info('Array: ', params);
console.info('Array: ', params);
return params;
}

View File

@ -0,0 +1,8 @@
import { helper } from '@ember/component/helper';
import { isNone as isN } from '@ember/utils';
export function isNone([param]) {
return isN(param);
}
export default helper(isNone);

View File

@ -0,0 +1,16 @@
import { helper } from '@ember/component/helper';
export function isPlainVal([val]) {
return typeof val === 'string' ||
typeof val === 'number' ||
typeof val === 'boolean' ||
(
(!!val && typeof val === 'object') &&
['[object String]',
'[object Number]',
'[object Boolean]'
].includes(Object.prototype.toString.call(val))
);
}
export default helper(isPlainVal);

View File

@ -0,0 +1,7 @@
import { helper } from '@ember/component/helper';
export function jsonStr([param]) {
return JSON.stringify(param);
}
export default helper(jsonStr);

View File

@ -2,7 +2,7 @@ import { helper } from '@ember/component/helper';
export function localProductHasPerm(params/*, hash*/) {
const user = params[0];
return user.admin || ['leli', 'chyxion'].includes(user.account);
return user.admin || ['leli', 'donghuang'].includes(user.account);
}
export default helper(localProductHasPerm);

View File

@ -1,7 +1,8 @@
import Ember from 'ember';
import $ from 'jquery'
export function objMerge(params) {
return Ember.$.extend(true, {}, ...params);
return $.extend(true, {}, ...params);
}
export default Ember.Helper.helper(objMerge);

View File

@ -1,7 +1,7 @@
import Ember from 'ember';
export function objQueryParams(params, hash) {
Ember.Logger.debug('Obj Query Params: ', params, hash);
console.debug('Obj Query Params: ', params, hash);
return Ember.Object.create({
isQueryParams: true,
values: hash.length > 0 ? hash : params[0]

View File

@ -2,16 +2,18 @@
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<title>Lemo CRM</title>
<meta name="description" content="Lemo CRM" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
{{content-for 'head'}}
<link rel="stylesheet" href="assets/css/emberjs.css">
<link rel="shortcut icon" type="image/png" href="assets/images/lemo-favicon.png">
<link rel="stylesheet" href="assets/css/vendor.css">
<link rel="stylesheet" href="assets/css/main.css">
<link rel="shortcut icon" type="image/png" href="assets/images/lemo-favicon.png">
<script src="assets/js/emberjs.js"></script>
<script src="assets/js/vendor.js"></script>
<script src="assets/js/main.js"></script>
<!--[if lte IE 9]>
<link rel="stylesheet" href="assets/css/ace-part2.css" />
@ -23,18 +25,15 @@
<script src="assets/js/respond.js"></script>
<![endif]-->
<script type="text/javascript">
if ('ontouchstart' in document.documentElement) {
if ('ontouchstart' in document.documentElement) {
document.write('<script src="assets/js/jquery.mobile.custom.js">' + '<' + '/script>');
}
</script>
</script>
{{content-for 'head-footer'}}
</head>
<body>
{{content-for 'body'}}
<script src="assets/js/emberjs.js"></script>
<script src="assets/js/vendor.js"></script>
<script src="assets/js/main.js"></script>
{{content-for 'body-footer'}}
</body>
</html>

View File

@ -1,8 +1,10 @@
import Ember from 'ember';
import $ from 'jquery';
export function initialize(/* appInstance */) {
// appInstance.inject('route', 'foo', 'service:foo');
Ember.$.fn.tooltip.Constructor.DEFAULTS.template =
$(function() {
$.fn.tooltip.Constructor.DEFAULTS.template =
'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><pre class="tooltip-inner"></pre></div>';
});
Ember.Component.reopen({
didInsertElement() {
@ -20,11 +22,11 @@ export function initialize(/* appInstance */) {
if (!('ontouchstart' in document.documentElement)) {
if ('tooltip' === me.get('data-rel')
&& me.get('title')) {
me.$().tooltip();
$(me.element).tooltip();
}
// may cause error
try {
me.$('[data-rel=tooltip]').tooltip();
$('[data-rel=tooltip]', me.element).tooltip();
}
catch(e) {
Ember.Logger.warn('Init tooltip error caused', e);

View File

@ -1,4 +1,5 @@
import Ember from 'ember';
import $ from 'jquery'
export default Ember.Mixin.create({
store: Ember.inject.service(),
@ -8,11 +9,11 @@ export default Ember.Mixin.create({
createConstraints: null,
updateConstraints: null,
find(params) {
Ember.Logger.debug('Find Model: ', params);
console.debug('Find Model: ', params);
return this._getStore().find(this.get('modelName'), params);
},
list(start, limit, params) {
Ember.Logger.debug('List Models Start: ', start, ', Limit: ', limit, ", Search: ", params);
console.debug('List Models Start: ', start, ', Limit: ', limit, ", Search: ", params);
return this._getStore().list(this.get('modelName'), start, limit, params);
},
listPage(page, params) {
@ -22,16 +23,16 @@ export default Ember.Mixin.create({
return me.list((page - 1) * pageSize, pageSize, params);
},
create(model) {
Ember.Logger.debug('Create Model: ', model);
console.debug('Create Model: ', model);
return this._getStore().create(this.get('modelName'), model);
},
update(model, defaultPromise) {
Ember.Logger.debug('Update Model: ', model);
console.debug('Update Model: ', model);
let me = this;
let p = me._getStore().update(me.get('modelName'), model);
if (defaultPromise) {
p.then((m) => {
Ember.Logger.debug('After Update: ', m);
console.debug('After Update: ', m);
!(model instanceof FormData) &&
Object.keys(m).forEach((prop) => {
Ember.set(model, prop, m[prop]);
@ -42,7 +43,7 @@ export default Ember.Mixin.create({
return p;
},
del(params) {
Ember.Logger.debug('Update Model: ', params);
console.debug('Update Model: ', params);
return this._getStore().del(this.get('modelName'), params);
},
ajaxGet(path, params) {
@ -53,12 +54,12 @@ export default Ember.Mixin.create({
},
validate(model, constraints) {
let me = this;
Ember.Logger.debug('Validate Model: ', model);
console.debug('Validate Model: ', model);
if (constraints) {
if (Ember.$.type(constraints) === 'string') {
if ($.type(constraints) === 'string') {
constraints = me.get(constraints);
}
else if (Ember.$.type(constraints) !== 'object') {
else if ($.type(constraints) !== 'object') {
validation = me.get('constraints');
}
}
@ -68,13 +69,13 @@ export default Ember.Mixin.create({
return validate(model, constraints || me.get('constraints'));
},
createValidate(model) {
Ember.Logger.debug('Create Validate Model: ', model);
console.debug('Create Validate Model: ', model);
let me = this;
let constraints = me.get('createConstraints') || me.get('constraints') || null;
return constraints && validate(model, constraints);
},
updateValidate(model) {
Ember.Logger.debug('Update Validate Model: ', model);
console.debug('Update Validate Model: ', model);
let me = this;
let constraints = me.get('updateConstraints') || me.get('constraints') || null;
return constraints && validate(model, constraints);

View File

@ -1,5 +1,6 @@
import Ember from 'ember';
import Route from '@ember/routing/route';
import $ from 'jquery'
export default Route.extend({
getLoginRoute() {
@ -11,18 +12,18 @@ export default Route.extend({
}
},
beforeModel: function(transition) {
Ember.Logger.info('Before Application Model.', transition);
console.info('Before Application Model.', transition);
this.transitionIntercept(transition);
},
activate() {
Ember.Logger.info('Application Activate.');
Ember.$('body').addClass('no-skin');
console.info('Application Activate.');
$('body').addClass('no-skin');
try{ace.settings.check('navbar', 'fixed');}catch(e){console.log(e)}
try{ace.settings.check('main-container', 'fixed');}catch(e){console.log(e)}
},
actions: {
loading(transition, originRoute) {
Ember.Logger.info('Application Loading...');
console.info('Application Loading...');
// var appCtrl = this.controllerFor('application');
this.router.one('didTransition', function() {
// appCtrl.set('loading', false);
@ -30,7 +31,7 @@ export default Route.extend({
return true;
},
willTransition(transition) {
Ember.Logger.info('Application Will Transition.', transition);
console.info('Application Will Transition.', transition);
this.transitionIntercept(transition);
},
goback() {

View File

@ -1,11 +1,12 @@
import Ember from 'ember';
import BaseRoute from './base';
import $ from 'jquery'
export default BaseRoute.extend({
model(params, transition) {
let me = this;
let extParams = null;
if (Ember.$.type(me.extraParams) === 'function') {
if ($.type(me.extraParams) === 'function') {
extParams = me.extraParams(params, transition);
}
if (Object.getOwnPropertyNames(params).length === 0 &&
@ -13,6 +14,6 @@ export default BaseRoute.extend({
params = transition.params[me.routeName.replace(/\.index$/, '')];
}
return me.get('service').find(
extParams ? Ember.$.extend(true, params, extParams) : params);
extParams ? $.extend(true, params, extParams) : params);
}
});

View File

@ -23,7 +23,7 @@ export default BaseListRoute.extend({
actions: {
select(it, selected) {
let me = this;
Ember.Logger.info('select: ', it, selected);
console.info('select: ', it, selected);
if (selected) {
me.set('controller.selectedId', it.id);
me.set('controller.selectedModel', it);
@ -41,7 +41,7 @@ export default BaseListRoute.extend({
if (itId) {
let it = me.get('controller.selectedModel');
if (it) {
Ember.Logger.info('select: ', it);
console.info('select: ', it);
Ember.set(parentModel, me.get('controller.idField'), itId);
Ember.set(parentModel, me.get('controller.nameField'), it.name);
}
@ -51,7 +51,7 @@ export default BaseListRoute.extend({
Ember.set(parentModel, me.get('controller.idField'), '');
Ember.set(parentModel, me.get('controller.nameField'), '');
}
me.transitionTo(parentRouteName);
me.router.transitionTo(parentRouteName);
}
},
getParentRouteName() {

View File

@ -1,5 +1,6 @@
import Ember from 'ember';
import BaseRoute from './base';
import $ from 'jquery'
export default BaseRoute.extend({
queryParams: {
@ -20,10 +21,10 @@ export default BaseRoute.extend({
mergeParams(params, transition) {
let me = this;
let extParams = null;
if (Ember.$.type(me.extraParams) === 'function') {
if ($.type(me.extraParams) === 'function') {
extParams = me.extraParams(params, transition);
}
return extParams ? Ember.$.extend(true, params, extParams) : params;
return extParams ? $.extend(true, params, extParams) : params;
},
getPage(params) {
let page = params.page;

View File

@ -10,11 +10,11 @@ export default Route.extend({
const routeName = me.get('routeName');
let service = me.get('toolService').getServiceByRouteName(routeName);
if (service) {
Ember.Logger.info(`Set Route [${routeName}] Service [${service}]`);
console.info(`Set Route [${routeName}] Service [${service}]`);
me.set('service', service);
}
else {
Ember.Logger.info(`No Service Found For Route [${routeName}]`);
console.info(`No Service Found For Route [${routeName}]`);
}
}
me._super(...arguments);

View File

@ -6,6 +6,6 @@ export default BaseListRoute.extend({
const me = this;
me._super(...arguments);
const user = me.get('ajax.user');
model.adminOrOwner = user.admin || model.data.filterBy('owner', user.id).length > 0;
model.adminOrOwner = (user && user.admin || model.data.filterBy('owner', user.id).length > 0);
}
});

View File

@ -5,7 +5,7 @@ export default BaseEditRoute.extend({
afterModel(model) {
let me = this;
let customerId = model.customerId;
Ember.Logger.info('edit: ', model);
console.info('edit: ', model);
me.set('breadcrumbs',
[{route: 'customer.list', params: 1, text: 'Customers'},
{route: 'customer.show', params: customerId, text: 'Customer [' + customerId + ']'},

View File

@ -61,14 +61,14 @@ export default Ember.Route.extend({
},
actions: {
addCriterion() {
Ember.Logger.info('Add Criterion.');
console.info('Add Criterion.');
this.get('controller.model.criteria').pushObject({
col: 'name',
op: 'eq'
});
},
removeCriterion(criterion) {
Ember.Logger.info('Route Remove Criterion: ', criterion);
console.info('Route Remove Criterion: ', criterion);
this.get('controller.model.criteria').removeObject(criterion);
},
query() {

View File

@ -13,10 +13,9 @@ export default Ember.Route.extend({
let me = this;
me.get('ajax').doPost('auth/login', model,
function(user) {
Ember.Logger.debug(`User ${user} Loggedin`);
console.debug(`User ${user} Loggedin`);
me.set('ajax.user', user);
me.message.alert('Sign in successfully');
// me.transitionTo('/');
window.location.href = '/';
$.trigger('LOGINED', true);
}, function(msg) {

View File

@ -9,7 +9,7 @@ export default BaseListRoute.extend({
},
breadcrumbs: [{text: 'Week Goal'}],
afterModel(model) {
Ember.Logger.info('after model: ', model);
console.info('after model: ', model);
model.groupData = [];
model.data.forEach(it => {
let group = model.groupData.findBy('userId', it.userId);
@ -22,6 +22,6 @@ export default BaseListRoute.extend({
model.groupData.forEach(g => {
g.data = g.data.sortBy('year').reverse();
});
Ember.Logger.info('after model grouped: ', model);
console.info('after model grouped: ', model);
}
});

View File

@ -33,7 +33,7 @@ export default BaseListRoute.extend({
},
actions: {
onUpdated(ytdSum) {
Ember.Logger.info('on updated: ', ytdSum);
console.info('on updated: ', ytdSum);
this.set('controller.model.ytdSum', ytdSum);
}
}

View File

@ -73,7 +73,7 @@ export default Ember.Service.extend({
}
}
else if (r.errcode === 4011) {
$.trigger('NOT_LOGIN', true);
// $.trigger('NOT_LOGIN', true);
Ember.getOwner(me).lookup('route:application').transitionTo('login');
}
// ignore fail callback

View File

@ -1,4 +1,5 @@
import Ember from 'ember';
import $ from 'jquery'
export default Ember.Service.extend({
alert(msg) {
@ -11,7 +12,7 @@ export default Ember.Service.extend({
danger: {
label: 'Close',
className: 'btn-danger',
callback: fnClose || Ember.$.noop
callback: fnClose || $.noop
}
}
});
@ -28,7 +29,7 @@ export default Ember.Service.extend({
danger: {
label: 'Cancel',
className: 'btn-danger',
callback: fnNo || Ember.$.noop
callback: fnNo || $.noop
}
}
});

View File

@ -1,4 +1,5 @@
import Ember from 'ember';
import $ from 'jquery'
export default Ember.Service.extend({
alert(msg) {
@ -8,7 +9,7 @@ export default Ember.Service.extend({
this._show_alert_(msg, '#F6F0F0');
},
_show_alert_(msg, bg) {
Ember.$([
$([
'<div style="position: absolute; left: 50%; top: -24px; z-index: 20480;">',
'<div style="position: relative; left: -50%; width: 320px; ">',
'<div style="border-radius: 8px; ',
@ -21,10 +22,10 @@ export default Ember.Service.extend({
'</p>',
'</div></div></div>'
].join(''))
.prependTo(Ember.$('body'))
.prependTo($('body'))
.animate({'top': '12px' }, 'slow')
.fadeOut(2000, function() {
Ember.$(this).remove();
$(this).remove();
});
}
});

View File

@ -1,4 +1,5 @@
import Ember from 'ember';
import $ from 'jquery'
export default Ember.Service.extend({
list(modelName, start, limit, params) {
@ -6,11 +7,11 @@ export default Ember.Service.extend({
start: start,
limit: limit
};
if (Ember.$.type(params) === 'string') {
if ($.type(params) === 'string') {
p.search = params;
}
else {
Ember.$.extend(true, p, params);
$.extend(true, p, params);
}
return this.ajaxGet(this._pathForType(modelName, '/list'), p);
},
@ -44,7 +45,7 @@ export default Ember.Service.extend({
_ajax_request(method, url, params) {
let me = this;
return new Ember.RSVP.Promise((resolve, reject) => {
let paramsType = Ember.$.type(params);
let paramsType = $.type(params);
me.ajax[method ? method : 'doGet'](url,
paramsType === 'string' ||
paramsType === 'number' ?

View File

@ -8,14 +8,14 @@ export default Ember.Service.extend({
let me = this;
let container = Ember.getOwner(me);
let service = container.lookup('service:' + routeName);
Ember.Logger.debug(`No Route Service [${routeName}] Found, Try To Find Model Service`);
console.debug(`No Route Service [${routeName}] Found, Try To Find Model Service`);
let indexTrimmedRouteName = null;
if (/\.index$/.test(routeName)) {
Ember.Logger.debug(`Route [${routeName}] Is Index, Try To Trim index Find Model Service`);
console.debug(`Route [${routeName}] Is Index, Try To Trim index Find Model Service`);
indexTrimmedRouteName = routeName.replace(/\.index$/, '');
service = container.lookup('service:' + indexTrimmedRouteName);
if (!service) {
Ember.Logger.debug(`Route [${indexTrimmedRouteName}] Is Trimed Index, But No Service Found Still.`);
console.debug(`Route [${indexTrimmedRouteName}] Is Trimed Index, But No Service Found Still.`);
service = container.lookup('service:' + indexTrimmedRouteName + '.service');
}
}
@ -25,14 +25,14 @@ export default Ember.Service.extend({
if (!service) {
let parentRouteName = (indexTrimmedRouteName || routeName).replace(/\.[^\.]+$/, '');
Ember.Logger.debug(`No Route Model Service [${routeName}.service] Found, Try To Find Parent Service [${parentRouteName}.service]`);
console.debug(`No Route Model Service [${routeName}.service] Found, Try To Find Parent Service [${parentRouteName}.service]`);
if (parentRouteName) {
Ember.Logger.debug(`Route [${parentRouteName}] Service Found`);
console.debug(`Route [${parentRouteName}] Service Found`);
service = container.lookup('service:' + parentRouteName + '.service');
}
if (!service) {
Ember.Logger.info('No Service Found, Create Default');
console.info('No Service Found, Create Default');
let ajax = Ajax.create();
service = BaseService.create({
modelName: parentRouteName.match(/\.?([^\.]+)$/)[1],

View File

@ -6,7 +6,7 @@ export default Service.extend({
connect() {
let me = this;
if (me.get('connected')) {
Ember.Logger.info('Websocket is connected, reconnect.');
console.info('Websocket is connected, reconnect.');
me.disconnect();
}
@ -15,13 +15,13 @@ export default Service.extend({
me.set('stompClient', Stomp.over(new SockJS('/stomp')));
}
me.get('stompClient').connect({}, function() {
Ember.Logger.info('Connect websocket.');
console.info('Connect websocket.');
me.stompClient.subscribe('/topic/websocket', function(msg) {
Ember.Logger.info('On websocket message: ', msg);
console.info('On websocket message: ', msg);
$.trigger('websocket', JSON.parse(msg.body));
});
me.set('connected', true);
Ember.Logger.info('Websocket connected.');
console.info('Websocket connected.');
});
},
willDestroy() {
@ -31,10 +31,10 @@ export default Service.extend({
if (me.get('connected') && me.get('stompClient')) {
me.get('stompClient').disconnect();
me.set('connected', false);
Ember.Logger.info('Websocket disconnected.');
console.info('Websocket disconnected.');
}
else {
Ember.Logger.info('Websocket is not connected, ignore disconnect.');
console.info('Websocket is not connected, ignore disconnect.');
}
},
disconnect: aliasMethod('willDestroy')

View File

@ -1,4 +1,4 @@
{{#if ajax.loading}}
{{#if this.ajax.loading}}
<div class="ajax-loading-overlay ajax-overlay-body">
<!-- <i class="ajax-loading-icon"></i> -->
<div class="progress center-block" style="width: 208px;">
@ -9,7 +9,7 @@
</div>
{{/if}}
{{#if login}}
{{#if this.login}}
{{outlet}}
{{else}}
{{top-navbar}}

View File

@ -0,0 +1 @@
{{yield}}

View File

@ -2,8 +2,8 @@
<i class="ace-icon fa fa-home home-icon"></i>
<a href="#/">Home</a>
</li>
{{log breadcrumbs}}
{{#each breadcrumbs as |breadcrumb|}}
{{log this.breadcrumbs}}
{{#each this.breadcrumbs as |breadcrumb|}}
<li>
{{#if breadcrumb.icon}}
<i class="ace-icon fa {{breadcrumb.icon}}"></i>

View File

@ -0,0 +1 @@
{{yield}}

View File

@ -1,19 +1,32 @@
{{#if label}}
<label for="{{if name name idField}}" class="{{get this 'label-class'}} control-label no-padding-right"> {{label}} </label>
<label class="{{label-class}} control-label no-padding-right">{{label}}</label>
{{/if}}
<div class="{{get this 'input-class'}}">
<div class="{{input-class}} no-padding-right">
<div class="row col-xs-12 no-padding">
<div class="col-xs-{{get this 'col-width'}} no-padding-right">
{{#x-select class='form-control'
name=name
value=(mut (get dataModel name))
action='onOptionChanged'
as |xs|}}
{{yield xs}}
{{/x-select}}
<div class="col-xs-{{col-width}} no-padding-right">
{{input-select
model=model
name=name
multiple=multiple
nullable=nullable
readonly=readonly
placeholder=placeholder
options=options
value-field=value-field
text-field=text-field
enabled-field=enabled-field
hidden-input=hidden-input
loose=loose
fire-init-change=fire-init-change
on-change=on-change
values-as-string=values-as-string
values-splitter=values-splitter
}}
</div>
</div>
</div>
{{#if (get this 'error-msg')}}
{{#if error-msg}}
{{form-input-errors-msg name=name}}
{{/if}}

View File

@ -1,28 +0,0 @@
<label class="{{get this 'label-class'}} control-label no-padding-right">{{label}}</label>
<div class="{{get this 'input-class'}} no-padding-right">
<div class="row col-xs-12 no-padding">
<div class="col-xs-{{col-width}} no-padding-right">
<select multiple={{multiple}}
data-placeholder={{if placeholder placeholder label}}
class="select2"
style="width: 100%;">
{{#each options as |option|}}
<option value={{get option (get this 'value-field')}} selected={{if option.selected 'selected'}}>
{{!text-exp: $text($value)}}
{{#if (get option (get this 'value-field'))}}
{{option-text-exp option (get this 'value-field') (get this 'text-field') (get this 'text-exp')}}
{{/if}}
</option>
{{/each}}
</select>
{{#each options as |option|}}
{{#if option.selected}}
<input type="hidden" name="{{name}}" value="{{get option (get this 'value-field')}}" />
{{/if}}
{{/each}}
</div>
</div>
</div>
{{#if (get this 'error-msg')}}
{{form-input-errors-msg name=name}}
{{/if}}

View File

@ -1,7 +1,7 @@
<label for="{{if name name idField}}" class="{{label-class}} control-label no-padding-right"> {{label}} </label>
<div class="{{input-class}}">
{{#if hasBlock}}
{{#if (has-block)}}
{{yield}}
{{else}}
{{#if (eq 'file' type)}}

View File

@ -1,5 +1,5 @@
<div class="widget-toolbar">
{{#if hasBlock}}
{{#if (has-block)}}
{{#if dropdownMenu}}
<div class="widget-menu">
<a href="#" data-rel="tooltip" data-action="settings" data-toggle="dropdown" title="Dropdown">

View File

@ -0,0 +1,50 @@
<select multiple={{multiple}}
data-placeholder={{placeholder}}
class="select2"
style="width: 100%;">
{{#if (and (not multiple) (and options.length nullable))}}
<option></option>
{{/if}}
{{#let (get model name) as |selected|}}
{{#each options as |opt|}}
{{#if (is-plain-val opt)}}
<option value={{opt}} data-option={{opt}}>
{{opt}}
</option>
{{else}}
{{#let (get opt value-field) as |val|}}
{{#unless (is-none val)}}
<option value={{val}}
data-option={{json-str opt}}
disabled={{if (and
(not (is-none enabled-field))
(not (get opt enabled-field))) 'disabled'}}>
{{option-text-exp
opt
value-field
text-field
text-exp}}
</option>
{{/unless}}
{{/let}}
{{/if}}
{{else}}
{{log 'select [' name '] has no options'}}
{{/each}}
{{/let}}
</select>
{{#if (and name hidden-input)}}
{{#let (get model name) as |val|}}
{{#if val}}
{{#if (is-array val)}}
{{#each val as |v|}}
<input type="hidden" name="{{name}}" value="{{v}}" />
{{/each}}
{{else}}
<input type="hidden" name="{{name}}" value="{{val}}" />
{{/if}}
{{/if}}
{{/let}}
{{/if}}

View File

@ -4,21 +4,21 @@
{{#if ajax.user.admin}}
<div class="sidebar-shortcuts-large" id="sidebar-shortcuts-large">
{{#link-to 'user.list' 1 class='btn btn-warning' title='Users'}}
<LinkTo @route="user.list" @model=1 class="btn btn-warning" title="Users">
<i class="ace-icon fa fa-users"></i>
{{/link-to}}
</LinkTo>
{{#link-to 'customer.list' 1 class='btn btn-info' title='Customers'}}
<LinkTo @route="customer.list" @model=1 class="btn btn-info" title="Customers">
<i class="ace-icon fa fa-address-book-o"></i>
{{/link-to}}
</LinkTo>
{{#link-to 'customer.import' class="btn btn-success" title='Import Customers'}}
<LinkTo @route="customer.import" class="btn btn-success" title="Import Customers">
<i class="ace-icon fa fa-address-card-o"></i>
{{/link-to}}
</LinkTo>
{{#link-to 'customer-ytd-sale.import' class="btn btn-danger" title='Import Customer Sales Data'}}
<LinkTo @route="customer-ytd-sale.import" class="btn btn-danger" title="Import Customer Sales Data">
<i class="ace-icon fa fa-line-chart"></i>
{{/link-to}}
</LinkTo>
</div>
<div class="sidebar-shortcuts-mini" id="sidebar-shortcuts-mini">
@ -33,70 +33,70 @@
<ul class="nav nav-list">
{{#if ajax.user.admin}}
<li>
{{#link-to 'user.list' 1}}
<LinkTo @route="user.list" @model=1>
<i class="menu-icon fa fa-users blue"></i>
<span class="menu-text"> Users </span>
{{/link-to}}
</LinkTo>
</li>
{{/if}}
<li>
{{#link-to 'customer.list' 1}}
<LinkTo @route="customer.list" @model=1>
<i class="menu-icon fa fa-address-book-o blue" aria-hidden="true"></i>
<span class="menu-text"> Customers </span>
{{/link-to}}
</LinkTo>
</li>
{{!--
<li>
{{#link-to 'week-goal.mine'}}
<LinkTo @route="week-goal.mine">
<i class="menu-icon fa fa-calendar-check-o blue" aria-hidden="true"></i>
<span class="menu-text"> My Week Goals </span>
{{/link-to}}
</LinkTo>
</li>
<li>
{{#link-to 'week-goal.list' 1}}
<LinkTo @route="week-goal.list" @model=1>
<i class="menu-icon fa fa-calendar blue" aria-hidden="true"></i>
<span class="menu-text"> Week Goals </span>
{{/link-to}}
</LinkTo>
</li>
--}}
{{#if ajax.user.admin}}
<li>
{{#link-to 'customer-status.list' 1}}
<LinkTo @route="customer-status.list" @model=1>
<i class="menu-icon fa fa-star-half-o blue"></i>
<span class="menu-text"> Customer Status </span>
{{/link-to}}
</LinkTo>
</li>
{{/if}}
<li>
{{#link-to 'customer-application.list' 1}}
<LinkTo @route="customer-application.list" @model=1>
<i class="menu-icon fa fa-cube blue"></i>
<span class="menu-text"> Customer Application </span>
{{/link-to}}
</LinkTo>
</li>
<li>
{{#link-to 'local-product.list' 1}}
<LinkTo @route="local-product.list" @model=1>
<i class="menu-icon fa fa-bullhorn blue"></i>
<span class="menu-text"> Local &amp; New Products </span>
{{/link-to}}
</LinkTo>
</li>
{{#if ajax.user.admin}}
<li>
{{#link-to 'import-record.list' 1}}
<LinkTo @route="import-record.list" @model=1>
<i class="menu-icon fa fa-th-list blue"></i>
<span class="menu-text"> Import Records </span>
{{/link-to}}
</LinkTo>
</li>
<li>
{{#link-to 'home-page.list' 1}}
<LinkTo @route="home-page.list" @model=1>
<i class="menu-icon fa fa-newspaper-o blue"></i>
<span class="menu-text"> Home Page </span>
{{/link-to}}
</LinkTo>
</li>
<li>
{{#link-to 'database-backup.list'}}
<LinkTo @route="database-backup.list">
<i class="menu-icon fa fa-archive blue"></i>
<span class="menu-text"> Database Backup </span>
{{/link-to}}
</LinkTo>
</li>
{{/if}}
</ul><!-- /.nav-list -->

View File

@ -1,7 +1,7 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header" style="padding: 9px;">
{{#if (not (get this 'no-close'))}}
{{#if (not no-close)}}
<button type="button" class="bootbox-close-button close" data-dismiss="modal" aria-hidden="true">
&times;
</button>
@ -12,15 +12,15 @@
<div class="modal-body no-padding">
{{yield}}
</div>
{{#if (not (get this 'no-footer'))}}
{{#if (not no-footer)}}
<div class="modal-footer no-margin-top">
{{#if (not (get this 'no-cancel'))}}
{{#if (not no-cancel)}}
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">
<i class="ace-icon fa fa-times"></i>
{{cancel-text}}
</button>
{{/if}}
{{#if (not (get this 'no-submit'))}}
{{#if (not no-submit)}}
<button type="button" class="btn btn-sm btn-primary"
{{action (if submit submit (route-action 'submit'))}}>
<i class="ace-icon fa fa-check"></i>

View File

@ -1,8 +1,8 @@
<h6 class="pull-left no-margin">
{{#if (gt total 1)}}
Total: {{total}} Records
{{#if (gt this.total 1)}}
Total: {{this.total}} Records
{{else if (eq total 1)}}
Total: {{total}} Record
Total: {{this.total}} Record
{{else}}
No Record
{{/if}}
@ -10,11 +10,11 @@
<ul class="pagination no-margin pull-right">
<li class="prev">
<a href="#" {{action 'gotoPage' prevPage}}>
<a href="#" {{action 'gotoPage' this.prevPage}}>
<i class="ace-icon fa fa-angle-double-left"></i>
</a>
</li>
{{#each pages as |page|}}
{{#each this.pages as |page|}}
<li class="{{if page.active 'active'}}">
<a href="#" {{action 'gotoPage' page.page}}>
{{page.text}}
@ -22,16 +22,16 @@
</li>
{{/each}}
<li class="next">
<a href="#" {{action 'gotoPage' nextPage}}>
<a href="#" {{action 'gotoPage' this.nextPage}}>
<i class="ace-icon fa fa-angle-double-right"></i>
</a>
</li>
{{#if (gt allPages.length 1)}}
{{#if (gt this.allPages.length 1)}}
<li>
<select style="width: 48px; margin: 1px 4px;"
onchange={{action 'gotoPage' value='target.value'}}>
{{#each allPages as |page|}}
<option value={{page}} selected={{if (eq currPage page) 'selected'}}>
{{#each this.allPages as |page|}}
<option value={{page}} selected={{if (eq this.currPage page) 'selected'}}>
{{page}}
</option>
{{/each}}

View File

@ -5,7 +5,7 @@
{{/if}}
<span>
{{#if hasBlock}}
{{#if (has-block)}}
{{yield}}
{{else}}
{{text}}

View File

@ -1,19 +1,28 @@
<span class="{{if filtered 'green'}} {{if (get this 'full-width') 'col-xs-12 no-padding'}}" data-rel="tooltip" title="Data Filter" {{action 'onClick'}}>
<span class="{{if hasFilter 'green'}} {{if full-width 'col-xs-12 no-padding'}}" data-rel="tooltip" title="Data Filter" {{action 'onClick'}}>
{{text}}
<i class="ace-icon fa fa-filter light-blue smaller-70 hidden-480"></i>
</span>
{{#if showModal}}
{{#modal-dialog title=(get this 'dialog-title') submit=(action 'onModalSubmit') on-close=(action 'onModalClose') close-to-parent=false}}
{{#modal-dialog title=(if dialog-title
dialog-title (if label label text))
submit=(action 'onModalSubmit')
on-close=(action 'onModalClose')
close-to-parent=false}}
<div class="widget-body">
<div class="widget-main">
<form class="form-horizontal">
{{form-input-select2
{{form-input-select
multiple=true
values-as-string=values-as-string
col-width=12
label=(if label label text)
options=options
value-field=value-field
text-field=text-field
text-exp=text-exp
loose=loose
name='filtered'
model=this
}}
</form>
</div>

View File

@ -307,17 +307,17 @@
<ul class="user-menu dropdown-menu-right dropdown-menu dropdown-yellow dropdown-caret dropdown-close">
<li>
{{#link-to 'user.update-password'}}
<LinkTo @route="user.update-password">
<i class="ace-icon fa fa-cog"></i>
Change Password
{{/link-to}}
</LinkTo>
</li>
<li>
{{#link-to 'user.profile'}}
<LinkTo @route="user.profile">
<i class="ace-icon fa fa-user"></i>
Profile
{{/link-to}}
</LinkTo>
</li>
<li class="divider"></li>

View File

@ -1,5 +1,5 @@
{{#form-content}}
{{form-input-select2
{{form-input-select
nullable=true
name='owner'
label='Owner'

View File

@ -1,7 +1,7 @@
{{#form-content}}
{{input type='hidden' name='id' value=model.id}}
{{#if ajax.user.admin}}
{{form-input-select2
{{form-input-select
nullable=true
name='owner'
label='Owner'

View File

@ -9,7 +9,7 @@
{{form-input name='salesperson' label='Salesperson' readonly='readonly'}}
{{form-input type='hidden' name='enabled'}}
{{form-input-select2
{{form-input-select
multiple=true
name='applications'
label='Application'
@ -19,7 +19,7 @@
col-width=12
}}
{{form-input-select2
{{form-input-select
name='status'
label='Status'
options=model.statusList

View File

@ -168,11 +168,11 @@
{{#if it.countYtdSales}}
{{#if it.expand}}
<a style="cursor: pointer;" {{action (route-action 'collapseYtdSales' it)}}>
<i class="ui-icon ace-icon fa fa-minus center blue bigger-110"></i>
<i class="ace-icon fa fa-minus center blue bigger-110"></i>
</a>
{{else}}
<a style="cursor: pointer;" {{action (route-action 'expandYtdSales' it)}}>
<i class="ui-icon ace-icon fa fa-plus center blue bigger-110"></i>
<i class="ace-icon fa fa-plus center blue bigger-110"></i>
</a>
{{/if}}
{{/if}}

View File

@ -10,7 +10,7 @@
{{form-input type='show' name='region' label='Region'}}
{{form-input type='show' name='salesperson' label='Salesperson'}}
{{form-input-select2
{{form-input-select
multiple=true
name='applications'
label='Application'
@ -19,7 +19,7 @@
text-field='name'
}}
{{form-input-select2
{{form-input-select
name='status'
label='Status'
options=model.statusList

View File

@ -1,6 +1,6 @@
{{!home-board}}
{{#main-content}}
<div class="col-sm-12 index-content">
{{model.content}}
{{this.model.content}}
</div>
{{/main-content}}

View File

@ -1,34 +0,0 @@
{
"name": "ambition-crm",
"description": "Ambition CRM",
"authors": [
"Shaun Chyxion <chyxion@163.com>"
],
"main": "",
"license": "MIT",
"homepage": "",
"dependencies": {
"bootstrap": "3.4.1",
"bootbox": "~4.4.0",
"moment": ">= 2.8.0",
"moment-timezone": ">= 0.1.0",
"validate": "~0.9.0",
"font-awesome": "^4.7.0",
"mjolnic-bootstrap-colorpicker": "bootstrap-colorpicker#^2.3.3",
"jquery-colorbox": "^1.6.4",
"fuelux": "^3.15.4",
"jquery.hotkeys": "*",
"bootstrap-wysiwyg": "*",
"responsive-bootstrap-toolkit": "responsive-toolkit#^2.6.3"
},
"resolutions": {
"ember": "release"
},
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View File

@ -1,18 +1,18 @@
/* global require, module */
'use strict';
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
const Funnel = require('broccoli-funnel');
// Babel transpiler
const BabelTranspiler = require('broccoli-babel-transpiler');
const glob = require('glob')
module.exports = function(defaults) {
const app = new EmberApp(defaults, {
'ember-cli-babel': {
includePolyfill: true
overwrite: true,
SRI: {
enabled: false
},
sourcemaps: {
enabled: EmberApp.env() !== 'production',
extensions: ['js', 'coffee']
},
sourcemaps: {
enabled: EmberApp.env() !== 'production',
extensions: ['js', 'coffee']
},
outputPaths: {
app: {
html: 'index.html',
@ -29,18 +29,18 @@ module.exports = function(defaults) {
}
});
// Use `app.import` to add additional libraries to the generated
// output files.
//
// If you need to use different assets in different
// environments, specify an object as the first parameter. That
// object's keys should be the environment name and the values
// should be the asset to use in that environment.
//
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
// Use `app.import` to add additional libraries to the generated
// output files.
//
// If you need to use different assets in different
// environments, specify an object as the first parameter. That
// object's keys should be the environment name and the values
// should be the asset to use in that environment.
//
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
function importVendor(app, resource, outputFile) {
if (/\.js$/.test(resource)) {
@ -51,72 +51,78 @@ module.exports = function(defaults) {
}
}
importVendor(app, 'bower_components/bootstrap/dist/css/bootstrap.css');
// importVendor(app, 'bower_components/bootstrap/dist/css/bootstrap-theme.css');
importVendor(app, 'bower_components/bootstrap/dist/js/bootstrap.js');
let bootstrapAssets = new Funnel('bower_components/bootstrap/dist/fonts', {
include: ['*.*'],
destDir: '/assets/fonts'
});
// Toolkit
importVendor(app, 'bower_components/responsive-bootstrap-toolkit/dist/bootstrap-toolkit.js');
importVendor(app, 'bower_components/bootbox/bootbox.js');
importVendor(app, 'bower_components/validate/validate.js');
// FueUX
importVendor(app, 'bower_components/fuelux/js/spinbox.js');
importVendor(app, 'bower_components/fuelux/js/tree.js');
// for image previews
importVendor(app, 'bower_components/jquery-colorbox/jquery.colorbox-min.js');
importVendor(app, 'bower_components/jquery-colorbox/example1/colorbox.css');
let jqColorboxAssets = new Funnel('bower_components/jquery-colorbox/example1/images', {
include: ['*.*'],
destDir: '/assets/css/images'
});
importVendor(app, 'node_modules/bootstrap/dist/css/bootstrap.css');
// importVendor(app, 'node_modules/bootstrap/dist/css/bootstrap-theme.css');
importVendor(app, 'node_modules/bootstrap/dist/js/bootstrap.js');
glob.sync('node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.*', {})
.forEach(file => app.import(file, { destDir: 'assets/fonts' }));
importVendor(app, 'node_modules/json-format-highlight/dist/json-format-highlight.js');
// font awesome
importVendor(app, 'bower_components/font-awesome/css/font-awesome.min.css');
let faAssets = new Funnel('bower_components/font-awesome/fonts', {
include: ['*.*'],
destDir: '/assets/fonts'
});
importVendor(app, 'node_modules/font-awesome/css/font-awesome.min.css');
glob.sync('node_modules/font-awesome/fonts/*.*', {})
.forEach(file => app.import(file, { destDir: 'assets/fonts' }));
// Toastr
importVendor(app, 'node_modules/toastr/build/toastr.min.js');
importVendor(app, 'node_modules/toastr/build/toastr.min.css');
// bootstrap color picker
importVendor(app, 'bower_components/mjolnic-bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css');
importVendor(app, 'bower_components/mjolnic-bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js');
let bcpAssets = new Funnel('bower_components/mjolnic-bootstrap-colorpicker/dist/img', {
include: ['bootstrap-colorpicker/*.*'],
destDir: '/assets/img'
});
// Tags
importVendor(app, 'node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.js');
importVendor(app, 'node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.css');
importVendor(app, 'node_modules/bootbox/src/bootbox.js');
importVendor(app, 'node_modules/validate.js/validate.js');
// FueUX
importVendor(app, 'node_modules/fuelux/js/spinbox.js');
// for colorpicker
importVendor(app, 'node_modules/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css');
importVendor(app, 'node_modules/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js');
glob.sync('node_modules/bootstrap-colorpicker/dist/img/bootstrap-colorpicker/*.*', {})
.forEach(file => app.import(file, { destDir: 'assets/img/bootstrap-colorpicker' }));
// for image previews
importVendor(app, 'node_modules/jquery-colorbox/jquery.colorbox-min.js');
importVendor(app, 'node_modules/jquery-colorbox/example1/colorbox.css');
glob.sync('node_modules/jquery-colorbox/example1/images/*.*', {})
.forEach(file => app.import(file, { destDir: 'assets/css/images' }));
// ACE CSS
// JQuery UI
importVendor(app, 'vendor/ace/css/jquery-ui.custom.css');
importVendor(app, 'vendor/ace/js/jquery-ui.custom.js');
// Datetime picker
importVendor(app, 'vendor/ace/css/datepicker.css');
importVendor(app, 'vendor/ace/js/date-time/bootstrap-datepicker.js');
importVendor(app, 'vendor/ace/css/bootstrap-datetimepicker.css');
importVendor(app, 'vendor/ace/js/date-time/bootstrap-datetimepicker.js');
// Dual listbox
importVendor(app, 'vendor/ace/css/bootstrap-duallistbox.css');
importVendor(app, 'vendor/ace/js/jquery.bootstrap-duallistbox.js');
// Select 2
importVendor(app, 'node_modules/select2/dist/css/select2.css');
importVendor(app, 'node_modules/select2/dist/js/select2.js');
// JQuery HotKeys
importVendor(app, 'bower_components/jquery.hotkeys/jquery.hotkeys.js');
// Bootstrap WYSIWYG
importVendor(app, 'bower_components/bootstrap-wysiwyg/bootstrap-wysiwyg.js');
importVendor(app, 'node_modules/bootstrap-wysiwyg/css/style.css');
importVendor(app, 'node_modules/bootstrap-wysiwyg/src/bootstrap-wysiwyg.js');
// Select2, must before ace
importVendor(app, 'vendor/ace/js/select2.js');
importVendor(app, 'vendor/ace/css/select2.css');
// WebSocket
importVendor(app, 'node_modules/sockjs-client/dist/sockjs.js');
importVendor(app, 'node_modules/stomp-websocket/lib/stomp.js');
let select2Images = new Funnel('vendor/ace/css', {
include: ['select2-spinner.gif', 'select2.png', 'select2x2.png'],
destDir: '/assets/css'
});
// Bootstrap Toolkit
importVendor(app, 'node_modules/responsive-toolkit/dist/bootstrap-toolkit.js');
// ACE CSS
importVendor(app, 'vendor/ace/css/ace.css');
importVendor(app, 'vendor/ace/css/ace-fonts.css');
let aceFonts = new Funnel('vendor/ace/fonts', {
include: ['*.*'],
destDir: '/assets/fonts'
});
let aceImages = new Funnel('vendor/ace/css/images', {
include: ['**/*.*'],
destDir: '/assets/css/images'
});
app.import('vendor/ace/fonts/OpenSans-300.woff', { destDir: 'assets/fonts' })
app.import('vendor/ace/fonts/OpenSans-400.woff', { destDir: 'assets/fonts' })
glob.sync('vendor/ace/css/images/*.*', { })
.forEach(file => app.import(file, { destDir: 'assets/css/images' }));
// ACE JS
// start up
@ -124,45 +130,22 @@ module.exports = function(defaults) {
importVendor(app, 'vendor/ace/js/ace-extra.js');
importVendor(app, 'vendor/ace/js/ace-elements.js');
// importVendor(app, 'vendor/ace/js/ace/elements.fileinput.js');
// importVendor(app, 'vendor/ace/js/ace/elements.spinner.js');
// importVendor(app, 'vendor/ace/js/ace/elements.treeview.js');
importVendor(app, 'vendor/ace/js/ace/elements.wysiwyg.js');
// importVendor(app, 'vendor/ace/js/jquery-ui.custom.js');
importVendor(app, 'vendor/ace/js/ace/ace.touch-drag.js');
importVendor(app, 'vendor/ace/js/ace/ace.sidebar.js');
importVendor(app, 'vendor/ace/js/ace/ace.sidebar-scroll-1.js');
importVendor(app, 'vendor/ace/js/ace/ace.submenu-hover.js');
importVendor(app, 'vendor/ace/js/ace/ace.settings.js');
importVendor(app, 'vendor/ace/js/ace/ace.settings-rtl.js');
importVendor(app, 'vendor/ace/js/ace/ace.settings-skin.js');
importVendor(app, 'vendor/ace/js/ace/ace.widget-box.js');
importVendor(app, 'vendor/ace/js/ace/ace.widget-on-reload.js');
importVendor(app, 'vendor/ace/js/ace/ace.searchbox-autocomplete.js');
// JQuery Qr Code
importVendor(app, 'vendor/jquery-qrcode/js/jquery-qrcode.js');
// JQuery Hot Keys
importVendor(app, 'vendor/jquery-hotkeys/js/jquery.hotkeys.min.js');
// JQuery PubSub
importVendor(app, 'vendor/jquery-pubsub/js/jquery.pubsub.js');
// compile public es6
const publicJs = BabelTranspiler('public', {
browserPolyfill: true,
filterExtensions: ['js']
});
// Audio Player
// importVendor(app, 'vendor/audioplayer/audioplayer.css');
// importVendor(app, 'vendor/audioplayer/audioplayer.js');
return app.toTree([bootstrapAssets,
jqColorboxAssets,
faAssets,
bcpAssets,
aceFonts,
aceImages,
select2Images,
publicJs
]);
return app.toTree();
};

View File

@ -1,6 +1,6 @@
{
"name": "ambition-crm",
"version": "0.0.1",
"version": "0.0.2",
"description": "Ambition CRM",
"private": true,
"directories": {
@ -16,44 +16,64 @@
"author": "Shaun Chyxion",
"license": "MIT",
"devDependencies": {
"broccoli-asset-rev": "^2.4.5",
"broccoli-funnel": "^1.0.1",
"ember-ajax": "^3.0.0",
"ember-browserify": "^1.1.11",
"ember-cli": "~2.14.2",
"ember-cli-app-version": "^3.0.0",
"ember-cli-babel": "^6.3.0",
"ember-cli-dependency-checker": "^1.3.0",
"ember-cli-eslint": "^3.0.0",
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-htmlbars-inline-precompile": "^0.4.3",
"ember-cli-inject-live-reload": "^1.4.1",
"ember-cli-jshint": "^1.0.0",
"ember-cli-less": "^1.5.5",
"ember-cli-moment-shim": "^1.2.0",
"ember-cli-qunit": "^4.0.0",
"ember-cli-release": "0.2.8",
"ember-cli-shims": "^1.1.0",
"ember-cli-sri": "^2.1.0",
"ember-cli-uglify": "^1.2.0",
"@ember/jquery": "1.1.0",
"@ember/optional-features": "^1.3.0",
"@ember/test-helpers": "^2.8.1",
"bootbox": "5.1.3",
"bootstrap": "3.4.1",
"bootstrap-colorpicker": "^2.5.2",
"bootstrap-tagsinput": "^0.7.1",
"bootstrap-wysiwyg": "^2.0.1",
"broccoli-asset-rev": "^3.0.0",
"ember-ajax": "^5.0.0",
"ember-auto-import": "^2.4.2",
"ember-cli": "3.28.5",
"ember-cli-app-version": "^5.0.0",
"ember-cli-babel": "^7.19.0",
"ember-cli-clipboard": "^0.16.0",
"ember-cli-dependency-checker": "^3.1.0",
"ember-cli-eslint": "^5.1.0",
"ember-cli-htmlbars": "^6.0.1",
"ember-cli-inject-live-reload": "^2.0.2",
"ember-cli-less": "^3.0.1",
"ember-cli-moment-shim": "^3.7.1",
"ember-cli-shims": "^1.2.0",
"ember-cli-sri": "^2.1.1",
"ember-cli-template-lint": "^2.0.2",
"ember-cli-uglify": "^3.0.0",
"ember-composable-helpers": "^3.1.1",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.0.0",
"ember-moment": "^6.1.0",
"ember-radio-button": "1.1.1",
"ember-resolver": "^4.0.0",
"ember-route-action-helper": "2.0.3",
"ember-source": "~2.16.0",
"ember-truth-helpers": "1.1.0",
"emberx-select": "3.0.1",
"glob": "^4.5.3",
"loader.js": "^4.2.3",
"morgan": "^1.7.0"
"ember-load-initializers": "^2.1.1",
"ember-maybe-import-regenerator": "^1.0.0",
"ember-moment": "^10.0.0",
"ember-qunit": "^5.1.5",
"ember-radio-button": "^2.0.1",
"ember-resolver": "^8.0.0",
"ember-route-action-helper": "^2.0.8",
"ember-source": "3.28.9",
"ember-truth-helpers": "^3.0.0",
"emberx-select": "3.1.1",
"eslint-plugin-ember": "^10.6.1",
"font-awesome": "^4.7.0",
"fuelux": "^3.17.0",
"glob": "^8.0.3",
"jquery-colorbox": "^1.6.4",
"json-format-highlight": "^1.0.4",
"loader.js": "^4.7.0",
"moment": "^2.24.0",
"qunit": "^2.19.1",
"qunit-dom": "^2.0.0",
"responsive-toolkit": "^2.6.3",
"select2": "^4.0.13",
"toastr": "^2.1.4",
"validate.js": "^0.13.1",
"webpack": "^5.73.0"
},
"dependencies": {
"sockjs-client": "^1.6.1",
"stomp-websocket": "^2.3.4-next"
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
"node": "6.* || 8.* || >= 10.*"
}
}

View File

@ -14882,6 +14882,39 @@ div.ColVis_collectionBackground {
right: auto;
left: 0;
}
.select2-container--default .select2-selection--single {
border: 1px solid #d5d5d5 !important;
border-radius: 0;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
line-height: 30px !important;
}
.select2-container .select2-selection--single {
height: 32px !important;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 30px !important;
}
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #d5d5d5 !important;
}
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: 1px solid #aaa !important;
}
.select2-container--default .select2-selection--multiple {
border: 1px solid #d5d5d5 !important;
border-radius: 0 !important;
}
/*
.select2-container .select2-choice {
border-radius: 0;
height: 32px;
@ -15102,6 +15135,7 @@ div.ColVis_collectionBackground {
.select2-container-multi.tag-input-style .select2-choices .select2-search-choice .select2-search-choice-close:hover:before {
color: #FFF;
}
*/
#colorbox:focus,
#colorbox:active {
outline: none;

1672
web/vendor/ace/css/font-awesome.css vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 B

View File

@ -1,68 +0,0 @@
//
// Alerts
// --------------------------------------------------
// Base styles
// -------------------------
.alert {
padding: @alert-padding;
margin-bottom: @line-height-computed;
border: 1px solid transparent;
border-radius: @alert-border-radius;
// Headings for larger alerts
h4 {
margin-top: 0;
// Specified for the h4 to prevent conflicts of changing @headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: @alert-link-font-weight;
}
// Improve alignment and spacing of inner content
> p,
> ul {
margin-bottom: 0;
}
> p + p {
margin-top: 5px;
}
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.
.alert-dismissible {
padding-right: (@alert-padding + 20);
// Adjust close link position
.close {
position: relative;
top: -2px;
right: -21px;
color: inherit;
}
}
// Alternate styles
//
// Generate contextual modifier classes for colorizing the alert.
.alert-success {
.alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);
}
.alert-info {
.alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);
}
.alert-warning {
.alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);
}
.alert-danger {
.alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);
}

View File

@ -1,61 +0,0 @@
//
// Badges
// --------------------------------------------------
// Base class
.badge {
display: inline-block;
min-width: 10px;
padding: 3px 7px;
font-size: @font-size-small;
font-weight: @badge-font-weight;
color: @badge-color;
line-height: @badge-line-height;
vertical-align: baseline;
white-space: nowrap;
text-align: center;
background-color: @badge-bg;
border-radius: @badge-border-radius;
// Empty badges collapse automatically (not available in IE8)
&:empty {
display: none;
}
// Quick fix for badges in buttons
.btn & {
position: relative;
top: -1px;
}
.btn-xs & {
top: 0;
padding: 1px 5px;
}
// Hover state, but only for links
a& {
&:hover,
&:focus {
color: @badge-link-hover-color;
text-decoration: none;
cursor: pointer;
}
}
// Account for badges in navs
.list-group-item.active > &,
.nav-pills > .active > a > & {
color: @badge-active-color;
background-color: @badge-active-bg;
}
.list-group-item > & {
float: right;
}
.list-group-item > & + & {
margin-right: 5px;
}
.nav-pills > li > a > & {
margin-left: 3px;
}
}

View File

@ -1,50 +0,0 @@
// Core variables and mixins
@import "variables.less";
@import "mixins.less";
// Reset and dependencies
@import "normalize.less";
@import "print.less";
@import "glyphicons.less";
// Core CSS
@import "scaffolding.less";
@import "type.less";
@import "code.less";
@import "grid.less";
@import "tables.less";
@import "forms.less";
@import "buttons.less";
// Components
@import "component-animations.less";
@import "dropdowns.less";
@import "button-groups.less";
@import "input-groups.less";
@import "navs.less";
@import "navbar.less";
@import "breadcrumbs.less";
@import "pagination.less";
@import "pager.less";
@import "labels.less";
@import "badges.less";
@import "jumbotron.less";
@import "thumbnails.less";
@import "alerts.less";
@import "progress-bars.less";
@import "media.less";
@import "list-group.less";
@import "panels.less";
@import "responsive-embed.less";
@import "wells.less";
@import "close.less";
// Components w/ JavaScript
@import "modals.less";
@import "tooltip.less";
@import "popovers.less";
@import "carousel.less";
// Utility classes
@import "utilities.less";
@import "responsive-utilities.less";

View File

@ -1,26 +0,0 @@
//
// Breadcrumbs
// --------------------------------------------------
.breadcrumb {
padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;
margin-bottom: @line-height-computed;
list-style: none;
background-color: @breadcrumb-bg;
border-radius: @border-radius-base;
> li {
display: inline-block;
+ li:before {
content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space
padding: 0 5px;
color: @breadcrumb-color;
}
}
> .active {
color: @breadcrumb-active-color;
}
}

View File

@ -1,243 +0,0 @@
//
// Button groups
// --------------------------------------------------
// Make the div behave like a button
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-block;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative;
float: left;
// Bring the "active" button to the front
&:hover,
&:focus,
&:active,
&.active {
z-index: 2;
}
}
}
// Prevent double borders when buttons are next to each other
.btn-group {
.btn + .btn,
.btn + .btn-group,
.btn-group + .btn,
.btn-group + .btn-group {
margin-left: -1px;
}
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
margin-left: -5px; // Offset the first child's margin
&:extend(.clearfix all);
.btn-group,
.input-group {
float: left;
}
> .btn,
> .btn-group,
> .input-group {
margin-left: 5px;
}
}
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
border-radius: 0;
}
// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
.btn-group > .btn:first-child {
margin-left: 0;
&:not(:last-child):not(.dropdown-toggle) {
.border-right-radius(0);
}
}
// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
.border-left-radius(0);
}
// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
.btn-group > .btn-group {
float: left;
}
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group > .btn-group:first-child {
> .btn:last-child,
> .dropdown-toggle {
.border-right-radius(0);
}
}
.btn-group > .btn-group:last-child > .btn:first-child {
.border-left-radius(0);
}
// On active and open, don't show outline
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
outline: 0;
}
// Sizing
//
// Remix the default button sizing classes into new ones for easier manipulation.
.btn-group-xs > .btn { &:extend(.btn-xs); }
.btn-group-sm > .btn { &:extend(.btn-sm); }
.btn-group-lg > .btn { &:extend(.btn-lg); }
// Split button dropdowns
// ----------------------
// Give the line between buttons some depth
.btn-group > .btn + .dropdown-toggle {
padding-left: 8px;
padding-right: 8px;
}
.btn-group > .btn-lg + .dropdown-toggle {
padding-left: 12px;
padding-right: 12px;
}
// The clickable button for toggling the menu
// Remove the gradient and set the same inset shadow as the :active state
.btn-group.open .dropdown-toggle {
.box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
// Show no shadow for `.btn-link` since it has no other button styles.
&.btn-link {
.box-shadow(none);
}
}
// Reposition the caret
.btn .caret {
margin-left: 0;
}
// Carets in other button sizes
.btn-lg .caret {
border-width: @caret-width-large @caret-width-large 0;
border-bottom-width: 0;
}
// Upside down carets for .dropup
.dropup .btn-lg .caret {
border-width: 0 @caret-width-large @caret-width-large;
}
// Vertical button groups
// ----------------------
.btn-group-vertical {
> .btn,
> .btn-group,
> .btn-group > .btn {
display: block;
float: none;
width: 100%;
max-width: 100%;
}
// Clear floats so dropdown menus can be properly placed
> .btn-group {
&:extend(.clearfix all);
> .btn {
float: none;
}
}
> .btn + .btn,
> .btn + .btn-group,
> .btn-group + .btn,
> .btn-group + .btn-group {
margin-top: -1px;
margin-left: 0;
}
}
.btn-group-vertical > .btn {
&:not(:first-child):not(:last-child) {
border-radius: 0;
}
&:first-child:not(:last-child) {
border-top-right-radius: @border-radius-base;
.border-bottom-radius(0);
}
&:last-child:not(:first-child) {
border-bottom-left-radius: @border-radius-base;
.border-top-radius(0);
}
}
.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group-vertical > .btn-group:first-child:not(:last-child) {
> .btn:last-child,
> .dropdown-toggle {
.border-bottom-radius(0);
}
}
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
.border-top-radius(0);
}
// Justified button groups
// ----------------------
.btn-group-justified {
display: table;
width: 100%;
table-layout: fixed;
border-collapse: separate;
> .btn,
> .btn-group {
float: none;
display: table-cell;
width: 1%;
}
> .btn-group .btn {
width: 100%;
}
> .btn-group .dropdown-menu {
left: auto;
}
}
// Checkbox and radio options
//
// In order to support the browser's form validation feedback, powered by the
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
// `display: none;` or `visibility: hidden;` as that also hides the popover.
// Simply visually hiding the inputs via `opacity` would leave them clickable in
// certain cases which is prevented by using `clip` and `pointer-events`.
// This way, we ensure a DOM element is visible to position the popover from.
//
// See https://github.com/twbs/bootstrap/pull/12794 and
// https://github.com/twbs/bootstrap/pull/14559 for more information.
[data-toggle="buttons"] {
> .btn,
> .btn-group > .btn {
input[type="radio"],
input[type="checkbox"] {
position: absolute;
clip: rect(0,0,0,0);
pointer-events: none;
}
}
}

View File

@ -1,160 +0,0 @@
//
// Buttons
// --------------------------------------------------
// Base styles
// --------------------------------------------------
.btn {
display: inline-block;
margin-bottom: 0; // For input.btn
font-weight: @btn-font-weight;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
border: 1px solid transparent;
white-space: nowrap;
.button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);
.user-select(none);
&,
&:active,
&.active {
&:focus,
&.focus {
.tab-focus();
}
}
&:hover,
&:focus,
&.focus {
color: @btn-default-color;
text-decoration: none;
}
&:active,
&.active {
outline: 0;
background-image: none;
.box-shadow(inset 0 3px 5px rgba(0,0,0,.125));
}
&.disabled,
&[disabled],
fieldset[disabled] & {
cursor: @cursor-disabled;
pointer-events: none; // Future-proof disabling of clicks
.opacity(.65);
.box-shadow(none);
}
}
// Alternate buttons
// --------------------------------------------------
.btn-default {
.button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);
}
.btn-primary {
.button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);
}
// Success appears as green
.btn-success {
.button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);
}
// Info appears as blue-green
.btn-info {
.button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);
}
// Warning appears as orange
.btn-warning {
.button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);
}
// Danger and error appear as red
.btn-danger {
.button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);
}
// Link buttons
// -------------------------
// Make a button look and behave like a link
.btn-link {
color: @link-color;
font-weight: normal;
border-radius: 0;
&,
&:active,
&.active,
&[disabled],
fieldset[disabled] & {
background-color: transparent;
.box-shadow(none);
}
&,
&:hover,
&:focus,
&:active {
border-color: transparent;
}
&:hover,
&:focus {
color: @link-hover-color;
text-decoration: underline;
background-color: transparent;
}
&[disabled],
fieldset[disabled] & {
&:hover,
&:focus {
color: @btn-link-disabled-color;
text-decoration: none;
}
}
}
// Button Sizes
// --------------------------------------------------
.btn-lg {
// line-height: ensure even-numbered height of button next to large input
.button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
}
.btn-sm {
// line-height: ensure proper height of button next to small input
.button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
}
.btn-xs {
.button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);
}
// Block button
// --------------------------------------------------
.btn-block {
display: block;
width: 100%;
}
// Vertically space out multiple block buttons
.btn-block + .btn-block {
margin-top: 5px;
}
// Specificity overrides
input[type="submit"],
input[type="reset"],
input[type="button"] {
&.btn-block {
width: 100%;
}
}

View File

@ -1,267 +0,0 @@
//
// Carousel
// --------------------------------------------------
// Wrapper for the slide container and indicators
.carousel {
position: relative;
}
.carousel-inner {
position: relative;
overflow: hidden;
width: 100%;
> .item {
display: none;
position: relative;
.transition(.6s ease-in-out left);
// Account for jankitude on images
> img,
> a > img {
&:extend(.img-responsive);
line-height: 1;
}
// WebKit CSS3 transforms for supported devices
@media all and (transform-3d), (-webkit-transform-3d) {
transition: transform .6s ease-in-out;
backface-visibility: hidden;
perspective: 1000;
&.next,
&.active.right {
transform: translate3d(100%, 0, 0);
left: 0;
}
&.prev,
&.active.left {
transform: translate3d(-100%, 0, 0);
left: 0;
}
&.next.left,
&.prev.right,
&.active {
transform: translate3d(0, 0, 0);
left: 0;
}
}
}
> .active,
> .next,
> .prev {
display: block;
}
> .active {
left: 0;
}
> .next,
> .prev {
position: absolute;
top: 0;
width: 100%;
}
> .next {
left: 100%;
}
> .prev {
left: -100%;
}
> .next.left,
> .prev.right {
left: 0;
}
> .active.left {
left: -100%;
}
> .active.right {
left: 100%;
}
}
// Left/right controls for nav
// ---------------------------
.carousel-control {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: @carousel-control-width;
.opacity(@carousel-control-opacity);
font-size: @carousel-control-font-size;
color: @carousel-control-color;
text-align: center;
text-shadow: @carousel-text-shadow;
// We can't have this transition here because WebKit cancels the carousel
// animation if you trip this while in the middle of another animation.
// Set gradients for backgrounds
&.left {
#gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));
}
&.right {
left: auto;
right: 0;
#gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));
}
// Hover/focus state
&:hover,
&:focus {
outline: 0;
color: @carousel-control-color;
text-decoration: none;
.opacity(.9);
}
// Toggles
.icon-prev,
.icon-next,
.glyphicon-chevron-left,
.glyphicon-chevron-right {
position: absolute;
top: 50%;
z-index: 5;
display: inline-block;
}
.icon-prev,
.glyphicon-chevron-left {
left: 50%;
margin-left: -10px;
}
.icon-next,
.glyphicon-chevron-right {
right: 50%;
margin-right: -10px;
}
.icon-prev,
.icon-next {
width: 20px;
height: 20px;
margin-top: -10px;
font-family: serif;
}
.icon-prev {
&:before {
content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)
}
}
.icon-next {
&:before {
content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)
}
}
}
// Optional indicator pips
//
// Add an unordered list with the following class and add a list item for each
// slide your carousel holds.
.carousel-indicators {
position: absolute;
bottom: 10px;
left: 50%;
z-index: 15;
width: 60%;
margin-left: -30%;
padding-left: 0;
list-style: none;
text-align: center;
li {
display: inline-block;
width: 10px;
height: 10px;
margin: 1px;
text-indent: -999px;
border: 1px solid @carousel-indicator-border-color;
border-radius: 10px;
cursor: pointer;
// IE8-9 hack for event handling
//
// Internet Explorer 8-9 does not support clicks on elements without a set
// `background-color`. We cannot use `filter` since that's not viewed as a
// background color by the browser. Thus, a hack is needed.
//
// For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we
// set alpha transparency for the best results possible.
background-color: #000 \9; // IE8
background-color: rgba(0,0,0,0); // IE9
}
.active {
margin: 0;
width: 12px;
height: 12px;
background-color: @carousel-indicator-active-bg;
}
}
// Optional captions
// -----------------------------
// Hidden by default for smaller viewports
.carousel-caption {
position: absolute;
left: 15%;
right: 15%;
bottom: 20px;
z-index: 10;
padding-top: 20px;
padding-bottom: 20px;
color: @carousel-caption-color;
text-align: center;
text-shadow: @carousel-text-shadow;
& .btn {
text-shadow: none; // No shadow for button elements in carousel-caption
}
}
// Scale up controls for tablets and up
@media screen and (min-width: @screen-sm-min) {
// Scale up the controls a smidge
.carousel-control {
.glyphicon-chevron-left,
.glyphicon-chevron-right,
.icon-prev,
.icon-next {
width: 30px;
height: 30px;
margin-top: -15px;
font-size: 30px;
}
.glyphicon-chevron-left,
.icon-prev {
margin-left: -15px;
}
.glyphicon-chevron-right,
.icon-next {
margin-right: -15px;
}
}
// Show and left align the captions
.carousel-caption {
left: 20%;
right: 20%;
padding-bottom: 30px;
}
// Move up the indicators
.carousel-indicators {
bottom: 20px;
}
}

View File

@ -1,33 +0,0 @@
//
// Close icons
// --------------------------------------------------
.close {
float: right;
font-size: (@font-size-base * 1.5);
font-weight: @close-font-weight;
line-height: 1;
color: @close-color;
text-shadow: @close-text-shadow;
.opacity(.2);
&:hover,
&:focus {
color: @close-color;
text-decoration: none;
cursor: pointer;
.opacity(.5);
}
// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
button& {
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
}
}

View File

@ -1,69 +0,0 @@
//
// Code (inline and block)
// --------------------------------------------------
// Inline and block code styles
code,
kbd,
pre,
samp {
font-family: @font-family-monospace;
}
// Inline code
code {
padding: 2px 4px;
font-size: 90%;
color: @code-color;
background-color: @code-bg;
border-radius: @border-radius-base;
}
// User input typically entered via keyboard
kbd {
padding: 2px 4px;
font-size: 90%;
color: @kbd-color;
background-color: @kbd-bg;
border-radius: @border-radius-small;
box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);
kbd {
padding: 0;
font-size: 100%;
font-weight: bold;
box-shadow: none;
}
}
// Blocks of code
pre {
display: block;
padding: ((@line-height-computed - 1) / 2);
margin: 0 0 (@line-height-computed / 2);
font-size: (@font-size-base - 1); // 14px to 13px
line-height: @line-height-base;
word-break: break-all;
word-wrap: break-word;
color: @pre-color;
background-color: @pre-bg;
border: 1px solid @pre-border-color;
border-radius: @border-radius-base;
// Account for some code outputs that place code tags in pre tags
code {
padding: 0;
font-size: inherit;
color: inherit;
white-space: pre-wrap;
background-color: transparent;
border-radius: 0;
}
}
// Enable scrollable blocks of code
.pre-scrollable {
max-height: @pre-scrollable-max-height;
overflow-y: scroll;
}

View File

@ -1,34 +0,0 @@
//
// Component animations
// --------------------------------------------------
// Heads up!
//
// We don't use the `.opacity()` mixin here since it causes a bug with text
// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.
.fade {
opacity: 0;
.transition(opacity .15s linear);
&.in {
opacity: 1;
}
}
.collapse {
display: none;
visibility: hidden;
&.in { display: block; visibility: visible; }
tr&.in { display: table-row; }
tbody&.in { display: table-row-group; }
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
.transition-property(~"height, visibility");
.transition-duration(.35s);
.transition-timing-function(ease);
}

View File

@ -1,213 +0,0 @@
//
// Dropdown menus
// --------------------------------------------------
// Dropdown arrow/caret
.caret {
display: inline-block;
width: 0;
height: 0;
margin-left: 2px;
vertical-align: middle;
border-top: @caret-width-base solid;
border-right: @caret-width-base solid transparent;
border-left: @caret-width-base solid transparent;
}
// The dropdown wrapper (div)
.dropdown {
position: relative;
}
// Prevent the focus on the dropdown toggle when closing dropdowns
.dropdown-toggle:focus {
outline: 0;
}
// The dropdown menu (ul)
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: @zindex-dropdown;
display: none; // none by default, but block on "open" of the menu
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0; // override default ul
list-style: none;
font-size: @font-size-base;
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
background-color: @dropdown-bg;
border: 1px solid @dropdown-fallback-border; // IE8 fallback
border: 1px solid @dropdown-border;
border-radius: @border-radius-base;
.box-shadow(0 6px 12px rgba(0,0,0,.175));
background-clip: padding-box;
// Aligns the dropdown menu to right
//
// Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`
&.pull-right {
right: 0;
left: auto;
}
// Dividers (basically an hr) within the dropdown
.divider {
.nav-divider(@dropdown-divider-bg);
}
// Links within the dropdown menu
> li > a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: @line-height-base;
color: @dropdown-link-color;
white-space: nowrap; // prevent links from randomly breaking onto new lines
}
}
// Hover/Focus state
.dropdown-menu > li > a {
&:hover,
&:focus {
text-decoration: none;
color: @dropdown-link-hover-color;
background-color: @dropdown-link-hover-bg;
}
}
// Active state
.dropdown-menu > .active > a {
&,
&:hover,
&:focus {
color: @dropdown-link-active-color;
text-decoration: none;
outline: 0;
background-color: @dropdown-link-active-bg;
}
}
// Disabled state
//
// Gray out text and ensure the hover/focus state remains gray
.dropdown-menu > .disabled > a {
&,
&:hover,
&:focus {
color: @dropdown-link-disabled-color;
}
// Nuke hover/focus effects
&:hover,
&:focus {
text-decoration: none;
background-color: transparent;
background-image: none; // Remove CSS gradient
.reset-filter();
cursor: @cursor-disabled;
}
}
// Open state for the dropdown
.open {
// Show the menu
> .dropdown-menu {
display: block;
}
// Remove the outline when :focus is triggered
> a {
outline: 0;
}
}
// Menu positioning
//
// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown
// menu with the parent.
.dropdown-menu-right {
left: auto; // Reset the default from `.dropdown-menu`
right: 0;
}
// With v3, we enabled auto-flipping if you have a dropdown within a right
// aligned nav component. To enable the undoing of that, we provide an override
// to restore the default dropdown menu alignment.
//
// This is only for left-aligning a dropdown menu within a `.navbar-right` or
// `.pull-right` nav component.
.dropdown-menu-left {
left: 0;
right: auto;
}
// Dropdown section headers
.dropdown-header {
display: block;
padding: 3px 20px;
font-size: @font-size-small;
line-height: @line-height-base;
color: @dropdown-header-color;
white-space: nowrap; // as with > li > a
}
// Backdrop to catch body clicks on mobile, etc.
.dropdown-backdrop {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: (@zindex-dropdown - 10);
}
// Right aligned dropdowns
.pull-right > .dropdown-menu {
right: 0;
left: auto;
}
// Allow for dropdowns to go bottom up (aka, dropup-menu)
//
// Just add .dropup after the standard .dropdown class and you're set, bro.
// TODO: abstract this so that the navbar fixed styles are not placed here?
.dropup,
.navbar-fixed-bottom .dropdown {
// Reverse the caret
.caret {
border-top: 0;
border-bottom: @caret-width-base solid;
content: "";
}
// Different positioning for bottom up menu
.dropdown-menu {
top: auto;
bottom: 100%;
margin-bottom: 1px;
}
}
// Component alignment
//
// Reiterate per navbar.less and the modified component alignment there.
@media (min-width: @grid-float-breakpoint) {
.navbar-right {
.dropdown-menu {
.dropdown-menu-right();
}
// Necessary for overrides of the default right aligned menu.
// Will remove come v4 in all likelihood.
.dropdown-menu-left {
.dropdown-menu-left();
}
}
}

View File

@ -1,546 +0,0 @@
//
// Forms
// --------------------------------------------------
// Normalize non-controls
//
// Restyle and baseline non-control form elements.
fieldset {
padding: 0;
margin: 0;
border: 0;
// Chrome and Firefox set a `min-width: min-content;` on fieldsets,
// so we reset that to ensure it behaves more like a standard block element.
// See https://github.com/twbs/bootstrap/issues/12359.
min-width: 0;
}
legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: @line-height-computed;
font-size: (@font-size-base * 1.5);
line-height: inherit;
color: @legend-color;
border: 0;
border-bottom: 1px solid @legend-border-color;
}
label {
display: inline-block;
//max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)
margin-bottom: 5px;
font-weight: bold;
}
// Normalize form controls
//
// While most of our form styles require extra classes, some basic normalization
// is required to ensure optimum display with or without those classes to better
// address browser inconsistencies.
// Override content-box in Normalize (* isn't specific enough)
input[type="search"] {
.box-sizing(border-box);
}
// Position radios and checkboxes better
input[type="radio"],
input[type="checkbox"] {
margin: 4px 0 0;
margin-top: 1px \9; // IE8-9
line-height: normal;
}
// Set the height of file controls to match text inputs
input[type="file"] {
display: block;
}
// Make range inputs behave like textual form controls
input[type="range"] {
display: block;
width: 100%;
}
// Make multiple select elements height not fixed
select[multiple],
select[size] {
height: auto;
}
// Focus for file, radio, and checkbox
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
.tab-focus();
}
// Adjust output element
output {
display: block;
padding-top: (@padding-base-vertical + 1);
font-size: @font-size-base;
line-height: @line-height-base;
color: @input-color;
}
// Common form controls
//
// Shared size and type resets for form controls. Apply `.form-control` to any
// of the following form controls:
//
// select
// textarea
// input[type="text"]
// input[type="password"]
// input[type="datetime"]
// input[type="datetime-local"]
// input[type="date"]
// input[type="month"]
// input[type="time"]
// input[type="week"]
// input[type="number"]
// input[type="email"]
// input[type="url"]
// input[type="search"]
// input[type="tel"]
// input[type="color"]
.form-control {
display: block;
width: 100%;
height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
padding: @padding-base-vertical @padding-base-horizontal;
font-size: @font-size-base;
line-height: @line-height-base;
color: @input-color;
background-color: @input-bg;
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
border: 1px solid @input-border;
border-radius: @input-border-radius;
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
.transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s");
// Customize the `:focus` state to imitate native WebKit styles.
.form-control-focus();
// Placeholder
.placeholder();
// Disabled and read-only inputs
//
// HTML5 says that controls under a fieldset > legend:first-child won't be
// disabled if the fieldset is disabled. Due to implementation difficulty, we
// don't honor that edge case; we style them as disabled anyway.
&[disabled],
&[readonly],
fieldset[disabled] & {
cursor: @cursor-disabled;
background-color: @input-bg-disabled;
opacity: 1; // iOS fix for unreadable disabled content
}
// Reset height for `textarea`s
textarea& {
height: auto;
}
}
// Search inputs in iOS
//
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
input[type="search"] {
-webkit-appearance: none;
}
// Special styles for iOS temporal inputs
//
// In Mobile Safari, setting `display: block` on temporal inputs causes the
// text within the input to become vertically misaligned. As a workaround, we
// set a pixel line-height that matches the given height of the input, but only
// for Safari.
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
line-height: @input-height-base;
}
input[type="date"].input-sm,
input[type="time"].input-sm,
input[type="datetime-local"].input-sm,
input[type="month"].input-sm {
line-height: @input-height-small;
}
input[type="date"].input-lg,
input[type="time"].input-lg,
input[type="datetime-local"].input-lg,
input[type="month"].input-lg {
line-height: @input-height-large;
}
}
// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.
.form-group {
margin-bottom: 15px;
}
// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.
.radio,
.checkbox {
position: relative;
display: block;
margin-top: 10px;
margin-bottom: 10px;
label {
min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text
padding-left: 20px;
margin-bottom: 0;
font-weight: normal;
cursor: pointer;
}
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
position: absolute;
margin-left: -20px;
margin-top: 4px \9;
}
.radio + .radio,
.checkbox + .checkbox {
margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
}
// Radios and checkboxes on same line
.radio-inline,
.checkbox-inline {
display: inline-block;
padding-left: 20px;
margin-bottom: 0;
vertical-align: middle;
font-weight: normal;
cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
margin-top: 0;
margin-left: 10px; // space out consecutive inline controls
}
// Apply same disabled cursor tweak as for inputs
// Some special care is needed because <label>s don't inherit their parent's `cursor`.
//
// Note: Neither radios nor checkboxes can be readonly.
input[type="radio"],
input[type="checkbox"] {
&[disabled],
&.disabled,
fieldset[disabled] & {
cursor: @cursor-disabled;
}
}
// These classes are used directly on <label>s
.radio-inline,
.checkbox-inline {
&.disabled,
fieldset[disabled] & {
cursor: @cursor-disabled;
}
}
// These classes are used on elements with <label> descendants
.radio,
.checkbox {
&.disabled,
fieldset[disabled] & {
label {
cursor: @cursor-disabled;
}
}
}
// Static form control text
//
// Apply class to a `p` element to make any string of text align with labels in
// a horizontal form layout.
.form-control-static {
// Size it appropriately next to real form controls
padding-top: (@padding-base-vertical + 1);
padding-bottom: (@padding-base-vertical + 1);
// Remove default margin from `p`
margin-bottom: 0;
&.input-lg,
&.input-sm {
padding-left: 0;
padding-right: 0;
}
}
// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
.input-sm,
.form-group-sm .form-control {
.input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);
}
.input-lg,
.form-group-lg .form-control {
.input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);
}
// Form control feedback states
//
// Apply contextual and semantic states to individual form controls.
.has-feedback {
// Enable absolute positioning
position: relative;
// Ensure icons don't overlap text
.form-control {
padding-right: (@input-height-base * 1.25);
}
}
// Feedback icon (requires .glyphicon classes)
.form-control-feedback {
position: absolute;
top: 0;
right: 0;
z-index: 2; // Ensure icon is above input groups
display: block;
width: @input-height-base;
height: @input-height-base;
line-height: @input-height-base;
text-align: center;
pointer-events: none;
}
.input-lg + .form-control-feedback {
width: @input-height-large;
height: @input-height-large;
line-height: @input-height-large;
}
.input-sm + .form-control-feedback {
width: @input-height-small;
height: @input-height-small;
line-height: @input-height-small;
}
// Feedback states
.has-success {
.form-control-validation(@state-success-text; @state-success-text; @state-success-bg);
}
.has-warning {
.form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);
}
.has-error {
.form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
}
// Reposition feedback icon if input has visible label above
.has-feedback label {
& ~ .form-control-feedback {
top: (@line-height-computed + 5); // Height of the `label` and its margin
}
&.sr-only ~ .form-control-feedback {
top: 0;
}
}
// Help text
//
// Apply to any element you wish to create light text for placement immediately
// below a form control. Use for general help, formatting, or instructional text.
.help-block {
display: block; // account for any element using help-block
margin-top: 5px;
margin-bottom: 10px;
color: lighten(@text-color, 25%); // lighten the text some for contrast
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
//
// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
.form-inline {
// Kick in the inline
@media (min-width: @screen-sm-min) {
// Inline-block all the things for "inline"
.form-group {
display: inline-block;
margin-bottom: 0;
vertical-align: middle;
}
// In navbar-form, allow folks to *not* use `.form-group`
.form-control {
display: inline-block;
width: auto; // Prevent labels from stacking above inputs in `.form-group`
vertical-align: middle;
}
// Make static controls behave like regular ones
.form-control-static {
display: inline-block;
}
.input-group {
display: inline-table;
vertical-align: middle;
.input-group-addon,
.input-group-btn,
.form-control {
width: auto;
}
}
// Input groups need that 100% width though
.input-group > .form-control {
width: 100%;
}
.control-label {
margin-bottom: 0;
vertical-align: middle;
}
// Remove default margin on radios/checkboxes that were used for stacking, and
// then undo the floating of radios and checkboxes to match (which also avoids
// a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).
.radio,
.checkbox {
display: inline-block;
margin-top: 0;
margin-bottom: 0;
vertical-align: middle;
label {
padding-left: 0;
}
}
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
position: relative;
margin-left: 0;
}
// Re-override the feedback icon.
.has-feedback .form-control-feedback {
top: 0;
}
}
}
// Horizontal forms
//
// Horizontal forms are built on grid classes and allow you to create forms with
// labels on the left and inputs on the right.
.form-horizontal {
// Consistent vertical alignment of radios and checkboxes
//
// Labels also get some reset styles, but that is scoped to a media query below.
.radio,
.checkbox,
.radio-inline,
.checkbox-inline {
margin-top: 0;
margin-bottom: 0;
padding-top: (@padding-base-vertical + 1); // Default padding plus a border
}
// Account for padding we're adding to ensure the alignment and of help text
// and other content below items
.radio,
.checkbox {
min-height: (@line-height-computed + (@padding-base-vertical + 1));
}
// Make form groups behave like rows
.form-group {
.make-row();
}
// Reset spacing and right align labels, but scope to media queries so that
// labels on narrow viewports stack the same as a default form example.
@media (min-width: @screen-sm-min) {
.control-label {
text-align: right;
margin-bottom: 0;
padding-top: (@padding-base-vertical + 1); // Default padding plus a border
}
}
// Validation states
//
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
.has-feedback .form-control-feedback {
right: (@grid-gutter-width / 2);
}
// Form group sizes
//
// Quick utility class for applying `.input-lg` and `.input-sm` styles to the
// inputs and labels within a `.form-group`.
.form-group-lg {
@media (min-width: @screen-sm-min) {
.control-label {
padding-top: ((@padding-large-vertical * @line-height-large) + 1);
}
}
}
.form-group-sm {
@media (min-width: @screen-sm-min) {
.control-label {
padding-top: (@padding-small-vertical + 1);
}
}
}
}

View File

@ -1,234 +0,0 @@
//
// Glyphicons for Bootstrap
//
// Since icons are fonts, they can be placed anywhere text is placed and are
// thus automatically sized to match the surrounding child. To use, create an
// inline element with the appropriate classes, like so:
//
// <a href="#"><span class="glyphicon glyphicon-star"></span> Star</a>
// Import the fonts
@font-face {
font-family: 'Glyphicons Halflings';
src: url('@{icon-font-path}@{icon-font-name}.eot');
src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),
url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),
url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),
url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');
}
// Catchall baseclass
.glyphicon {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
// Individual icons
.glyphicon-asterisk { &:before { content: "\2a"; } }
.glyphicon-plus { &:before { content: "\2b"; } }
.glyphicon-euro,
.glyphicon-eur { &:before { content: "\20ac"; } }
.glyphicon-minus { &:before { content: "\2212"; } }
.glyphicon-cloud { &:before { content: "\2601"; } }
.glyphicon-envelope { &:before { content: "\2709"; } }
.glyphicon-pencil { &:before { content: "\270f"; } }
.glyphicon-glass { &:before { content: "\e001"; } }
.glyphicon-music { &:before { content: "\e002"; } }
.glyphicon-search { &:before { content: "\e003"; } }
.glyphicon-heart { &:before { content: "\e005"; } }
.glyphicon-star { &:before { content: "\e006"; } }
.glyphicon-star-empty { &:before { content: "\e007"; } }
.glyphicon-user { &:before { content: "\e008"; } }
.glyphicon-film { &:before { content: "\e009"; } }
.glyphicon-th-large { &:before { content: "\e010"; } }
.glyphicon-th { &:before { content: "\e011"; } }
.glyphicon-th-list { &:before { content: "\e012"; } }
.glyphicon-ok { &:before { content: "\e013"; } }
.glyphicon-remove { &:before { content: "\e014"; } }
.glyphicon-zoom-in { &:before { content: "\e015"; } }
.glyphicon-zoom-out { &:before { content: "\e016"; } }
.glyphicon-off { &:before { content: "\e017"; } }
.glyphicon-signal { &:before { content: "\e018"; } }
.glyphicon-cog { &:before { content: "\e019"; } }
.glyphicon-trash { &:before { content: "\e020"; } }
.glyphicon-home { &:before { content: "\e021"; } }
.glyphicon-file { &:before { content: "\e022"; } }
.glyphicon-time { &:before { content: "\e023"; } }
.glyphicon-road { &:before { content: "\e024"; } }
.glyphicon-download-alt { &:before { content: "\e025"; } }
.glyphicon-download { &:before { content: "\e026"; } }
.glyphicon-upload { &:before { content: "\e027"; } }
.glyphicon-inbox { &:before { content: "\e028"; } }
.glyphicon-play-circle { &:before { content: "\e029"; } }
.glyphicon-repeat { &:before { content: "\e030"; } }
.glyphicon-refresh { &:before { content: "\e031"; } }
.glyphicon-list-alt { &:before { content: "\e032"; } }
.glyphicon-lock { &:before { content: "\e033"; } }
.glyphicon-flag { &:before { content: "\e034"; } }
.glyphicon-headphones { &:before { content: "\e035"; } }
.glyphicon-volume-off { &:before { content: "\e036"; } }
.glyphicon-volume-down { &:before { content: "\e037"; } }
.glyphicon-volume-up { &:before { content: "\e038"; } }
.glyphicon-qrcode { &:before { content: "\e039"; } }
.glyphicon-barcode { &:before { content: "\e040"; } }
.glyphicon-tag { &:before { content: "\e041"; } }
.glyphicon-tags { &:before { content: "\e042"; } }
.glyphicon-book { &:before { content: "\e043"; } }
.glyphicon-bookmark { &:before { content: "\e044"; } }
.glyphicon-print { &:before { content: "\e045"; } }
.glyphicon-camera { &:before { content: "\e046"; } }
.glyphicon-font { &:before { content: "\e047"; } }
.glyphicon-bold { &:before { content: "\e048"; } }
.glyphicon-italic { &:before { content: "\e049"; } }
.glyphicon-text-height { &:before { content: "\e050"; } }
.glyphicon-text-width { &:before { content: "\e051"; } }
.glyphicon-align-left { &:before { content: "\e052"; } }
.glyphicon-align-center { &:before { content: "\e053"; } }
.glyphicon-align-right { &:before { content: "\e054"; } }
.glyphicon-align-justify { &:before { content: "\e055"; } }
.glyphicon-list { &:before { content: "\e056"; } }
.glyphicon-indent-left { &:before { content: "\e057"; } }
.glyphicon-indent-right { &:before { content: "\e058"; } }
.glyphicon-facetime-video { &:before { content: "\e059"; } }
.glyphicon-picture { &:before { content: "\e060"; } }
.glyphicon-map-marker { &:before { content: "\e062"; } }
.glyphicon-adjust { &:before { content: "\e063"; } }
.glyphicon-tint { &:before { content: "\e064"; } }
.glyphicon-edit { &:before { content: "\e065"; } }
.glyphicon-share { &:before { content: "\e066"; } }
.glyphicon-check { &:before { content: "\e067"; } }
.glyphicon-move { &:before { content: "\e068"; } }
.glyphicon-step-backward { &:before { content: "\e069"; } }
.glyphicon-fast-backward { &:before { content: "\e070"; } }
.glyphicon-backward { &:before { content: "\e071"; } }
.glyphicon-play { &:before { content: "\e072"; } }
.glyphicon-pause { &:before { content: "\e073"; } }
.glyphicon-stop { &:before { content: "\e074"; } }
.glyphicon-forward { &:before { content: "\e075"; } }
.glyphicon-fast-forward { &:before { content: "\e076"; } }
.glyphicon-step-forward { &:before { content: "\e077"; } }
.glyphicon-eject { &:before { content: "\e078"; } }
.glyphicon-chevron-left { &:before { content: "\e079"; } }
.glyphicon-chevron-right { &:before { content: "\e080"; } }
.glyphicon-plus-sign { &:before { content: "\e081"; } }
.glyphicon-minus-sign { &:before { content: "\e082"; } }
.glyphicon-remove-sign { &:before { content: "\e083"; } }
.glyphicon-ok-sign { &:before { content: "\e084"; } }
.glyphicon-question-sign { &:before { content: "\e085"; } }
.glyphicon-info-sign { &:before { content: "\e086"; } }
.glyphicon-screenshot { &:before { content: "\e087"; } }
.glyphicon-remove-circle { &:before { content: "\e088"; } }
.glyphicon-ok-circle { &:before { content: "\e089"; } }
.glyphicon-ban-circle { &:before { content: "\e090"; } }
.glyphicon-arrow-left { &:before { content: "\e091"; } }
.glyphicon-arrow-right { &:before { content: "\e092"; } }
.glyphicon-arrow-up { &:before { content: "\e093"; } }
.glyphicon-arrow-down { &:before { content: "\e094"; } }
.glyphicon-share-alt { &:before { content: "\e095"; } }
.glyphicon-resize-full { &:before { content: "\e096"; } }
.glyphicon-resize-small { &:before { content: "\e097"; } }
.glyphicon-exclamation-sign { &:before { content: "\e101"; } }
.glyphicon-gift { &:before { content: "\e102"; } }
.glyphicon-leaf { &:before { content: "\e103"; } }
.glyphicon-fire { &:before { content: "\e104"; } }
.glyphicon-eye-open { &:before { content: "\e105"; } }
.glyphicon-eye-close { &:before { content: "\e106"; } }
.glyphicon-warning-sign { &:before { content: "\e107"; } }
.glyphicon-plane { &:before { content: "\e108"; } }
.glyphicon-calendar { &:before { content: "\e109"; } }
.glyphicon-random { &:before { content: "\e110"; } }
.glyphicon-comment { &:before { content: "\e111"; } }
.glyphicon-magnet { &:before { content: "\e112"; } }
.glyphicon-chevron-up { &:before { content: "\e113"; } }
.glyphicon-chevron-down { &:before { content: "\e114"; } }
.glyphicon-retweet { &:before { content: "\e115"; } }
.glyphicon-shopping-cart { &:before { content: "\e116"; } }
.glyphicon-folder-close { &:before { content: "\e117"; } }
.glyphicon-folder-open { &:before { content: "\e118"; } }
.glyphicon-resize-vertical { &:before { content: "\e119"; } }
.glyphicon-resize-horizontal { &:before { content: "\e120"; } }
.glyphicon-hdd { &:before { content: "\e121"; } }
.glyphicon-bullhorn { &:before { content: "\e122"; } }
.glyphicon-bell { &:before { content: "\e123"; } }
.glyphicon-certificate { &:before { content: "\e124"; } }
.glyphicon-thumbs-up { &:before { content: "\e125"; } }
.glyphicon-thumbs-down { &:before { content: "\e126"; } }
.glyphicon-hand-right { &:before { content: "\e127"; } }
.glyphicon-hand-left { &:before { content: "\e128"; } }
.glyphicon-hand-up { &:before { content: "\e129"; } }
.glyphicon-hand-down { &:before { content: "\e130"; } }
.glyphicon-circle-arrow-right { &:before { content: "\e131"; } }
.glyphicon-circle-arrow-left { &:before { content: "\e132"; } }
.glyphicon-circle-arrow-up { &:before { content: "\e133"; } }
.glyphicon-circle-arrow-down { &:before { content: "\e134"; } }
.glyphicon-globe { &:before { content: "\e135"; } }
.glyphicon-wrench { &:before { content: "\e136"; } }
.glyphicon-tasks { &:before { content: "\e137"; } }
.glyphicon-filter { &:before { content: "\e138"; } }
.glyphicon-briefcase { &:before { content: "\e139"; } }
.glyphicon-fullscreen { &:before { content: "\e140"; } }
.glyphicon-dashboard { &:before { content: "\e141"; } }
.glyphicon-paperclip { &:before { content: "\e142"; } }
.glyphicon-heart-empty { &:before { content: "\e143"; } }
.glyphicon-link { &:before { content: "\e144"; } }
.glyphicon-phone { &:before { content: "\e145"; } }
.glyphicon-pushpin { &:before { content: "\e146"; } }
.glyphicon-usd { &:before { content: "\e148"; } }
.glyphicon-gbp { &:before { content: "\e149"; } }
.glyphicon-sort { &:before { content: "\e150"; } }
.glyphicon-sort-by-alphabet { &:before { content: "\e151"; } }
.glyphicon-sort-by-alphabet-alt { &:before { content: "\e152"; } }
.glyphicon-sort-by-order { &:before { content: "\e153"; } }
.glyphicon-sort-by-order-alt { &:before { content: "\e154"; } }
.glyphicon-sort-by-attributes { &:before { content: "\e155"; } }
.glyphicon-sort-by-attributes-alt { &:before { content: "\e156"; } }
.glyphicon-unchecked { &:before { content: "\e157"; } }
.glyphicon-expand { &:before { content: "\e158"; } }
.glyphicon-collapse-down { &:before { content: "\e159"; } }
.glyphicon-collapse-up { &:before { content: "\e160"; } }
.glyphicon-log-in { &:before { content: "\e161"; } }
.glyphicon-flash { &:before { content: "\e162"; } }
.glyphicon-log-out { &:before { content: "\e163"; } }
.glyphicon-new-window { &:before { content: "\e164"; } }
.glyphicon-record { &:before { content: "\e165"; } }
.glyphicon-save { &:before { content: "\e166"; } }
.glyphicon-open { &:before { content: "\e167"; } }
.glyphicon-saved { &:before { content: "\e168"; } }
.glyphicon-import { &:before { content: "\e169"; } }
.glyphicon-export { &:before { content: "\e170"; } }
.glyphicon-send { &:before { content: "\e171"; } }
.glyphicon-floppy-disk { &:before { content: "\e172"; } }
.glyphicon-floppy-saved { &:before { content: "\e173"; } }
.glyphicon-floppy-remove { &:before { content: "\e174"; } }
.glyphicon-floppy-save { &:before { content: "\e175"; } }
.glyphicon-floppy-open { &:before { content: "\e176"; } }
.glyphicon-credit-card { &:before { content: "\e177"; } }
.glyphicon-transfer { &:before { content: "\e178"; } }
.glyphicon-cutlery { &:before { content: "\e179"; } }
.glyphicon-header { &:before { content: "\e180"; } }
.glyphicon-compressed { &:before { content: "\e181"; } }
.glyphicon-earphone { &:before { content: "\e182"; } }
.glyphicon-phone-alt { &:before { content: "\e183"; } }
.glyphicon-tower { &:before { content: "\e184"; } }
.glyphicon-stats { &:before { content: "\e185"; } }
.glyphicon-sd-video { &:before { content: "\e186"; } }
.glyphicon-hd-video { &:before { content: "\e187"; } }
.glyphicon-subtitles { &:before { content: "\e188"; } }
.glyphicon-sound-stereo { &:before { content: "\e189"; } }
.glyphicon-sound-dolby { &:before { content: "\e190"; } }
.glyphicon-sound-5-1 { &:before { content: "\e191"; } }
.glyphicon-sound-6-1 { &:before { content: "\e192"; } }
.glyphicon-sound-7-1 { &:before { content: "\e193"; } }
.glyphicon-copyright-mark { &:before { content: "\e194"; } }
.glyphicon-registration-mark { &:before { content: "\e195"; } }
.glyphicon-cloud-download { &:before { content: "\e197"; } }
.glyphicon-cloud-upload { &:before { content: "\e198"; } }
.glyphicon-tree-conifer { &:before { content: "\e199"; } }
.glyphicon-tree-deciduous { &:before { content: "\e200"; } }

Some files were not shown because too many files have changed in this diff Show More