UNPKG

d2

Version:

Javascript library for DHIS2

303 lines (271 loc) 9.46 kB
/** * @module system * * @requires module:api/Api */ import Api from '../api/Api' import SystemSettings from './SystemSettings' import SystemConfiguration from './SystemConfiguration' /** * @description * Represents the system that can be interacted with. There is a single instance of this pre-defined onto the d2 * object after initialisation. This can be interacted with using its property objects to among other be used * to get and save systemSettings. * * @memberof module:system */ class System { constructor(settings, configuration) { /** * Contains a reference to a `SystemSettings` instance that can be used * to retrieve and save system settings. * * ```js * d2.system.settings.get('keyLastSuccessfulResourceTablesUpdate') * .then(systemSettingsValue => { * console.log('Analytics was last updated on: ' + systemSettingsValue); * }); * ``` * @type {SystemSettings} * */ this.settings = settings /** * A representation of the system configuration, * that can be used to retrieve and change system configuration options. * @type {SystemConfiguration} */ this.configuration = configuration /** * An object containing system information about the DHIS2 instance * @type {Object} */ this.systemInfo = undefined /** * An object containing version information about the DHIS2 instance * @type {Object} */ this.version = undefined /** * An array of all the webapps that are installed on the current DHIS2 instance * @type {Array} */ this.installedApps = undefined } /** * Sets the systemInfo and version properties * * @param systemInfo */ setSystemInfo(systemInfo) { this.version = System.parseVersionString(systemInfo.version) this.systemInfo = systemInfo } /** * Sets the list of currently installed webapps * * @param apps */ setInstalledApps(apps) { this.installedApps = apps } /** * Refreshes the list of currently installed webapps * * @returns {Promise} A promise that resolves to the list of installed apps */ loadInstalledApps() { const api = Api.getApi() return api.get('apps').then(apps => { this.setInstalledApps(apps) return apps }) } /** * Upload and install a zip file containing a new webapp * * @param zipFile Zip file data from a file input form field * @param onProgress An optional callback that will be called whenever file upload progress info is available * @returns {Promise} */ uploadApp(zipFile, onProgress) { const api = Api.getApi() const data = new FormData() let xhr data.append('file', zipFile) if (onProgress !== undefined) { xhr = new XMLHttpRequest() xhr.upload.onprogress = progress => { if (progress.lengthComputable) { onProgress(progress.loaded / progress.total) } } } return api.post('apps', data, { contentType: false, processData: false, xhr: xhr !== undefined ? () => xhr : undefined, }) } /** * Load the list of apps available in the DHIS 2 app store * * @param compatibleOnly If true, apps that are incompatible with the current system will be filtered out * @returns {Promise} */ loadAppStore(compatibleOnly = true) { return new Promise((resolve, reject) => { const api = Api.getApi() api.get('appStore') .then(appStoreData => resolve( appStoreData .map(appData => { const app = Object.assign({}, appData) if (compatibleOnly) { app.versions = app.versions.filter( versionData => System.isVersionCompatible( this.version, versionData ) ) } return app }) .filter(appData => appData.versions.length > 0) ) ) .catch(err => reject(err)) }) } /** * Install the specified app version from the DHIS 2 app store * * @param uid The uid of the app version to install * @returns {Promise} */ installAppVersion(uid) { const api = Api.getApi() return new Promise((resolve, reject) => { api.post(['appStore', uid].join('/'), '', { dataType: 'text' }) .then(() => { resolve() }) .catch(err => { reject(err) }) }) } /** * Remove the specified app from the system * * @param appKey The key of the app to remove * @returns {Promise} */ uninstallApp(appKey) { const api = Api.getApi() return ( api .delete(['apps', appKey].join('/')) // TODO: Stop jQuery from rejecting successful promises .catch(() => undefined) ) } /** * Refresh the list of apps that are installed on the server * * @returns {Promise} A promise that resolves to the updated list of installed apps */ reloadApps() { const api = Api.getApi() return api.update('apps').then(() => this.loadInstalledApps()) } /** * @static * @typedef {Object} ParsedVersion * @property {number} major - Major version of the parsed-string (before .) * @property {number} minor - Minor version of the parsed-string (after .) * @property {boolean} snapshot - If it's a snapshot-version */ // TODO: Validate string // TODO: Handle valid version objects too /** * Parses a version string into an object describing the version. * @param {string} version Version-string to parse * @returns {module:system.ParsedVersion} */ static parseVersionString(version) { return { major: Number.parseInt(version, 10), minor: Number.parseInt( version.substring(version.indexOf('.') + 1), 10 ), snapshot: version.indexOf('-SNAPSHOT') >= 0, } } // Disable eslint complexity warning /* eslint-disable complexity */ /** * Compares version a to version b. * @param a {string|module:system.ParsedVersion} * @param b {string|module:system.ParsedVersion} * @returns {number} 0 if same version, else a - b. */ static compareVersions(a, b) { const from = typeof a === 'string' || a instanceof String ? System.parseVersionString(a) : a const to = typeof b === 'string' || b instanceof String ? System.parseVersionString(b) : b if (from.major !== to.major) { return from.major - to.major } if (from.minor !== to.minor) { return from.minor - to.minor } return (from.snapshot ? 0 : 1) - (to.snapshot ? 0 : 1) } /** * Checks if systemVersion is compatible with appVersion. * Versions are compatible if appVersion.minDhisVersion <= parsed systemVersion and * if appVersion.maxDhisVersion >= parsed systemVersion. * @param systemVersion {string|module:system.ParsedVersion} systemVersion to check * @param {Object} appVersion - AppVersion object to check * @returns {boolean} true if compatible, false otherwise. */ static isVersionCompatible(systemVersion, appVersion) { const minVersion = appVersion.minDhisVersion || appVersion.min_platform_version || null const maxVersion = appVersion.maxDhisVersion || appVersion.max_platform_version || null const isNewEnough = minVersion ? System.compareVersions(systemVersion, minVersion) >= 0 : true const isNotTooOld = maxVersion ? System.compareVersions(systemVersion, maxVersion) <= 0 : true return isNewEnough && isNotTooOld } /* eslint-enable */ /** * Get a new instance of the system object. This will function as a singleton, when a System object has been created * when requesting getSystem again the original version will be returned. * * @returns {System} Object with the system interaction properties */ static getSystem() { if (!System.getSystem.system) { System.getSystem.system = new System( new SystemSettings(), new SystemConfiguration() ) } return System.getSystem.system } } export default System