You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2015/10/15 21:01:24 UTC

[37/42] allura git commit: [#7919] Integrate 'Add new tool' menu with admin toolbar

[#7919] Integrate 'Add new tool' menu with admin toolbar


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/99d2ea94
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/99d2ea94
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/99d2ea94

Branch: refs/heads/hs/7919
Commit: 99d2ea943eb213f5f5409c4f218393edcb553e54
Parents: 147f059
Author: Heith Seewald <hs...@hsmb.local>
Authored: Thu Oct 15 14:56:38 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Thu Oct 15 15:00:19 2015 -0400

----------------------------------------------------------------------
 Allura/allura/public/nf/css/navbar.css   | 195 ++++++++++++++++++--------
 Allura/allura/public/nf/js/navbar.es6.js | 184 ++++++++++++++++++------
 2 files changed, 279 insertions(+), 100 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/99d2ea94/Allura/allura/public/nf/css/navbar.css
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/css/navbar.css b/Allura/allura/public/nf/css/navbar.css
index 8c28509..0dec309 100644
--- a/Allura/allura/public/nf/css/navbar.css
+++ b/Allura/allura/public/nf/css/navbar.css
@@ -79,6 +79,7 @@ nav {
     display: flex;
 }
 
+
 #top_nav_admin {
     display: grid;
     flex-direction: row;
@@ -91,7 +92,6 @@ nav {
     border-radius: 4px;
     width: 940px;
 }
-
 .btn-bar {
     display: block;
     clear: both;
@@ -260,6 +260,10 @@ ul.dropdown .hover, ul.dropdown li:hover {
     cursor: not-allowed;
 }
 
+#add_tool_menu{
+    position: relative;
+}
+
 .tool-partition {
     height: 0;
     margin-top: 5px;
@@ -267,88 +271,116 @@ ul.dropdown .hover, ul.dropdown li:hover {
 }
 
 .installable-tool-box {
+    /* margin: 0 0 15px 50px; */
     list-style: none;
     display: flex;
     background-color: #FFFEFA;
     flex-wrap: wrap;
+    margin-bottom: 0;
+    margin-left: 0;
     justify-content: space-around;
 }
 
 .installable-tool-box li {
-    margin-top: 15px;
-
+    /* margin: 5px 10px 20px 60px; */
+    /* margin-left: 80px; */
+    margin-top: 5px;
+    clear: both;
     height: auto;
     border-radius: 4px;
+    /* vertical-align: middle; */
+    /* padding-bottom:10px; */
     padding: 10px;
     text-align: center;
-    font-size: x-large;
+    font-size: medium;
     list-style: none;
     cursor: pointer;
-}
+        border: 1px solid transparent;
+        -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    -o-user-select: none;
+    user-select: none;
 
-.installable-tool-box li:hover {
+}
+.selected-tool{
     background: #09C;
     color: white;
+
 }
 
-.selected-tool {
+.installable-tool-box li:hover {
     background: white;
     border: 1px solid #09C;
 }
 
+
+
 .installable-tool-box li.selected-tool:hover {
     background: white;
     color: rgb(85, 85, 85);
 }
 
-#add_tool_menu{
-    position: relative;
-    z-index: 1000;
-}
-
 .tool-card {
-    width: 800px;
-    /* margin-left: 25px; */
-    background-color: #CB6666;
+    width: 600px;
     display: block;
-    border: 1px solid #777;
+    border: 2px solid #4E4E4E;
     border-radius: 2px 2px 5px 5px;
-    height: auto;
+    overflow-y: visible;
+    margin-bottom: 50px;
+    background: white;
+    right: 22px;
+    top: 94px;
     position: absolute;
-    overflow: auto;
-    right: 0;
-    min-height: 21rem;
-    z-index: inherit;
+    z-index: 1000;
+}
+
+.tool-card::before {
+    content: "▲";/* left point triangle in escaped unicode */
+    color: #4E4E4E;
+    font-size: xx-large;
+    position: absolute;
+    right: 0px;
+    top: -14px;
+    overflow: visible;
+    float: right;
+    /* position: relative; */
+    height: 1.5rem;
 }
 
 .box-title {
-    width: 800px;
+    z-index: 60;
     height: auto;
-    font-size: large;
+    font-size: small;
     text-align: center;
-    padding-bottom: 10px;
-    padding-top: 10px;
-    background: #606060;
-    color: white;
+    padding-bottom: 3px;
+    position: relative;
+    padding-top: 3px;
+    background: #4E4E4E;
+    color: #DEDEDE;
 }
 
 .tool-info {
-    min-height: 12rem;
-    padding: 35px 5px 5px 10px;
+    min-height: 15rem;
+    /* padding: 35px 5px 5px 10px; */
+    /* background-color: #40AFD4; */
     display: block;
+    clear: both;
 }
 
 .tool-info-left p {
     text-align: center;
-    padding-bottom: 0;
     vertical-align: text-top;
-    padding-top: 18px;
-    position: relative;
+    padding-top: 0;
     left: 0;
+    /* text-shadow: 1px 2px 1px  #444; */
     font-size: large;
     font-weight: 400;
-    margin: 2rem 80px 100px 90px;
+    margin: 2rem;
+    margin-left: 33px;
+    margin-right: 33px;
     color: #CCCBC8;
+    padding-bottom: 20px;
 }
 
 .tool-info-left h1 {
@@ -356,46 +388,53 @@ ul.dropdown .hover, ul.dropdown li:hover {
     padding-bottom: 0;
     vertical-align: text-top;
     padding-top: 18px;
-    position: relative;
+    /* text-shadow: 1px 2px 1px #C8C8C8; */
     left: 0;
-    font-size: xx-large;
-    background-color: #E7E7E7;
+    font-size: large;
+    background-color: #AEF4FF;
     color: #5B5B5B;
     height: 3rem;
 }
 
 .add-tool-button {
-    width: auto;
+    width: 140px;
     height: auto;
     background: white;
     min-width: 6rem;
     min-height: 2.6rem;
     font-size: large;
-    clear: both;
-    position: relative;
-    right: -4.8rem;
-    bottom: 0.1rem;
+    bottom: -0.3rem;
+    right: -30px;
 }
 
+
 .tool-info-left {
-    background: #727170;
+    background: #636363;
     width: 60%;
-    height: auto;
+    height: 260px;
     left: 0;
+    float: left;
     top: 0;
     color: white;
-    position: absolute;
 }
 
 .tool-info-right {
-    background: rgba(239, 239, 239, 1);
     width: 40%;
-    height: 100%;
-    right: 0;
+    float: right;
+    overflow: hidden;
+    position: relative;
     display: block;
-    clear: both;
     top: 0;
-    position: absolute;
+}
+
+.tool-info-right form {
+
+    /* display: grid; */
+    /* position: relative; */
+    /* padding-top: 30px; */
+
+
+
 }
 
 .tool-form {
@@ -408,14 +447,14 @@ ul.dropdown .hover, ul.dropdown li:hover {
     height: auto;
 }
 
-#add-tool-form > label {
+#add-tool-form > label{
     padding: 0;
     font-size: 13pt;
     position: absolute;
-    margin-left: 42px;
+    margin-left: 18px;
 }
 
-#add-tool-form > p {
+#add-tool-form > p{
     font-size: large;
 
 }
@@ -423,22 +462,58 @@ ul.dropdown .hover, ul.dropdown li:hover {
 #add-tool-form > input {
     padding-top: 10px;
     padding-left: 10px;
-    width: 63%;
-    margin: 22px 62px 10px 40px;
+    width: 77%;
+    margin: 23px 60px 11px 19px;
 }
 
-#add-tool-form {
-    position: absolute;
-    left: auto;
+#add-tool-form{
     padding-top: 20px;
+    /* clear: both; */
     padding-left: 25px;
-    display: block;
+    /* width: 20%; */
+    /* display: block; */
     padding-right: 25px;
 }
 
-.tool-form-fields {
+.tool-form-fields{
     clear: both;
     position: relative;
     display: flex;
     flex-direction: row;
-}
\ No newline at end of file
+}
+
+#mount_point :invalid{
+    background: #333;
+}
+
+.add-tool-toggle{
+    background: rgba(255, 255, 255, 0.32);
+    clear: both;
+    float: right;
+    /* font-size: x-large; */
+    color: #777;
+    font-weight: 900;
+    /* position: absolute; */
+    padding: 3px;
+    margin: 1px;
+    padding-top: 5px;
+    right: 127px;
+    position: absolute;
+    padding-left: 5px;
+    padding-right: 5px;
+    border: 2px dashed #777;
+    top: 18px;
+    width: 5.7rem;
+    border-radius: 4px;
+    height: 1.5rem;
+    cursor: pointer;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    -o-user-select: none;
+    user-select: none;
+}
+.add-tool-toggle:hover{
+    background: #F4F4F4;
+}
+

http://git-wip-us.apache.org/repos/asf/allura/blob/99d2ea94/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index a5ece5b..8aae568 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -13,6 +13,16 @@ function _getProjectUrl(rest = true) {
     return rest ? `${base}/rest/${nbhd}/${proj}` : `${base}/${nbhd}/${proj}`;
 }
 
+function slugify(text)
+{
+  return text.toString().toLowerCase()
+    .replace(/\s+/g, '-')           // Replace spaces with -
+    .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
+    .replace(/\-\-+/g, '-')         // Replace multiple - with single -
+    .replace(/^-+/, '')             // Trim - from start of text
+    .replace(/-+$/, '');            // Trim - from end of text
+}
+
 /**
  * Get a tool label from a NavBarItem node.
  * @constructor
@@ -294,6 +304,26 @@ var ToggleAdminButton = React.createClass({
     }
 });
 
+/**
+ * Add new tool button.
+ * @constructor
+ */
+var ToggleAddNewTool = React.createClass({
+    render: function () {
+        var classes = this.props.visible ? 'fa fa-unlock' : 'fa fa-lock';
+        return (
+            <div>
+                <div onClick={ this.props.handleToggleAddNewTool } className="add-tool-toggle">
+                    + Add new...
+                </div>
+                                {this.props.showMenu &&
+                <NewToolMain />
+                }
+            </div>
+        );
+    }
+});
+
 //////////////////
 // Add New Tool //
 //////////////////
@@ -324,6 +354,7 @@ var NewToolMenu = React.createClass({
 
     render: function () {
         var _this = this;
+        var showInfo = this.props.active.name !== "Add a tool";
 
         var tools = this.props.tools.map(function (tool, i) {
             var classes;
@@ -338,25 +369,27 @@ var NewToolMenu = React.createClass({
                     id={"add-new-" + tool.name}
                     key={`new-tool-btn-${i}`}
                     onClick={_this.props.handleChangeTool}>
-                    {tool.name}
+                    {tool.tool_label}
                 </li>
             )
         });
 
         return (
             <div className="tool-card">
-                <div className="box-title">Add a new tool
-                </div>
+                <div className="box-title">Add a new ...</div>
                 <div id="installable-items">
                     <ul className="installable-tool-box">
                         {tools}
                     </ul>
                 </div>
                 <div className="tool-partition"></div>
+
+                {showInfo &&
                 <NewToolInfo {...this.props}
-                    name={this.props.active.name}
+                    name={this.props.active.tool_label}
                     description={this.props.active.description}
                     handleAddButton={this.props.handleAddButton}/>
+                }
             </div>
         );
     }
@@ -364,31 +397,33 @@ var NewToolMenu = React.createClass({
 
 var InstallNewToolForm = React.createClass({
     render: function () {
-        console.log(this.props.active.name);
-        if (this.props.active.name === "Add a tool"){
+        //console.log(this.props.active.name);
 
-            return(<div></div>);
-        }
-        var default_mount_point = this.props.active.defaults.default_mount_point;
-        var default_mount_label = this.props.active.defaults.default_mount_label;
+        //var default_mount_label = this.props.active.defaults.default_mount_label;
 
         return (
             <form id="add-tool-form">
                 <label htmlFor="mount_label">Label</label>
-                <input id="mount_label" onChange={this.props.handleChangeForm} value={default_mount_label} />
+                <input required
+                       id="mount_label"
+                       onChange={this.props.handleChangeForm}
+                       value={this.props.formData.mount_label} />
 
                 <label htmlFor="mount_point">Url Path</label>
-                <input id="mount_point"
+                <input required
+                       id="mount_point"
                        onChange={this.props.handleChangeForm}
-                       onBlur={this.props.validateMountPoint}
+                       onBlur={this.props.toolFormIsValid}
+                       placeholder={slugify(this.props.formData.mount_label)}
                        value={this.props.formData.mount_point}/>
+                <span>{this.props.validationErrors.mount_point}</span>
 
                 <p style={{"color": "grey"}}><small>http://hs/p/finna/</small><strong style={{"color": "orange"}}>
                     {this.props.formData.mount_point}
                 </strong></p>
 
                 <button id="new-tool-submit"
-                        onClick={this.props.handleAddButton}
+                        onClick={this.props.handleSubmit}
                         className="add-tool-button">
                     Add Tool
                 </button>
@@ -425,14 +460,21 @@ var NewToolMain = React.createClass({
     getInitialState: function () {
         let toolPlaceHolder = {
             name: "Add a tool",
+            tool_label: "Add a tool",
             description: "click on one of the tools shown above to add it to your project."
         };
 
         return {
+            visible: false,
             installableTools: [toolPlaceHolder],
             active: toolPlaceHolder,
+            errors: {
+                mount_point: [],
+                mount_label: []
+            },
             new_tool: {
                 mount_point: "",
+                tool_label: "",
                 mount_label: ""
             }
         };
@@ -453,9 +495,8 @@ var NewToolMain = React.createClass({
     },
     handleAddButton: function (e) {
         e.preventDefault();
-        console.log('Add new too button pushed');
-        console.log('e.target.name', e);
-        console.log(e.target.textContent);
+        console.log('current active tool', this.state.active);
+        console.log('new_tool', this.state.new_tool);
 
     },
     handleChangeTool: function (e) {
@@ -463,12 +504,19 @@ var NewToolMain = React.createClass({
         this._setActiveByName(e.target.textContent);
 
     },
-    _setActiveByName: function (name) {
+    _setActiveByName: function (tool_label) {
         var index = this.state.installableTools.findIndex(
-            x => x.name === name
+            x => x.tool_label === tool_label
         );
+        var active = this.state.installableTools[index];
+        var _new_tool = this.state.new_tool;
+
+        _new_tool['mount_label'] = active.defaults.default_mount_label;
+        _new_tool['mount_point'] = "";
+
         this.setState({
-            active: this.state.installableTools[index]
+            active: active,
+            new_tool: _new_tool
         });
     },
 
@@ -486,40 +534,74 @@ var NewToolMain = React.createClass({
     },
     handleSubmit: function (e) {
         e.preventDefault();
-        var nextItems = this.state.items.concat([this.state.text]);
-        var nextText = '';
-        this.setState({items: nextItems, text: nextText});
+        var data = {
+            _session_id: $.cookie('_session_id'),
+            tool: this.state.active.name,
+            mount_label: this.state.new_tool.mount_label,
+            mount_point: this.state.new_tool.mount_point
+        };
+
+        var url = _getProjectUrl() + "/admin/install_tool/";
+
+         $.ajax({
+            type: 'POST',
+            url: url,
+            data: data,
+            success: function () {
+                $('#messages').notify('Tool created',
+                    {
+                        status: 'confirm'
+                    });
+            },
+
+            error: function () {
+                $('#messages').notify('Error creating tool.',
+                    {
+                        status: 'error'
+                    });
+            }
+        });
+
     },
 
-    validateMountPoint: function (e) {
+    toolFormIsValid: function (e) {
         e.preventDefault();
-        let url = _getProjectUrl(true) + '/admin/mount_point/';
+
+        var isValid = true;
+        var errors = {
+            mount_point: []
+        };
+
+        if (this.state.new_tool.mount_point.length < 3) {
+            errors.mount_point.push("Mount point must have at least 3 characters.");
+        }
 
         let data = {
             'mount_point': e.target.value,
             '_session_id': $.cookie('_session_id')
         };
 
-        let d = $.post(url, data).done(function (result) {
-            console.log(result);
-        });
+        let result = $.post(_getProjectUrl() + '/admin/mount_point/', data);
+            if (!result.responseJSON) {
+                console.log("ALREADY EXISTS", result);
+                errors.mount_point.push("Mount point already exists.");
+            }
 
-        if(d.responseJSON.exists){
-            alert('exists');
-        }else{
-            alert('does not exist');
-        }
+        this.setState({errors: errors})
 
     },
 
     render: function () {
+        //var visible =
         return <NewToolMenu
             active={this.state.active}
             tools={this.state.installableTools}
             formData={this.state.new_tool}
             handleChangeTool={this.handleChangeTool}
+            handleSubmit={this.handleSubmit}
             handleChangeForm={this.handleChangeForm}
-            validateMountPoint={this.validateMountPoint}
+            toolFormIsValid={this.toolFormIsValid}
+            validationErrors={this.state.errors}
             handleAddButton={this.handleAddButton}/>;
     }
 });
@@ -541,6 +623,7 @@ var Main = React.createClass({
         return {
             data: this.props.initialData,
             visible: false,
+            showAddToolMenu: false,
             _session_id: $.cookie('_session_id')
         };
     },
@@ -569,6 +652,15 @@ var Main = React.createClass({
     },
 
     /**
+     * Handles the the display of the "Add new tool" menu.
+     */
+    handleToggleAddNewTool: function () {
+        this.setState({
+            showAddToolMenu: !this.state.showAddToolMenu
+        });
+    },
+
+    /**
      * Handles the changing of the NavBars grouping threshold.
      * @param {object} event
      */
@@ -651,12 +743,24 @@ var Main = React.createClass({
         var navBarSwitch = (showAdmin) => {
             if (showAdmin) {
                 return (
-                    <AdminNav tools={ _this.state.data.children } data={ _this.state.data } onToolReorder={ _this.onToolReorder }
-                              onUpdateMountOrder={ _this.onUpdateMountOrder } editMode={ _this.state.visible }
+                    <AdminNav tools={ _this.state.data.children }
+                              data={ _this.state.data }
+                              onToolReorder={ _this.onToolReorder }
+                              onUpdateMountOrder={ _this.onUpdateMountOrder }
+                              editMode={ _this.state.visible }
                         />
                 );
             } else {
-                return <NormalNavBar items={ _this.state.data.children } key={ `normalNav-${_.uniqueId()}` }/>;
+                return (
+                    <div>
+                        <NormalNavBar items={ _this.state.data.children } key={ `normalNav-${_.uniqueId()}` }/>
+
+                        <ToggleAddNewTool
+                            handleToggleAddNewTool={this.handleToggleAddNewTool}
+                            showMenu={this.state.showAddToolMenu}
+                            />
+                    </div>
+                )
             }
         };
         var navBar = navBarSwitch(this.state.visible);
@@ -673,6 +777,6 @@ var Main = React.createClass({
         );
     }
 });
-
-   React.render(React.createElement(NewToolMain, {
-        }), document.getElementById("add_tool_menu"));
\ No newline at end of file
+   //
+   //React.render(React.createElement(NewToolMain, {
+   //     }), document.getElementById("add_tool_menu"));
\ No newline at end of file