mirror of
https://github.com/mentos1386/zdravko.git
synced 2024-11-21 23:33:34 +00:00
feat: working target history
This commit is contained in:
parent
034f530923
commit
315b7c1381
17 changed files with 162 additions and 94 deletions
28
internal/server/activities/add_target_history.go
Normal file
28
internal/server/activities/add_target_history.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package activities
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/mentos1386/zdravko/database/models"
|
||||||
|
"github.com/mentos1386/zdravko/internal/server/services"
|
||||||
|
"github.com/mentos1386/zdravko/internal/temporal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *Activities) AddTargetHistory(ctx context.Context, param temporal.ActivityAddTargetHistoryParam) (*temporal.ActivityAddTargetHistoryResult, error) {
|
||||||
|
|
||||||
|
status := models.TargetStatusUnknown
|
||||||
|
if param.Status == temporal.AddTargetHistoryStatusSuccess {
|
||||||
|
status = models.TargetStatusSuccess
|
||||||
|
}
|
||||||
|
if param.Status == temporal.AddTargetHistoryStatusFailure {
|
||||||
|
status = models.TargetStatusFailure
|
||||||
|
}
|
||||||
|
|
||||||
|
err := services.AddHistoryForTarget(ctx, a.db, &models.TargetHistory{
|
||||||
|
TargetId: param.Target.Id,
|
||||||
|
Status: status,
|
||||||
|
Note: param.Note,
|
||||||
|
})
|
||||||
|
|
||||||
|
return &temporal.ActivityAddTargetHistoryResult{}, err
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
package activities
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/mentos1386/zdravko/internal/temporal"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (a *Activities) ProcessCheckOutcome(ctx context.Context, param temporal.ActivityProcessCheckOutcomeParam) (*temporal.ActivityProcessCheckOutcomeResult, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
|
@ -37,10 +37,12 @@ func (a *Activities) TargetsFilter(ctx context.Context, param temporal.ActivityT
|
||||||
a.logger.Info("TargetsFilter", "target", target)
|
a.logger.Info("TargetsFilter", "target", target)
|
||||||
|
|
||||||
targetWithMedatada := &struct {
|
targetWithMedatada := &struct {
|
||||||
|
Id string
|
||||||
Name string
|
Name string
|
||||||
Group string
|
Group string
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
}{
|
}{
|
||||||
|
Id: target.Id,
|
||||||
Name: target.Name,
|
Name: target.Name,
|
||||||
Group: target.Group,
|
Group: target.Group,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
|
@ -57,6 +59,7 @@ func (a *Activities) TargetsFilter(ctx context.Context, param temporal.ActivityT
|
||||||
}
|
}
|
||||||
if value.Export().(bool) {
|
if value.Export().(bool) {
|
||||||
filteredTargets = append(filteredTargets, &temporal.Target{
|
filteredTargets = append(filteredTargets, &temporal.Target{
|
||||||
|
Id: target.Id,
|
||||||
Name: target.Name,
|
Name: target.Name,
|
||||||
Group: target.Group,
|
Group: target.Group,
|
||||||
Metadata: target.Metadata,
|
Metadata: target.Metadata,
|
||||||
|
|
|
@ -85,7 +85,7 @@ filter: |
|
||||||
|
|
||||||
target: |
|
target: |
|
||||||
kind: Http
|
kind: Http
|
||||||
tags:
|
labels:
|
||||||
production: "true"
|
production: "true"
|
||||||
spec:
|
spec:
|
||||||
url: "https://test.k6.io"
|
url: "https://test.k6.io"
|
||||||
|
|
|
@ -6,53 +6,71 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mentos1386/zdravko/internal/temporal"
|
"github.com/mentos1386/zdravko/internal/temporal"
|
||||||
"github.com/mentos1386/zdravko/pkg/api"
|
|
||||||
"go.temporal.io/sdk/workflow"
|
"go.temporal.io/sdk/workflow"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *Workflows) CheckWorkflowDefinition(ctx workflow.Context, param temporal.WorkflowCheckParam) (api.CheckStatus, error) {
|
func (w *Workflows) CheckWorkflowDefinition(ctx workflow.Context, param temporal.WorkflowCheckParam) error {
|
||||||
workerGroupIds := param.WorkerGroupIds
|
workerGroupIds := param.WorkerGroupIds
|
||||||
sort.Strings(workerGroupIds)
|
sort.Strings(workerGroupIds)
|
||||||
|
|
||||||
ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
|
|
||||||
StartToCloseTimeout: 60 * time.Second,
|
|
||||||
TaskQueue: temporal.TEMPORAL_SERVER_QUEUE,
|
|
||||||
})
|
|
||||||
targetsFilterParam := temporal.ActivityTargetsFilterParam{
|
|
||||||
Filter: param.Filter,
|
|
||||||
}
|
|
||||||
targetsFilterResult := temporal.ActivityTargetsFilterResult{}
|
targetsFilterResult := temporal.ActivityTargetsFilterResult{}
|
||||||
err := workflow.ExecuteActivity(ctx, temporal.ActivityTargetsFilterName, targetsFilterParam).Get(ctx, &targetsFilterResult)
|
err := workflow.ExecuteActivity(
|
||||||
|
workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
|
||||||
|
StartToCloseTimeout: 60 * time.Second,
|
||||||
|
TaskQueue: temporal.TEMPORAL_SERVER_QUEUE,
|
||||||
|
}),
|
||||||
|
temporal.ActivityTargetsFilterName,
|
||||||
|
temporal.ActivityTargetsFilterParam{
|
||||||
|
Filter: param.Filter,
|
||||||
|
},
|
||||||
|
).Get(ctx, &targetsFilterResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.CheckStatusUnknown, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, target := range targetsFilterResult.Targets {
|
for _, target := range targetsFilterResult.Targets {
|
||||||
for _, workerGroupId := range workerGroupIds {
|
for _, workerGroupId := range workerGroupIds {
|
||||||
ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
|
|
||||||
StartToCloseTimeout: 60 * time.Second,
|
|
||||||
TaskQueue: workerGroupId,
|
|
||||||
})
|
|
||||||
|
|
||||||
heatlcheckParam := temporal.ActivityCheckParam{
|
|
||||||
Script: param.Script,
|
|
||||||
Target: target,
|
|
||||||
}
|
|
||||||
|
|
||||||
var checkResult *temporal.ActivityCheckResult
|
var checkResult *temporal.ActivityCheckResult
|
||||||
err := workflow.ExecuteActivity(ctx, temporal.ActivityCheckName, heatlcheckParam).Get(ctx, &checkResult)
|
err := workflow.ExecuteActivity(
|
||||||
|
workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
|
||||||
|
StartToCloseTimeout: 60 * time.Second,
|
||||||
|
TaskQueue: workerGroupId,
|
||||||
|
}),
|
||||||
|
temporal.ActivityCheckName,
|
||||||
|
temporal.ActivityCheckParam{
|
||||||
|
Script: param.Script,
|
||||||
|
Target: target,
|
||||||
|
},
|
||||||
|
).Get(ctx, &checkResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.CheckStatusUnknown, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
status := api.CheckStatusFailure
|
status := temporal.AddTargetHistoryStatusFailure
|
||||||
if checkResult.Success {
|
if checkResult.Success {
|
||||||
status = api.CheckStatusSuccess
|
status = temporal.AddTargetHistoryStatusSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
var addTargetHistoryResult *temporal.ActivityAddTargetHistoryResult
|
||||||
|
err = workflow.ExecuteActivity(
|
||||||
|
workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
|
||||||
|
StartToCloseTimeout: 60 * time.Second,
|
||||||
|
TaskQueue: temporal.TEMPORAL_SERVER_QUEUE,
|
||||||
|
}),
|
||||||
|
temporal.ActivityAddTargetHistoryName,
|
||||||
|
&temporal.ActivityAddTargetHistoryParam{
|
||||||
|
Target: target,
|
||||||
|
Status: status,
|
||||||
|
Note: checkResult.Note,
|
||||||
|
},
|
||||||
|
).Get(ctx, &addTargetHistoryResult)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Info("Check %s status: %s", param.CheckId, status)
|
slog.Info("Check %s status: %s", param.CheckId, status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.CheckStatusSuccess, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
20
internal/temporal/activity_add_target_history.go
Normal file
20
internal/temporal/activity_add_target_history.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package temporal
|
||||||
|
|
||||||
|
type AddTargetHistoryStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
AddTargetHistoryStatusSuccess AddTargetHistoryStatus = "SUCCESS"
|
||||||
|
AddTargetHistoryStatusFailure AddTargetHistoryStatus = "FAILURE"
|
||||||
|
AddTargetHistoryStatusUnknown AddTargetHistoryStatus = "UNKNOWN"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActivityAddTargetHistoryParam struct {
|
||||||
|
Target *Target
|
||||||
|
Status AddTargetHistoryStatus
|
||||||
|
Note string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActivityAddTargetHistoryResult struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
const ActivityAddTargetHistoryName = "ADD_TARGET_HISTORY"
|
|
@ -1,10 +0,0 @@
|
||||||
package temporal
|
|
||||||
|
|
||||||
type ActivityProcessCheckOutcomeParam struct {
|
|
||||||
Outcome string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ActivityProcessCheckOutcomeResult struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
const ActivityProcessCheckOutcomeName = "PROCESS_CHECK_OUTCOME"
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Target struct {
|
type Target struct {
|
||||||
|
Id string
|
||||||
Name string
|
Name string
|
||||||
Group string
|
Group string
|
||||||
Metadata string
|
Metadata string
|
||||||
|
|
|
@ -1,15 +1 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
type CheckStatus string
|
|
||||||
|
|
||||||
const (
|
|
||||||
CheckStatusSuccess CheckStatus = "SUCCESS"
|
|
||||||
CheckStatusFailure CheckStatus = "FAILURE"
|
|
||||||
CheckStatusUnknown CheckStatus = "UNKNOWN"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ApiV1ChecksHistoryPOSTBody struct {
|
|
||||||
Status CheckStatus `json:"status"`
|
|
||||||
Note string `json:"note"`
|
|
||||||
WorkerGroupId string `json:"worker_group"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ func NewWorker(temporalClient client.Client, cfg *config.ServerConfig, logger *s
|
||||||
|
|
||||||
// Register Activities
|
// Register Activities
|
||||||
worker.RegisterActivityWithOptions(a.TargetsFilter, activity.RegisterOptions{Name: temporal.ActivityTargetsFilterName})
|
worker.RegisterActivityWithOptions(a.TargetsFilter, activity.RegisterOptions{Name: temporal.ActivityTargetsFilterName})
|
||||||
worker.RegisterActivityWithOptions(a.ProcessCheckOutcome, activity.RegisterOptions{Name: temporal.ActivityProcessCheckOutcomeName})
|
worker.RegisterActivityWithOptions(a.AddTargetHistory, activity.RegisterOptions{Name: temporal.ActivityAddTargetHistoryName})
|
||||||
|
|
||||||
return &Worker{
|
return &Worker{
|
||||||
worker: worker,
|
worker: worker,
|
||||||
|
|
|
@ -1798,6 +1798,10 @@ code {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
|
.sm\:col-span-2 {
|
||||||
|
grid-column: span 2 / span 2;
|
||||||
|
}
|
||||||
|
|
||||||
.sm\:w-auto {
|
.sm\:w-auto {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,26 +35,26 @@
|
||||||
<code>@yearly</code>.
|
<code>@yearly</code>.
|
||||||
</p>
|
</p>
|
||||||
<label for="filter">Filter</label>
|
<label for="filter">Filter</label>
|
||||||
<textarea required id="filter" name="filter" class="h-12">
|
<textarea required id="filter" name="filter" class="sm:col-span-2 h-12">
|
||||||
{{ ScriptUnescapeString .ExampleFilter }}</textarea
|
{{ ScriptUnescapeString .ExampleFilter }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-filter"
|
id="editor-filter"
|
||||||
class="hidden block w-full h-12 rounded-lg border border-gray-300 overflow-hidden"
|
class="hidden sm:col-span-2 block w-full h-12 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
With filter we specify what targets the check will run on. The must be a
|
With filter we specify what targets the check will run on. The must be a
|
||||||
javascript expression that returns a boolean.
|
javascript expression that returns a boolean.
|
||||||
</p>
|
</p>
|
||||||
<label for="script">Script</label>
|
<label for="script">Script</label>
|
||||||
<textarea required id="script" name="script" class="h-96">
|
<textarea required id="script" name="script" class="sm:col-span-2 h-96">
|
||||||
{{ ScriptUnescapeString .ExampleScript }}</textarea
|
{{ ScriptUnescapeString .ExampleScript }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-script"
|
id="editor-script"
|
||||||
class="hidden block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
class="hidden sm:col-span-2 block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
Script is what determines the status of a service. You can read more
|
Script is what determines the status of a service. You can read more
|
||||||
about it on
|
about it on
|
||||||
<a target="_blank" href="https://k6.io/docs/using-k6/http-requests/"
|
<a target="_blank" href="https://k6.io/docs/using-k6/http-requests/"
|
||||||
|
@ -68,7 +68,13 @@
|
||||||
<script src="/static/monaco/vs/loader.js"></script>
|
<script src="/static/monaco/vs/loader.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const items = [
|
const items = [
|
||||||
{ name: "filter", language: "javascript" },
|
{
|
||||||
|
name: "filter",
|
||||||
|
language: "javascript",
|
||||||
|
options: {
|
||||||
|
quickSuggestions: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
{ name: "script", language: "javascript" },
|
{ name: "script", language: "javascript" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -80,7 +86,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.editors = {};
|
window.editors = {};
|
||||||
for (const { name, language } of items) {
|
for (const { name, language, options = {} } of items) {
|
||||||
const textarea = document.getElementById(name);
|
const textarea = document.getElementById(name);
|
||||||
const editor = document.getElementById("editor-" + name);
|
const editor = document.getElementById("editor-" + name);
|
||||||
|
|
||||||
|
@ -96,6 +102,8 @@
|
||||||
codeLens: false,
|
codeLens: false,
|
||||||
contextmenu: false,
|
contextmenu: false,
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
|
wordWrap: "on",
|
||||||
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver((entries) => {
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
|
|
@ -29,26 +29,26 @@
|
||||||
<code>@yearly</code>.
|
<code>@yearly</code>.
|
||||||
</p>
|
</p>
|
||||||
<label for="filter">Filter</label>
|
<label for="filter">Filter</label>
|
||||||
<textarea required id="filter" name="filter" class="h-12">
|
<textarea required id="filter" name="filter" class="sm:col-span-2 h-12">
|
||||||
{{ ScriptUnescapeString .Check.Filter }}</textarea
|
{{ ScriptUnescapeString .Check.Filter }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-filter"
|
id="editor-filter"
|
||||||
class="hidden block w-full h-12 rounded-lg border border-gray-300 overflow-hidden"
|
class="hidden sm:col-span-2 block w-full h-12 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
With filter we specify what targets the check will run on. The must be a
|
With filter we specify what targets the check will run on. The must be a
|
||||||
javascript expression that returns a boolean.
|
javascript expression that returns a boolean.
|
||||||
</p>
|
</p>
|
||||||
<label for="script">Script</label>
|
<label for="script">Script</label>
|
||||||
<textarea required id="script" name="script" class="h-96">
|
<textarea required id="script" name="script" class="sm:col-span-2 h-96">
|
||||||
{{ ScriptUnescapeString .Check.Script }}</textarea
|
{{ ScriptUnescapeString .Check.Script }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-script"
|
id="editor-script"
|
||||||
class="block w-full h-96 rounded-lg border border-gray-300 overflow-hidden hidden"
|
class="hidden sm:col-span-2 block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
Script is what determines the status of a service. You can read more
|
Script is what determines the status of a service. You can read more
|
||||||
about it on
|
about it on
|
||||||
<a target="_blank" href="https://k6.io/docs/using-k6/http-requests/"
|
<a target="_blank" href="https://k6.io/docs/using-k6/http-requests/"
|
||||||
|
@ -184,7 +184,13 @@
|
||||||
<script src="/static/monaco/vs/loader.js"></script>
|
<script src="/static/monaco/vs/loader.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const items = [
|
const items = [
|
||||||
{ name: "filter", language: "javascript" },
|
{
|
||||||
|
name: "filter",
|
||||||
|
language: "javascript",
|
||||||
|
options: {
|
||||||
|
quickSuggestions: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
{ name: "script", language: "javascript" },
|
{ name: "script", language: "javascript" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -196,7 +202,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.editors = {};
|
window.editors = {};
|
||||||
for (const { name, language } of items) {
|
for (const { name, language, options = {} } of items) {
|
||||||
const textarea = document.getElementById(name);
|
const textarea = document.getElementById(name);
|
||||||
const editor = document.getElementById("editor-" + name);
|
const editor = document.getElementById("editor-" + name);
|
||||||
|
|
||||||
|
@ -212,6 +218,8 @@
|
||||||
codeLens: false,
|
codeLens: false,
|
||||||
contextmenu: false,
|
contextmenu: false,
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
|
wordWrap: "on",
|
||||||
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver((entries) => {
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
|
|
@ -28,14 +28,19 @@
|
||||||
homepage.
|
homepage.
|
||||||
</p>
|
</p>
|
||||||
<label for="metadata">Metadata</label>
|
<label for="metadata">Metadata</label>
|
||||||
<textarea required id="metadata" name="metadata" class="h-96">
|
<textarea
|
||||||
|
required
|
||||||
|
id="metadata"
|
||||||
|
name="metadata"
|
||||||
|
class="sm:col-span-2 h-96"
|
||||||
|
>
|
||||||
{{ ScriptUnescapeString .Example }}</textarea
|
{{ ScriptUnescapeString .Example }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-metadata"
|
id="editor-metadata"
|
||||||
class="hidden block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
class="hidden sm:col-span-2 block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
Metadata is a YAML object that contains the configuration for the
|
Metadata is a YAML object that contains the configuration for the
|
||||||
target. This configuration can be then used for <code>Checks</code> to
|
target. This configuration can be then used for <code>Checks</code> to
|
||||||
filter the targets to act on as well as by using
|
filter the targets to act on as well as by using
|
||||||
|
@ -58,7 +63,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.editors = {};
|
window.editors = {};
|
||||||
for (const { name, language } of items) {
|
for (const { name, language, options = {} } of items) {
|
||||||
const textarea = document.getElementById(name);
|
const textarea = document.getElementById(name);
|
||||||
const editor = document.getElementById("editor-" + name);
|
const editor = document.getElementById("editor-" + name);
|
||||||
|
|
||||||
|
@ -74,6 +79,7 @@
|
||||||
codeLens: false,
|
codeLens: false,
|
||||||
contextmenu: false,
|
contextmenu: false,
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver((entries) => {
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
|
|
@ -35,14 +35,19 @@
|
||||||
homepage.
|
homepage.
|
||||||
</p>
|
</p>
|
||||||
<label for="metadata">Metadata</label>
|
<label for="metadata">Metadata</label>
|
||||||
<textarea required id="metadata" name="metadata" class="h-96">
|
<textarea
|
||||||
|
required
|
||||||
|
id="metadata"
|
||||||
|
name="metadata"
|
||||||
|
class="sm:col-span-2 h-96"
|
||||||
|
>
|
||||||
{{ ScriptUnescapeString .Target.Metadata }}</textarea
|
{{ ScriptUnescapeString .Target.Metadata }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-metadata"
|
id="editor-metadata"
|
||||||
class="hidden block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
class="hidden sm:col-span-2 block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
Metadata is a YAML object that contains the configuration for the
|
Metadata is a YAML object that contains the configuration for the
|
||||||
target. This configuration can be then used for <code>Targets</code> to
|
target. This configuration can be then used for <code>Targets</code> to
|
||||||
filter the targets to act on as well as by using
|
filter the targets to act on as well as by using
|
||||||
|
|
|
@ -10,14 +10,14 @@
|
||||||
/>
|
/>
|
||||||
<p>Name of the trigger can be anything.</p>
|
<p>Name of the trigger can be anything.</p>
|
||||||
<label for="script">Script</label>
|
<label for="script">Script</label>
|
||||||
<textarea required id="script" name="script" class="h-96">
|
<textarea required id="script" name="script" class="sm:col-span-2 h-96">
|
||||||
{{ ScriptUnescapeString .Example }}</textarea
|
{{ ScriptUnescapeString .Example }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-script"
|
id="editor-script"
|
||||||
class="hidden block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
class="hidden sm:col-span-2 block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
The trigger script executes for every matching <code>target</code>'s
|
The trigger script executes for every matching <code>target</code>'s
|
||||||
execution of <code>trigger</code>. The outcome of that
|
execution of <code>trigger</code>. The outcome of that
|
||||||
<code>trigger</code> is passed to the script as a
|
<code>trigger</code> is passed to the script as a
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.editors = {};
|
window.editors = {};
|
||||||
for (const { name, language } of items) {
|
for (const { name, language, options = {} } of items) {
|
||||||
const textarea = document.getElementById(name);
|
const textarea = document.getElementById(name);
|
||||||
const editor = document.getElementById("editor-" + name);
|
const editor = document.getElementById("editor-" + name);
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@
|
||||||
codeLens: false,
|
codeLens: false,
|
||||||
contextmenu: false,
|
contextmenu: false,
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver((entries) => {
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
<form action="/settings/triggers/{{ .Trigger.Id }}" method="post">
|
<form action="/settings/triggers/{{ .Trigger.Id }}" method="post">
|
||||||
<h2>Configuration</h2>
|
<h2>Configuration</h2>
|
||||||
<label for="script">Script</label>
|
<label for="script">Script</label>
|
||||||
<textarea required id="script" name="script" class="h-96">
|
<textarea required id="script" name="script" class="sm:col-span-2 h-96">
|
||||||
{{ ScriptUnescapeString .Trigger.Script }}</textarea
|
{{ ScriptUnescapeString .Trigger.Script }}</textarea
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="editor-script"
|
id="editor-script"
|
||||||
class="block w-full h-96 rounded-lg border border-gray-300 overflow-hidden hidden"
|
class="hidden sm:col-span-2 block w-full h-96 rounded-lg border border-gray-300 overflow-hidden"
|
||||||
></div>
|
></div>
|
||||||
<p>
|
<p class="sm:col-span-2">
|
||||||
The trigger script executes for every matching <code>target</code>'s
|
The trigger script executes for every matching <code>target</code>'s
|
||||||
execution of <code>trigger</code>. The outcome of that
|
execution of <code>trigger</code>. The outcome of that
|
||||||
<code>trigger</code> is passed to the script as a
|
<code>trigger</code> is passed to the script as a
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.editors = {};
|
window.editors = {};
|
||||||
for (const { name, language } of items) {
|
for (const { name, language, options = {} } of items) {
|
||||||
const textarea = document.getElementById(name);
|
const textarea = document.getElementById(name);
|
||||||
const editor = document.getElementById("editor-" + name);
|
const editor = document.getElementById("editor-" + name);
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@
|
||||||
codeLens: false,
|
codeLens: false,
|
||||||
contextmenu: false,
|
contextmenu: false,
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserver((entries) => {
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
|
Loading…
Reference in a new issue