Ongoing UI work

This commit is contained in:
jamesread 2021-10-17 23:32:05 +01:00
parent d68dba13bd
commit 48fe7b7dd4
6 changed files with 171 additions and 39 deletions

View File

@ -14,14 +14,15 @@ message ActionButton {
}
message ActionArgument {
string variable = 1;
string name = 1;
string label = 2;
string type = 3;
string defaultValue = 4;
repeated ActionArgumentValue values = 4;
repeated ActionArgumentChoice choices = 5;
}
message ActionArgumentValue {
message ActionArgumentChoice {
string value = 1;
string label = 2;
}

View File

@ -15,13 +15,14 @@ type ActionButton struct {
}
type ActionArgument struct {
Variable string
Name string
Label string
Type string
Values []ActionArgumentValue
Default string
Choices []ActionArgumentChoice
}
type ActionArgumentValue struct {
type ActionArgumentChoice struct {
Value string
Label string
}

View File

@ -2,16 +2,14 @@ package grpcapi
import (
ctx "context"
"crypto/md5"
"fmt"
pb "github.com/jamesread/OliveTin/gen/grpc"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"net"
acl "github.com/jamesread/OliveTin/internal/acl"
config "github.com/jamesread/OliveTin/internal/config"
executor "github.com/jamesread/OliveTin/internal/executor"
acl "github.com/jamesread/OliveTin/internal/acl"
)
var (
@ -54,22 +52,8 @@ func (api *oliveTinAPI) GetButtons(ctx ctx.Context, req *pb.GetButtonsRequest) (
continue
}
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 {
Label: cfgArg.Label,
}
btn.Arguments = append(btn.Arguments, &pbArg)
}
res.Actions = append(res.Actions, &btn)
btn := buildButton(action, user)
res.Actions = append(res.Actions, btn)
}
if len(res.Actions) == 0 {

View File

@ -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;
}

View File

@ -2,17 +2,86 @@
class ArgumentForm extends window.HTMLFormElement {
setup(json, callback) {
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)
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
}
}

View File

@ -249,11 +249,41 @@ details[open] {
}
form.actionArguments {
border-radius: 1em;
position: absolute;
top: 1em;
left: 1em;
right: 1em;
top: 0;
bottom: 0;
left: 0;
right: 0;
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;
}