You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2015/10/27 22:36:54 UTC
[28/47] 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/37fad09f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/37fad09f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/37fad09f
Branch: refs/heads/db/7919
Commit: 37fad09f067e7904e4a2373996ee41da62926b11
Parents: 29e7bad
Author: Heith Seewald <hs...@hsmb.local>
Authored: Thu Oct 15 14:56:38 2015 -0400
Committer: Heith Seewald <hs...@hsmb.local>
Committed: Fri Oct 23 13:10:03 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/37fad09f/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/37fad09f/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