@protobase/schema 0.67.10 → 0.67.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/built-in-field-types.d.ts +6 -1
- package/dist/built-in-field-types.js +9 -2
- package/dist/internal.d.ts +2 -1
- package/dist/internal.js +2 -1
- package/dist/workflows/step-types.d.ts +30 -0
- package/dist/workflows/step-types.js +70 -0
- package/dist/workflows/workflow-resources.d.ts +2 -0
- package/dist/workflows/workflow-resources.js +44 -5
- package/package.json +1 -1
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
//#region src/built-in-field-types.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* The field types Protobase brings, which a view chooses with `.widget(name)` like a plugin's, by the storage types
|
|
4
|
-
* each shows: `members`, a JSON array of the user ids of an organization's members
|
|
4
|
+
* each shows: `json`, any JSON value edited as JSON text, `members`, a JSON array of the user ids of an organization's members, `workflow`, a workflow's
|
|
5
|
+
* definition drawn as a graph to edit, and `workflow_run`, a run's id, drawn as its steps on its workflow's graph. A
|
|
6
|
+
* plugin's of the same name wins.
|
|
5
7
|
*/
|
|
6
8
|
export declare const builtInFieldTypes: {
|
|
9
|
+
readonly json: readonly ["json"];
|
|
7
10
|
readonly members: readonly ["json"];
|
|
11
|
+
readonly workflow: readonly ["json"];
|
|
12
|
+
readonly workflow_run: readonly ["uuid"];
|
|
8
13
|
};
|
|
9
14
|
//#endregion
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
//#region src/built-in-field-types.ts
|
|
2
2
|
/**
|
|
3
3
|
* The field types Protobase brings, which a view chooses with `.widget(name)` like a plugin's, by the storage types
|
|
4
|
-
* each shows: `members`, a JSON array of the user ids of an organization's members
|
|
4
|
+
* each shows: `json`, any JSON value edited as JSON text, `members`, a JSON array of the user ids of an organization's members, `workflow`, a workflow's
|
|
5
|
+
* definition drawn as a graph to edit, and `workflow_run`, a run's id, drawn as its steps on its workflow's graph. A
|
|
6
|
+
* plugin's of the same name wins.
|
|
5
7
|
*/
|
|
6
|
-
const builtInFieldTypes = {
|
|
8
|
+
const builtInFieldTypes = {
|
|
9
|
+
json: ["json"],
|
|
10
|
+
members: ["json"],
|
|
11
|
+
workflow: ["json"],
|
|
12
|
+
workflow_run: ["uuid"]
|
|
13
|
+
};
|
|
7
14
|
//#endregion
|
|
8
15
|
export { builtInFieldTypes };
|
package/dist/internal.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { parseCapability } from "./access/capability.js";
|
|
|
11
11
|
import { checkEventFilter } from "./events/event-models.js";
|
|
12
12
|
import { webhookResources } from "./webhooks/webhook-resources.js";
|
|
13
13
|
import { workflowResources } from "./workflows/workflow-resources.js";
|
|
14
|
+
import { StepInput, StepInputKind, WorkflowStepType, requiredStepInputs, workflowStepTypes } from "./workflows/step-types.js";
|
|
14
15
|
import { PropShapes, RefShape, pruneByShape, shapes } from "./ref-shape.js";
|
|
15
16
|
import { SearchTerm, matchedSearchField, matchesSearch, searchTerms, termMatches } from "./search-match.js";
|
|
16
17
|
import { defaultRecentLimit, navRecentErrors, statusTones } from "./nav-recent.js";
|
|
@@ -44,4 +45,4 @@ import { builtInFieldTypes } from "./built-in-field-types.js";
|
|
|
44
45
|
import { CallCandidate, CallClientMessage, CallDescription, CallGuestLink, CallGuestRefusal, CallGuestState, CallLeftReason, CallLobbyGuest, CallMode, CallRemoteTrack, CallResume, CallRosterMember, CallServerMessage, CallTrackRequest, CallTrackSource, CallVideoLayer } from "./calls/call-protocol.js";
|
|
45
46
|
import { guestCallsPath } from "./calls/call-guests.js";
|
|
46
47
|
import { CallRing, callsChannelEvent, declineWord, ringNotice, ringsPath } from "./calls/call-rings.js";
|
|
47
|
-
export { type AddressCheck, type Availability, type CallCandidate, type CallClientMessage, type CallDescription, type CallGuestLink, type CallGuestRefusal, type CallGuestState, type CallLeftReason, type CallLobbyGuest, type CallMode, type CallRemoteTrack, type CallResume, type CallRing, type CallRosterMember, type CallServerMessage, type CallTrackRequest, type CallTrackSource, type CallVideoLayer, type FormulaNode, type Locale, type MobileReleaseAnswer, type PersonStatus, type PluginHost, type PluginRequirement, type PropShapes, type RefShape, type ReleaseBinding, type SearchTerm, type StatusInput, actionConditionError, actionInputErrors, addressErrors, addressPlaceholders, apiOriginMeta, appHrefError, applyAssistantEvent, authBasePath, availabilities, boardErrors, bottomBarFor, builtInFieldTypes, callsChannelEvent, capacitorOrigin, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, confirmationMinutes, datesErrors, declineWord, decodeKey, defaultRecentLimit, deviceIdParam, devicesPath, displayFields, emailCodeMinutes, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, firstPartyCodeKey, guestCallsPath, heldStatus, historyIdParam, historyIdPattern, historyPath, hrefField, hrefPlaceholders, humanize, inRange, isFieldRef, isGroupChart, isLocale, labelFieldOf, layoutItems, leavesApp, linkActionError, listColumnNames, locales, markFieldRefs, matchedSearchField, matchesSearch, maxStatusText, mobileReleaseBasePath, mobileReleaseParams, mobileReleasePath, mobileReleaseQuery, mobileReleasesPath, navRecentErrors, parseCapability, parseFormula, parseSize, parseTable, pickLocale, pluginProblem, promptError, promptFields, pruneByShape, pushRecord, readEventStream, recordTitle, recordTitleField, redactSecrets, releaseManifestFile, releaseStatementContext, releaseStatementFile, renderPrompt, ringNotice, ringsPath, searchTerms, serviceWorkerFile, shapes, shownInputs, statusPath, statusTextProblem, statusTones, tableDisplay, termMatches, unmarkFieldRefs, updateSetErrors, updateValues, viewOfList, webhookResources, workflowResources };
|
|
48
|
+
export { type AddressCheck, type Availability, type CallCandidate, type CallClientMessage, type CallDescription, type CallGuestLink, type CallGuestRefusal, type CallGuestState, type CallLeftReason, type CallLobbyGuest, type CallMode, type CallRemoteTrack, type CallResume, type CallRing, type CallRosterMember, type CallServerMessage, type CallTrackRequest, type CallTrackSource, type CallVideoLayer, type FormulaNode, type Locale, type MobileReleaseAnswer, type PersonStatus, type PluginHost, type PluginRequirement, type PropShapes, type RefShape, type ReleaseBinding, type SearchTerm, type StatusInput, type StepInput, type StepInputKind, type WorkflowStepType, actionConditionError, actionInputErrors, addressErrors, addressPlaceholders, apiOriginMeta, appHrefError, applyAssistantEvent, authBasePath, availabilities, boardErrors, bottomBarFor, builtInFieldTypes, callsChannelEvent, capacitorOrigin, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, confirmationMinutes, datesErrors, declineWord, decodeKey, defaultRecentLimit, deviceIdParam, devicesPath, displayFields, emailCodeMinutes, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, firstPartyCodeKey, guestCallsPath, heldStatus, historyIdParam, historyIdPattern, historyPath, hrefField, hrefPlaceholders, humanize, inRange, isFieldRef, isGroupChart, isLocale, labelFieldOf, layoutItems, leavesApp, linkActionError, listColumnNames, locales, markFieldRefs, matchedSearchField, matchesSearch, maxStatusText, mobileReleaseBasePath, mobileReleaseParams, mobileReleasePath, mobileReleaseQuery, mobileReleasesPath, navRecentErrors, parseCapability, parseFormula, parseSize, parseTable, pickLocale, pluginProblem, promptError, promptFields, pruneByShape, pushRecord, readEventStream, recordTitle, recordTitleField, redactSecrets, releaseManifestFile, releaseStatementContext, releaseStatementFile, renderPrompt, requiredStepInputs, ringNotice, ringsPath, searchTerms, serviceWorkerFile, shapes, shownInputs, statusPath, statusTextProblem, statusTones, tableDisplay, termMatches, unmarkFieldRefs, updateSetErrors, updateValues, viewOfList, webhookResources, workflowResources, workflowStepTypes };
|
package/dist/internal.js
CHANGED
|
@@ -19,6 +19,7 @@ import { bottomBarFor } from "./bottom-bar.js";
|
|
|
19
19
|
import { decodeKey, encodeKey } from "./keys.js";
|
|
20
20
|
import { webhookResources } from "./webhooks/webhook-resources.js";
|
|
21
21
|
import { workflowResources } from "./workflows/workflow-resources.js";
|
|
22
|
+
import { requiredStepInputs, workflowStepTypes } from "./workflows/step-types.js";
|
|
22
23
|
import { pruneByShape, shapes } from "./ref-shape.js";
|
|
23
24
|
import { inRange, pluginProblem } from "./plugin-version.js";
|
|
24
25
|
import { redactSecrets } from "./redact-secrets.js";
|
|
@@ -43,4 +44,4 @@ import { listColumnNames } from "./list-columns.js";
|
|
|
43
44
|
import { builtInFieldTypes } from "./built-in-field-types.js";
|
|
44
45
|
import { guestCallsPath } from "./calls/call-guests.js";
|
|
45
46
|
import { callsChannelEvent, declineWord, ringNotice, ringsPath } from "./calls/call-rings.js";
|
|
46
|
-
export { actionConditionError, actionInputErrors, addressErrors, addressPlaceholders, apiOriginMeta, appHrefError, applyAssistantEvent, authBasePath, availabilities, boardErrors, bottomBarFor, builtInFieldTypes, callsChannelEvent, capacitorOrigin, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, confirmationMinutes, datesErrors, declineWord, decodeKey, defaultRecentLimit, deviceIdParam, devicesPath, displayFields, emailCodeMinutes, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, firstPartyCodeKey, guestCallsPath, heldStatus, historyIdParam, historyIdPattern, historyPath, hrefField, hrefPlaceholders, humanize, inRange, isFieldRef, isGroupChart, isLocale, labelFieldOf, layoutItems, leavesApp, linkActionError, listColumnNames, locales, markFieldRefs, matchedSearchField, matchesSearch, maxStatusText, mobileReleaseBasePath, mobileReleaseParams, mobileReleasePath, mobileReleaseQuery, mobileReleasesPath, navRecentErrors, parseCapability, parseFormula, parseSize, parseTable, pickLocale, pluginProblem, promptError, promptFields, pruneByShape, pushRecord, readEventStream, recordTitle, recordTitleField, redactSecrets, releaseManifestFile, releaseStatementContext, releaseStatementFile, renderPrompt, ringNotice, ringsPath, searchTerms, serviceWorkerFile, shapes, shownInputs, statusPath, statusTextProblem, statusTones, tableDisplay, termMatches, unmarkFieldRefs, updateSetErrors, updateValues, viewOfList, webhookResources, workflowResources };
|
|
47
|
+
export { actionConditionError, actionInputErrors, addressErrors, addressPlaceholders, apiOriginMeta, appHrefError, applyAssistantEvent, authBasePath, availabilities, boardErrors, bottomBarFor, builtInFieldTypes, callsChannelEvent, capacitorOrigin, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, confirmationMinutes, datesErrors, declineWord, decodeKey, defaultRecentLimit, deviceIdParam, devicesPath, displayFields, emailCodeMinutes, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, firstPartyCodeKey, guestCallsPath, heldStatus, historyIdParam, historyIdPattern, historyPath, hrefField, hrefPlaceholders, humanize, inRange, isFieldRef, isGroupChart, isLocale, labelFieldOf, layoutItems, leavesApp, linkActionError, listColumnNames, locales, markFieldRefs, matchedSearchField, matchesSearch, maxStatusText, mobileReleaseBasePath, mobileReleaseParams, mobileReleasePath, mobileReleaseQuery, mobileReleasesPath, navRecentErrors, parseCapability, parseFormula, parseSize, parseTable, pickLocale, pluginProblem, promptError, promptFields, pruneByShape, pushRecord, readEventStream, recordTitle, recordTitleField, redactSecrets, releaseManifestFile, releaseStatementContext, releaseStatementFile, renderPrompt, requiredStepInputs, ringNotice, ringsPath, searchTerms, serviceWorkerFile, shapes, shownInputs, statusPath, statusTextProblem, statusTones, tableDisplay, termMatches, unmarkFieldRefs, updateSetErrors, updateValues, viewOfList, webhookResources, workflowResources, workflowStepTypes };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/workflows/step-types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* How a step type's argument is written: `text`, one line, which may be an expression; `choice`, one of `options`;
|
|
4
|
+
* `json`, any JSON value or an expression, such as an object of field values.
|
|
5
|
+
*/
|
|
6
|
+
export type StepInputKind = 'text' | 'choice' | 'json';
|
|
7
|
+
/** An argument of a step type: its name in `Arguments`, how it is written, and whether a save needs it. */
|
|
8
|
+
export type StepInput = {
|
|
9
|
+
name: string;
|
|
10
|
+
kind: StepInputKind;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
options?: readonly string[];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The step types a workflow's Task names as its `Resource`, each with its arguments: the server runs them, a save
|
|
16
|
+
* refuses a Task without a required one, and the editor draws a form of them.
|
|
17
|
+
*/
|
|
18
|
+
export declare const workflowStepTypes: {
|
|
19
|
+
readonly 'app:http': readonly [StepInput, StepInput, StepInput, StepInput, StepInput, StepInput];
|
|
20
|
+
readonly 'app:records.create': readonly [StepInput, StepInput];
|
|
21
|
+
readonly 'app:records.update': readonly [StepInput, StepInput, StepInput];
|
|
22
|
+
readonly 'app:records.get': readonly [StepInput, StepInput];
|
|
23
|
+
readonly 'app:records.list': readonly [StepInput, StepInput, StepInput, StepInput];
|
|
24
|
+
readonly 'app:mail.send': readonly [StepInput, StepInput, StepInput, StepInput, StepInput];
|
|
25
|
+
readonly 'app:piece': readonly [StepInput, StepInput, StepInput, StepInput];
|
|
26
|
+
};
|
|
27
|
+
export type WorkflowStepType = keyof typeof workflowStepTypes;
|
|
28
|
+
/** The names of the arguments each step type needs, as the definition check takes them. */
|
|
29
|
+
export declare const requiredStepInputs: Record<WorkflowStepType, string[]>;
|
|
30
|
+
//#endregion
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//#region src/workflows/step-types.ts
|
|
2
|
+
const text = (name, required = false) => ({
|
|
3
|
+
name,
|
|
4
|
+
kind: "text",
|
|
5
|
+
...required && { required }
|
|
6
|
+
});
|
|
7
|
+
const json = (name, required = false) => ({
|
|
8
|
+
name,
|
|
9
|
+
kind: "json",
|
|
10
|
+
...required && { required }
|
|
11
|
+
});
|
|
12
|
+
const choice = (name, options) => ({
|
|
13
|
+
name,
|
|
14
|
+
kind: "choice",
|
|
15
|
+
options
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* The step types a workflow's Task names as its `Resource`, each with its arguments: the server runs them, a save
|
|
19
|
+
* refuses a Task without a required one, and the editor draws a form of them.
|
|
20
|
+
*/
|
|
21
|
+
const workflowStepTypes = {
|
|
22
|
+
"app:http": [
|
|
23
|
+
text("url", true),
|
|
24
|
+
choice("method", [
|
|
25
|
+
"GET",
|
|
26
|
+
"POST",
|
|
27
|
+
"PUT",
|
|
28
|
+
"PATCH",
|
|
29
|
+
"DELETE"
|
|
30
|
+
]),
|
|
31
|
+
json("headers"),
|
|
32
|
+
json("query"),
|
|
33
|
+
json("body"),
|
|
34
|
+
choice("response", [
|
|
35
|
+
"json",
|
|
36
|
+
"text",
|
|
37
|
+
"file"
|
|
38
|
+
])
|
|
39
|
+
],
|
|
40
|
+
"app:records.create": [text("resource", true), json("data", true)],
|
|
41
|
+
"app:records.update": [
|
|
42
|
+
text("resource", true),
|
|
43
|
+
json("key", true),
|
|
44
|
+
json("data", true)
|
|
45
|
+
],
|
|
46
|
+
"app:records.get": [text("resource", true), json("key", true)],
|
|
47
|
+
"app:records.list": [
|
|
48
|
+
text("resource", true),
|
|
49
|
+
text("filter"),
|
|
50
|
+
text("order_by"),
|
|
51
|
+
json("limit")
|
|
52
|
+
],
|
|
53
|
+
"app:mail.send": [
|
|
54
|
+
json("to", true),
|
|
55
|
+
text("subject", true),
|
|
56
|
+
text("text", true),
|
|
57
|
+
text("html"),
|
|
58
|
+
json("attachments")
|
|
59
|
+
],
|
|
60
|
+
"app:piece": [
|
|
61
|
+
text("piece", true),
|
|
62
|
+
text("action", true),
|
|
63
|
+
text("connection"),
|
|
64
|
+
json("props")
|
|
65
|
+
]
|
|
66
|
+
};
|
|
67
|
+
/** The names of the arguments each step type needs, as the definition check takes them. */
|
|
68
|
+
const requiredStepInputs = Object.fromEntries(Object.entries(workflowStepTypes).map(([type, inputs]) => [type, inputs.filter((input) => input.required).map((input) => input.name)]));
|
|
69
|
+
//#endregion
|
|
70
|
+
export { requiredStepInputs, workflowStepTypes };
|
|
@@ -57,6 +57,7 @@ export declare const workflowResources: (schema: string) => {
|
|
|
57
57
|
readonly cause: Field<string | null>;
|
|
58
58
|
readonly resume_at: Field<string | null>;
|
|
59
59
|
readonly started_by: Field<string | null>;
|
|
60
|
+
readonly rerun_of: Field<string | number | null>;
|
|
60
61
|
readonly tenant_id: Field<string | null>;
|
|
61
62
|
readonly created_at: Field<string>;
|
|
62
63
|
readonly finished_at: Field<string | null>;
|
|
@@ -74,6 +75,7 @@ export declare const workflowResources: (schema: string) => {
|
|
|
74
75
|
readonly cause: Field<string | null>;
|
|
75
76
|
readonly resume_at: Field<string | null>;
|
|
76
77
|
readonly started_by: Field<string | null>;
|
|
78
|
+
readonly rerun_of: Field<string | number | null>;
|
|
77
79
|
readonly tenant_id: Field<string | null>;
|
|
78
80
|
readonly created_at: Field<string>;
|
|
79
81
|
readonly finished_at: Field<string | null>;
|
|
@@ -35,7 +35,7 @@ const workflowsView = view("workflows").names({
|
|
|
35
35
|
singular: "Workflow",
|
|
36
36
|
plural: "Workflows"
|
|
37
37
|
}).icon("workflow").title((r) => r.name).help("Steps that run one after another along their edges, written in the States Language with JSONata expressions. Each save that changes its definition is a new version; a run keeps the version it started on.").fields((r) => ({
|
|
38
|
-
definition: r.definition.help("Its trigger and its
|
|
38
|
+
definition: r.definition.help("Its trigger and its steps, drawn as a graph that lays itself out. Every value is read by name: the run's input as $states.context.Execution.Input, an earlier result by the variable a state assigned").widget("workflow"),
|
|
39
39
|
updated_at: r.updated_at.label("Updated")
|
|
40
40
|
})).list((r) => ({
|
|
41
41
|
columns: [
|
|
@@ -44,7 +44,15 @@ const workflowsView = view("workflows").names({
|
|
|
44
44
|
r.updated_at
|
|
45
45
|
],
|
|
46
46
|
sort: [[r.updated_at, "desc"]]
|
|
47
|
-
})).
|
|
47
|
+
})).actions((a) => [a.link("test_run", {
|
|
48
|
+
label: "Test run",
|
|
49
|
+
icon: "play",
|
|
50
|
+
to: {
|
|
51
|
+
kind: "create",
|
|
52
|
+
resource: "workflow_runs",
|
|
53
|
+
values: { workflow_id: "{id}" }
|
|
54
|
+
}
|
|
55
|
+
})]).layout((r) => [
|
|
48
56
|
layout.section("Workflow", [
|
|
49
57
|
r.name,
|
|
50
58
|
r.description,
|
|
@@ -60,9 +68,10 @@ const workflowsView = view("workflows").names({
|
|
|
60
68
|
field: "workflow_id",
|
|
61
69
|
columns: [
|
|
62
70
|
"status",
|
|
63
|
-
"
|
|
71
|
+
"started_by",
|
|
64
72
|
"created_at",
|
|
65
73
|
"duration_ms",
|
|
74
|
+
"version",
|
|
66
75
|
"error"
|
|
67
76
|
]
|
|
68
77
|
}),
|
|
@@ -117,6 +126,7 @@ const runsResource = (schema) => resource("workflow_runs").table(`${schema}.runs
|
|
|
117
126
|
cause: f.text().optional().readOnly(),
|
|
118
127
|
resume_at: f.timestamp().optional().readOnly(),
|
|
119
128
|
started_by: f.text().optional().readOnly(),
|
|
129
|
+
rerun_of: f.relation("workflow_runs").optional().filterable(),
|
|
120
130
|
tenant_id: f.text().optional().readOnly(),
|
|
121
131
|
created_at: f.timestamp().readOnly().dbDefault().sortable(),
|
|
122
132
|
finished_at: f.timestamp().optional().readOnly(),
|
|
@@ -129,8 +139,10 @@ const runsView = view("workflow_runs").names({
|
|
|
129
139
|
singular: "Workflow run",
|
|
130
140
|
plural: "Workflow runs"
|
|
131
141
|
}).icon("play").title((r) => r.created_at).help("A run of a workflow with its input. It takes up where it stands after a restart; each of its steps is listed with what it read, gave and logged.").fields((r) => ({
|
|
142
|
+
id: r.id.label("Steps").widget("workflow_run"),
|
|
132
143
|
workflow_id: r.workflow_id.label("Workflow"),
|
|
133
|
-
input: r.input.help("Read by every state as $states.context.Execution.Input"),
|
|
144
|
+
input: r.input.widget("json").help("Read by every state as $states.context.Execution.Input; a re-run takes the input of the run it re-runs"),
|
|
145
|
+
rerun_of: r.rerun_of.label("Re-run of").help("A failed run of the workflow: the re-run keeps its steps before the one that failed, and goes on from there on the workflow as it is now"),
|
|
134
146
|
key: r.key.help("A workflow runs once per key, such as the record a trigger found ready"),
|
|
135
147
|
status: r.status.valueLabels({
|
|
136
148
|
queued: "Queued",
|
|
@@ -142,6 +154,7 @@ const runsView = view("workflow_runs").names({
|
|
|
142
154
|
succeeded: "green",
|
|
143
155
|
failed: "red"
|
|
144
156
|
}),
|
|
157
|
+
output: r.output.widget("json"),
|
|
145
158
|
resume_at: r.resume_at.label("Goes on at"),
|
|
146
159
|
started_by: r.started_by.label("Started by"),
|
|
147
160
|
created_at: r.created_at.label("Started"),
|
|
@@ -152,11 +165,25 @@ const runsView = view("workflow_runs").names({
|
|
|
152
165
|
r.created_at,
|
|
153
166
|
r.workflow_id,
|
|
154
167
|
r.status,
|
|
168
|
+
r.started_by,
|
|
155
169
|
r.duration_ms,
|
|
156
170
|
r.error
|
|
157
171
|
],
|
|
158
172
|
sort: [[r.created_at, "desc"]]
|
|
159
|
-
})).
|
|
173
|
+
})).actions((a) => [a.link("rerun", {
|
|
174
|
+
label: "Re-run from the failed step",
|
|
175
|
+
icon: "restart",
|
|
176
|
+
to: {
|
|
177
|
+
kind: "create",
|
|
178
|
+
resource: "workflow_runs",
|
|
179
|
+
values: {
|
|
180
|
+
workflow_id: "{workflow_id}",
|
|
181
|
+
rerun_of: "{id}"
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
when: "status = \"failed\""
|
|
185
|
+
})]).layout((r) => [
|
|
186
|
+
layout.section("Trace", [r.id]),
|
|
160
187
|
layout.section("Run", [
|
|
161
188
|
r.workflow_id,
|
|
162
189
|
r.input,
|
|
@@ -168,6 +195,7 @@ const runsView = view("workflow_runs").names({
|
|
|
168
195
|
r.status,
|
|
169
196
|
r.version,
|
|
170
197
|
r.started_by,
|
|
198
|
+
r.rerun_of,
|
|
171
199
|
r.created_at,
|
|
172
200
|
r.resume_at,
|
|
173
201
|
r.finished_at,
|
|
@@ -185,6 +213,17 @@ const runsView = view("workflow_runs").names({
|
|
|
185
213
|
"duration_ms",
|
|
186
214
|
"error"
|
|
187
215
|
]
|
|
216
|
+
}),
|
|
217
|
+
layout.related("Re-runs", {
|
|
218
|
+
resource: "workflow_runs",
|
|
219
|
+
field: "rerun_of",
|
|
220
|
+
columns: [
|
|
221
|
+
"status",
|
|
222
|
+
"started_by",
|
|
223
|
+
"created_at",
|
|
224
|
+
"duration_ms",
|
|
225
|
+
"error"
|
|
226
|
+
]
|
|
188
227
|
})
|
|
189
228
|
]);
|
|
190
229
|
/** Every step of every run: its input with secrets redacted, output, variables, logs, timing, try and error. */
|