salix/front/core/lib/module-loader.js

110 lines
3.6 KiB
JavaScript

import ngModule from '../module';
import moduleImport from 'module-import';
factory.$inject = ['$http', '$window', '$ocLazyLoad', '$translatePartialLoader', '$translate', '$q'];
export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $translate, $q) {
/**
* Used to load application modules lazily.
*/
class ModuleLoader {
constructor() {
this.loaded = {};
this.imports = {};
this.moduleImport = moduleImport;
this.modelInfo = $http.get(`Schemas/modelInfo`)
.then(json => {
this.onModelInfoReady(json);
this.modelInfo = true;
});
}
/**
* Loads the passed module and it's dependencies. Loading a module
* implies load the webpack chunk, translations, recursively load
* module dependencies and finally register all of them into Angular.
*
* @param {String} mod The module name to load
* @return {Promise} Will be resolved when loaded, when module is
* already loaded it returns a resolved promise
*/
load(mod) {
let mods = [];
return this.loadRec(mod, mods);
}
loadRec(mod, mods) {
let loaded = this.loaded[mod];
if (loaded === true || mods.indexOf(mod) != -1)
return $q.resolve(true);
if (loaded instanceof $q)
return loaded;
let moduleConf = $window.routes.find(i => i && i.module == mod);
if (!moduleConf)
return $q.reject(new Error(`Module not found: ${mod}`));
let promises = [];
if (this.modelInfo instanceof $q)
promises.push(this.modelInfo);
$translatePartialLoader.addPart(mod);
promises.push($translate.refresh());
let modImport = this.imports[mod];
if (!modImport) {
modImport = this.imports[mod] = this.moduleImport(mod)
.then(() => this.imports[mod] = true);
}
if (modImport && modImport.then)
promises.push(modImport);
let deps = moduleConf.dependencies;
if (deps) {
mods.push(mod);
for (let dep of deps)
promises.push(this.loadRec(dep, mods));
mods.pop();
}
this.loaded[mod] = $q.all(promises)
.then(() => $ocLazyLoad.load({name: mod}))
.then(() => this.loaded[mod] = true);
return this.loaded[mod];
}
onModelInfoReady(json) {
let entities = json.data;
for (let entity in entities) {
let fields = entities[entity].validations;
for (let field in fields) {
let validations = fields[field];
for (let validation of validations)
this.parseValidation(validation);
}
}
Object.assign($window.validations, json.data);
}
parseValidation(val) {
switch (val.validation) {
case 'custom':
// TODO: Don't use eval() because it's "evil".
// How to do the same without eval?
val.bindedFunction = eval(`(${val.bindedFunction})`);
break;
case 'format':
val.with = new RegExp(val.with);
break;
}
}
}
return new ModuleLoader();
}
ngModule.factory('vnModuleLoader', factory);