/**
* Copyright (C) 1998-2018 by Northwoods Software Corporation
* All Rights Reserved.
*
* Go Cloud Storage Manager
*/
import * as go from "../../release/go";
import * as gcs from "./GoCloudStorage";
import {Promise} from "es6-promise";
/**
* Class for easily saving / loading Diagram
* models to / from a user-defined set of Cloud Storage Services with a pre-defined UI.
*
GoCloudStorageManager holds a set of {@link GoCloudStorage} subclass instances ({@link storages}) to manage. When one is selected from the
* storage selection {@link menu}, it becomes the {@link currentStorage} property, which is used to save / load / delete / create files.
* @category Storage
*/
export class GoCloudStorageManager {
private _storages: go.Set
private _currentStorage: gcs.GoCloudStorage
private _menu: HTMLElement;
private _deferredPromise: gcs.DeferredPromise;
private _iconsRelativeDirectory: string;
/**
* @constructor
* @param {go.Set} storages Contains valid instances of {@link GoCloudStorage} subclasses. Use at most one instance of each subclass.
* @param {string} iconsRelativeDirectory The directory path relative to the page in which this instance of GoCloudStorageManager exists, in which
* the storage service brand icons can be found. The default value is "../goCloudStorageIcons/".
* Note: If this parameter is supplied, it is used as for the "iconsRelativeDirectory" constructor parameter for each instance
* this instance of GoCloudStorageManager manages in {@link storages}.
*/
constructor(storages: go.Set|gcs.GoCloudStorage[], iconsRelativeDirectory?: string) {
if (storages instanceof Array) {
let storagesSet = new go.Set();
for (var i = 0; i < storages.length; i++) {
if (!(storages[i] instanceof gcs.GoCloudStorage)) {
throw Error("Cannot create GoCloudStorageManager; provided 'storages' parameter elements are not all of type GoCloudStorage");
} else {
storagesSet.add(storages[i]);
}
}
storages = storagesSet;
}
if (!(storages instanceof go.Set) || !storages) throw Error ("Cannot create GoCloudStorageManager with provided 'storages' parameter");
const storageManager = this;
storageManager._storages = storages;
storageManager._currentStorage = storages.first();
var menu = document.createElement('div');
menu.id = 'goCloudStorageManagerMenu';
storageManager._menu = menu;
storageManager._deferredPromise = { promise: gcs.GoCloudStorage.prototype.makeDeferredPromise() };
storageManager._iconsRelativeDirectory = (!!iconsRelativeDirectory) ? iconsRelativeDirectory : "../goCloudStorageIcons/";
if (iconsRelativeDirectory) {
storageManager._storages.iterator.each(function(storage){
storage.iconsRelativeDirectory = iconsRelativeDirectory;
});
}
if (window.location.href.indexOf("account_id=dbid") !== -1) {
storages.iterator.each(function(storage){
if (storage.constructor["name"] === "GoDropBox") {
storageManager._currentStorage = storage;
}
});
}
}
/**
* Get storages ({@link GoCloudStorage} subclass instances) managed by an instance of GoCloudStorageManager. At most, there should be only one instance of each subclass.
* This is set with a parameter during construction.
* @function.
* @return {go.Set}
*/
get storages(): go.Set { return this._storages }
/**
* Get / set iconsRelativeDirectory, the directory path relative to the page in which this instance of GoCloudStorageManager exists, in which
* the storage service brand icons can be found. The default value is "../goCloudStorageIcons/".
* @function.
* @return {string}
*/
get iconsRelativeDirectory(): string { return this._iconsRelativeDirectory }
set iconsRelativeDirectory(value: string) { this._iconsRelativeDirectory = value }
/**
* Get GoCloudStorageManager menu, from which a user chooses which storage service for this instance of GoCloudStorageManager to actively manage (see {@link currentStorage}).
* This is created (as a blank div) during construction. Its contents are populated during {@link selectStorageService}.
* @function.
* @return {HTMLElement}
*/
get menu(): HTMLElement { return this._menu }
/**
* Get / set the {@link GoCloudStorage} subclass this instance of GoCloudStorageManager is actively managing.
* @function.
* @return {gcs.GoCloudStorage}
*/
get currentStorage() { return this._currentStorage }
set currentStorage(value: gcs.GoCloudStorage) { this._currentStorage = value }
/**
* Creates a new diagram with {@link currentStorage}'s default model data (see {@link GoCloudStorage.defaultModel}.
* If currentStorage.isAutoSaving is true, prompt to save it to to currentStorage's storage service.
* if {@link currentStorage}'s {@link GoCloudStorage.isAutoSaving} is true).
* @return {Promise} Returns a Promise that resolves a {@link DiagramFile} representing the newly created file (if file was saved).
*/
public create() {
const storageManager = this;
return new Promise(function(resolve: Function, reject: Function){
resolve(storageManager.handleAction("Create"));
});
}
/**
* Launches the load interface for {@link currentStorage}.
* @return {Promise} Returns a Promise that resolves with a {@link DiagramFile} representing the loaded file.
*/
public load() {
const storageManager = this;
return new Promise(function (resolve: Function, reject: Function) {
resolve(storageManager.handleAction("Load"));
});
}
/**
* Launches the remove interface for {@link currentStorage}.
* @return {Promise} Returns a Promise that resolves with a {@link DiagramFile} representing the deleted file.
*/
public remove() {
const storageManager = this;
return new Promise(function (resolve: Function, reject: Function) {
resolve(storageManager.handleAction("Remove"));
});
}
/**
* Either launches the save interface for {@link currentStorage} or just saves the {@link GoCloudStorage.managedDiagrams}' model data to
* storage at the path supplied in currentStorage's {@link GoCloudStorage.currentDiagramFile}.path value, depending on a parameter.
* @param {boolean} isSaveAs If true, show the save interface for currentStorage. If false, save currentStorage's managedDiagrams' model data to storage.
* Default value is true.
* @return {Promise} Returns a Promise that resolves with a {@link DiagramFile} representing the saved file.
*/
public save(isSaveAs: boolean = true) {
const storageManager = this;
return new Promise(function (resolve: Function, reject: Function) {
if (isSaveAs) resolve(storageManager.handleAction("SaveAs"));
else resolve(storageManager.handleAction("Save"));
});
}
/**
* Display a message on the screen for a given number of seconds. Can be used for a variety of purposes, but a common one is to
* notify users when a file has been loaded / saved / deleted / created by handling the {@link DiagramFile} argument in the
* "then" function of returned Promises (from functions {@link load}, {@link create}, {@link save},
* {@link remove}) by displaying it as a message.
* @param msg Message to display
* @param seconds Number of seconds to display the message for. If no value is provided, the message will display for two seconds.
*/
public showMessage(msg: string, seconds?: number) {
if (!seconds) seconds = 2;
let messageBox = document.createElement("div");
messageBox.id = "goCloudStorageManagerMessageBox";
messageBox.innerHTML = "
" + msg + "
";
document.body.appendChild(messageBox);
setTimeout(function() {
messageBox.style.opacity = '0';
setTimeout(function() {messageBox.parentNode.removeChild(messageBox)}, 1000);
}, 1000*seconds);
}
/**
* Display options ({@link storages}) supported by this instance of GoCloudStorageManager.
* Sets {@link currentStorage} to user's choice.
* @return {Promise} Returns a Promise that resolves with the new {@link currentStorage} instance
*/
public selectStorageService() {
const storageManager = this;
const storages = this.storages;
return new Promise(function(resolve: Function, reject: Function){
const menu = storageManager.menu;
let title: string = 'Select Storage Service';
menu.innerHTML = "" + title + "";
document.getElementsByTagName('body')[0].appendChild(storageManager.menu);
storageManager.menu.style.visibility = 'visible';
let optionsDiv: HTMLElement = document.createElement('div');
optionsDiv.id = 'storageOptions';
let it = storages.iterator;
it.each(function(storage) {
// create a radio input box for each service managed by this instace of GoCloudStorageManager
let src: string = storageManager.iconsRelativeDirectory;
let type = storage.constructor['name'];
switch (type) {
case 'GoGoogleDrive': src += 'googleDrive.jpg'; break;
case 'GoOneDrive': src += 'oneDrive.png'; break;
case 'GoLocalStorage': src += 'localStorage.png'; break;
case 'GoDropBox': src += 'dropBox.png'; break;
}
optionsDiv.innerHTML +=
"