Index: main/plugin-core-ui/i18n/messages_en.xml =================================================================== --- main/plugin-core-ui/i18n/messages_en.xml (revision 38750) +++ main/plugin-core-ui/i18n/messages_en.xml (working copy) @@ -805,4 +805,15 @@ Notifications Open the notification tool.<br/><br/>A figure on the ribbon icon displays the number of unread message. The color indicates the most serious message type among these unread messages: red for error, yellow for warning, and blue for simple information. + + About Ametys... + Information about Ametys + About + OK + - + from + Error retrieving information about the application + Index: main/plugin-core-ui/i18n/messages_fr.xml =================================================================== --- main/plugin-core-ui/i18n/messages_fr.xml (revision 38750) +++ main/plugin-core-ui/i18n/messages_fr.xml (working copy) @@ -805,5 +805,16 @@ Cliquez ici pour filtrer l'événements de l'historique de navigation Notifications Ouvrir l'outil des notifications.<br/><br/>Le chiffre indique le nombre de message non lus. La couleur indique le type de message le plus grave parmi ces messages non lus : rouge pour erreur, orange pour avertissement et bleu pour simple information. + + + A propos d'Ametys... + Informations à propos d'Ametys + A propos de + OK + - + du + Erreur lors de la récupération des informations sur l'application Index: main/plugin-core-ui/plugin.xml =================================================================== --- main/plugin-core-ui/plugin.xml (revision 38750) +++ main/plugin-core-ui/plugin.xml (working copy) @@ -1283,6 +1283,35 @@ + + + + + + + + + Ametys.plugins.coreui.about.AboutActions.openAboutDialogBox + + + PLUGINS_CORE_UI_ABOUT_DESCRIPTION + + flaticon-question13 + + + js/Ametys/plugins/coreui/about/AboutActions.js + + + css/about/About.css + + + + + ", + iconCls: "flaticon-question13", + maxHeight: 600, + + width: 500, + layout: { + type: "vbox", + align: "middle", + padding: '0 0 15px 0' + }, + + items: itemsCfg, + bodyCls: 'about-dialog', + + closeAction: 'hide', + buttons: [{ + text: "", + handler: function() { this._aboutBox.close(); }, + scope: this + }] + }); + + Ametys.data.ServerComm.callMethod({ + role: "org.ametys.plugins.core.ui.about.AboutInfoProvider", + methodName: "getInfo", + parameters: [Ametys.getAppParameter("user").locale], + callback: { + handler: this._getInfoCb, + scope: this + }, + waitMessage: false + }); + //Ametys.about.AboutDAO.getInfo([Ametys.getAppParameter("user").locale], this._getInfoCb, {scope: this}); + + this._aboutIsInitialized = true; + } + }, + + /** + * @private + * Creates the items config of the "about" dialogbox + * @return {Object[]} The configs of the box items + */ + _createItemsCfg: function() + { + var itemsCfg = [ + { + xtype: "image", + src: Ametys.getPluginResourcesPrefix('core-ui') + '/img/Ametys/common/logo.png', + alt: 'Ametys', + cls: 'about-logo' + }, + { + xtype: "component", + itemId: "appName", + cls: 'about-app-name', + html: "", + scrollable: false + }, + { + xtype: "component", + itemId: "versions", + cls: 'about-versions', + html: "", + scrollable: false + }, + { + xtype: "component", + itemId: "license", + width: "95%", + flex: 1, + cls: 'about-license', + html: "", + scrollable: true + } + ]; + return itemsCfg; + }, + + /** + * @private + * Callback method after the information are retrieved from the server. + * Updates the texts of the dialog box (app name, versions, license). + * @param {Object} response The server response + */ + _getInfoCb: function(response) + { + this._updateAppName(response.applicationName); + this._updateVersions(response.versions); + this._updateLicenseText(response.licenseText); + }, + + /** + * @private + * Updates the displayed application name + * @param {String} appName The application name + */ + _updateAppName: function(appName) + { + var cmp = this._aboutBox.items.get("appName"); + cmp.update(appName); + }, + + /** + * @private + * Updates the displayed versions + * @param {Object} versions The versions handled by the application as a map. The key is the version name, and the value is a mpa containing the version number and the date. + */ + _updateVersions: function(versions) + { + var cmp = this._aboutBox.items.get("versions"); + + var html = ""; + Ext.Object.each(versions, function(key, value) { + html += '' + key + "" + "" + value['version']; + + var millisDate = value["date"]; + var dateFormat = Ext.Date.patterns.FriendlyDateTime; + if (millisDate != "") + { + html += "" + Ext.util.Format.date(new Date(value["date"]), dateFormat); + } + + html += "
"; + }, this); + + cmp.update(html ); + }, + + /** + * @private + * Updates the license text + * @param {String} license The license text + */ + _updateLicenseText: function(license) + { + var cmp = this._aboutBox.items.get("license"); + cmp.update(license); + } + +}); \ No newline at end of file Index: main/plugin-core-ui/src/org/ametys/plugins/core/ui/about/AboutInfoProvider.java =================================================================== --- main/plugin-core-ui/src/org/ametys/plugins/core/ui/about/AboutInfoProvider.java (revision 0) +++ main/plugin-core-ui/src/org/ametys/plugins/core/ui/about/AboutInfoProvider.java (revision 0) @@ -0,0 +1,166 @@ +/* + * Copyright 2016 Anyware Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ametys.plugins.core.ui.about; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.avalon.framework.component.Component; +import org.apache.avalon.framework.context.Context; +import org.apache.avalon.framework.context.ContextException; +import org.apache.avalon.framework.context.Contextualizable; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.Serviceable; +import org.apache.cocoon.Constants; + +import org.ametys.core.ui.Callable; +import org.ametys.core.util.I18nUtils; +import org.ametys.core.version.Version; +import org.ametys.core.version.VersionsHandler; +import org.ametys.runtime.i18n.I18nizableText; +import org.ametys.runtime.plugin.component.AbstractLogEnabled; + +/** + * Helper providing information for "About Ametys" feature. + */ +public class AboutInfoProvider extends AbstractLogEnabled implements Serviceable, Component, Contextualizable +{ + /** The Avalon role */ + public static final String ROLE = AboutInfoProvider.class.getName(); + + /** The path of the license text file */ + private static final String LICENSE_FILE_PATH = "/"; + /** The name of the license text file */ + private static final String LICENSE_FILE_NAME = "NOTICE.txt"; + + /** The versions handler */ + private VersionsHandler _versionsHandler; + /** The cocoon context */ + private org.apache.cocoon.environment.Context _cocoonContext; + + @Override + public void service(ServiceManager manager) throws ServiceException + { + _versionsHandler = (VersionsHandler) manager.lookup(VersionsHandler.ROLE); + } + + @Override + public void contextualize(Context context) throws ContextException + { + _cocoonContext = (org.apache.cocoon.environment.Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); + } + + /** + * Gets the information for "About Ametys" feature + * @param lang the lang + * @return A map of information needed for "About Ametys" feature. + * Contains the application name, the versions of the application and the license text. + * @throws FileNotFoundException + * @throws IOException + */ + @Callable + public Map getInfo(String lang) throws FileNotFoundException, IOException + { + Map result = new LinkedHashMap<>(); + + result.put("applicationName", getApplicationName(lang)); + result.put("versions", getVersions()); + result.put("licenseText", getLicenseText()); + + return result; + } + + /** + * Gets the application name + * @param lang The lang + * @return The name of the application. + */ + @Callable + public String getApplicationName(String lang) + { + return I18nUtils.getInstance().translate(new I18nizableText("application", "APPLICATION_PRODUCT_LABEL"), lang); + } + + /** + * Gets the available versions of the application. + * @return A map of versions. + */ + @Callable + public Map getVersions() + { + Map result = new LinkedHashMap<>(); + + Collection versions = _versionsHandler.getVersions(); + + Iterator it = versions.iterator(); + while (it.hasNext()) + { + Version version = it.next(); + Map versionInfos = new LinkedHashMap<>(); + versionInfos.put("version", "4.0.0alpha"); + //versionInfos.put("version", version.getVersion() != null ? version.getVersion() : ""); + versionInfos.put("date", new Date()); + //versionInfos.put("date", version.getDate() != null ? version.getDate() : ""); + result.put(version.getName(), versionInfos); + } + + return result; + } + + /** + * Gets the content of the license text. + * @return The content of the license text. + * @throws FileNotFoundException + * @throws IOException + */ + @Callable + public String getLicenseText() throws FileNotFoundException, IOException + { + String path = _cocoonContext.getRealPath(AboutInfoProvider.LICENSE_FILE_PATH); + String fileName = AboutInfoProvider.LICENSE_FILE_NAME; + File licenseFile = new File(path + fileName); + if (licenseFile.exists() && licenseFile.isFile()) + { + StringBuffer sb = new StringBuffer(); + try ( BufferedReader reader = new BufferedReader(new FileReader(licenseFile)) ) + { + String line; + while ((line = reader.readLine()) != null) + { + sb.append(line); + sb.append("
"); + } + } + + return sb.toString(); + } + else + { + getLogger().warn("License file {} is not present at {}", fileName, path); + return ""; + } + } + +}