diff --git a/Gruntfile.js b/Gruntfile.js
index bb4229f0c5..90bc67f49e 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -35,10 +35,41 @@ module.exports = function (grunt) {
'client/lib/bootstrap.min.js',
'client/lib/bootstrap-datepicker.js',
'client/lib/bull.js',
+ 'client/lib/marked.min.js',
+
'client/src/namespace.js',
'client/src/exceptions.js',
'client/src/loader.js',
- 'client/src/utils.js'
+ 'client/src/utils.js',
+
+ 'client/src/acl.js',
+ 'client/src/model.js',
+ 'client/src/model-offline.js',
+ 'client/src/ajax.js',
+ 'client/src/controller.js',
+
+ 'client/src/ui.js',
+ 'client/src/acl-manager.js',
+ 'client/src/cache.js',
+ 'client/src/storage.js',
+ 'client/src/models/settings.js',
+ 'client/src/language.js',
+ 'client/src/metadata.js',
+ 'client/src/field-manager.js',
+ 'client/src/models/user.js',
+ 'client/src/models/preferences.js',
+ 'client/src/model-factory.js',
+ 'client/src/collection-factory.js',
+ 'client/src/pre-loader.js',
+ 'client/src/controllers/base.js',
+ 'client/src/router.js',
+ 'client/src/date-time.js',
+ 'client/src/layout-manager.js',
+ 'client/src/theme-manager.js',
+ 'client/src/session-storage.js',
+ 'client/src/view-helper.js',
+
+ 'client/src/app.js'
];
function camelCaseToHyphen (string){
diff --git a/client/cfg/pre-load.json b/client/cfg/pre-load.json
index 30bf7b6dfe..2395ba2607 100644
--- a/client/cfg/pre-load.json
+++ b/client/cfg/pre-load.json
@@ -6,10 +6,10 @@
"header",
"list",
"login",
- "modals.edit",
- "modals.select-records",
- "site.header",
- "site.navbar"
+ "modals/edit",
+ "modals/select-records",
+ "site/header",
+ "site/navbar"
],
"layoutTypes": [
"columns-2",
diff --git a/client/src/app.js b/client/src/app.js
index 93f2595a5b..2576ef392b 100644
--- a/client/src/app.js
+++ b/client/src/app.js
@@ -44,15 +44,37 @@ Espo.define(
'model-factory',
'collection-factory',
'pre-loader',
- 'view-helper',
'controllers/base',
'router',
'date-time',
'layout-manager',
'theme-manager',
- 'session-storage'
+ 'session-storage',
+ 'view-helper'
],
- function (Ui, Utils, AclManager, Cache, Storage, Settings, Language, Metadata, FieldManager, User, Preferences, ModelFactory, CollectionFactory, PreLoader, ViewHelper, BaseController, Router, DateTime, LayoutManager, ThemeManager, SessionStorage) {
+ function (
+ Ui,
+ Utils,
+ AclManager,
+ Cache,
+ Storage,
+ Settings,
+ Language,
+ Metadata,
+ FieldManager,
+ User,
+ Preferences,
+ ModelFactory,
+ CollectionFactory,
+ PreLoader,
+ BaseController,
+ Router,
+ DateTime,
+ LayoutManager,
+ ThemeManager,
+ SessionStorage,
+ ViewHelper
+ ) {
var App = function (options, callback) {
var options = options || {};
@@ -71,7 +93,7 @@ Espo.define(
this.controllers = {};
if (this.useCache) {
- this.cache = new Cache();
+ this.cache = new Cache(options.cacheTimestamp);
if (options.cacheTimestamp) {
this.cache.handleActuality(options.cacheTimestamp);
} else {
diff --git a/client/src/cache.js b/client/src/cache.js
index aaa2d0c3cd..ce481c34f5 100644
--- a/client/src/cache.js
+++ b/client/src/cache.js
@@ -28,7 +28,11 @@
Espo.define('cache', [], function () {
- var Cache = function () {
+ var Cache = function (cacheTimestamp) {
+ this.basePrefix = this.prefix;
+ if (cacheTimestamp) {
+ this.prefix = this.basePrefix + '-' + cacheTimestamp;
+ }
if (!this.get('app', 'timestamp')) {
this.storeTimestamp();
}
@@ -36,7 +40,7 @@ Espo.define('cache', [], function () {
_.extend(Cache.prototype, {
- _prefix: 'cache',
+ prefix: 'cache',
handleActuality: function (cacheTimestamp) {
var stored = parseInt(this.get('app', 'cacheTimestamp'));
@@ -58,24 +62,24 @@ Espo.define('cache', [], function () {
this.set('app', 'timestamp', frontendCacheTimestamp);
},
- _composeFullPrefix: function (type) {
- return this._prefix + '-' + type;
+ composeFullPrefix: function (type) {
+ return this.prefix + '-' + type;
},
- _composeKey: function (type, name) {
- return this._composeFullPrefix(type) + '-' + name;
+ composeKey: function (type, name) {
+ return this.composeFullPrefix(type) + '-' + name;
},
- _checkType: function (type) {
+ checkType: function (type) {
if (typeof type === 'undefined' && toString.call(type) != '[object String]') {
throw new TypeError("Bad type \"" + type + "\" passed to Cache().");
}
},
get: function (type, name) {
- this._checkType(type);
+ this.checkType(type);
- var key = this._composeKey(type, name);
+ var key = this.composeKey(type, name);
try {
var stored = localStorage.getItem(key);
@@ -101,8 +105,8 @@ Espo.define('cache', [], function () {
},
set: function (type, name, value) {
- this._checkType(type);
- var key = this._composeKey(type, name);
+ this.checkType(type);
+ var key = this.composeKey(type, name);
if (value instanceof Object || Array.isArray(value)) {
value = '__JSON__:' + JSON.stringify(value);
}
@@ -117,12 +121,12 @@ Espo.define('cache', [], function () {
var reText;
if (typeof type !== 'undefined') {
if (typeof name === 'undefined') {
- reText = '^' + this._composeFullPrefix(type);
+ reText = '^' + this.composeFullPrefix(type);
} else {
- reText = '^' + this._composeKey(type, name);
+ reText = '^' + this.composeKey(type, name);
}
} else {
- reText = '^' + this._prefix + '-';
+ reText = '^' + this.basePrefix + '-';
}
var re = new RegExp(reText);
for (var i in localStorage) {
@@ -137,7 +141,3 @@ Espo.define('cache', [], function () {
return Cache;
});
-
-
-
-
diff --git a/client/src/loader.js b/client/src/loader.js
index f346cc580c..1ff8f93f0b 100644
--- a/client/src/loader.js
+++ b/client/src/loader.js
@@ -118,7 +118,7 @@ var Espo = Espo || {classMap:{}};
if (!o) {
if (self.cache) {
- self.cache.clear('script', subject);
+ self.cache.clear('a', subject);
}
throw new Error("Could not load '" + subject + "'");
}
@@ -271,7 +271,7 @@ var Espo = Espo || {classMap:{}};
}
if (this.cache) {
- var cached = this.cache.get(type, name);
+ var cached = this.cache.get('a', name);
if (cached) {
if (type == 'class') {
this.loadingSubject = name;
@@ -321,7 +321,7 @@ var Espo = Espo || {classMap:{}};
url: this.basePath + path,
success: function (response) {
if (this.cache) {
- this.cache.set(type, name, response);
+ this.cache.set('a', name, response);
}
this._addLoadCallback(name, callback);
@@ -363,7 +363,7 @@ var Espo = Espo || {classMap:{}};
loadLib: function (url, callback) {
if (this.cache) {
- var script = this.cache.get('script', url);
+ var script = this.cache.get('a', url);
if (script) {
this._execute(script);
if (typeof callback == 'function') {
diff --git a/client/src/storage.js b/client/src/storage.js
index 8c1afdeea0..215ec820a3 100644
--- a/client/src/storage.js
+++ b/client/src/storage.js
@@ -33,35 +33,35 @@ Espo.define('storage', [], function () {
_.extend(Storage.prototype, {
- _prefix: 'espo',
+ prefix: 'espo',
storageObject: localStorage,
- _composeFullPrefix: function (type) {
- return this._prefix + '-' + type;
+ composeFullPrefix: function (type) {
+ return this.prefix + '-' + type;
},
- _composeKey: function (type, name) {
- return this._composeFullPrefix(type) + '-' + name;
+ composeKey: function (type, name) {
+ return this.composeFullPrefix(type) + '-' + name;
},
- _checkType: function (type) {
+ checkType: function (type) {
if (typeof type === 'undefined' && toString.call(type) != '[object String]' || type == 'cache') {
throw new TypeError("Bad type \"" + type + "\" passed to Espo.Storage.");
}
},
has: function (type, name) {
- this._checkType(type);
- var key = this._composeKey(type, name);
+ this.checkType(type);
+ var key = this.composeKey(type, name);
return this.storageObject.getItem(key) !== null;
},
get: function (type, name) {
- this._checkType(type);
+ this.checkType(type);
- var key = this._composeKey(type, name);
+ var key = this.composeKey(type, name);
var stored = this.storageObject.getItem(key);
if (stored) {
@@ -80,9 +80,9 @@ Espo.define('storage', [], function () {
},
set: function (type, name, value) {
- this._checkType(type);
+ this.checkType(type);
- var key = this._composeKey(type, name);
+ var key = this.composeKey(type, name);
if (value instanceof Object) {
value = JSON.stringify(value);
}
@@ -93,12 +93,12 @@ Espo.define('storage', [], function () {
var reText;
if (typeof type !== 'undefined') {
if (typeof name === 'undefined') {
- reText = '^' + this._composeFullPrefix(type);
+ reText = '^' + this.composeFullPrefix(type);
} else {
- reText = '^' + this._composeKey(type, name);
+ reText = '^' + this.composeKey(type, name);
}
} else {
- reText = '^' + this._prefix + '-';
+ reText = '^' + this.prefix + '-';
}
var re = new RegExp(reText);
for (var i in this.storageObject) {
diff --git a/client/src/view-helper.js b/client/src/view-helper.js
index cd010e3836..11f46ed8f0 100644
--- a/client/src/view-helper.js
+++ b/client/src/view-helper.js
@@ -26,7 +26,7 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
-Espo.define('view-helper', ['lib!client/lib/marked.min.js'], function () {
+Espo.define('view-helper', [], function () {
var ViewHelper = function (options) {
this.urlRegex = /(^|[^\(])(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
diff --git a/frontend/html/main.html b/frontend/html/main.html
index 716854ae15..bfc756a145 100644
--- a/frontend/html/main.html
+++ b/frontend/html/main.html
@@ -21,6 +21,7 @@
+
diff --git a/frontend/html/portal.html b/frontend/html/portal.html
index 16e998a219..7be2ceede3 100644
--- a/frontend/html/portal.html
+++ b/frontend/html/portal.html
@@ -21,6 +21,7 @@
+