~humaid/workflow-engine unlisted

da930b368aae69a9235606eb297ce0a9c6dd5e9d — Humaid AlQassimi 7 months ago 1a77fe9
admin: editing of service, and show all step fields
M Makefile => Makefile +1 -1
@@ 3,7 3,7 @@ GC = go
all: format test build

build: main.go
	$(GC) build
	env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GC) build -a

format:
	$(GC) fmt ./...

M admin.go => admin.go +39 -1
@@ 78,11 78,45 @@ func (e *Engine) RunWebInterface() {
			m.Get("/step/:service/:channel", newStepHandler)
			m.Post("/step/:service/:channel", binding.BindIgnErr(newStepForm{}), postNewStepHandler)
		})
		m.Group("/edit", func() {
			m.Get("/service/:service", editServiceHandler)
			m.Post("/service/:service", binding.BindIgnErr(newServiceForm{}), postEditServiceHandler)
		})
		m.Get("/commit", commitHandler)
	}, requireLogin)
	log.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", e.Options.AdminPort), m))
}

func editServiceHandler(ctx *macaron.Context, f *session.Flash) {
	e := ctx.Data["Engine"].(*Engine)
	s := e.getService(ctx.Params("service"))
	if s == nil {
		f.Error("Service not found")
		ctx.Redirect("/dash")
		return
	}
	ctx.Data["Service"] = s
	ctx.HTML(http.StatusOK, "edit-service")
}

func postEditServiceHandler(ctx *macaron.Context, f *session.Flash, errs binding.Errors, form newServiceForm) {
	if errs.Len() > 0 {
		f.Error("Make sure to fill required fields")
		ctx.Redirect("/edit/service/" + ctx.Params("service"))
		return
	}
	e := ctx.Data["Engine"].(*Engine)
	s := e.getService(ctx.Params("service"))
	if s == nil {
		f.Error("Service not found")
		ctx.Redirect("/dash")
		return
	}
	s.Category = form.Category
	s.Description = form.Description
	ctx.Redirect("/s/" + s.ServiceID)
}

func toFileFriendly(id string) string {
	id = strings.ToLower(id)
	id = strings.ReplaceAll(id, " ", "-")


@@ 264,7 298,10 @@ func stepHandler(ctx *macaron.Context, sess session.Store, f *session.Flash) {
	}
	var step *WorkflowStep
	for _, st := range c.Steps {
		step = &st
		if st.StepID == ctx.Params("step") {
			step = &st
			break
		}
	}
	if step == nil {
		f.Error("Step not found")


@@ 275,6 312,7 @@ func stepHandler(ctx *macaron.Context, sess session.Store, f *session.Flash) {
	ctx.Data["ChannelID"] = ctx.Params("channel")
	ctx.Data["Channel"] = c
	ctx.Data["Step"] = step
	ctx.Data["Rel"] = fmt.Sprintf("%s/%s/%s", ctx.Params("service"), ctx.Params("channel"), step.StepID)
	ctx.HTML(http.StatusOK, "step")
}


M engine.go => engine.go +9 -0
@@ 104,6 104,15 @@ func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	g.ServeHTTP(w, r)
}

func (e *Engine) getService(service string) *Service {
	for i, s := range e.Services {
		if s.ServiceID == service {
			return &e.Services[i]
		}
	}
	return nil
}

func (e *Engine) getChannel(service, channel string) *Channel {
	for i, s := range e.Services {
		if s.ServiceID == service {

M public/bindata.go => public/bindata.go +1 -1
@@ 1,6 1,6 @@
// Code generated by go-bindata. (@generated) DO NOT EDIT.

 //Package public generated by go-bindata.// sources:
//Package public generated by go-bindata.// sources:
// public/bindata.go
// public/css/main.css
// public/css/normalize-8.0.1.min.css

M public/css/main.css => public/css/main.css +5 -0
@@ 11,6 11,7 @@

  --danger-btn: #fc4e51;
}

/* Page style */
body {
  font-family: "Lucidia Grande", "Segoe UI", "Roboto", sans-serif;


@@ 112,6 113,10 @@ code {
  text-decoration: none;
}

.inline {
  display: inline !important;
}

.meta a {
  padding: 0;
  margin: 0 0 5px 15px;

M templates/bindata.go => templates/bindata.go +1 -1
@@ 1,6 1,6 @@
// Code generated by go-bindata. (@generated) DO NOT EDIT.

 //Package templates generated by go-bindata.// sources:
//Package templates generated by go-bindata.// sources:
// templates/base/footer.tmpl
// templates/base/head.tmpl
// templates/bindata.go

M templates/service.tmpl => templates/service.tmpl +4 -2
@@ 3,8 3,10 @@
	{{template "partials/flash" .}}
	<h2>{{.Service.ServiceID}}</h2>
	<p>{{if .Service.Description}}<b>Description</b>: {{.Service.Description}}{{else}}
	No description provided{{end}}</p>
	<p><a class="btn" href="/edit/channel/{{.Service.ServiceID}}">Edit channel</a></p>
	<i>No description provided</i>{{end}}</p>
	<p><b>Category</b>: {{if .Service.Category}}{{.Service.Category}}{{else}}
	<i>None</i>{{end}}</p>
	<p><a class="btn" href="/edit/service/{{.Service.ServiceID}}">Edit service</a></p>
	<h3>Registered channels</h3>
	<p><a class="btn" href="/new/channel/{{.Service.ServiceID}}">Add a new channel</a></p>
	{{range .Service.Channels}}

M templates/step.tmpl => templates/step.tmpl +40 -1
@@ 18,21 18,60 @@
	<p><small><b>Note</b>: You may hover dotted text for help
	message.</small></p>
	<p><a class="btn"
	href="/edit/step/{{.ServiceID}}/{{.StepID}}/{{.StepID}}">Edit attributes</a></p>
	href="/edit/step/{{.Rel}}">Edit attributes</a></p>
	<h3>Execution Criteria</h3>
	<p><i>These are criterion required to pass before the step is allowed to
	start.</i></p>
	{{range .Step.CriteriaExec}}
	<div class="entry">
		<a href="/edit/criteria-exec/">{{if .CriteriaName}}{{.CriteriaName}}{{else}}No
		Name!{{end}}</a>
		<div class="meta">
			<p><a href="#"><code>{{.Expression}}</code></a></p>
			<p><a href="#">Fail message: {{if .FailMessage}}{{.FailMessage}}{{else}}None{{end}}</a></p>
		</div>
	</div>
	{{end}}
	<h3>Finalisation Criteria</h3>
	<p><i>These are criterion required to pass before the step is allowed to be
	marked as complete.</i></p>
	{{range .Step.CriteriaFinal}}
	<div class="entry">
		<a href="/s/">{{if .CriteriaName}}{{.CriteriaName}}{{else}}No
		Name!{{end}}</a>
		<div class="meta">
			<p><a href="#"><code>{{.Expression}}</code></a></p>
			<p><a href="#">Fail message: {{if .FailMessage}}{{.FailMessage}}{{else}}None{{end}}</a></p>
		</div>
	</div>
	{{end}}
	<h3>Pull Data</h3>
	<p><i>This is the external services called via HTTP POST.</i></p>
	<h3>Commit Objects</h3>
	<p><i>These are objects which are created before committing, and are loaded
	in the commit scripting environment.</i></p>
	{{range .Step.CommitObjects}}
	<div class="entry">
		<a href="/s/"><code>{{.Name}}</code> (type: {{.Type}})</a>
		<div class="meta">
			{{range $key, $value := .Variables}}
			<p><a href="">{{$key}}: <code>{{$value}}</code></a></p>
			{{end}}
		</div>
	</div>
	{{end}}
	<h3>Commit</h3>
	<p><i>These are the scripts which are run against the database when the
	step is finalised.</i></p>
	{{range .Step.Commit}}
	<div class="entry">
		<a href="/s/"><code>{{.}}</code></a>
		<div class="">
			<p>(<a class="inline" href="">delete</a> | <a class="inline"
			href="">edit</a>)</p>
		</div>
	</div>
	{{end}}


	<h3></h3>