@protobase/schema 0.19.14 → 0.19.15
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/action-inputs.d.ts +59 -0
- package/dist/action-inputs.js +105 -0
- package/dist/index.d.ts +2 -2
- package/dist/internal.d.ts +2 -1
- package/dist/internal.js +2 -1
- package/dist/model.d.ts +42 -0
- package/dist/view-actions.d.ts +8 -2
- package/dist/view-actions.js +16 -2
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ActionInputModel, JsonValue } from "./model.js";
|
|
2
|
+
//#region src/action-inputs.d.ts
|
|
3
|
+
/** @inline */
|
|
4
|
+
type InputOptions<D> = {
|
|
5
|
+
label: string;
|
|
6
|
+
help?: string;
|
|
7
|
+
/** It may be left empty. */
|
|
8
|
+
optional?: boolean;
|
|
9
|
+
/** An AIP-160 condition over the inputs before it, such as `plan = 'pro'`; it shows only while it holds. */
|
|
10
|
+
when?: string;
|
|
11
|
+
/** What it holds when the dialog opens. */
|
|
12
|
+
default?: D;
|
|
13
|
+
};
|
|
14
|
+
/** The builders `inputs: (i) => [...]` gets, one per kind of answer. */
|
|
15
|
+
export declare const inputs: {
|
|
16
|
+
/** A line of text, or several with `multiline`; `max` is the most characters it may have. */
|
|
17
|
+
text: (name: string, o: InputOptions<string> & {
|
|
18
|
+
multiline?: boolean;
|
|
19
|
+
max?: number;
|
|
20
|
+
}) => ActionInputModel;
|
|
21
|
+
/** A whole number; the handler gets a number. */
|
|
22
|
+
integer: (name: string, o: InputOptions<number>) => ActionInputModel;
|
|
23
|
+
/** A number with decimals; the handler gets its text, as the API gives decimals, so no digit is lost. */
|
|
24
|
+
decimal: (name: string, o: InputOptions<string>) => ActionInputModel;
|
|
25
|
+
/** A switch; the handler gets `true` or `false`, so it is never required. */
|
|
26
|
+
boolean: (name: string, o: {
|
|
27
|
+
label: string;
|
|
28
|
+
help?: string;
|
|
29
|
+
when?: string;
|
|
30
|
+
default?: boolean;
|
|
31
|
+
}) => ActionInputModel;
|
|
32
|
+
/** A date as `YYYY-MM-DD`. */
|
|
33
|
+
date: (name: string, o: InputOptions<string>) => ActionInputModel;
|
|
34
|
+
/** One of `options`, each a value with its label, or a record of `resource`, whose key the handler gets. */
|
|
35
|
+
choice: (name: string, o: InputOptions<string> & ({
|
|
36
|
+
options: Array<{
|
|
37
|
+
value: string;
|
|
38
|
+
label: string;
|
|
39
|
+
}>;
|
|
40
|
+
} | {
|
|
41
|
+
resource: string;
|
|
42
|
+
})) => ActionInputModel;
|
|
43
|
+
/**
|
|
44
|
+
* What a project component edits, registered in `defineUi({ components })` under `component`: it gets the answer as
|
|
45
|
+
* `value`, `onChange`, whether the answer is refused (`invalid`) and `props`.
|
|
46
|
+
*/
|
|
47
|
+
custom: (name: string, o: InputOptions<JsonValue> & {
|
|
48
|
+
component: string;
|
|
49
|
+
props?: Record<string, JsonValue>;
|
|
50
|
+
}) => ActionInputModel;
|
|
51
|
+
};
|
|
52
|
+
/** What is wrong with an action's inputs: a name given twice, a default that is no option, a `when` over no input before it. */
|
|
53
|
+
export declare const actionInputErrors: (entries: ActionInputModel[]) => string[];
|
|
54
|
+
/**
|
|
55
|
+
* The names of the inputs that show for these answers, keyed by input name (null when empty): each input whose `when`
|
|
56
|
+
* holds, reading the answer of an input that does not show as null.
|
|
57
|
+
*/
|
|
58
|
+
export declare const shownInputs: (entries: ActionInputModel[], answers: Record<string, unknown>) => Set<string>;
|
|
59
|
+
//#endregion
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { parseFilter } from "./filter/parse.js";
|
|
2
|
+
import { checkFilter } from "./filter/check.js";
|
|
3
|
+
import { evaluateFilter } from "./filter/evaluate.js";
|
|
4
|
+
//#region src/action-inputs.ts
|
|
5
|
+
const input = (name, kind, o, extra = {}) => ({
|
|
6
|
+
name,
|
|
7
|
+
kind,
|
|
8
|
+
label: o.label,
|
|
9
|
+
required: kind !== "boolean" && !o.optional,
|
|
10
|
+
...o.help !== void 0 && { help: o.help },
|
|
11
|
+
...o.when !== void 0 && { when: o.when },
|
|
12
|
+
...o.default !== void 0 && { default: o.default },
|
|
13
|
+
...extra
|
|
14
|
+
});
|
|
15
|
+
/** The builders `inputs: (i) => [...]` gets, one per kind of answer. */
|
|
16
|
+
const inputs = {
|
|
17
|
+
/** A line of text, or several with `multiline`; `max` is the most characters it may have. */
|
|
18
|
+
text: (name, o) => input(name, "text", o, {
|
|
19
|
+
...o.multiline && { multiline: true },
|
|
20
|
+
...o.max !== void 0 && { max: o.max }
|
|
21
|
+
}),
|
|
22
|
+
/** A whole number; the handler gets a number. */
|
|
23
|
+
integer: (name, o) => input(name, "integer", o),
|
|
24
|
+
/** A number with decimals; the handler gets its text, as the API gives decimals, so no digit is lost. */
|
|
25
|
+
decimal: (name, o) => input(name, "decimal", o),
|
|
26
|
+
/** A switch; the handler gets `true` or `false`, so it is never required. */
|
|
27
|
+
boolean: (name, o) => input(name, "boolean", o),
|
|
28
|
+
/** A date as `YYYY-MM-DD`. */
|
|
29
|
+
date: (name, o) => input(name, "date", o),
|
|
30
|
+
/** One of `options`, each a value with its label, or a record of `resource`, whose key the handler gets. */
|
|
31
|
+
choice: (name, o) => input(name, "choice", o, "options" in o ? { options: o.options.map(({ value, label }) => ({
|
|
32
|
+
value,
|
|
33
|
+
label
|
|
34
|
+
})) } : { resource: o.resource }),
|
|
35
|
+
/**
|
|
36
|
+
* What a project component edits, registered in `defineUi({ components })` under `component`: it gets the answer as
|
|
37
|
+
* `value`, `onChange`, whether the answer is refused (`invalid`) and `props`.
|
|
38
|
+
*/
|
|
39
|
+
custom: (name, o) => input(name, "custom", o, {
|
|
40
|
+
component: o.component,
|
|
41
|
+
...o.props !== void 0 && { props: o.props }
|
|
42
|
+
})
|
|
43
|
+
};
|
|
44
|
+
const filterTypes = {
|
|
45
|
+
text: "text",
|
|
46
|
+
integer: "integer",
|
|
47
|
+
decimal: "decimal",
|
|
48
|
+
boolean: "boolean",
|
|
49
|
+
date: "date",
|
|
50
|
+
choice: "text",
|
|
51
|
+
custom: "json"
|
|
52
|
+
};
|
|
53
|
+
const inputField = (entry) => ({
|
|
54
|
+
name: entry.name,
|
|
55
|
+
column: entry.name,
|
|
56
|
+
type: entry.options ? "enum" : filterTypes[entry.kind],
|
|
57
|
+
nullable: true,
|
|
58
|
+
readOnly: false,
|
|
59
|
+
filterable: entry.kind !== "custom",
|
|
60
|
+
sortable: false,
|
|
61
|
+
aliases: [],
|
|
62
|
+
...entry.options && { enumValues: entry.options.map((option) => option.value) }
|
|
63
|
+
});
|
|
64
|
+
const answersModel = (entries) => ({
|
|
65
|
+
name: "inputs",
|
|
66
|
+
table: { name: "inputs" },
|
|
67
|
+
fields: Object.fromEntries(entries.map((entry) => [entry.name, inputField(entry)])),
|
|
68
|
+
primaryKey: []
|
|
69
|
+
});
|
|
70
|
+
const checkedWhen = (entries, index) => {
|
|
71
|
+
const source = entries[index].when;
|
|
72
|
+
if (source === void 0) return void 0;
|
|
73
|
+
const parsed = parseFilter(source);
|
|
74
|
+
if (!parsed.ok) return parsed.errors.map((error) => error.message).join("; ");
|
|
75
|
+
if (!parsed.ast) return "it is empty";
|
|
76
|
+
const checked = checkFilter(answersModel(entries.slice(0, index)), parsed.ast);
|
|
77
|
+
return checked.ok ? checked.filter : checked.errors.map((error) => error.message).join("; ");
|
|
78
|
+
};
|
|
79
|
+
/** What is wrong with an action's inputs: a name given twice, a default that is no option, a `when` over no input before it. */
|
|
80
|
+
const actionInputErrors = (entries) => entries.flatMap((entry, index) => {
|
|
81
|
+
const errors = [];
|
|
82
|
+
if (entries.findIndex((other) => other.name === entry.name) !== index) errors.push(`input "${entry.name}" is declared twice`);
|
|
83
|
+
if (entry.options && entry.default !== void 0 && !entry.options.some((option) => option.value === entry.default)) errors.push(`input "${entry.name}": default "${String(entry.default)}" is not one of its options`);
|
|
84
|
+
const when = checkedWhen(entries, index);
|
|
85
|
+
if (typeof when === "string") errors.push(`input "${entry.name}": "when" is not a valid condition over the inputs before it: ${when}`);
|
|
86
|
+
return errors;
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* The names of the inputs that show for these answers, keyed by input name (null when empty): each input whose `when`
|
|
90
|
+
* holds, reading the answer of an input that does not show as null.
|
|
91
|
+
*/
|
|
92
|
+
const shownInputs = (entries, answers) => {
|
|
93
|
+
const shown = /* @__PURE__ */ new Set();
|
|
94
|
+
const seen = {};
|
|
95
|
+
entries.forEach((entry, index) => {
|
|
96
|
+
const when = checkedWhen(entries, index);
|
|
97
|
+
if (typeof when === "string") throw new Error(`Input "${entry.name}": ${when}`);
|
|
98
|
+
const visible = when === void 0 || evaluateFilter(when, seen) === true;
|
|
99
|
+
if (visible) shown.add(entry.name);
|
|
100
|
+
seen[entry.name] = visible ? answers[entry.name] ?? null : null;
|
|
101
|
+
});
|
|
102
|
+
return shown;
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
export { actionInputErrors, inputs, shownInputs };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FileOptions, FileProcessor, FileProcessorInput, ImageFormat, ImageVariant, ImageVariantOptions, imageFormats } from "./files/file-options.js";
|
|
2
|
-
import { ActionModel, ActionRun, AppAddress, BadgeShape, BottomBarItemModel, BottomBarModel, CardFavoriteModel, CardPhotosModel, ChartGranularity, ChartModel, ChartRange, CheckedFilter, CompareOp, CreateModel, CustomSectionModel, DatePreset, DurationLiteral, DurationUnit, EventModel, EventOperation, ExportModel, FieldFormat, FieldModel, FieldPath, FieldType, FieldViewModel, FieldWidgetModel, FileFieldModel, FilterError, FilterErrorCode, FilterExpr, FilterLayout, FilterOf, FilterValue, FilterWidgetModel, GalleryModel, HelpWhen, JsonValue, KeyValue, LayoutItemModel, ListDisplayModel, ListModel, ListQuery, Literal, MapSectionModel, MapView, NavModel, NavRecentModel, NowValue, OrderByItem, RecordMode, RelatedColumnModel, RelatedModel, ResourceModel, SaveFeedback, SaveSearchModel, SearchMatch, SearchResultModel, SearchesOfModel, SectionPresentation, ShowWhen, SignInPromptModel, SignInViewModel, SortSpec, Span, StatusTone, UserMenuItemModel, UserMenuModel, ViewModel } from "./model.js";
|
|
2
|
+
import { ActionInputKind, ActionInputModel, ActionModel, ActionRun, AppAddress, BadgeShape, BottomBarItemModel, BottomBarModel, CardFavoriteModel, CardPhotosModel, ChartGranularity, ChartModel, ChartRange, CheckedFilter, CompareOp, CreateModel, CustomSectionModel, DatePreset, DurationLiteral, DurationUnit, EventModel, EventOperation, ExportModel, FieldFormat, FieldModel, FieldPath, FieldType, FieldViewModel, FieldWidgetModel, FileFieldModel, FilterError, FilterErrorCode, FilterExpr, FilterLayout, FilterOf, FilterValue, FilterWidgetModel, GalleryModel, HelpWhen, JsonValue, KeyValue, LayoutItemModel, ListDisplayModel, ListModel, ListQuery, Literal, MapSectionModel, MapView, NavModel, NavRecentModel, NowValue, OrderByItem, RecordMode, RelatedColumnModel, RelatedModel, ResourceModel, SaveFeedback, SaveSearchModel, SearchMatch, SearchResultModel, SearchesOfModel, SectionPresentation, ShowWhen, SignInPromptModel, SignInViewModel, SortSpec, Span, StatusTone, UserMenuItemModel, UserMenuModel, ViewModel } from "./model.js";
|
|
3
3
|
import { AccessAction, AccessContext, AccessFn, AccessResult, AccessUser, FieldAccess, FieldRule } from "./access/types.js";
|
|
4
4
|
import { AnyField, Constraint, Field, FieldMeta, FieldTypeDef } from "./field.js";
|
|
5
5
|
import { RelationField } from "./relation-field.js";
|
|
@@ -38,4 +38,4 @@ import { AccessSource, ResolveOptions, ResolvedAccess, RowFilterOperation, acces
|
|
|
38
38
|
import { restrictModel } from "./access/restrict.js";
|
|
39
39
|
import "./access/index.js";
|
|
40
40
|
import { AssistantAction, AssistantActionRequest, AssistantCardPart, AssistantDiff, AssistantEvent, AssistantMessage, AssistantMessageRequest, AssistantPart, AssistantState, AssistantStep, AssistantStepState, AssistantTablePart, AssistantTextPart, AssistantTone, AssistantWidgetPart } from "./assistant/protocol.js";
|
|
41
|
-
export { type Access, type AccessAction, type AccessContext, type AccessFn, type AccessResult, type AccessSource, type AccessUser, type ActionModel, type ActionRun, type AnyField, type AppAddress, type AssistantAction, type AssistantActionRequest, type AssistantCardPart, type AssistantDiff, type AssistantEvent, type AssistantMessage, type AssistantMessageRequest, type AssistantPart, type AssistantState, type AssistantStep, type AssistantStepState, type AssistantTablePart, type AssistantTextPart, type AssistantTone, type AssistantWidgetPart, type BadgeShape, type BottomBarItemModel, type BottomBarModel, type BottomBarNames, type BottomBarSource, type Capability, type CapabilityAction, type CapabilityLimit, type CapabilityScope, type CardFavoriteModel, type CardPhotosModel, type ChartGranularity, type ChartModel, type ChartRange, type CheckResult, type CheckedFilter, type CompareOp, type ComponentRef, type Constraint, type CreateModel, type CreatedOptions, type CustomSectionModel, type DatePreset, type DeletedOptions, type DurationLiteral, type DurationUnit, type EvaluateOptions, type EventActor, type EventContext, type EventHelpers, type EventMatch, type EventModel, type EventOperation, type EventSpec, type ExportModel, type Field, type FieldAccess, type FieldFormat, type FieldMeta, type FieldModel, type FieldPath, type FieldRefValue, type FieldRefs, type FieldRule, type FieldType, type FieldTypeDef, type FieldView, type FieldViewModel, type FieldViews, type FieldWidgetModel, type FieldsInput, type FileField, type FileFieldModel, type FileOptions, type FileProcessor, type FileProcessorInput, type FilterError, type FilterErrorCode, type FilterExpr, type FilterLayout, type FilterLimits, type FilterOf, type FilterParse, type FilterValue, type FilterWidgetModel, type GalleryModel, type Grant, type HeldCapability, type HelpWhen, type ImageFormat, type ImageVariant, type ImageVariantOptions, type InferRecord, type Issue, type JsonValue, type KeyOf, type KeyRefs, type KeyType, type KeyValue, type LayoutItemModel, type ListColumn, type ListDisplayModel, type ListModel, type ListQuery, type Literal, type MapSectionModel, type MapView, type NavModel, type NavRecentModel, type NowValue, type OrderByCheck, type OrderByItem, type OrderByParse, type RecordKey, type RecordMode, type RecordOf, type Ref, type Refs, type RelatedColumnModel, type RelatedModel, type RelationField, type ResolveOptions, type ResolvedAccess, type ResourceBuilder, type ResourceModel, type RoleEntry, type RoleLimit, type Roles, type RolesOptions, type RowFilterOperation, type Rule, type SaveFeedback, type SaveSearchModel, type SearchMatch, type SearchRef, type SearchRefs, type SearchResultModel, type SearchesOfModel, type SectionPresentation, type ShowWhen, type SignInAddress, type SignInPromptModel, type SignInStep, type SignInViewModel, type SortSpec, type Span, type StatusTone, type UndeletedOptions, type UpdatedOptions, type UserMenuItemModel, type UserMenuModel, type UserMenuSource, type Validator, type ViewBuilder, type ViewModel, type ViewProps, accessWarnings, addressWords, anonymousRole, appPath, bottomBar, bottomBarErrors, checkFilter, checkOrderBy, checkRecord, createWhere, defineRoles, enumLabel, evaluateFilter, f, fieldRef, fieldsUsedBy, imageFormats, keyTypes, layout as l, maxBottomBarItems, parseFilter, parseOrderBy, pickView, printFilter, printOrderBy, readAppPath, readSignInAddress, resolveAccess, resource, restrictModel, rule, signInParams, signInPath, signInRoute, signInSteps, userMenu, view, where };
|
|
41
|
+
export { type Access, type AccessAction, type AccessContext, type AccessFn, type AccessResult, type AccessSource, type AccessUser, type ActionInputKind, type ActionInputModel, type ActionModel, type ActionRun, type AnyField, type AppAddress, type AssistantAction, type AssistantActionRequest, type AssistantCardPart, type AssistantDiff, type AssistantEvent, type AssistantMessage, type AssistantMessageRequest, type AssistantPart, type AssistantState, type AssistantStep, type AssistantStepState, type AssistantTablePart, type AssistantTextPart, type AssistantTone, type AssistantWidgetPart, type BadgeShape, type BottomBarItemModel, type BottomBarModel, type BottomBarNames, type BottomBarSource, type Capability, type CapabilityAction, type CapabilityLimit, type CapabilityScope, type CardFavoriteModel, type CardPhotosModel, type ChartGranularity, type ChartModel, type ChartRange, type CheckResult, type CheckedFilter, type CompareOp, type ComponentRef, type Constraint, type CreateModel, type CreatedOptions, type CustomSectionModel, type DatePreset, type DeletedOptions, type DurationLiteral, type DurationUnit, type EvaluateOptions, type EventActor, type EventContext, type EventHelpers, type EventMatch, type EventModel, type EventOperation, type EventSpec, type ExportModel, type Field, type FieldAccess, type FieldFormat, type FieldMeta, type FieldModel, type FieldPath, type FieldRefValue, type FieldRefs, type FieldRule, type FieldType, type FieldTypeDef, type FieldView, type FieldViewModel, type FieldViews, type FieldWidgetModel, type FieldsInput, type FileField, type FileFieldModel, type FileOptions, type FileProcessor, type FileProcessorInput, type FilterError, type FilterErrorCode, type FilterExpr, type FilterLayout, type FilterLimits, type FilterOf, type FilterParse, type FilterValue, type FilterWidgetModel, type GalleryModel, type Grant, type HeldCapability, type HelpWhen, type ImageFormat, type ImageVariant, type ImageVariantOptions, type InferRecord, type Issue, type JsonValue, type KeyOf, type KeyRefs, type KeyType, type KeyValue, type LayoutItemModel, type ListColumn, type ListDisplayModel, type ListModel, type ListQuery, type Literal, type MapSectionModel, type MapView, type NavModel, type NavRecentModel, type NowValue, type OrderByCheck, type OrderByItem, type OrderByParse, type RecordKey, type RecordMode, type RecordOf, type Ref, type Refs, type RelatedColumnModel, type RelatedModel, type RelationField, type ResolveOptions, type ResolvedAccess, type ResourceBuilder, type ResourceModel, type RoleEntry, type RoleLimit, type Roles, type RolesOptions, type RowFilterOperation, type Rule, type SaveFeedback, type SaveSearchModel, type SearchMatch, type SearchRef, type SearchRefs, type SearchResultModel, type SearchesOfModel, type SectionPresentation, type ShowWhen, type SignInAddress, type SignInPromptModel, type SignInStep, type SignInViewModel, type SortSpec, type Span, type StatusTone, type UndeletedOptions, type UpdatedOptions, type UserMenuItemModel, type UserMenuModel, type UserMenuSource, type Validator, type ViewBuilder, type ViewModel, type ViewProps, accessWarnings, addressWords, anonymousRole, appPath, bottomBar, bottomBarErrors, checkFilter, checkOrderBy, checkRecord, createWhere, defineRoles, enumLabel, evaluateFilter, f, fieldRef, fieldsUsedBy, imageFormats, keyTypes, layout as l, maxBottomBarItems, parseFilter, parseOrderBy, pickView, printFilter, printOrderBy, readAppPath, readSignInAddress, resolveAccess, resource, restrictModel, rule, signInParams, signInPath, signInRoute, signInSteps, userMenu, view, where };
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { checkedAccept, checkedProvider, parseSize } from "./files/file-options.js";
|
|
2
|
+
import { actionInputErrors, shownInputs } from "./action-inputs.js";
|
|
2
3
|
import { cardPhotoLimit, displayFields, tableDisplay } from "./view-displays.js";
|
|
3
4
|
import { fieldRefsIn, isFieldRef, markFieldRefs, unmarkFieldRefs } from "./field-ref.js";
|
|
4
5
|
import { bottomBarFor } from "./bottom-bar.js";
|
|
@@ -14,4 +15,4 @@ import { addressPlaceholders, appHrefError, fillAddress, hrefField, hrefPlacehol
|
|
|
14
15
|
import { AddressCheck, addressErrors } from "./address-errors.js";
|
|
15
16
|
import { applyAssistantEvent, emptyAssistantState } from "./assistant/apply-event.js";
|
|
16
17
|
import { readEventStream } from "./assistant/event-stream.js";
|
|
17
|
-
export { type AddressCheck, type PluginHost, type PluginRequirement, type PropShapes, type RefShape, type SearchTerm, addressErrors, addressPlaceholders, appHrefError, applyAssistantEvent, bottomBarFor, cardPhotoLimit, checkEventFilter, checkedAccept, checkedProvider, decodeKey, defaultRecentLimit, displayFields, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, hrefField, hrefPlaceholders, inRange, isFieldRef, leavesApp, linkActionError, markFieldRefs, matchedSearchField, matchesSearch, navRecentErrors, parseSize, pluginProblem, pruneByShape, readEventStream, redactSecrets, searchTerms, shapes, statusTones, tableDisplay, termMatches, unmarkFieldRefs, webhookResources };
|
|
18
|
+
export { type AddressCheck, type PluginHost, type PluginRequirement, type PropShapes, type RefShape, type SearchTerm, actionInputErrors, addressErrors, addressPlaceholders, appHrefError, applyAssistantEvent, bottomBarFor, cardPhotoLimit, checkEventFilter, checkedAccept, checkedProvider, decodeKey, defaultRecentLimit, displayFields, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, hrefField, hrefPlaceholders, inRange, isFieldRef, leavesApp, linkActionError, markFieldRefs, matchedSearchField, matchesSearch, navRecentErrors, parseSize, pluginProblem, pruneByShape, readEventStream, redactSecrets, searchTerms, shapes, shownInputs, statusTones, tableDisplay, termMatches, unmarkFieldRefs, webhookResources };
|
package/dist/internal.js
CHANGED
|
@@ -2,6 +2,7 @@ import { checkedAccept, checkedProvider, parseSize } from "./files/file-options.
|
|
|
2
2
|
import { matchedSearchField, matchesSearch, searchTerms, termMatches } from "./search-match.js";
|
|
3
3
|
import { checkEventFilter } from "./events/event-models.js";
|
|
4
4
|
import { defaultRecentLimit, navRecentErrors, statusTones } from "./nav-recent.js";
|
|
5
|
+
import { actionInputErrors, shownInputs } from "./action-inputs.js";
|
|
5
6
|
import { addressPlaceholders, appHrefError, fillAddress, hrefField, hrefPlaceholders, leavesApp, linkActionError } from "./address-template.js";
|
|
6
7
|
import { fieldRefsIn, isFieldRef, markFieldRefs, unmarkFieldRefs } from "./field-ref.js";
|
|
7
8
|
import { cardPhotoLimit, displayFields, tableDisplay } from "./view-displays.js";
|
|
@@ -14,4 +15,4 @@ import { redactSecrets } from "./redact-secrets.js";
|
|
|
14
15
|
import { addressErrors } from "./address-errors.js";
|
|
15
16
|
import { applyAssistantEvent, emptyAssistantState } from "./assistant/apply-event.js";
|
|
16
17
|
import { readEventStream } from "./assistant/event-stream.js";
|
|
17
|
-
export { addressErrors, addressPlaceholders, appHrefError, applyAssistantEvent, bottomBarFor, cardPhotoLimit, checkEventFilter, checkedAccept, checkedProvider, decodeKey, defaultRecentLimit, displayFields, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, hrefField, hrefPlaceholders, inRange, isFieldRef, leavesApp, linkActionError, markFieldRefs, matchedSearchField, matchesSearch, navRecentErrors, parseSize, pluginProblem, pruneByShape, readEventStream, redactSecrets, searchTerms, shapes, statusTones, tableDisplay, termMatches, unmarkFieldRefs, webhookResources };
|
|
18
|
+
export { actionInputErrors, addressErrors, addressPlaceholders, appHrefError, applyAssistantEvent, bottomBarFor, cardPhotoLimit, checkEventFilter, checkedAccept, checkedProvider, decodeKey, defaultRecentLimit, displayFields, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, hrefField, hrefPlaceholders, inRange, isFieldRef, leavesApp, linkActionError, markFieldRefs, matchedSearchField, matchesSearch, navRecentErrors, parseSize, pluginProblem, pruneByShape, readEventStream, redactSecrets, searchTerms, shapes, shownInputs, statusTones, tableDisplay, termMatches, unmarkFieldRefs, webhookResources };
|
package/dist/model.d.ts
CHANGED
|
@@ -722,6 +722,48 @@ export type ActionModel = {
|
|
|
722
722
|
bulk: boolean;
|
|
723
723
|
/** What it does; without it the app runs the handler registered under `name`. */
|
|
724
724
|
run?: ActionRun;
|
|
725
|
+
/** What the button asks for in a dialog before the handler runs, which gets the answers as `values` (`a.action`'s `inputs`). */
|
|
726
|
+
inputs?: ActionInputModel[];
|
|
727
|
+
};
|
|
728
|
+
/**
|
|
729
|
+
* What an input of a named action asks for: a line of `text`, a whole number (`integer`), a number with decimals
|
|
730
|
+
* (`decimal`), a yes or no (`boolean`), a `date`, one of `options` or a record of `resource` (`choice`), or what a
|
|
731
|
+
* project component edits (`custom`).
|
|
732
|
+
*/
|
|
733
|
+
export type ActionInputKind = 'text' | 'integer' | 'decimal' | 'boolean' | 'date' | 'choice' | 'custom';
|
|
734
|
+
/** One input of a named action's dialog (`inputs: (i) => [...]`); see [Named actions](website/src/content/docs/reference/ui-config.mdx#actions-that-ask-for-input). */
|
|
735
|
+
export type ActionInputModel = {
|
|
736
|
+
/** The input's name: the key of its answer in the handler's `values`, and how `when` names it. */
|
|
737
|
+
name: string;
|
|
738
|
+
/** What it asks for. */
|
|
739
|
+
kind: ActionInputKind;
|
|
740
|
+
/** Its label. */
|
|
741
|
+
label: string;
|
|
742
|
+
/** A line under it. */
|
|
743
|
+
help?: string;
|
|
744
|
+
/** Whether it must be answered before the action runs; a boolean never must. */
|
|
745
|
+
required: boolean;
|
|
746
|
+
/** An AIP-160 condition over the inputs before it, such as `plan = 'pro'`; it shows, and is answered, only while it holds. */
|
|
747
|
+
when?: string;
|
|
748
|
+
/** What it holds when the dialog opens. */
|
|
749
|
+
default?: JsonValue;
|
|
750
|
+
/** A text that runs over several lines, in a box that grows with it. */
|
|
751
|
+
multiline?: boolean;
|
|
752
|
+
/** The most characters a text may have. */
|
|
753
|
+
max?: number;
|
|
754
|
+
/** A choice's values, each with its label, in order. */
|
|
755
|
+
options?: Array<{
|
|
756
|
+
/** The value the handler gets. */
|
|
757
|
+
value: string;
|
|
758
|
+
/** What it reads as. */
|
|
759
|
+
label: string;
|
|
760
|
+
}>;
|
|
761
|
+
/** The resource a choice picks a record of; the handler gets its key. */
|
|
762
|
+
resource?: string;
|
|
763
|
+
/** The project component (`defineUi({ components })`) a custom input is, which gets `ActionInputProps`. */
|
|
764
|
+
component?: string;
|
|
765
|
+
/** The plain data a custom input's component gets as `props`. */
|
|
766
|
+
props?: Record<string, JsonValue>;
|
|
725
767
|
};
|
|
726
768
|
/** The colour of a status dot in the sidebar. */
|
|
727
769
|
export type StatusTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
|
package/dist/view-actions.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ActionModel, AppAddress } from "./model.js";
|
|
1
|
+
import { ActionInputModel, ActionModel, AppAddress } from "./model.js";
|
|
2
|
+
import { inputs } from "./action-inputs.js";
|
|
2
3
|
//#region src/view-actions.d.ts
|
|
3
4
|
/** @inline */
|
|
4
5
|
type ActionOptions = {
|
|
@@ -7,9 +8,14 @@ type ActionOptions = {
|
|
|
7
8
|
confirm?: string;
|
|
8
9
|
};
|
|
9
10
|
export declare const actions: {
|
|
10
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* An action the app implements: it runs the handler registered under `name`. With `inputs`, such as
|
|
13
|
+
* `(i) => [i.text('reason', { label: 'Reason' })]`, the button first asks for them in a dialog, and the handler gets the
|
|
14
|
+
* answers as `values`.
|
|
15
|
+
*/
|
|
11
16
|
action: (name: string, o: ActionOptions & {
|
|
12
17
|
bulk?: boolean;
|
|
18
|
+
inputs?: (i: typeof inputs) => ActionInputModel[];
|
|
13
19
|
}) => ActionModel;
|
|
14
20
|
/** Sets fields of the record, as one update with its ETag, for example `{ status: 'paid' }`. */
|
|
15
21
|
update: (name: string, o: ActionOptions & {
|
package/dist/view-actions.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { actionInputErrors, inputs } from "./action-inputs.js";
|
|
1
2
|
import { linkActionError } from "./address-template.js";
|
|
2
3
|
//#region src/view-actions.ts
|
|
3
4
|
const named = (name, o) => ({
|
|
@@ -8,8 +9,21 @@ const named = (name, o) => ({
|
|
|
8
9
|
...o.confirm !== void 0 && { confirm: o.confirm }
|
|
9
10
|
});
|
|
10
11
|
const actions = {
|
|
11
|
-
/**
|
|
12
|
-
action:
|
|
12
|
+
/**
|
|
13
|
+
* An action the app implements: it runs the handler registered under `name`. With `inputs`, such as
|
|
14
|
+
* `(i) => [i.text('reason', { label: 'Reason' })]`, the button first asks for them in a dialog, and the handler gets the
|
|
15
|
+
* answers as `values`.
|
|
16
|
+
*/
|
|
17
|
+
action: (name, o) => {
|
|
18
|
+
if (!o.inputs) return named(name, o);
|
|
19
|
+
const built = o.inputs(inputs);
|
|
20
|
+
const errors = actionInputErrors(built);
|
|
21
|
+
if (errors.length > 0) throw new Error(`Action "${name}": ${errors.join("; ")}`);
|
|
22
|
+
return {
|
|
23
|
+
...named(name, o),
|
|
24
|
+
inputs: built
|
|
25
|
+
};
|
|
26
|
+
},
|
|
13
27
|
/** Sets fields of the record, as one update with its ETag, for example `{ status: 'paid' }`. */
|
|
14
28
|
update: (name, o) => ({
|
|
15
29
|
...named(name, o),
|