import Flow from '@flowjs/ng-flow/dist/ng-flow-standalone';
const FileSaver = require('file-saver');
window.Flow = Flow;
const templateUrls = {
header: require('./header.html'),
save: require('./save-dialog.html')
}
/**
* @module avHeader
* @memberof app.ui
* @restrict E
* @description
*
* The `avHeader` directive holds the header logic of create, load and save config file. It is also responsible
* for language switch
*
*/
angular
.module('app.ui')
.directive('avHeader', avHeader);
/**
* `avHeader` directive body.
*
* @function avHeader
* @return {Object} directive body
*/
function avHeader() {
const directive = {
restrict: 'E',
templateUrl: templateUrls.header,
scope: { },
controller: Controller,
controllerAs: 'self',
bindToController: true
};
return directive;
}
function Controller($q, $mdDialog, $timeout, $rootElement, $http, events, modelManager, commonService, constants) {
'ngInject';
const self = this;
self.create = create;
self.filesSubmitted = filesSubmitted;
self.save = save;
self.setLanguage = setLanguage;
self.setTemplate = setTemplate;
// get all avialable languages and set the first one as current
self.languages = commonService.getLangs();
self.language = self.languages[0];
localStorage.setItem('fgpa-lang', self.language);
// get al value for templateUrls
self.templates = getTemplates();
self.template = self.templates[0];
// set active file name
self.saveName = self.template.file;
/**
* When create is clicked, broadcast a newModel event
* @function create
*/
function create() {
// show splash with update event as parameter
events.$broadcast(events.avShowSplash, events.avSchemaUpdate);
// set active file name
self.saveName = self.template.file;
}
/**
* Set the current language
* @function setLanguage
*/
function setLanguage() {
commonService.setLang(self.language);
localStorage.setItem('fgpa-lang', self.language);
}
/**
* Get templates available for the user from data-av-config attribute on html page
* @function getTemplates
* @return {Array} templates templates available for the user
*/
function getTemplates() {
const configAttr = $rootElement.attr('data-av-config');
let templates = [];
if (typeof configAttr !== 'undefined') {
angular.fromJson(configAttr).map(item => {
templates.push({ 'path': item, 'file': item.split('/')[item.split('/').length - 1].split('.')[0] });
});
} else {
templates = [{ 'path': 'config-default.json', 'file': 'default' }];
}
return templates;
}
/**
* Set the current template
* @function setTemplate
*/
function setTemplate() {
// load selected configuration
$http.get(self.template.path).then(obj => modelManager.setDefault(obj.data));
}
/**
* Starts file upload.
* @function filesSubmitted
* @param {Array} files uploaded array of files
*/
function filesSubmitted(files) {
if (files.length > 0) {
// show splash when new model load
events.$broadcast(events.avShowSplash);
// set active file name
self.saveName = files[0].name.replace('.json', '');
// read the file but add a timeout for the animation to start
const file = files[0];
$timeout(() => {
_readFile(file.file).then(data => modelManager.setModels(JSON.parse(data))
).catch(error => {
console.log('error upload');
});
}, constants.delayEventSplash);
}
/**
* Reads HTML5 File object data.
* @private
* @param {File} file a file object to read
* @param {Function} progressCallback a function which is called during the process of reading file indicating how much of the total data has been read
* @return {Promise} promise resolving with file's data
*/
function _readFile(file) {
const dataPromise = $q((resolve, reject) => {
const reader = new FileReader();
reader.onerror = () => {
reject('Failed to read a file');
};
reader.onload = () =>
resolve(reader.result);
reader.readAsText(file);
});
return dataPromise;
}
}
/**
* Open a dialog window to save current model
* @function save
*/
function save() {
// FIXME: we can't know the real saved file name because FileSaver.onwriteend doesn/t workaround
// so if there is duplicate name the name will become nyname(1) on disk but will be myname on display
$mdDialog.show({
controller: SaveController,
controllerAs: 'self',
templateUrl: templateUrls.save,
parent: $('.fgpa'),
disableParentScroll: false,
clickOutsideToClose: true,
fullscreen: false,
onRemoving: element => { self.saveName = element[0].getElementsByTagName('input')[0].value; }
});
}
function SaveController($mdDialog, constants) {
'ngInject';
const self = this;
self.close = $mdDialog.hide;
self.cancel = $mdDialog.hide;
self.save = save;
self.fileName = '';
/**
* Save current models to file
* @function save
*/
function save() {
// save the file. Some browsers like IE and Edge doesn't support File constructor, use blob
// https://stackoverflow.com/questions/39266801/saving-file-on-ie11-with-filesaver
const file = new Blob([modelManager.save()], { type: 'application/json' });
FileSaver.saveAs(file, `${self.fileName}.json`);
self.close();
}
}
}