/** * 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 += "