Explorar o código

Merge pull request #271 from pwm-project/angular-html-editor

Introduced the HTML editor component to the settings page for email templates.
Jason %!s(int64=7) %!d(string=hai) anos
pai
achega
7790e46db1

+ 1 - 1
client/package.json

@@ -13,7 +13,7 @@
     "test": "karma start --NODE_ENV=test",
     "test-single-run": "karma start --NODE_ENV=test --singleRun --no-auto-watch",
     "start": "webpack-dev-server --config=webpack.dev.js --NODE_ENV=dev --colors",
-    "sync": "webpack --config=webpack.build.js --NODE_ENV=production --output-path=../server/src/main/webapp/public/resources/webjars/pwm-client --watch --colors"
+    "sync": "webpack --config=webpack.build.js --NODE_ENV=production --output-path=../server/target/pwm-1.8.0-SNAPSHOT/public/resources/webjars/pwm-client --watch --colors"
   },
   "author": "",
   "license": "ISC",

+ 50 - 0
client/src/pages/configeditor/configeditor.controller.ts

@@ -0,0 +1,50 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2017 The PWM Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+import {element, ICompileService, IScope, ITemplateCacheService, module} from 'angular';
+
+/**
+ * Angular controller for the configeditor.jsp page.  This class is used to transition the page from JSPs into
+ * eventually a single page angular application.
+ */
+export default class ConfigEditorController {
+    static $inject = ['$scope', '$compile'];
+    constructor(
+        private $scope: IScope,
+        private $compile: ICompileService
+    ) {
+        $scope.$on('content-added', (event, elementId) => {
+            this.digestNewContent(elementId);
+        });
+    }
+
+    digestNewContent(elementId: string) {
+        if (elementId) {
+            const element = document.getElementById(elementId);
+
+            if (element) {
+                this.$compile(element)(this.$scope);
+                this.$scope.$digest();
+            }
+        }
+    }
+}

+ 27 - 0
client/src/pages/configeditor/configeditor.module.ts

@@ -0,0 +1,27 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2017 The PWM Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+import { module } from 'angular';
+import ConfigEditorController from './configeditor.controller';
+
+module('configeditor.module', ['textAngular'])
+    .controller('ConfigEditorController', ConfigEditorController);

+ 2 - 1
client/webpack.build.js

@@ -29,7 +29,8 @@ module.exports = webpackMerge(commonConfig, {
     devtool: 'source-map',
     entry: {
         'peoplesearch.ng': './src/main',
-        'changepassword.ng': './src/pages/changepassword/changepassword.module'
+        'changepassword.ng': './src/pages/changepassword/changepassword.module',
+        'configeditor.ng': './src/pages/configeditor/configeditor.module'
     },
     module: {
         loaders: [

+ 2 - 1
client/webpack.dev.js

@@ -29,7 +29,8 @@ module.exports = webpackMerge(commonConfig, {
     devtool: 'cheap-module-source-map',
     entry: {
         'peoplesearch.ng': './src/main.dev',
-        'changepassword.ng': './src/pages/changepassword/changepassword.module'
+        'changepassword.ng': './src/pages/changepassword/changepassword.module',
+        'configeditor.ng': './src/pages/configeditor/configeditor.module'
     },
     module: {
         loaders: [

+ 11 - 0
server/pom.xml

@@ -848,6 +848,17 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>org.webjars.bower</groupId>
+            <artifactId>textAngular</artifactId>
+            <version>1.5.16</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.webjars.bower</groupId>
+                    <artifactId>angular</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <repositories>

+ 20 - 1
server/src/main/webapp/WEB-INF/jsp/configeditor.jsp

@@ -66,7 +66,7 @@
             </div>
         </div>
     </div>
-    <div id="centerbody-config" class="centerbody-config">
+    <div id="centerbody-config" class="centerbody-config" ng-app="configeditor.module" ng-controller="ConfigEditorController as $ctrl">
         <div id="settingSearchPanel">
             <table class="noborder settingSearchPanelTable">
                 <colgroup>
@@ -161,6 +161,25 @@
 <pwm:script-ref url="/public/resources/js/configeditor-settings-customlink.js"/>
 <pwm:script-ref url="/public/resources/js/configeditor-settings-remotewebservices.js"/>
 <pwm:script-ref url="/public/resources/js/admin.js"/>
+
+<%--Add support for angular--%>
+<pwm:script-ref url="/public/resources/webjars/angular/angular.min.js" />
+<pwm:script-ref url="/public/resources/webjars/angular-ui-router/release/angular-ui-router.min.js" />
+<pwm:script-ref url="/public/resources/webjars/angular-translate/dist/angular-translate.min.js" />
+<%--/ Add support for angular--%>
+
+<%--Add support for the "textAngular" library (a control for editing HTML)--%>
+<link rel="stylesheet" type="text/css" href="<pwm:url url='/public/resources/webjars/textAngular/dist/textAngular.css' addContext="true"/>"/>
+<pwm:script-ref url="/public/resources/webjars/textAngular/dist/textAngular-rangy.min.js" />
+<pwm:script-ref url="/public/resources/webjars/textAngular/dist/textAngular-sanitize.min.js" />
+<pwm:script-ref url="/public/resources/webjars/textAngular/dist/textAngular.min.js" />
+<%--/ Add support for the "textAngular" library (a control for editing HTML)--%>
+
+<%--Provide the angular code we made specifically for this page:--%>
+<link rel="stylesheet" type="text/css" href="<pwm:url url='/public/resources/html-editor.css' addContext="true"/>"/>
+<pwm:script-ref url="/public/resources/webjars/pwm-client/configeditor.ng.js" />
+<%--/ Provide the angular code we made specifically for this page:--%>
+
 <%@ include file="fragment/footer.jsp" %>
 </body>
 </html>

+ 85 - 0
server/src/main/webapp/public/resources/html-editor.css

@@ -0,0 +1,85 @@
+.html-editor {
+    height: 350px;
+}
+
+.html-editor .ta-editor {
+    border: 1px solid #EAEAEA;
+    height: 300px;
+    margin-top: 10px;
+    overflow: auto;
+    width: 790px;
+}
+
+.html-editor .btn-group {
+    display: inline-block;
+    margin-right: 5px;
+}
+
+.html-editor .btn-group .btn {
+    background: #eaeaea;
+    border-radius: 0;
+    border: 1px solid #ccc;
+    border-right: 0;
+    color: #434c50;
+    display: inline-block;
+    font-size: 14px;
+    margin: 0;
+    padding: 0px;
+    vertical-align: bottom;
+}
+
+.html-editor .btn-group .btn.active {
+    background-color: #a1a6a8;
+    color: #f6f9f8;
+}
+
+.html-editor .btn-group .btn:hover:not(.active) {
+    background-color: #f6f9f8;
+    border-color: #01a9e7;
+    color: #007cd0;
+}
+
+.html-editor .btn-group .btn:hover:not(.active) + .btn {
+    border-left-color: #01a9e7;
+}
+
+.html-editor .btn-group button {
+    height: 24px;
+    width: 24px;
+}
+
+.html-editor .btn-group .btn:first-of-type {
+    border-top-left-radius: 3px;
+    border-bottom-left-radius: 3px;
+}
+
+.html-editor .btn-group .btn:last-of-type {
+    border-right: 1px solid #ccc;
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+}
+
+.html-editor .btn-group .btn:hover:last-of-type {
+    border-right-color: #01a9e7;
+}
+
+.html-editor.focussed .ta-scroll-window.form-control {
+    border-color: #01a9e7;
+    box-shadow: none;
+}
+
+.html-editor .ta-scroll-window > .ta-bind {
+    min-height: 285px;
+}
+
+.html-editor.focussed .ta-scroll-window > .ta-bind {
+    outline: none;
+}
+
+.ta-editor p {
+    max-width: none;
+    position: static;
+    margin-left: 0;
+    margin-right: 0;
+    font-size: 14px;
+}

+ 26 - 32
server/src/main/webapp/public/resources/js/configeditor-settings.js

@@ -1923,39 +1923,33 @@ EmailTableHandler.instrumentRow = function(settingKey, localeName) {
 
 
 EmailTableHandler.htmlBodyEditor = function(keyName, localeName) {
-    require(["dijit/Editor","dijit/_editor/plugins/AlwaysShowToolbar","dijit/_editor/plugins/LinkDialog","dijit/_editor/plugins/ViewSource","dijit/_editor/plugins/FontChoice","dijit/_editor/plugins/TextColor"],
-        function(Editor,AlwaysShowToolbar){
-            var idValue = keyName + "_" + localeName + "_htmlEditor";
-            var bodyText = '';
-            bodyText += '<div id="' + idValue + '" style="border:2px solid #EAEAEA; height:300px"></div>';
-            PWM_MAIN.showDialog({
-                title: "HTML Editor",
-                text: bodyText,
-                showClose:true,
-                showCancel:true,
-                dialogClass: 'wide',
-                loadFunction:function(){
-                    PWM_MAIN.clearDijitWidget(idValue);
-                    new Editor({
-                        extraPlugins: [
-                            AlwaysShowToolbar,"viewsource",
-                            {name:"dijit/_editor/plugins/LinkDialog",command:"createLink",urlRegExp:".*"},
-                            "fontName","foreColor"
-                        ],
-                        height: '300px',
-                        value: PWM_VAR['clientSettingCache'][keyName][localeName]['bodyHtml'],
-                        style: '',
-                        onChange: function(){PWM_VAR['temp-dialogInputValue'] = this.get('value')},
-                        onKeyUp: function(){PWM_VAR['temp-dialogInputValue'] = this.get('value')}
-                    },idValue).startup();
-                },
-                okAction:function(){
-                    PWM_VAR['clientSettingCache'][keyName][localeName]['bodyHtml'] = PWM_VAR['temp-dialogInputValue'];
-                    EmailTableHandler.writeSetting(keyName,true);
-                }
-            });
+    // Grab the scope from the angular controller we created on the div element with ID: centerbody-config
+    var $scope = angular.element(document.getElementById("centerbody-config")).scope();
+    var idValue = keyName + "_" + localeName + "_htmlEditor";
+    var toolbarButtons =
+        "[" +
+        "['h1','h2','h3','h4','h5','h6','p','pre','quote']," +
+        "['bold','italics','underline','strikeThrough','ul','ol','undo','redo','clear']," +
+        "['justifyLeft','justifyCenter','justifyRight','justifyFull','indent','outdent']," +
+        "['html','insertImage','insertLink','insertVideo']" +
+        "]";
+
+    PWM_MAIN.showDialog({
+        title: "HTML Editor",
+        text: '<div id="' + idValue + '" text-angular ng-model="htmlText" ta-toolbar="' + toolbarButtons + '" class="html-editor"></div>',
+        showClose:true,
+        showCancel:true,
+        dialogClass: 'wide',
+        loadFunction: function(){
+            // Put the existing value into the scope, and tell the controller to process the element with ID: idValue
+            $scope.htmlText =  PWM_VAR['clientSettingCache'][keyName][localeName]['bodyHtml'];
+            $scope.$broadcast("content-added", idValue);
+        },
+        okAction:function(){
+            PWM_VAR['clientSettingCache'][keyName][localeName]['bodyHtml'] = $scope.htmlText;
+            EmailTableHandler.writeSetting(keyName,true);
         }
-    );
+    });
 };