First commit waiting for Budget Alert
This commit is contained in:
240
sophal/js/lib/dialogs.js
Normal file
240
sophal/js/lib/dialogs.js
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2005-2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var dialogs = {
|
||||
|
||||
config: {
|
||||
yesNo: false
|
||||
},
|
||||
|
||||
say: function(str) {
|
||||
return this.box(str, {
|
||||
title: _t('Information')
|
||||
});
|
||||
},
|
||||
|
||||
warn: function(str, callback) {
|
||||
return this.box(str, {
|
||||
title: _t('Warning'),
|
||||
onClose: callback
|
||||
});
|
||||
},
|
||||
|
||||
error: function(str, callback) {
|
||||
return this.box(str, {
|
||||
title: _t('Error'),
|
||||
onClose: callback
|
||||
});
|
||||
},
|
||||
|
||||
confirm: function(str, callback, options) {
|
||||
var element = null,
|
||||
opts = null,
|
||||
cb = angular.noop,
|
||||
doCall = true;
|
||||
|
||||
for (var i = 1; i < 3; i++) {
|
||||
var arg = arguments[i];
|
||||
if (_.isFunction(arg)) cb = arg;
|
||||
if (_.isObject(arg)) opts = arg;
|
||||
}
|
||||
|
||||
opts = _.extend({
|
||||
title: _t('Question')
|
||||
}, this.config, opts);
|
||||
|
||||
var titleOK = opts.yesNo ? _t('Yes') : _t('OK');
|
||||
var titleCancel = opts.yesNo ? _t('No') : _t('Cancel');
|
||||
|
||||
element = this.box(str, {
|
||||
title: opts.title,
|
||||
onClose: function() {
|
||||
if (doCall) cb(false);
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
text: titleCancel,
|
||||
'class': 'btn',
|
||||
click: function() {
|
||||
cb(false);
|
||||
doCall = false;
|
||||
element.dialog('close');
|
||||
}
|
||||
},
|
||||
{
|
||||
text: titleOK,
|
||||
'class': 'btn btn-primary',
|
||||
click: function() {
|
||||
cb(true);
|
||||
doCall = false;
|
||||
element.dialog('close');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
box: function(str, options) {
|
||||
|
||||
var opts = $.extend({}, options);
|
||||
var title = opts.title || _t('Information');
|
||||
var onClose = opts.onClose || $.noop;
|
||||
var onOpen = opts.onOpen || $.noop;
|
||||
var buttons = opts.buttons || [
|
||||
{
|
||||
'text' : _t('OK'),
|
||||
'class' : 'btn btn-primary',
|
||||
'click' : function() {
|
||||
element.dialog('close');
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var element = $('<div class="message-box" style="padding: 15px;"></div>').attr('title', title).html(str);
|
||||
var dialog = element.dialog({
|
||||
dialogClass: 'ui-dialog-responsive ui-dialog-small ui-dialog-dragged',
|
||||
resizable: false,
|
||||
draggable: true,
|
||||
autoOpen: false,
|
||||
closeOnEscape: true,
|
||||
modal: true,
|
||||
zIndex: 1100,
|
||||
open: function(e) {
|
||||
onOpen(e);
|
||||
},
|
||||
close: function(e) {
|
||||
onClose(e);
|
||||
element.dialog('destroy');
|
||||
element.remove();
|
||||
},
|
||||
show: {
|
||||
effect: 'fade',
|
||||
duration: 300
|
||||
},
|
||||
buttons: buttons
|
||||
});
|
||||
|
||||
dialog.dialog('open');
|
||||
|
||||
return dialog;
|
||||
}
|
||||
};
|
||||
|
||||
// patch ui.dialog to maintain overlay opacity
|
||||
['open', 'close', 'moveToTop'].forEach(function (name) {
|
||||
var func = $.ui.dialog.prototype[name];
|
||||
$.ui.dialog.prototype[name] = function () {
|
||||
func.apply(this, arguments);
|
||||
var all = $('body > .ui-widget-overlay').css('opacity', 0);
|
||||
var last = name === 'close' ? all.last() : $(this.overlay.$el);
|
||||
last.css('opacity', 0.3);
|
||||
};
|
||||
});
|
||||
|
||||
var elemNotifyStack = null;
|
||||
var elemNotifyText = '<div class="alert alert-block fade in">'+
|
||||
' <button type="button" class="close" data-dismiss="alert">×</button>'+
|
||||
' <h4 class="alert-heading">#title#</h4>'+
|
||||
' <p>#message#</p>'+
|
||||
'</div>';
|
||||
var elemNotifyText2 = '<div class="alert alert-block fade in">'+
|
||||
' <button type="button" class="close" data-dismiss="alert">×</button>'+
|
||||
' <strong>#title#</strong> #message#'+
|
||||
'</div>';
|
||||
|
||||
function doNotify(message, options) {
|
||||
if (elemNotifyStack === null) {
|
||||
elemNotifyStack = $('<div class="notify-stack"></div>')
|
||||
.css('position', 'fixed')
|
||||
.css('bottom', 0)
|
||||
.css('right', 10)
|
||||
.zIndex(9999999)
|
||||
.appendTo("body");
|
||||
}
|
||||
|
||||
var opts = _.extend({
|
||||
timeout: 5000
|
||||
}, options);
|
||||
var tmpl, elem;
|
||||
|
||||
tmpl = opts.alt ? elemNotifyText2 : elemNotifyText;
|
||||
tmpl = tmpl.replace("#title#", opts.title || '').replace("#message#", message);
|
||||
tmpl = axelor.sanitize(tmpl);
|
||||
|
||||
elem = $(tmpl)
|
||||
.css('margin-bottom', 7)
|
||||
.appendTo(elemNotifyStack);
|
||||
|
||||
if (opts.css) {
|
||||
elem.addClass(opts.css);
|
||||
}
|
||||
|
||||
_.delay(function () {
|
||||
if (elem) {
|
||||
elem.alert("close");
|
||||
elem = null;
|
||||
}
|
||||
}, opts.timeout);
|
||||
|
||||
elem.alert();
|
||||
}
|
||||
|
||||
var notify = {
|
||||
|
||||
info: function(message, options) {
|
||||
var opts = _.extend({
|
||||
title: _t('Information'),
|
||||
css: 'alert-info'
|
||||
}, options);
|
||||
return doNotify(message, opts);
|
||||
},
|
||||
|
||||
alert: function(message, options) {
|
||||
var opts = _.extend({
|
||||
title: _t('Alert')
|
||||
}, options);
|
||||
return doNotify(message, opts);
|
||||
},
|
||||
|
||||
success: function(message, options) {
|
||||
var opts = _.extend({
|
||||
title: _t('Success'),
|
||||
css: 'alert-primary'
|
||||
}, options);
|
||||
return doNotify(message, opts);
|
||||
},
|
||||
|
||||
error: function(message, options) {
|
||||
var opts = _.extend({
|
||||
title: _t('Error'),
|
||||
css: 'alert-error'
|
||||
}, options);
|
||||
return doNotify(message, opts);
|
||||
}
|
||||
};
|
||||
|
||||
this.axelor = this.axelor || {};
|
||||
this.axelor.dialogs = dialogs;
|
||||
this.axelor.notify = notify;
|
||||
|
||||
}).call(this);
|
||||
38
sophal/js/lib/i18n.js
Normal file
38
sophal/js/lib/i18n.js
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2005-2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var bundle = (window._t || {}).bundle || {};
|
||||
|
||||
function gettext(key) {
|
||||
var message = bundle[key] || bundle[(key||'').trim()] || key;
|
||||
if (message && arguments.length > 1) {
|
||||
for(var i = 1 ; i < arguments.length ; i++) {
|
||||
var placeholder = new RegExp('\\{' + (i-1) + '\\}', 'g');
|
||||
var value = arguments[i];
|
||||
message = message.replace(placeholder, value);
|
||||
}
|
||||
}
|
||||
return axelor.sanitize(message);
|
||||
}
|
||||
|
||||
this._t = gettext;
|
||||
|
||||
}).call(this);
|
||||
209
sophal/js/lib/tabs.js
Normal file
209
sophal/js/lib/tabs.js
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2005-2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var BSTabs = function(element) {
|
||||
this.element = $(element);
|
||||
this._setup();
|
||||
};
|
||||
|
||||
BSTabs.prototype = {
|
||||
|
||||
constructor: BSTabs,
|
||||
|
||||
_setup: function() {
|
||||
|
||||
this.$elemStrip = this.element.find('.nav-tabs-strip:first');
|
||||
this.$elemLeftScroller = this.element.find('.nav-tabs-scroll-l:first');
|
||||
this.$elemRightScroller = this.element.find('.nav-tabs-scroll-r:first');
|
||||
this.$elemMenu = this.element.find('.nav-tabs-menu:first');
|
||||
|
||||
this.$elemTabs = this.element.find('.nav-tabs:first').addClass('nav-tabs-scrollable');
|
||||
|
||||
if (this.$elemMenu.length) {
|
||||
this.$elemRightScroller.css('right', 16);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.$elemLeftScroller.click(function(){
|
||||
self._scrollLeft();
|
||||
return false;
|
||||
});
|
||||
this.$elemRightScroller.click(function(){
|
||||
self._scrollRight();
|
||||
return false;
|
||||
});
|
||||
|
||||
var _onResize = _.debounce(function () { self._adjustScroll(); }, 300);
|
||||
var _onAdjustSize = _.debounce(function () { self._adjustScroll(); });
|
||||
var _onAdjust = function(event) {
|
||||
event.stopPropagation();
|
||||
setTimeout(function (){
|
||||
self._adjustScroll();
|
||||
});
|
||||
};
|
||||
|
||||
$(window).on('resize', _onResize);
|
||||
$(document).on('adjust:size', _onAdjustSize);
|
||||
|
||||
this.element.on('adjust:tabs', _onAdjust);
|
||||
|
||||
this.$elemTabs.on("click", " > li > a", function(event){
|
||||
self._adjustTab($(this).parent(), true);
|
||||
});
|
||||
|
||||
this.element.on('$destroy', function () {
|
||||
$(window).off('resize', _onResize);
|
||||
$(document).off('adjust:size', _onAdjustSize);
|
||||
});
|
||||
},
|
||||
|
||||
_getTabsWidth: function() {
|
||||
var widthTabs = 0;
|
||||
this.$elemTabs.find('> li:visible').each(function(){
|
||||
widthTabs += $(this).outerWidth(true);
|
||||
});
|
||||
return widthTabs;
|
||||
},
|
||||
|
||||
_scrollLeft: function() {
|
||||
if (this.$elemLeftScroller.hasClass('disabled'))
|
||||
return;
|
||||
|
||||
var x = this.$elemTabs.position().left;
|
||||
var scrollTo = Math.min(0, x + 100);
|
||||
|
||||
this._scrollTabs(scrollTo, true);
|
||||
},
|
||||
|
||||
_scrollRight: function() {
|
||||
if (this.$elemRightScroller.hasClass('disabled'))
|
||||
return;
|
||||
|
||||
var x = this.$elemTabs.position().left;
|
||||
var w = this._getTabsWidth();
|
||||
|
||||
var mx = - (w - this.$elemStrip.width());
|
||||
|
||||
var scrollTo = Math.max(mx, x - 100);
|
||||
|
||||
this._scrollTabs(scrollTo, true);
|
||||
},
|
||||
|
||||
_scrollTabs: function(scrollTo, animate) {
|
||||
if (scrollTo === this._lastScrollTo) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._lastScrollTo = scrollTo;
|
||||
|
||||
if (animate) {
|
||||
var self = this;
|
||||
return this.$elemTabs.animate({
|
||||
'left': scrollTo
|
||||
}, 300, function() {
|
||||
self._activateScrollers();
|
||||
});
|
||||
}
|
||||
this.$elemTabs.css('left', scrollTo);
|
||||
this._activateScrollers();
|
||||
},
|
||||
|
||||
_activateScrollers: function() {
|
||||
|
||||
if (this.$elemTabs.position().left < 0) {
|
||||
this.$elemLeftScroller.removeClass('disabled');
|
||||
} else {
|
||||
this.$elemLeftScroller.addClass('disabled');
|
||||
}
|
||||
|
||||
if (this._getTabsWidth() + this.$elemTabs.position().left > this.$elemStrip.width() + 1) {
|
||||
this.$elemRightScroller.removeClass('disabled');
|
||||
} else {
|
||||
this.$elemRightScroller.addClass('disabled');
|
||||
}
|
||||
},
|
||||
|
||||
_adjustTab: function(tab, animate) {
|
||||
|
||||
if (!$(tab).length) return;
|
||||
|
||||
var w = this.$elemStrip.innerWidth();
|
||||
var scrollTo = this.$elemTabs.position().left;
|
||||
|
||||
var left = $(tab).position().left + scrollTo;
|
||||
var right = left + $(tab).outerWidth(true);
|
||||
|
||||
if (left < 0) {
|
||||
scrollTo -= left;
|
||||
} else if (right > w){
|
||||
scrollTo -= right - w;
|
||||
}
|
||||
|
||||
this._scrollTabs(scrollTo, animate);
|
||||
},
|
||||
|
||||
_adjustScroll: function() {
|
||||
|
||||
var widthStrip = this.$elemStrip.width();
|
||||
var widthTabs = this._getTabsWidth();
|
||||
|
||||
this.element.toggleClass("nav-tabs-overflow", widthStrip < widthTabs);
|
||||
|
||||
var scrollTo = 0;
|
||||
|
||||
if (widthStrip >= widthTabs) {
|
||||
this.$elemLeftScroller.hide();
|
||||
this.$elemRightScroller.hide();
|
||||
this.$elemMenu.hide();
|
||||
this.$elemStrip.css('margin', '0');
|
||||
} else {
|
||||
this.$elemLeftScroller.show();
|
||||
this.$elemRightScroller.show();
|
||||
this.$elemMenu.show();
|
||||
this.$elemStrip.css('margin', this.$elemMenu.length ? '0 32px 0 16px' : '0 16px');
|
||||
|
||||
var left = this.$elemTabs.position().left;
|
||||
var right = widthTabs + left;
|
||||
if (right < widthStrip) {
|
||||
scrollTo = left + (widthStrip - right);
|
||||
} else {
|
||||
var tab = this.$elemTabs.find('> li.active');
|
||||
if (tab) {
|
||||
return this._adjustTab(tab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._scrollTabs(scrollTo);
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.bsTabs = function () {
|
||||
return this.each(function () {
|
||||
var $this = $(this),
|
||||
data = $this.data('bsTabs');
|
||||
if (!data) $this.data('bsTabs', (data = new BSTabs(this)));
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.bsTabs.Constructor = BSTabs;
|
||||
|
||||
})();
|
||||
95
sophal/js/lib/utils.js
Normal file
95
sophal/js/lib/utils.js
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2005-2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
// integrate underscore.string with underscore
|
||||
_.mixin(_.str.exports());
|
||||
|
||||
var util = this.util ? this.util : this.util = {};
|
||||
|
||||
/**
|
||||
* Based on the `util.inherits` of `Node.js` with some additional features
|
||||
*
|
||||
* 1. The super prototype is attached to the base prototype as `super_`.
|
||||
* 2. The base prototype can be provided as third argument.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* function Hello(message) {
|
||||
* this.message = message;
|
||||
* }
|
||||
*
|
||||
* Hello.prototype.say = function(what) {
|
||||
* console.log(what || this.message);
|
||||
* }
|
||||
*
|
||||
* function HelloWorld(message) {
|
||||
* this.super_.constructor.apply(this, arguments);
|
||||
* }
|
||||
*
|
||||
* util.inherits(HelloWorld, Hello, {
|
||||
*
|
||||
* say: function(what) {
|
||||
* // do something
|
||||
* this.super_.say.apply(this, arguments);
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* @param ctor the base constructor
|
||||
* @param superCtor the super constructor
|
||||
* @param proto the prototype of the base constructor (optional)
|
||||
*
|
||||
* @returns the base constructor
|
||||
*/
|
||||
util.inherits = function(ctor, superCtor, /* optional */ proto) {
|
||||
|
||||
var props = {
|
||||
constructor: {
|
||||
value: ctor,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
};
|
||||
|
||||
Object.getOwnPropertyNames(proto||{}).forEach(function(name) {
|
||||
props[name] = Object.getOwnPropertyDescriptor(proto, name);
|
||||
});
|
||||
|
||||
ctor.super_ = superCtor;
|
||||
ctor.prototype = Object.create(superCtor.prototype, props);
|
||||
ctor.prototype.super_ = superCtor.prototype;
|
||||
|
||||
return ctor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut to `util.inherits`.
|
||||
*
|
||||
* @param superCtor the super constructor
|
||||
* @param proto the prototype for this contructor
|
||||
*
|
||||
* @returns this constructor itself
|
||||
*/
|
||||
Function.prototype.inherits = function(superCtor, /* optional */ proto) {
|
||||
return util.inherits(this, superCtor, proto);
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
Reference in New Issue
Block a user