Ongoing UI work
This commit is contained in:
parent
39647c6d2d
commit
afd8353b6f
|
|
@ -14,14 +14,15 @@ message ActionButton {
|
||||||
}
|
}
|
||||||
|
|
||||||
message ActionArgument {
|
message ActionArgument {
|
||||||
string variable = 1;
|
string name = 1;
|
||||||
string label = 2;
|
string label = 2;
|
||||||
string type = 3;
|
string type = 3;
|
||||||
|
string defaultValue = 4;
|
||||||
|
|
||||||
repeated ActionArgumentValue values = 4;
|
repeated ActionArgumentChoice choices = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ActionArgumentValue {
|
message ActionArgumentChoice {
|
||||||
string value = 1;
|
string value = 1;
|
||||||
string label = 2;
|
string label = 2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,14 @@ type ActionButton struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionArgument struct {
|
type ActionArgument struct {
|
||||||
Variable string
|
Name string
|
||||||
Label string
|
Label string
|
||||||
Type string
|
Type string
|
||||||
Values []ActionArgumentValue
|
Default string
|
||||||
|
Choices []ActionArgumentChoice
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionArgumentValue struct {
|
type ActionArgumentChoice struct {
|
||||||
Value string
|
Value string
|
||||||
Label string
|
Label string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,14 @@ package grpcapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
ctx "context"
|
ctx "context"
|
||||||
"crypto/md5"
|
|
||||||
"fmt"
|
|
||||||
pb "github.com/jamesread/OliveTin/gen/grpc"
|
pb "github.com/jamesread/OliveTin/gen/grpc"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
acl "github.com/jamesread/OliveTin/internal/acl"
|
|
||||||
config "github.com/jamesread/OliveTin/internal/config"
|
config "github.com/jamesread/OliveTin/internal/config"
|
||||||
executor "github.com/jamesread/OliveTin/internal/executor"
|
executor "github.com/jamesread/OliveTin/internal/executor"
|
||||||
|
acl "github.com/jamesread/OliveTin/internal/acl"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -66,22 +64,8 @@ func actionButtonsCfgToPb(cfgActionButtons []config.ActionButton, user *acl.User
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
btn := pb.ActionButton{
|
btn := buildButton(action, user)
|
||||||
Id: fmt.Sprintf("%x", md5.Sum([]byte(action.Title))),
|
res.Actions = append(res.Actions, btn)
|
||||||
Title: action.Title,
|
|
||||||
Icon: lookupHTMLIcon(action.Icon),
|
|
||||||
CanExec: acl.IsAllowedExec(cfg, user, &action),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, cfgArg := range action.Arguments {
|
|
||||||
pbArg := pb.ActionArgument {
|
|
||||||
Label: cfgArg.Label,
|
|
||||||
}
|
|
||||||
|
|
||||||
btn.Arguments = append(btn.Arguments, &pbArg)
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Actions = append(res.Actions, &btn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package grpcapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"crypto/md5"
|
||||||
|
pb "github.com/jamesread/OliveTin/gen/grpc"
|
||||||
|
config "github.com/jamesread/OliveTin/internal/config"
|
||||||
|
acl "github.com/jamesread/OliveTin/internal/acl"
|
||||||
|
)
|
||||||
|
|
||||||
|
func buildButton(action config.ActionButton, user *acl.User) (*pb.ActionButton) {
|
||||||
|
btn := pb.ActionButton{
|
||||||
|
Id: fmt.Sprintf("%x", md5.Sum([]byte(action.Title))),
|
||||||
|
Title: action.Title,
|
||||||
|
Icon: lookupHTMLIcon(action.Icon),
|
||||||
|
CanExec: acl.IsAllowedExec(cfg, user, &action),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cfgArg := range action.Arguments {
|
||||||
|
pbArg := pb.ActionArgument {
|
||||||
|
Name: cfgArg.Name,
|
||||||
|
Label: cfgArg.Label,
|
||||||
|
Type: cfgArg.Type,
|
||||||
|
DefaultValue: cfgArg.Default,
|
||||||
|
Choices: buildChoices(cfgArg.Choices),
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.Arguments = append(btn.Arguments, &pbArg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &btn
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildChoices(choices []config.ActionArgumentChoice) ([]*pb.ActionArgumentChoice) {
|
||||||
|
ret := []*pb.ActionArgumentChoice{}
|
||||||
|
|
||||||
|
for _, cfgChoice := range choices {
|
||||||
|
pbChoice := pb.ActionArgumentChoice {
|
||||||
|
Value: cfgChoice.Value,
|
||||||
|
Label: cfgChoice.Label,
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = append(ret, &pbChoice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
@ -2,17 +2,86 @@
|
||||||
class ArgumentForm extends window.HTMLFormElement {
|
class ArgumentForm extends window.HTMLFormElement {
|
||||||
setup(json, callback) {
|
setup(json, callback) {
|
||||||
this.setAttribute('class', 'actionArguments')
|
this.setAttribute('class', 'actionArguments')
|
||||||
this.title = document.createElement("h1")
|
|
||||||
this.title.innerHTML = "Action Arguments"
|
|
||||||
|
|
||||||
this.appendChild(this.title);
|
|
||||||
|
|
||||||
let a = document.createElement("span")
|
|
||||||
a.innerText = "Hi"
|
|
||||||
frm.appendChild(a)
|
|
||||||
|
|
||||||
|
|
||||||
console.log(json)
|
console.log(json)
|
||||||
|
|
||||||
|
this.domWrapper = document.createElement('div')
|
||||||
|
this.domWrapper.classList += 'wrapper'
|
||||||
|
this.appendChild(this.domWrapper)
|
||||||
|
|
||||||
|
this.domTitle = document.createElement('h2')
|
||||||
|
this.domTitle.innerText = json.title + ": Arguments"
|
||||||
|
this.domWrapper.appendChild(this.domTitle);
|
||||||
|
|
||||||
|
this.domIcon = document.createElement('span');
|
||||||
|
this.domIcon.classList += 'icon'
|
||||||
|
this.domIcon.setAttribute('role', 'img')
|
||||||
|
this.domIcon.innerHTML = json.icon
|
||||||
|
this.domTitle.prepend(this.domIcon)
|
||||||
|
|
||||||
|
let a = document.createElement("span")
|
||||||
|
a.innerText = "This is test version of the form."
|
||||||
|
this.domWrapper.appendChild(a)
|
||||||
|
|
||||||
|
this.createDomFormArguments(json.arguments)
|
||||||
|
this.domWrapper.appendChild(this.createDomSubmit())
|
||||||
|
|
||||||
|
console.log(json)
|
||||||
|
}
|
||||||
|
|
||||||
|
createDomSubmit() {
|
||||||
|
let el = document.createElement('button')
|
||||||
|
el.setAttribute('action', 'submit')
|
||||||
|
el.innerText = "Run"
|
||||||
|
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
createDomFormArguments(args) {
|
||||||
|
for (let arg of args) {
|
||||||
|
let domFieldWrapper = document.createElement('p');
|
||||||
|
|
||||||
|
domFieldWrapper.appendChild(this.createDomLabel(arg))
|
||||||
|
domFieldWrapper.appendChild(this.createDomInput(arg))
|
||||||
|
|
||||||
|
this.domWrapper.appendChild(domFieldWrapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createDomLabel(arg) {
|
||||||
|
let domLbl = document.createElement('label')
|
||||||
|
domLbl.innerText = arg.label + ':';
|
||||||
|
domLbl.setAttribute('for', arg.name)
|
||||||
|
|
||||||
|
return domLbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
createDomInput(arg) {
|
||||||
|
let domEl = null;
|
||||||
|
|
||||||
|
if (arg.choices.length > 0) {
|
||||||
|
domEl = document.createElement('select')
|
||||||
|
|
||||||
|
for (let choice of arg.choices) {
|
||||||
|
domEl.appendChild(this.createSelectOption(choice))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
domEl = document.createElement('input')
|
||||||
|
}
|
||||||
|
|
||||||
|
domEl.setAttribute('id', arg.name)
|
||||||
|
domEl.value = arg.defaultValue
|
||||||
|
|
||||||
|
return domEl;
|
||||||
|
}
|
||||||
|
|
||||||
|
createSelectOption(choice) {
|
||||||
|
let domEl = document.createElement('option')
|
||||||
|
|
||||||
|
domEl.setAttribute('value', choice.value)
|
||||||
|
domEl.innerText = choice.label
|
||||||
|
|
||||||
|
return domEl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -237,11 +237,41 @@ details[open] {
|
||||||
}
|
}
|
||||||
|
|
||||||
form.actionArguments {
|
form.actionArguments {
|
||||||
border-radius: 1em;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 1em;
|
top: 0;
|
||||||
left: 1em;
|
bottom: 0;
|
||||||
right: 1em;
|
left: 0;
|
||||||
|
right: 0;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: #fff;
|
box-shadow: 0 0 6px 0 #aaa;
|
||||||
|
background-color: #dee3e7;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 span.icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-right: .2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
form div.wrapper {
|
||||||
|
border-radius: 1em;
|
||||||
|
box-shadow: 0 0 10px 0 #444;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #999;
|
||||||
|
text-align: left;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
width: 30%;
|
||||||
|
text-align: right;
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: .6em;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue