@protobase/schema 0.22.8 → 0.22.10
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/app-address.d.ts +2 -0
- package/dist/app-address.js +7 -2
- package/dist/index.d.ts +2 -2
- package/dist/internal.js +1 -1
- package/dist/layout-items.d.ts +1 -1
- package/dist/layout-items.js +2 -2
- package/dist/layout.d.ts +7 -0
- package/dist/layout.js +15 -0
- package/dist/model.d.ts +14 -1
- package/dist/view.js +14 -2
- package/package.json +1 -1
package/dist/app-address.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ export declare const addressWords: {
|
|
|
27
27
|
readonly edit: "edit";
|
|
28
28
|
/** A record page's open collapsed group, by title, once per group. */
|
|
29
29
|
readonly open: "open";
|
|
30
|
+
/** A record page's shown tab, by title. */
|
|
31
|
+
readonly tab: "tab";
|
|
30
32
|
};
|
|
31
33
|
/** The path of `address` below `basePath` (such as `/admin`), every name and key encoded the one way the app reads them. */
|
|
32
34
|
export declare const appPath: (address: AppAddress, basePath?: string) => string;
|
package/dist/app-address.js
CHANGED
|
@@ -26,7 +26,9 @@ const addressWords = {
|
|
|
26
26
|
/** A record's form, `edit=true`, on a view whose record page opens as a read view or locked. */
|
|
27
27
|
edit: "edit",
|
|
28
28
|
/** A record page's open collapsed group, by title, once per group. */
|
|
29
|
-
open: "open"
|
|
29
|
+
open: "open",
|
|
30
|
+
/** A record page's shown tab, by title. */
|
|
31
|
+
tab: "tab"
|
|
30
32
|
};
|
|
31
33
|
const listWords = [
|
|
32
34
|
"list",
|
|
@@ -81,6 +83,7 @@ const recordQuery = (address) => {
|
|
|
81
83
|
const query = new URLSearchParams();
|
|
82
84
|
if (address.edit) query.set(addressWords.edit, "true");
|
|
83
85
|
for (const title of address.open ?? []) query.append(addressWords.open, title);
|
|
86
|
+
if (address.tab) query.set(addressWords.tab, address.tab);
|
|
84
87
|
const text = query.toString();
|
|
85
88
|
return text ? `?${text}` : "";
|
|
86
89
|
};
|
|
@@ -130,12 +133,14 @@ const readAppPath = (pathAndQuery, pages) => {
|
|
|
130
133
|
}
|
|
131
134
|
if (second !== void 0) {
|
|
132
135
|
const open = [...new Set(url.searchParams.getAll(addressWords.open).filter((title) => title !== ""))];
|
|
136
|
+
const tab = url.searchParams.get(addressWords.tab) || void 0;
|
|
133
137
|
return {
|
|
134
138
|
kind: "record",
|
|
135
139
|
resource: first,
|
|
136
140
|
key: second,
|
|
137
141
|
...url.searchParams.get(addressWords.edit) === "true" && { edit: true },
|
|
138
|
-
...open.length > 0 && { open }
|
|
142
|
+
...open.length > 0 && { open },
|
|
143
|
+
...tab && { tab }
|
|
139
144
|
};
|
|
140
145
|
}
|
|
141
146
|
const params = url.searchParams;
|
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 { ActionInputKind, ActionInputModel, ActionModel, ActionRun, AppAddress, BadgeShape, BottomBarItemModel, BottomBarModel, CalendarView, CardFavoriteModel, CardPhotosModel, ChartGranularity, ChartModel, ChartRange, CheckedFilter, CommentsSectionModel, CompareOp, CreateModel, CustomSectionModel, DatePreset, DurationLiteral, DurationUnit, EventModel, EventOperation, ExportModel, FieldFormat, FieldModel, FieldPath, FieldType, FieldViewModel, FieldWidgetModel, FileFieldModel, FilterError, FilterErrorCode, FilterExpr, FilterLayout, FilterOf, FilterValue, FilterWidgetModel, FormModel, GalleryModel, GroupChartModel, GroupItemModel, GroupModel, HelpWhen, HistorySectionModel, JsonValue, KeyValue, LayoutItemModel, ListDisplayModel, ListModel, ListQuery, Literal, MapSectionModel, MapView, NamedListModel, NavModel, NavRecentModel, NowValue, OrderByItem, PeriodChartModel, RecordMode, RecordWhen, RelatedColumnModel, RelatedModel, ResourceModel, SaveFeedback, SaveSearchModel, SearchMatch, SearchResultModel, SearchesOfModel, SectionModel, SectionPresentation, ShowWhen, SignInPromptModel, SignInViewModel, SortSpec, Span, StatusTone, UserMenuItemModel, UserMenuModel, ViewModel } from "./model.js";
|
|
2
|
+
import { ActionInputKind, ActionInputModel, ActionModel, ActionRun, AppAddress, BadgeShape, BottomBarItemModel, BottomBarModel, CalendarView, CardFavoriteModel, CardPhotosModel, ChartGranularity, ChartModel, ChartRange, CheckedFilter, CommentsSectionModel, CompareOp, CreateModel, CustomSectionModel, DatePreset, DurationLiteral, DurationUnit, EventModel, EventOperation, ExportModel, FieldFormat, FieldModel, FieldPath, FieldType, FieldViewModel, FieldWidgetModel, FileFieldModel, FilterError, FilterErrorCode, FilterExpr, FilterLayout, FilterOf, FilterValue, FilterWidgetModel, FormModel, GalleryModel, GroupChartModel, GroupItemModel, GroupModel, HelpWhen, HistorySectionModel, JsonValue, KeyValue, LayoutItemModel, ListDisplayModel, ListModel, ListQuery, Literal, MapSectionModel, MapView, NamedListModel, NavModel, NavRecentModel, NowValue, OrderByItem, PeriodChartModel, RecordMode, RecordWhen, RelatedColumnModel, RelatedModel, ResourceModel, SaveFeedback, SaveSearchModel, SearchMatch, SearchResultModel, SearchesOfModel, SectionModel, SectionPresentation, ShowWhen, SignInPromptModel, SignInViewModel, SortSpec, Span, StatusTone, TabItemModel, TabModel, 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";
|
|
@@ -42,4 +42,4 @@ import { AccessSource, ResolveOptions, ResolvedAccess, RowFilterOperation, acces
|
|
|
42
42
|
import { restrictModel } from "./access/restrict.js";
|
|
43
43
|
import "./access/index.js";
|
|
44
44
|
import { AssistantAction, AssistantActionRequest, AssistantCardPart, AssistantDiff, AssistantEvent, AssistantMessage, AssistantMessageRequest, AssistantPart, AssistantState, AssistantStep, AssistantStepState, AssistantTablePart, AssistantTextPart, AssistantTone, AssistantWidgetPart } from "./assistant/protocol.js";
|
|
45
|
-
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 CalendarView, type Capability, type CapabilityAction, type CapabilityLimit, type CapabilityScope, type CardFavoriteModel, type CardPhotosModel, type ChartGranularity, type ChartInput, type ChartModel, type ChartRange, type CheckResult, type CheckedFilter, type CommentsSectionModel, 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 FormAddress, type FormInput, type FormModel, type GalleryModel, type Grant, type GroupChartInput, type GroupChartModel, type GroupItemModel, type GroupModel, type HeldCapability, type HelpWhen, type HistorySectionModel, 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 NamedListModel, type NavModel, type NavRecentModel, type NowValue, type OrderByCheck, type OrderByItem, type OrderByParse, type PeriodChartInput, type PeriodChartModel, type RecordKey, type RecordMode, type RecordOf, type RecordWhen, 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 SectionModel, 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, fitsKeyType, formPath, formRoute, imageFormats, isRecordCondition, keyTypes, layout as l, maxBottomBarItems, parseFilter, parseOrderBy, pickView, printFilter, printOrderBy, readAppPath, readFormAddress, readSignInAddress, resolveAccess, resource, restrictModel, rule, signInParams, signInPath, signInRoute, signInSteps, userMenu, view, where };
|
|
45
|
+
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 CalendarView, type Capability, type CapabilityAction, type CapabilityLimit, type CapabilityScope, type CardFavoriteModel, type CardPhotosModel, type ChartGranularity, type ChartInput, type ChartModel, type ChartRange, type CheckResult, type CheckedFilter, type CommentsSectionModel, 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 FormAddress, type FormInput, type FormModel, type GalleryModel, type Grant, type GroupChartInput, type GroupChartModel, type GroupItemModel, type GroupModel, type HeldCapability, type HelpWhen, type HistorySectionModel, 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 NamedListModel, type NavModel, type NavRecentModel, type NowValue, type OrderByCheck, type OrderByItem, type OrderByParse, type PeriodChartInput, type PeriodChartModel, type RecordKey, type RecordMode, type RecordOf, type RecordWhen, 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 SectionModel, type SectionPresentation, type ShowWhen, type SignInAddress, type SignInPromptModel, type SignInStep, type SignInViewModel, type SortSpec, type Span, type StatusTone, type TabItemModel, type TabModel, 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, fitsKeyType, formPath, formRoute, imageFormats, isRecordCondition, keyTypes, layout as l, maxBottomBarItems, parseFilter, parseOrderBy, pickView, printFilter, printOrderBy, readAppPath, readFormAddress, readSignInAddress, resolveAccess, resource, restrictModel, rule, signInParams, signInPath, signInRoute, signInSteps, userMenu, view, where };
|
package/dist/internal.js
CHANGED
|
@@ -3,6 +3,7 @@ import { promptError, promptFields, renderPrompt } from "./ai-prompt.js";
|
|
|
3
3
|
import { checkedAccept, checkedProvider, parseSize } from "./files/file-options.js";
|
|
4
4
|
import { matchedSearchField, matchesSearch, searchTerms, termMatches } from "./search-match.js";
|
|
5
5
|
import { checkEventFilter } from "./events/event-models.js";
|
|
6
|
+
import { layoutItems } from "./layout-items.js";
|
|
6
7
|
import { viewOfList } from "./named-list.js";
|
|
7
8
|
import { defaultRecentLimit, navRecentErrors, statusTones } from "./nav-recent.js";
|
|
8
9
|
import { actionInputErrors, shownInputs } from "./action-inputs.js";
|
|
@@ -19,5 +20,4 @@ import { redactSecrets } from "./redact-secrets.js";
|
|
|
19
20
|
import { addressErrors } from "./address-errors.js";
|
|
20
21
|
import { applyAssistantEvent, emptyAssistantState } from "./assistant/apply-event.js";
|
|
21
22
|
import { readEventStream } from "./assistant/event-stream.js";
|
|
22
|
-
import { layoutItems } from "./layout-items.js";
|
|
23
23
|
export { actionInputErrors, addressErrors, addressPlaceholders, appHrefError, applyAssistantEvent, boardErrors, bottomBarFor, calendarErrors, cardPhotoLimit, chartFields, checkEventFilter, checkedAccept, checkedProvider, decodeKey, defaultRecentLimit, displayFields, emptyAssistantState, encodeKey, fieldRefsIn, fillAddress, hrefField, hrefPlaceholders, inRange, isFieldRef, isGroupChart, layoutItems, leavesApp, linkActionError, markFieldRefs, matchedSearchField, matchesSearch, navRecentErrors, parseSize, pluginProblem, promptError, promptFields, pruneByShape, readEventStream, redactSecrets, renderPrompt, searchTerms, shapes, shownInputs, statusTones, tableDisplay, termMatches, unmarkFieldRefs, updateSetErrors, updateValues, viewOfList, webhookResources };
|
package/dist/layout-items.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LayoutItemModel } from "./model.js";
|
|
2
2
|
//#region src/layout-items.d.ts
|
|
3
|
-
/** The layout's items with every group's items in its place, for code that looks for
|
|
3
|
+
/** The layout's items with every tab's and group's items in its place, for code that looks for items wherever they sit. */
|
|
4
4
|
export declare const layoutItems: (layout: readonly LayoutItemModel[]) => LayoutItemModel[];
|
|
5
5
|
//#endregion
|
package/dist/layout-items.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/layout-items.ts
|
|
2
|
-
/** The layout's items with every group's items in its place, for code that looks for
|
|
3
|
-
const layoutItems = (layout) => layout.flatMap((item) => item.kind === "group" ? item.items : [item]);
|
|
2
|
+
/** The layout's items with every tab's and group's items in its place, for code that looks for items wherever they sit. */
|
|
3
|
+
const layoutItems = (layout) => layout.flatMap((item) => item.kind === "group" || item.kind === "tab" ? layoutItems(item.items) : [item]);
|
|
4
4
|
//#endregion
|
|
5
5
|
export { layoutItems };
|
package/dist/layout.d.ts
CHANGED
|
@@ -59,6 +59,13 @@ export declare const layout: {
|
|
|
59
59
|
collapsed?: boolean;
|
|
60
60
|
when?: RecordWhen;
|
|
61
61
|
}) => LayoutItemModel;
|
|
62
|
+
/**
|
|
63
|
+
* A tab of the record page holding main-column items: sections, groups, related tables, custom components, maps,
|
|
64
|
+
* galleries, history and comments. A view's tabs stand together and show as one strip, the first tab open unless the
|
|
65
|
+
* address names another; items before and after them show on every tab. Throws on a sidebar item or another tab. See
|
|
66
|
+
* [Tabs](website/src/content/docs/reference/ui-config.mdx#tabs).
|
|
67
|
+
*/
|
|
68
|
+
tab: (title: string, items: LayoutItemModel[]) => LayoutItemModel;
|
|
62
69
|
/** A table of the records of another resource that point at this one, directly or through a join table. */
|
|
63
70
|
related: (title: string, o: Omit<RelatedModel, "kind" | "title">) => LayoutItemModel;
|
|
64
71
|
/**
|
package/dist/layout.js
CHANGED
|
@@ -75,6 +75,21 @@ const layout = {
|
|
|
75
75
|
...o.when !== void 0 && { when: o.when }
|
|
76
76
|
};
|
|
77
77
|
},
|
|
78
|
+
/**
|
|
79
|
+
* A tab of the record page holding main-column items: sections, groups, related tables, custom components, maps,
|
|
80
|
+
* galleries, history and comments. A view's tabs stand together and show as one strip, the first tab open unless the
|
|
81
|
+
* address names another; items before and after them show on every tab. Throws on a sidebar item or another tab. See
|
|
82
|
+
* [Tabs](website/src/content/docs/reference/ui-config.mdx#tabs).
|
|
83
|
+
*/
|
|
84
|
+
tab: (title, items) => {
|
|
85
|
+
const wrong = items.find((item) => item.kind === "sidebar" || item.kind === "tab" || (item.kind === "custom" || item.kind === "map") && item.sidebar);
|
|
86
|
+
if (wrong) throw new Error(`l.tab "${title}" holds main-column items, not ${wrong.kind === "sidebar" || wrong.kind === "tab" ? wrong.kind : `a sidebar ${wrong.kind}`}`);
|
|
87
|
+
return {
|
|
88
|
+
kind: "tab",
|
|
89
|
+
title,
|
|
90
|
+
items
|
|
91
|
+
};
|
|
92
|
+
},
|
|
78
93
|
/** A table of the records of another resource that point at this one, directly or through a join table. */
|
|
79
94
|
related: (title, o) => ({
|
|
80
95
|
kind: "related",
|
package/dist/model.d.ts
CHANGED
|
@@ -222,6 +222,8 @@ export type AppAddress = {
|
|
|
222
222
|
edit?: boolean;
|
|
223
223
|
/** The titles of the record page's collapsed groups that are open. */
|
|
224
224
|
open?: readonly string[];
|
|
225
|
+
/** The title of the record page's tab shown; the first tab when omitted. */
|
|
226
|
+
tab?: string;
|
|
225
227
|
} | {
|
|
226
228
|
/** The form for a new record. */
|
|
227
229
|
kind: 'create';
|
|
@@ -754,7 +756,7 @@ export type LayoutItemModel = SectionModel | {
|
|
|
754
756
|
fields: string[];
|
|
755
757
|
/** Whether it shows on the form, the read view or both, or a condition on the saved record that it shows while it holds. */
|
|
756
758
|
when?: RecordWhen;
|
|
757
|
-
} | RelatedModel | GroupModel | CustomSectionModel | MapSectionModel | GalleryModel | HistorySectionModel | CommentsSectionModel;
|
|
759
|
+
} | RelatedModel | GroupModel | CustomSectionModel | MapSectionModel | GalleryModel | HistorySectionModel | CommentsSectionModel | TabModel;
|
|
758
760
|
/** A titled group of sections and related tables on the record page, closed until opened with `collapsed`; see [Groups](website/src/content/docs/reference/ui-config.mdx#groups). */
|
|
759
761
|
export type GroupModel = {
|
|
760
762
|
/** A group of sections and related tables. */
|
|
@@ -770,6 +772,17 @@ export type GroupModel = {
|
|
|
770
772
|
};
|
|
771
773
|
/** An item a group may hold. */
|
|
772
774
|
export type GroupItemModel = SectionModel | RelatedModel;
|
|
775
|
+
/** A tab of the record page, holding main-column items; a view's tabs stand together as one strip. See [Tabs](website/src/content/docs/reference/ui-config.mdx#tabs). */
|
|
776
|
+
export type TabModel = {
|
|
777
|
+
/** A tab of the record page. */
|
|
778
|
+
kind: 'tab';
|
|
779
|
+
/** Its label, unique among the view's tabs: the address names the open tab by it. */
|
|
780
|
+
title: string;
|
|
781
|
+
/** The main-column items it shows, in order. */
|
|
782
|
+
items: TabItemModel[];
|
|
783
|
+
};
|
|
784
|
+
/** An item a tab may hold: any of the main column. */
|
|
785
|
+
export type TabItemModel = SectionModel | RelatedModel | GroupModel | CustomSectionModel | MapSectionModel | GalleryModel | HistorySectionModel | CommentsSectionModel;
|
|
773
786
|
/**
|
|
774
787
|
* A record's photos as tiles in the main column under `title`, one large and the next few smaller, opening a lightbox
|
|
775
788
|
* that steps through them all: first the record's own file field `image`, then the `image` of the records of
|
package/dist/view.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRefs, ref } from "./refs.js";
|
|
2
2
|
import { formNamePattern } from "./form-address.js";
|
|
3
|
+
import { layoutItems } from "./layout-items.js";
|
|
3
4
|
import { isMenuHref } from "./menu-href.js";
|
|
4
5
|
import { viewOfList } from "./named-list.js";
|
|
5
6
|
import { navRecentErrors } from "./nav-recent.js";
|
|
@@ -301,12 +302,23 @@ var ViewBuilder = class ViewBuilder {
|
|
|
301
302
|
const clash = resource ? list?.relatedColumns?.find((column) => Object.hasOwn(resource.fields, column.name)) : void 0;
|
|
302
303
|
if (clash) throw new Error(`View "${this.state.resource}": related column "${clash.name}" has the name of a field of the resource`);
|
|
303
304
|
const groupTitles = /* @__PURE__ */ new Set();
|
|
304
|
-
|
|
305
|
+
const tabs = this.state.layout.flatMap((item, index) => item.kind === "tab" ? [{
|
|
306
|
+
item,
|
|
307
|
+
index
|
|
308
|
+
}] : []);
|
|
309
|
+
const apart = tabs.find((tab, at) => at > 0 && tab.index !== tabs[at - 1].index + 1);
|
|
310
|
+
if (apart) throw new Error(`View "${this.state.resource}": tabs stand together, and "${apart.item.title}" is apart from the others`);
|
|
311
|
+
const tabTitles = /* @__PURE__ */ new Set();
|
|
312
|
+
for (const { item } of tabs) {
|
|
313
|
+
if (tabTitles.has(item.title)) throw new Error(`View "${this.state.resource}": two tabs are titled "${item.title}"`);
|
|
314
|
+
tabTitles.add(item.title);
|
|
315
|
+
}
|
|
316
|
+
for (const item of this.state.layout.flatMap((item) => item.kind === "tab" ? item.items : [item])) {
|
|
305
317
|
if (item.kind !== "group") continue;
|
|
306
318
|
if (groupTitles.has(item.title)) throw new Error(`View "${this.state.resource}": two groups are titled "${item.title}"`);
|
|
307
319
|
groupTitles.add(item.title);
|
|
308
320
|
}
|
|
309
|
-
for (const item of resource ? this.state.layout : []) {
|
|
321
|
+
for (const item of resource ? layoutItems(this.state.layout) : []) {
|
|
310
322
|
if (item.kind !== "gallery" || item.image === void 0) continue;
|
|
311
323
|
if (!Object.hasOwn(resource.fields, item.image)) throw new Error(`View "${this.state.resource}": gallery "${item.title}" names field "${item.image}", which the resource does not have`);
|
|
312
324
|
if (resource.fields[item.image].type !== "file") throw new Error(`View "${this.state.resource}": gallery "${item.title}" shows "${item.image}" as its image, which is not a file field`);
|