Everything is basically done.
It's really crude, and ugly, but it works, it's simple.
This commit is contained in:
parent
a754264a1d
commit
70c9f60d8f
@ -112,9 +112,20 @@
|
||||
<li class="pure-menu-item">
|
||||
<span class="breadcrumb-separator">/</span>
|
||||
</li>
|
||||
<li class="pure-menu-item">
|
||||
<a href="/project/{{project.id}}" class="pure-menu-link">{{project.name}}</a>
|
||||
</li>
|
||||
{{#if !version && !currentStage}}
|
||||
<li class="pure-menu-item pure-menu-has-children" decorator="menu">
|
||||
<a href="#" id="projectMenu" class="pure-menu-link">{{project.name}}</a>
|
||||
<ul class="pure-menu-children">
|
||||
<li class="pure-menu-item">
|
||||
<a href="#" class="pure-menu-link" on-click="triggerBuild">Trigger Build</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{{else}}
|
||||
<li class="pure-menu-item">
|
||||
<a href="/project/{{project.id}}" class="pure-menu-link">{{project.name}}</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if project && version}}
|
||||
<li class="pure-menu-item">
|
||||
|
212
web/js/index.js
212
web/js/index.js
@ -24,11 +24,43 @@ Ractive.DEBUG = false;
|
||||
releases: {},
|
||||
};
|
||||
},
|
||||
decorators: {
|
||||
menu: function(node) {
|
||||
new PureDropdown(node);
|
||||
return {
|
||||
teardown: function() {
|
||||
return;
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
setPaths();
|
||||
|
||||
|
||||
r.on({
|
||||
"triggerBuild": function(event) {
|
||||
event.original.preventDefault();
|
||||
var secret = window.prompt("Please enter the trigger secret for this project:");
|
||||
triggerBuild(r.get("project.id"), secret);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
function triggerBuild(projectID, secret) {
|
||||
ajax("POST", "/trigger/" + projectID, {
|
||||
secret: secret
|
||||
},
|
||||
function(result) {
|
||||
window.location = "/";
|
||||
},
|
||||
function(result) {
|
||||
r.set("error", err(result).message);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function setPaths() {
|
||||
var paths = window.location.pathname.split("/");
|
||||
|
||||
@ -66,7 +98,19 @@ Ractive.DEBUG = false;
|
||||
setStatus(result.data[i]);
|
||||
hasRelease(result.data[i].id, "");
|
||||
}
|
||||
|
||||
result.data.sort(function(a, b) {
|
||||
if (a.name > b.name) {
|
||||
return 1;
|
||||
}
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
r.set("projects", result.data);
|
||||
|
||||
window.setTimeout(getProjects, 10000);
|
||||
},
|
||||
function(result) {
|
||||
r.set("error", err(result).message);
|
||||
@ -157,7 +201,13 @@ function ajax(type, url, data, success, error) {
|
||||
req.onload = function() {
|
||||
if (req.status >= 200 && req.status < 400) {
|
||||
if (success && typeof success === 'function') {
|
||||
success(JSON.parse(req.responseText));
|
||||
var result;
|
||||
try {
|
||||
result = JSON.parse(req.responseText);
|
||||
} catch (e) {
|
||||
result = "";
|
||||
}
|
||||
success(result);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -174,11 +224,13 @@ function ajax(type, url, data, success, error) {
|
||||
};
|
||||
}
|
||||
|
||||
var sendData;
|
||||
if (type != "get") {
|
||||
req.setRequestHeader("Content-Type", "application/json");
|
||||
sendData = JSON.stringify(data);
|
||||
}
|
||||
|
||||
req.send(data);
|
||||
req.send(sendData);
|
||||
}
|
||||
|
||||
function get(url, success, error) {
|
||||
@ -209,3 +261,159 @@ function formatDate(strDate) {
|
||||
}
|
||||
return date.toLocaleDateString() + " at " + date.toLocaleTimeString();
|
||||
}
|
||||
|
||||
|
||||
function PureDropdown(dropdownParent) {
|
||||
"use strict";
|
||||
|
||||
var PREFIX = 'pure-',
|
||||
ACTIVE_CLASS_NAME = PREFIX + 'menu-active',
|
||||
ARIA_ROLE = 'role',
|
||||
ARIA_HIDDEN = 'aria-hidden',
|
||||
MENU_OPEN = 0,
|
||||
MENU_CLOSED = 1,
|
||||
MENU_PARENT_CLASS_NAME = 'pure-menu-has-children',
|
||||
MENU_ACTIVE_SELECTOR = '.pure-menu-active',
|
||||
MENU_LINK_SELECTOR = '.pure-menu-link',
|
||||
MENU_SELECTOR = '.pure-menu-children',
|
||||
DISMISS_EVENT = (window.hasOwnProperty &&
|
||||
window.hasOwnProperty('ontouchstart')) ?
|
||||
'touchstart' : 'mousedown',
|
||||
|
||||
ARROW_KEYS_ENABLED = true,
|
||||
|
||||
ddm = this; // drop down menu
|
||||
|
||||
this._state = MENU_CLOSED;
|
||||
|
||||
this.show = function() {
|
||||
if (this._state !== MENU_OPEN) {
|
||||
this._dropdownParent.classList.add(ACTIVE_CLASS_NAME);
|
||||
this._menu.setAttribute(ARIA_HIDDEN, false);
|
||||
this._state = MENU_OPEN;
|
||||
}
|
||||
};
|
||||
|
||||
this.hide = function() {
|
||||
if (this._state !== MENU_CLOSED) {
|
||||
this._dropdownParent.classList.remove(ACTIVE_CLASS_NAME);
|
||||
this._menu.setAttribute(ARIA_HIDDEN, true);
|
||||
this._link.focus();
|
||||
this._state = MENU_CLOSED;
|
||||
}
|
||||
};
|
||||
|
||||
this.toggle = function() {
|
||||
this[this._state === MENU_CLOSED ? 'show' : 'hide']();
|
||||
};
|
||||
|
||||
this.halt = function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
this._dropdownParent = dropdownParent;
|
||||
this._link = this._dropdownParent.querySelector(MENU_LINK_SELECTOR);
|
||||
this._menu = this._dropdownParent.querySelector(MENU_SELECTOR);
|
||||
this._firstMenuLink = this._menu.querySelector(MENU_LINK_SELECTOR);
|
||||
|
||||
// Set ARIA attributes
|
||||
this._link.setAttribute('aria-haspopup', 'true');
|
||||
this._menu.setAttribute(ARIA_ROLE, 'menu');
|
||||
this._menu.setAttribute('aria-labelledby', this._link.getAttribute('id'));
|
||||
this._menu.setAttribute('aria-hidden', 'true');
|
||||
[].forEach.call(
|
||||
this._menu.querySelectorAll('li'),
|
||||
function(el) {
|
||||
el.setAttribute(ARIA_ROLE, 'presentation');
|
||||
}
|
||||
);
|
||||
[].forEach.call(
|
||||
this._menu.querySelectorAll('a'),
|
||||
function(el) {
|
||||
el.setAttribute(ARIA_ROLE, 'menuitem');
|
||||
}
|
||||
);
|
||||
|
||||
// Toggle on click
|
||||
this._link.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
ddm.toggle();
|
||||
});
|
||||
|
||||
// Keyboard navigation
|
||||
document.addEventListener('keydown', function(e) {
|
||||
var currentLink,
|
||||
previousSibling,
|
||||
nextSibling,
|
||||
previousLink,
|
||||
nextLink;
|
||||
|
||||
// if the menu isn't active, ignore
|
||||
if (ddm._state !== MENU_OPEN) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the menu is the parent of an open, active submenu, ignore
|
||||
if (ddm._menu.querySelector(MENU_ACTIVE_SELECTOR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentLink = ddm._menu.querySelector(':focus');
|
||||
|
||||
// Dismiss an open menu on ESC
|
||||
if (e.keyCode === 27) {
|
||||
/* Esc */
|
||||
ddm.halt(e);
|
||||
ddm.hide();
|
||||
}
|
||||
// Go to the next link on down arrow
|
||||
else if (ARROW_KEYS_ENABLED && e.keyCode === 40) {
|
||||
/* Down arrow */
|
||||
ddm.halt(e);
|
||||
// get the nextSibling (an LI) of the current link's LI
|
||||
nextSibling = (currentLink) ? currentLink.parentNode.nextSibling : null;
|
||||
// if the nextSibling is a text node (not an element), go to the next one
|
||||
while (nextSibling && nextSibling.nodeType !== 1) {
|
||||
nextSibling = nextSibling.nextSibling;
|
||||
}
|
||||
nextLink = (nextSibling) ? nextSibling.querySelector('.pure-menu-link') : null;
|
||||
// if there is no currently focused link, focus the first one
|
||||
if (!currentLink) {
|
||||
ddm._menu.querySelector('.pure-menu-link').focus();
|
||||
} else if (nextLink) {
|
||||
nextLink.focus();
|
||||
}
|
||||
}
|
||||
// Go to the previous link on up arrow
|
||||
else if (ARROW_KEYS_ENABLED && e.keyCode === 38) {
|
||||
/* Up arrow */
|
||||
ddm.halt(e);
|
||||
// get the currently focused link
|
||||
previousSibling = (currentLink) ? currentLink.parentNode.previousSibling : null;
|
||||
while (previousSibling && previousSibling.nodeType !== 1) {
|
||||
previousSibling = previousSibling.previousSibling;
|
||||
}
|
||||
previousLink = (previousSibling) ? previousSibling.querySelector('.pure-menu-link') : null;
|
||||
// if there is no currently focused link, focus the last link
|
||||
if (!currentLink) {
|
||||
ddm._menu.querySelector('.pure-menu-item:last-child .pure-menu-link').focus();
|
||||
}
|
||||
// else if there is a previous item, go to the previous item
|
||||
else if (previousLink) {
|
||||
previousLink.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Dismiss an open menu on outside event
|
||||
document.addEventListener(DISMISS_EVENT, function(e) {
|
||||
var target = e.target;
|
||||
if (target !== ddm._link && !ddm._menu.contains(target)) {
|
||||
ddm.hide();
|
||||
ddm._link.blur();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -240,6 +240,11 @@ func triggerPost(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if strings.TrimSpace(project.TriggerSecret) == "" {
|
||||
four04(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
input := &triggerInput{}
|
||||
if errHandled(parseInput(r, input), w, r) {
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user