sg-widgets-core 0.2.0 → 0.3.0

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.
@@ -115,6 +115,8 @@ interface RawFieldSchema {
115
115
  editable: RawProperty<boolean>;
116
116
  mandatory: RawProperty<boolean>;
117
117
  unique: RawProperty<boolean>;
118
+ /** `editable` here says whether the site may hide the field (056_stock_vs_custom_field). */
119
+ visible?: RawProperty<boolean>;
118
120
  properties: Record<string, RawProperty<unknown>>;
119
121
  }
120
122
  type RawFieldsResponse = {
@@ -145,6 +147,12 @@ interface FieldSchema {
145
147
  operators?: Operator[];
146
148
  defaultValue?: unknown;
147
149
  description?: string;
150
+ /**
151
+ * `visible.editable`: whether the site may hide the field. False is stock and safe to
152
+ * depend on; true is every custom field and a few stock ones, so a strong hint and not
153
+ * a proof. The `sg_` prefix decides nothing (056_stock_vs_custom_field).
154
+ */
155
+ hideable?: boolean;
148
156
  }
149
157
  /**
150
158
  * Fields the schema types one way and the API answers another, keyed
@@ -380,6 +388,13 @@ interface EntityRow {
380
388
  data: EntityRef | EntityRef[] | null;
381
389
  }>;
382
390
  }
391
+ /** What `read` asks for. */
392
+ interface ReadOptions {
393
+ /** The fields to return. Dotted paths are allowed. */
394
+ fields?: string[];
395
+ /** Read a retired row, which answers 404 otherwise; a live row then answers 404 (get_entity_type_id, 103_batch_delete_revive). */
396
+ retired?: boolean;
397
+ }
383
398
  interface SearchResult {
384
399
  data: EntityRow[];
385
400
  /** True when another page exists. Computed from data length, not `links.next`, which is emitted on empty pages too (probe 006). */
@@ -639,6 +654,15 @@ interface SgClient {
639
654
  */
640
655
  fieldWithProject(entityType: string, field: string, projectId: number): Promise<FieldSchema>;
641
656
  search(entityType: string, options: SearchOptions): Promise<SearchResult>;
657
+ /**
658
+ * One row by id, in the `_search` row shape.
659
+ *
660
+ * A row that is not there rejects 404 code 104, and a retired row answers the same
661
+ * 404 unless read with `retired`: only that second read tells the two apart
662
+ * (get_entity_type_id). A batch create with no `project` answers an id this read
663
+ * never reaches (recipes/002).
664
+ */
665
+ read(entityType: string, id: number, options?: ReadOptions): Promise<EntityRow>;
642
666
  /**
643
667
  * Free-text search across several types at once. Every word must match, each as
644
668
  * a case-insensitive substring of the row's name or of the linked row's name
@@ -796,6 +820,7 @@ declare class RestClient implements SgClient {
796
820
  fields(entityType: string, projectId?: number): Promise<Record<string, FieldSchema>>;
797
821
  fieldWithProject(entityType: string, field: string, projectId: number): Promise<FieldSchema>;
798
822
  search(entityType: string, options: SearchOptions): Promise<SearchResult>;
823
+ read(entityType: string, id: number, options?: ReadOptions): Promise<EntityRow>;
799
824
  textSearch(text: string, entityTypes: Record<string, TextSearchFilter>, page?: {
800
825
  size?: number;
801
826
  number?: number;
@@ -817,4 +842,4 @@ declare class RestClient implements SgClient {
817
842
  /** One `_search` row of `EventLogEntry`, with `meta` decoded as the API returns it. */
818
843
  declare function normalizeEventLogEntry(row: EntityRow): EventLogEntry;
819
844
  //#endregion
820
- export { NativeStatus as $, isDataType as $t, UploadFile as A, TextSearchFilter as At, StatusOption as B, toApi3Hash as Bt, SummaryField as C, ConditionValue as Ct, TextSearchRow as D, FilterNode as Dt, SummaryType as E, FilterGroup as Et, normalizeEventLogEntry as F, fromWire as Ft, parseBgColor as G, NEGATING_OPERATORS as Gt, StatusRecord as H, walk as Ht, normalizeHierarchyNode as I, group as It, statusGlyph as J, Operator as Jt, relativeLuminance as K, OPERATORS as Kt, Rgb as L, isBlankCondition as Lt, batchResults as M, WireGroup as Mt, eventLogFilters as N, condition as Nt, ThreadAuthor as O, LogicalOperator as Ot, hierarchyEntity as P, emptyFilter as Pt, NATIVE_STATUSES as Q, ValueShape as Qt, StatusGlyph as R, isEmptyFilter as Rt, SummarizeResult as S, undeclaredField as St, SummaryGrouping as T, FilterCondition as Tt, foregroundFor as U, DATA_TYPES as Ut, StatusPaint as V, toFilterArray as Vt, intersectStatuses as W, DataType as Wt, statusPaint as X, TimeUnit as Xt, statusLabel as Y, TIME_UNITS as Yt, usableStatuses as Z, VALUE_SHAPE as Zt, SearchOptions as _, fieldSchemaOverride as _t, EntityTypeInfo as a, operatorsFor as an, StockIconSource as at, SgClient as b, statusFieldFor as bt, EventLogResult as c, spriteStyle as ct, HierarchyPath as d, FIELD_SCHEMA_OVERRIDES as dt, isFilterable as en, STOCK_ICON_CELLS as et, HierarchyRef as f, FieldSchema as ft, RestClientOptions as g, displayNameOf as gt, RestClient as h, RawProperty as ht, EntityRow as i, isTemporalType as in, SpriteCell as it, UploadResult as j, WireCondition as jt, ThreadRow as k, Scalar as kt, FollowingOptions as l, stockIconSource as lt, RawHierarchyNode as m, RawFieldsResponse as mt, BatchResult as n, isNumericType as nn, STOCK_ICON_KEYS as nt, EventLogEntry as o, supportsOperator as on, isNativeStatus as ot, RawBatchRow as p, RawFieldSchema as pt, rgbToCss as q, OPERATORS_BY_TYPE as qt, EVENT_LOG_FIELDS as r, isOperator as rn, STOCK_SPRITE_PATH as rt, EventLogOptions as s, nativeStatus as st, BatchRequest as t, isLinkType as tn, STOCK_ICON_DATA_URLS as tt, HierarchyNode as u, DISPLAY_NAME_FIELDS as ut, SearchResult as v, normalizeField as vt, SummaryGroup as w, EntityRef as wt, SummarizeOptions as x, statusFieldNameFor as xt, SgApiError as y, normalizeFields as yt, StatusIcon as z, referencedPaths as zt };
845
+ export { NATIVE_STATUSES as $, ValueShape as $t, ThreadRow as A, Scalar as At, StatusIcon as B, referencedPaths as Bt, SummarizeResult as C, undeclaredField as Ct, SummaryType as D, FilterGroup as Dt, SummaryGrouping as E, FilterCondition as Et, hierarchyEntity as F, emptyFilter as Ft, intersectStatuses as G, DataType as Gt, StatusPaint as H, toFilterArray as Ht, normalizeEventLogEntry as I, fromWire as It, rgbToCss as J, OPERATORS_BY_TYPE as Jt, parseBgColor as K, NEGATING_OPERATORS as Kt, normalizeHierarchyNode as L, group as Lt, UploadResult as M, WireCondition as Mt, batchResults as N, WireGroup as Nt, TextSearchRow as O, FilterNode as Ot, eventLogFilters as P, condition as Pt, usableStatuses as Q, VALUE_SHAPE as Qt, Rgb as R, isBlankCondition as Rt, SummarizeOptions as S, statusFieldNameFor as St, SummaryGroup as T, EntityRef as Tt, StatusRecord as U, walk as Ut, StatusOption as V, toApi3Hash as Vt, foregroundFor as W, DATA_TYPES as Wt, statusLabel as X, TIME_UNITS as Xt, statusGlyph as Y, Operator as Yt, statusPaint as Z, TimeUnit as Zt, RestClientOptions as _, displayNameOf as _t, EntityTypeInfo as a, isTemporalType as an, SpriteCell as at, SgApiError as b, normalizeFields as bt, EventLogResult as c, nativeStatus as ct, HierarchyPath as d, DISPLAY_NAME_FIELDS as dt, isDataType as en, NativeStatus as et, HierarchyRef as f, FIELD_SCHEMA_OVERRIDES as ft, RestClient as g, RawProperty as gt, ReadOptions as h, RawFieldsResponse as ht, EntityRow as i, isOperator as in, STOCK_SPRITE_PATH as it, UploadFile as j, TextSearchFilter as jt, ThreadAuthor as k, LogicalOperator as kt, FollowingOptions as l, spriteStyle as lt, RawHierarchyNode as m, RawFieldSchema as mt, BatchResult as n, isLinkType as nn, STOCK_ICON_DATA_URLS as nt, EventLogEntry as o, operatorsFor as on, StockIconSource as ot, RawBatchRow as p, FieldSchema as pt, relativeLuminance as q, OPERATORS as qt, EVENT_LOG_FIELDS as r, isNumericType as rn, STOCK_ICON_KEYS as rt, EventLogOptions as s, supportsOperator as sn, isNativeStatus as st, BatchRequest as t, isFilterable as tn, STOCK_ICON_CELLS as tt, HierarchyNode as u, stockIconSource as ut, SearchOptions as v, fieldSchemaOverride as vt, SummaryField as w, ConditionValue as wt, SgClient as x, statusFieldFor as xt, SearchResult as y, normalizeField as yt, StatusGlyph as z, isEmptyFilter as zt };
@@ -452,6 +452,7 @@ function normalizeField(name, raw) {
452
452
  if (defaultValue !== void 0) field.defaultValue = defaultValue;
453
453
  const description = prop(props, "description");
454
454
  if (description) field.description = description;
455
+ if (raw.visible) field.hideable = raw.visible.editable;
455
456
  return {
456
457
  ...field,
457
458
  ...fieldSchemaOverride(field.entityType, name)
@@ -760,6 +761,13 @@ var RestClient = class {
760
761
  hasMore: res.data.length === size
761
762
  };
762
763
  }
764
+ async read(entityType, id, options = {}) {
765
+ const params = {
766
+ fields: options.fields?.join(","),
767
+ "options[return_only]": options.retired ? "retired" : void 0
768
+ };
769
+ return (await this.request("GET", `/entity/${pluralPath(entityType)}/${id}`, void 0, params)).data;
770
+ }
763
771
  async textSearch(text, entityTypes, page) {
764
772
  const types = {};
765
773
  for (const [t, f] of Object.entries(entityTypes)) types[t] = toHashGroup(f);
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as NativeStatus, $t as isDataType, A as UploadFile, At as TextSearchFilter, B as StatusOption, Bt as toApi3Hash, C as SummaryField, Ct as ConditionValue, D as TextSearchRow, Dt as FilterNode, E as SummaryType, Et as FilterGroup, F as normalizeEventLogEntry, Ft as fromWire, G as parseBgColor, Gt as NEGATING_OPERATORS, H as StatusRecord, Ht as walk, I as normalizeHierarchyNode, It as group, J as statusGlyph, Jt as Operator, K as relativeLuminance, Kt as OPERATORS, L as Rgb, Lt as isBlankCondition, M as batchResults, Mt as WireGroup, N as eventLogFilters, Nt as condition, O as ThreadAuthor, Ot as LogicalOperator, P as hierarchyEntity, Pt as emptyFilter, Q as NATIVE_STATUSES, Qt as ValueShape, R as StatusGlyph, Rt as isEmptyFilter, S as SummarizeResult, St as undeclaredField, T as SummaryGrouping, Tt as FilterCondition, U as foregroundFor, Ut as DATA_TYPES, V as StatusPaint, Vt as toFilterArray, W as intersectStatuses, Wt as DataType, X as statusPaint, Xt as TimeUnit, Y as statusLabel, Yt as TIME_UNITS, Z as usableStatuses, Zt as VALUE_SHAPE, _ as SearchOptions, _t as fieldSchemaOverride, a as EntityTypeInfo, an as operatorsFor, at as StockIconSource, b as SgClient, bt as statusFieldFor, c as EventLogResult, ct as spriteStyle, d as HierarchyPath, dt as FIELD_SCHEMA_OVERRIDES, en as isFilterable, et as STOCK_ICON_CELLS, f as HierarchyRef, ft as FieldSchema, g as RestClientOptions, gt as displayNameOf, h as RestClient, ht as RawProperty, i as EntityRow, in as isTemporalType, it as SpriteCell, j as UploadResult, jt as WireCondition, k as ThreadRow, kt as Scalar, l as FollowingOptions, lt as stockIconSource, m as RawHierarchyNode, mt as RawFieldsResponse, n as BatchResult, nn as isNumericType, nt as STOCK_ICON_KEYS, o as EventLogEntry, on as supportsOperator, ot as isNativeStatus, p as RawBatchRow, pt as RawFieldSchema, q as rgbToCss, qt as OPERATORS_BY_TYPE, r as EVENT_LOG_FIELDS, rn as isOperator, rt as STOCK_SPRITE_PATH, s as EventLogOptions, st as nativeStatus, t as BatchRequest, tn as isLinkType, tt as STOCK_ICON_DATA_URLS, u as HierarchyNode, ut as DISPLAY_NAME_FIELDS, v as SearchResult, vt as normalizeField, w as SummaryGroup, wt as EntityRef, x as SummarizeOptions, xt as statusFieldNameFor, y as SgApiError, yt as normalizeFields, z as StatusIcon, zt as referencedPaths } from "./client-B2PCySg9.mjs";
1
+ import { $ as NATIVE_STATUSES, $t as ValueShape, A as ThreadRow, At as Scalar, B as StatusIcon, Bt as referencedPaths, C as SummarizeResult, Ct as undeclaredField, D as SummaryType, Dt as FilterGroup, E as SummaryGrouping, Et as FilterCondition, F as hierarchyEntity, Ft as emptyFilter, G as intersectStatuses, Gt as DataType, H as StatusPaint, Ht as toFilterArray, I as normalizeEventLogEntry, It as fromWire, J as rgbToCss, Jt as OPERATORS_BY_TYPE, K as parseBgColor, Kt as NEGATING_OPERATORS, L as normalizeHierarchyNode, Lt as group, M as UploadResult, Mt as WireCondition, N as batchResults, Nt as WireGroup, O as TextSearchRow, Ot as FilterNode, P as eventLogFilters, Pt as condition, Q as usableStatuses, Qt as VALUE_SHAPE, R as Rgb, Rt as isBlankCondition, S as SummarizeOptions, St as statusFieldNameFor, T as SummaryGroup, Tt as EntityRef, U as StatusRecord, Ut as walk, V as StatusOption, Vt as toApi3Hash, W as foregroundFor, Wt as DATA_TYPES, X as statusLabel, Xt as TIME_UNITS, Y as statusGlyph, Yt as Operator, Z as statusPaint, Zt as TimeUnit, _ as RestClientOptions, _t as displayNameOf, a as EntityTypeInfo, an as isTemporalType, at as SpriteCell, b as SgApiError, bt as normalizeFields, c as EventLogResult, ct as nativeStatus, d as HierarchyPath, dt as DISPLAY_NAME_FIELDS, en as isDataType, et as NativeStatus, f as HierarchyRef, ft as FIELD_SCHEMA_OVERRIDES, g as RestClient, gt as RawProperty, h as ReadOptions, ht as RawFieldsResponse, i as EntityRow, in as isOperator, it as STOCK_SPRITE_PATH, j as UploadFile, jt as TextSearchFilter, k as ThreadAuthor, kt as LogicalOperator, l as FollowingOptions, lt as spriteStyle, m as RawHierarchyNode, mt as RawFieldSchema, n as BatchResult, nn as isLinkType, nt as STOCK_ICON_DATA_URLS, o as EventLogEntry, on as operatorsFor, ot as StockIconSource, p as RawBatchRow, pt as FieldSchema, q as relativeLuminance, qt as OPERATORS, r as EVENT_LOG_FIELDS, rn as isNumericType, rt as STOCK_ICON_KEYS, s as EventLogOptions, sn as supportsOperator, st as isNativeStatus, t as BatchRequest, tn as isFilterable, tt as STOCK_ICON_CELLS, u as HierarchyNode, ut as stockIconSource, v as SearchOptions, vt as fieldSchemaOverride, w as SummaryField, wt as ConditionValue, x as SgClient, xt as statusFieldFor, y as SearchResult, yt as normalizeField, z as StatusGlyph, zt as isEmptyFilter } from "./client-CP9sWEVZ.mjs";
2
2
  //#region src/field-icons.d.ts
3
3
  /** The catch-all glyph, used for a data type this build does not know. */
4
4
  export declare const DEFAULT_FIELD_ICON = "file-text";
@@ -1154,6 +1154,11 @@ export interface EntitySource {
1154
1154
  loadMore(): Promise<void>;
1155
1155
  /** Read every page already shown again, keeping the row count. */
1156
1156
  refresh(): Promise<void>;
1157
+ /**
1158
+ * Read these paths as well. The rows already shown are read again when one of them
1159
+ * is new, keeping the row count and the total; otherwise nothing is read.
1160
+ */
1161
+ addFields(paths: readonly string[]): Promise<void>;
1157
1162
  setFilters(filters: SourceFilters): Promise<void>;
1158
1163
  setSort(sort: SortSpec[]): Promise<void>;
1159
1164
  /** Show one page of the set. `pages` mode only. */
@@ -1766,6 +1771,7 @@ export declare class ProxyClient implements SgClient {
1766
1771
  fields(entityType: string, projectId?: number): Promise<Record<string, FieldSchema>>;
1767
1772
  fieldWithProject(entityType: string, field: string, projectId: number): Promise<FieldSchema>;
1768
1773
  search(entityType: string, options: SearchOptions): Promise<SearchResult>;
1774
+ read(entityType: string, id: number, options?: ReadOptions): Promise<EntityRow>;
1769
1775
  textSearch(text: string, entityTypes: Record<string, TextSearchFilter>, page?: {
1770
1776
  size?: number;
1771
1777
  number?: number;
@@ -1788,7 +1794,7 @@ export declare class ProxyClient implements SgClient {
1788
1794
  //#endregion
1789
1795
  //#region src/proxy-handler.d.ts
1790
1796
  /** The methods the protocol carries, one POST each. */
1791
- export declare const PROXY_METHODS: readonly ['entityTypes', 'fields', 'fieldWithProject', 'search', 'textSearch', 'statuses', 'create', 'update', 'upload', 'hierarchyExpand', 'hierarchySearch', 'summarize', 'threadContents', 'eventLog', 'following', 'delete', 'revive', 'batch'];
1797
+ export declare const PROXY_METHODS: readonly ['entityTypes', 'fields', 'fieldWithProject', 'search', 'read', 'textSearch', 'statuses', 'create', 'update', 'upload', 'hierarchyExpand', 'hierarchySearch', 'summarize', 'threadContents', 'eventLog', 'following', 'delete', 'revive', 'batch'];
1792
1798
  export type ProxyMethod = (typeof PROXY_METHODS)[number];
1793
1799
  /** An error as it crosses the wire. `ProxyClient` rebuilds an `SgApiError` from it. */
1794
1800
  export interface ProxyError {
@@ -2357,6 +2363,94 @@ export declare function collapseStateFrom(state: CollapseState, shut: readonly s
2357
2363
  /** True when two collapse states shut the same groups. */
2358
2364
  export declare function sameCollapse(a: CollapseState, b: CollapseState): boolean;
2359
2365
  //#endregion
2366
+ //#region src/selection.d.ts
2367
+ /** Where a range starts and what it is laid over. */
2368
+ export interface SelectionAnchor {
2369
+ /** The row the range runs from, `Type:id`. */
2370
+ key: string;
2371
+ /** True when the range selects, false when it clears: what the anchor row became. */
2372
+ on: boolean;
2373
+ /** The selection the range is laid over. */
2374
+ base: EntityRef[];
2375
+ /** The selection the last step produced. One that no longer reads this has moved under the anchor. */
2376
+ last: EntityRef[];
2377
+ }
2378
+ /** A selection and the anchor the next Shift gesture ranges from. */
2379
+ export interface SelectionStep {
2380
+ selection: EntityRef[];
2381
+ anchor: SelectionAnchor | null;
2382
+ }
2383
+ /** What a press on a row does: toggle it, or range to it. */
2384
+ export type SelectionGesture = 'toggle' | 'range';
2385
+ /** What a key does to the selection. */
2386
+ export type SelectionKeyIntent = 'toggle' | 'extend-up' | 'extend-down' | 'all';
2387
+ interface Modifiers {
2388
+ shiftKey?: boolean;
2389
+ metaKey?: boolean;
2390
+ ctrlKey?: boolean;
2391
+ altKey?: boolean;
2392
+ }
2393
+ /** Shift ranges; a plain press and Cmd or Ctrl both toggle. */
2394
+ export declare function gestureOf(event: Modifiers): SelectionGesture;
2395
+ /** Space toggles, Shift+ArrowUp and Shift+ArrowDown extend, Cmd or Ctrl+A takes every loaded row. */
2396
+ export declare function selectionKeyIntent(event: Modifiers & {
2397
+ key: string;
2398
+ }): SelectionKeyIntent | null;
2399
+ /** `selection` with every ref of `refs` added, or every one of them dropped. */
2400
+ export declare function setRefs(selection: readonly EntityRef[], refs: readonly EntityRef[], on: boolean): EntityRef[];
2401
+ /** Toggle the row at `index` and anchor on it. A disabled row refuses. */
2402
+ export declare function toggleRow(selection: readonly EntityRef[], anchor: SelectionAnchor | null, rows: readonly EntityRow[], index: number, isRowDisabled?: RowDisabledFn | null): SelectionStep;
2403
+ /**
2404
+ * Range from the anchor to the row at `index`, skipping disabled rows.
2405
+ *
2406
+ * With no anchor among the rows, the row pressed is selected and becomes the anchor.
2407
+ */
2408
+ export declare function extendRange(selection: readonly EntityRef[], anchor: SelectionAnchor | null, rows: readonly EntityRow[], index: number, isRowDisabled?: RowDisabledFn | null): SelectionStep;
2409
+ /**
2410
+ * Shift+arrow: move the far end of the range from row `from` to row `to`. With no
2411
+ * anchor among the rows, the row the cursor leaves becomes one, selecting.
2412
+ */
2413
+ export declare function extendByStep(selection: readonly EntityRef[], anchor: SelectionAnchor | null, rows: readonly EntityRow[], from: number, to: number, isRowDisabled?: RowDisabledFn | null): SelectionStep;
2414
+ /** What the line offering the whole set reads. */
2415
+ export interface MatchingOffer {
2416
+ show: boolean;
2417
+ /** How many rows the set holds, when something counted it. */
2418
+ total: number | null;
2419
+ }
2420
+ /**
2421
+ * Whether to offer every row the filter matches: once every loaded row is picked and
2422
+ * the set holds more than is loaded, until the selection covers a counted set.
2423
+ */
2424
+ export declare function matchingOffer(state: {
2425
+ allLoaded: boolean;
2426
+ loaded: number;
2427
+ selected: number;
2428
+ hasMore: boolean;
2429
+ total: number | null;
2430
+ }): MatchingOffer;
2431
+ //#endregion
2432
+ //#region src/column-choice.d.ts
2433
+ /** Where a choice is kept: the caller's key, or one per entity type. */
2434
+ export declare function columnsStorageKey(entityType: string, key?: string | null): string;
2435
+ /** A stored choice as paths. Null for nothing, an empty list, or anything that is not a list of paths. */
2436
+ export declare function parseColumnChoice(raw: string | null | undefined): string[] | null;
2437
+ /** The string a choice is kept as. */
2438
+ export declare function serializeColumnChoice(paths: readonly string[]): string;
2439
+ /** The paths of a column list, in order. */
2440
+ export declare function columnPaths(columns: readonly CollectionColumn[]): string[];
2441
+ /** True when two path lists name the same columns in the same order. */
2442
+ export declare function sameColumnPaths(a: readonly string[], b: readonly string[]): boolean;
2443
+ /** The paths a source with `fields` does not read yet. */
2444
+ export declare function unreadPaths(fields: readonly string[], paths: readonly string[]): string[];
2445
+ /** The known columns in the order `paths` names them. A path none of them carries is dropped. */
2446
+ export declare function arrangeColumns(paths: readonly string[], known: readonly CollectionColumn[]): CollectionColumn[];
2447
+ /**
2448
+ * A choice as columns: the ones already resolved are kept as they are, the rest are
2449
+ * resolved from the schema, and a path the type does not have is skipped, so a
2450
+ * choice kept before a field was removed still opens.
2451
+ */
2452
+ export declare function resolveColumnChoice(schema: SchemaService, entityType: string, paths: readonly string[], known: readonly CollectionColumn[]): Promise<CollectionColumn[]>;
2453
+ //#endregion
2360
2454
  //#region src/entity-card.d.ts
2361
2455
  export interface EntityCardOptions {
2362
2456
  /** Dotted field paths for the grid, in order. */
@@ -2726,4 +2820,4 @@ export declare function markOverflow(list: HTMLElement | null | undefined): bool
2726
2820
  */
2727
2821
  export declare function watchOverflow(list: HTMLElement | null | undefined): () => void;
2728
2822
  //#endregion
2729
- export { BatchRequest, BatchResult, ConditionValue, DATA_TYPES, DISPLAY_NAME_FIELDS, DataType, EVENT_LOG_FIELDS, EntityRef, EntityRow, EntityTypeInfo, EventLogEntry, EventLogOptions, EventLogResult, FIELD_SCHEMA_OVERRIDES, FieldSchema, FilterCondition, FilterGroup, FilterNode, FollowingOptions, HierarchyNode, HierarchyPath, HierarchyRef, LogicalOperator, NATIVE_STATUSES, NEGATING_OPERATORS, NativeStatus, OPERATORS, OPERATORS_BY_TYPE, Operator, RawBatchRow, RawFieldSchema, RawFieldsResponse, RawHierarchyNode, RawProperty, RestClient, RestClientOptions, Rgb, STOCK_ICON_CELLS, STOCK_ICON_DATA_URLS, STOCK_ICON_KEYS, STOCK_SPRITE_PATH, Scalar, SearchOptions, SearchResult, SgApiError, SgClient, SpriteCell, StatusGlyph, StatusIcon, StatusOption, StatusPaint, StatusRecord, StockIconSource, SummarizeOptions, SummarizeResult, SummaryField, SummaryGroup, SummaryGrouping, SummaryType, TIME_UNITS, TextSearchFilter, TextSearchRow, ThreadAuthor, ThreadRow, TimeUnit, UploadFile, UploadResult, VALUE_SHAPE, ValueShape, WireCondition, WireGroup, batchResults, condition, displayNameOf, emptyFilter, eventLogFilters, fieldSchemaOverride, foregroundFor, fromWire, group, hierarchyEntity, intersectStatuses, isBlankCondition, isDataType, isEmptyFilter, isFilterable, isLinkType, isNativeStatus, isNumericType, isOperator, isTemporalType, nativeStatus, normalizeEventLogEntry, normalizeField, normalizeFields, normalizeHierarchyNode, operatorsFor, parseBgColor, referencedPaths, relativeLuminance, rgbToCss, spriteStyle, statusFieldFor, statusFieldNameFor, statusGlyph, statusLabel, statusPaint, stockIconSource, supportsOperator, toApi3Hash, toFilterArray, undeclaredField, usableStatuses, walk };
2823
+ export { BatchRequest, BatchResult, ConditionValue, DATA_TYPES, DISPLAY_NAME_FIELDS, DataType, EVENT_LOG_FIELDS, EntityRef, EntityRow, EntityTypeInfo, EventLogEntry, EventLogOptions, EventLogResult, FIELD_SCHEMA_OVERRIDES, FieldSchema, FilterCondition, FilterGroup, FilterNode, FollowingOptions, HierarchyNode, HierarchyPath, HierarchyRef, LogicalOperator, NATIVE_STATUSES, NEGATING_OPERATORS, NativeStatus, OPERATORS, OPERATORS_BY_TYPE, Operator, RawBatchRow, RawFieldSchema, RawFieldsResponse, RawHierarchyNode, RawProperty, ReadOptions, RestClient, RestClientOptions, Rgb, STOCK_ICON_CELLS, STOCK_ICON_DATA_URLS, STOCK_ICON_KEYS, STOCK_SPRITE_PATH, Scalar, SearchOptions, SearchResult, SgApiError, SgClient, SpriteCell, StatusGlyph, StatusIcon, StatusOption, StatusPaint, StatusRecord, StockIconSource, SummarizeOptions, SummarizeResult, SummaryField, SummaryGroup, SummaryGrouping, SummaryType, TIME_UNITS, TextSearchFilter, TextSearchRow, ThreadAuthor, ThreadRow, TimeUnit, UploadFile, UploadResult, VALUE_SHAPE, ValueShape, WireCondition, WireGroup, batchResults, condition, displayNameOf, emptyFilter, eventLogFilters, fieldSchemaOverride, foregroundFor, fromWire, group, hierarchyEntity, intersectStatuses, isBlankCondition, isDataType, isEmptyFilter, isFilterable, isLinkType, isNativeStatus, isNumericType, isOperator, isTemporalType, nativeStatus, normalizeEventLogEntry, normalizeField, normalizeFields, normalizeHierarchyNode, operatorsFor, parseBgColor, referencedPaths, relativeLuminance, rgbToCss, spriteStyle, statusFieldFor, statusFieldNameFor, statusGlyph, statusLabel, statusPaint, stockIconSource, supportsOperator, toApi3Hash, toFilterArray, undeclaredField, usableStatuses, walk };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as NEGATING_OPERATORS, B as isTemporalType, C as isBlankCondition, D as toFilterArray, E as toApi3Hash, F as isDataType, H as supportsOperator, I as isFilterable, L as isLinkType, M as OPERATORS_BY_TYPE, N as TIME_UNITS, O as walk, P as VALUE_SHAPE, R as isNumericType, S as group, T as referencedPaths, V as operatorsFor, _ as undeclaredField, a as eventLogFilters, b as emptyFilter, c as normalizeHierarchyNode, d as displayNameOf, f as fieldSchemaOverride, g as statusFieldNameFor, h as statusFieldFor, i as batchResults, j as OPERATORS, k as DATA_TYPES, l as DISPLAY_NAME_FIELDS, m as normalizeFields, n as RestClient, o as hierarchyEntity, p as normalizeField, r as SgApiError, s as normalizeEventLogEntry, t as EVENT_LOG_FIELDS, u as FIELD_SCHEMA_OVERRIDES, w as isEmptyFilter, x as fromWire, y as condition, z as isOperator } from "./client-BdePDloQ.mjs";
1
+ import { A as NEGATING_OPERATORS, B as isTemporalType, C as isBlankCondition, D as toFilterArray, E as toApi3Hash, F as isDataType, H as supportsOperator, I as isFilterable, L as isLinkType, M as OPERATORS_BY_TYPE, N as TIME_UNITS, O as walk, P as VALUE_SHAPE, R as isNumericType, S as group, T as referencedPaths, V as operatorsFor, _ as undeclaredField, a as eventLogFilters, b as emptyFilter, c as normalizeHierarchyNode, d as displayNameOf, f as fieldSchemaOverride, g as statusFieldNameFor, h as statusFieldFor, i as batchResults, j as OPERATORS, k as DATA_TYPES, l as DISPLAY_NAME_FIELDS, m as normalizeFields, n as RestClient, o as hierarchyEntity, p as normalizeField, r as SgApiError, s as normalizeEventLogEntry, t as EVENT_LOG_FIELDS, u as FIELD_SCHEMA_OVERRIDES, w as isEmptyFilter, x as fromWire, y as condition, z as isOperator } from "./client-izKszX7l.mjs";
2
2
  //#region src/field-icons.ts
3
3
  const ICONS = {
4
4
  text: "type",
@@ -3689,6 +3689,7 @@ function createQueryCache(client, options = {}) {
3689
3689
  }
3690
3690
  function invalidateSearches(entityType) {
3691
3691
  drop(`search:[${JSON.stringify(entityType)}`);
3692
+ drop(`read:[${JSON.stringify(entityType)}`);
3692
3693
  drop("textSearch");
3693
3694
  drop(`summarize:[${JSON.stringify(entityType)}`);
3694
3695
  }
@@ -3708,6 +3709,7 @@ function createQueryCache(client, options = {}) {
3708
3709
  function invalidateAllRows() {
3709
3710
  for (const prefix of [
3710
3711
  "search",
3712
+ "read",
3711
3713
  "textSearch",
3712
3714
  "summarize",
3713
3715
  "threadContents",
@@ -3732,6 +3734,13 @@ function createQueryCache(client, options = {}) {
3732
3734
  search(entityType, searchOptions) {
3733
3735
  return run("search", [entityType, searchOptions], () => client.search(entityType, searchOptions));
3734
3736
  },
3737
+ read(entityType, id, readOptions) {
3738
+ return run("read", [
3739
+ entityType,
3740
+ id,
3741
+ readOptions ?? null
3742
+ ], () => client.read(entityType, id, readOptions));
3743
+ },
3735
3744
  textSearch(text, entityTypes, page) {
3736
3745
  return run("textSearch", [
3737
3746
  text,
@@ -4710,6 +4719,7 @@ const PROXY_METHODS = [
4710
4719
  "fields",
4711
4720
  "fieldWithProject",
4712
4721
  "search",
4722
+ "read",
4713
4723
  "textSearch",
4714
4724
  "statuses",
4715
4725
  "create",
@@ -4828,6 +4838,7 @@ function call(client, method, p) {
4828
4838
  case "fields": return client.fields(str(p.entityType, "entityType"), optionalNum(p.projectId, "projectId"));
4829
4839
  case "fieldWithProject": return client.fieldWithProject(str(p.entityType, "entityType"), str(p.field, "field"), num(p.projectId, "projectId"));
4830
4840
  case "search": return client.search(str(p.entityType, "entityType"), p.options ?? {});
4841
+ case "read": return client.read(str(p.entityType, "entityType"), num(p.id, "id"), p.options ?? {});
4831
4842
  case "textSearch": return client.textSearch(str(p.text, "text"), p.entityTypes ?? {}, p.page ?? void 0);
4832
4843
  case "statuses": return client.statuses();
4833
4844
  case "create": return client.create(str(p.entityType, "entityType"), obj(p.body, "body"));
@@ -4905,6 +4916,13 @@ var ProxyClient = class {
4905
4916
  options
4906
4917
  });
4907
4918
  }
4919
+ read(entityType, id, options = {}) {
4920
+ return this.post("read", {
4921
+ entityType,
4922
+ id,
4923
+ options
4924
+ });
4925
+ }
4908
4926
  textSearch(text, entityTypes, page) {
4909
4927
  return this.post("textSearch", {
4910
4928
  text,
@@ -6475,7 +6493,7 @@ function asError$1(value) {
6475
6493
  }
6476
6494
  function createEntitySource(options) {
6477
6495
  const { client, entityType } = options;
6478
- const fields = [.../* @__PURE__ */ new Set(["id", ...options.fields])];
6496
+ let fields = [.../* @__PURE__ */ new Set(["id", ...options.fields])];
6479
6497
  let state = {
6480
6498
  rows: [],
6481
6499
  status: "idle",
@@ -6561,7 +6579,9 @@ function createEntitySource(options) {
6561
6579
  }
6562
6580
  const source = {
6563
6581
  entityType,
6564
- fields,
6582
+ get fields() {
6583
+ return fields;
6584
+ },
6565
6585
  get rows() {
6566
6586
  return state.rows;
6567
6587
  },
@@ -6614,6 +6634,15 @@ function createEntitySource(options) {
6614
6634
  set({ total: null });
6615
6635
  return run(() => read(pages, "loading", [], 1));
6616
6636
  },
6637
+ addFields(paths) {
6638
+ const added = paths.filter((path) => path && !fields.includes(path));
6639
+ if (added.length === 0) return Promise.resolve();
6640
+ fields = [...fields, ...new Set(added)];
6641
+ if (state.status === "idle") return Promise.resolve();
6642
+ if (state.mode === "pages") return run(() => read(1, "loading", [], state.page));
6643
+ const pages = Math.max(1, Math.ceil(state.rows.length / state.pageSize));
6644
+ return run(() => read(pages, "loading", [], 1));
6645
+ },
6617
6646
  setFilters(filters) {
6618
6647
  set({ filters: toWireGroup(filters) });
6619
6648
  return source.load();
@@ -7012,6 +7041,175 @@ function sameCollapse(a, b) {
7012
7041
  return a.all === b.all && sameIds(a.except, b.except);
7013
7042
  }
7014
7043
  //#endregion
7044
+ //#region src/selection.ts
7045
+ const refOf = (row) => ({
7046
+ type: row.type,
7047
+ id: row.id
7048
+ });
7049
+ /** Shift ranges; a plain press and Cmd or Ctrl both toggle. */
7050
+ function gestureOf(event) {
7051
+ return event.shiftKey ? "range" : "toggle";
7052
+ }
7053
+ /** Space toggles, Shift+ArrowUp and Shift+ArrowDown extend, Cmd or Ctrl+A takes every loaded row. */
7054
+ function selectionKeyIntent(event) {
7055
+ const command = event.metaKey || event.ctrlKey;
7056
+ if (event.key === " " && !command && !event.altKey) return "toggle";
7057
+ if (event.shiftKey && !command && !event.altKey) {
7058
+ if (event.key === "ArrowDown") return "extend-down";
7059
+ if (event.key === "ArrowUp") return "extend-up";
7060
+ }
7061
+ if (command && !event.shiftKey && !event.altKey && event.key.toLowerCase() === "a") return "all";
7062
+ return null;
7063
+ }
7064
+ /** `selection` with every ref of `refs` added, or every one of them dropped. */
7065
+ function setRefs(selection, refs, on) {
7066
+ const named = new Set(refs.map(rowKey));
7067
+ if (!on) return selection.filter((entry) => !named.has(rowKey(entry)));
7068
+ const held = new Set(selection.map(rowKey));
7069
+ return [...selection, ...refs.filter((entry) => !held.has(rowKey(entry))).map((entry) => ({ ...entry }))];
7070
+ }
7071
+ /** Toggle the row at `index` and anchor on it. A disabled row refuses. */
7072
+ function toggleRow(selection, anchor, rows, index, isRowDisabled) {
7073
+ const row = rows[index];
7074
+ if (!row || rowIsDisabled(row, isRowDisabled)) return {
7075
+ selection: [...selection],
7076
+ anchor
7077
+ };
7078
+ const key = rowKey(row);
7079
+ const on = !selection.some((entry) => rowKey(entry) === key);
7080
+ const next = setRefs(selection, [refOf(row)], on);
7081
+ return {
7082
+ selection: next,
7083
+ anchor: {
7084
+ key,
7085
+ on,
7086
+ base: next,
7087
+ last: next
7088
+ }
7089
+ };
7090
+ }
7091
+ /**
7092
+ * Range from the anchor to the row at `index`, skipping disabled rows.
7093
+ *
7094
+ * With no anchor among the rows, the row pressed is selected and becomes the anchor.
7095
+ */
7096
+ function extendRange(selection, anchor, rows, index, isRowDisabled) {
7097
+ const row = rows[index];
7098
+ if (!row) return {
7099
+ selection: [...selection],
7100
+ anchor
7101
+ };
7102
+ const from = anchor ? rows.findIndex((entry) => rowKey(entry) === anchor.key) : -1;
7103
+ if (!anchor || from < 0) {
7104
+ if (rowIsDisabled(row, isRowDisabled)) return {
7105
+ selection: [...selection],
7106
+ anchor
7107
+ };
7108
+ const next = setRefs(selection, [refOf(row)], true);
7109
+ return {
7110
+ selection: next,
7111
+ anchor: {
7112
+ key: rowKey(row),
7113
+ on: true,
7114
+ base: next,
7115
+ last: next
7116
+ }
7117
+ };
7118
+ }
7119
+ const base = sameRefs(selection, anchor.last) ? anchor.base : [...selection];
7120
+ const [lo, hi] = from <= index ? [from, index] : [index, from];
7121
+ const next = setRefs(base, rows.slice(lo, hi + 1).filter((entry) => !rowIsDisabled(entry, isRowDisabled)).map(refOf), anchor.on);
7122
+ return {
7123
+ selection: next,
7124
+ anchor: {
7125
+ ...anchor,
7126
+ base,
7127
+ last: next
7128
+ }
7129
+ };
7130
+ }
7131
+ /**
7132
+ * Shift+arrow: move the far end of the range from row `from` to row `to`. With no
7133
+ * anchor among the rows, the row the cursor leaves becomes one, selecting.
7134
+ */
7135
+ function extendByStep(selection, anchor, rows, from, to, isRowDisabled) {
7136
+ const start = rows[from];
7137
+ return extendRange(selection, anchor !== null && rows.some((entry) => rowKey(entry) === anchor.key) || !start ? anchor : {
7138
+ key: rowKey(start),
7139
+ on: true,
7140
+ base: [...selection],
7141
+ last: [...selection]
7142
+ }, rows, to, isRowDisabled);
7143
+ }
7144
+ /**
7145
+ * Whether to offer every row the filter matches: once every loaded row is picked and
7146
+ * the set holds more than is loaded, until the selection covers a counted set.
7147
+ */
7148
+ function matchingOffer(state) {
7149
+ const { allLoaded, loaded, selected, hasMore, total } = state;
7150
+ return {
7151
+ show: allLoaded && (hasMore || total !== null && total > loaded) && !(total !== null && selected >= total),
7152
+ total
7153
+ };
7154
+ }
7155
+ //#endregion
7156
+ //#region src/column-choice.ts
7157
+ const PREFIX = "sg-widgets:columns:";
7158
+ /** Where a choice is kept: the caller's key, or one per entity type. */
7159
+ function columnsStorageKey(entityType, key) {
7160
+ return key ? key : `${PREFIX}${entityType}`;
7161
+ }
7162
+ /** A stored choice as paths. Null for nothing, an empty list, or anything that is not a list of paths. */
7163
+ function parseColumnChoice(raw) {
7164
+ if (!raw) return null;
7165
+ let value;
7166
+ try {
7167
+ value = JSON.parse(raw);
7168
+ } catch {
7169
+ return null;
7170
+ }
7171
+ if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string")) return null;
7172
+ const paths = [...new Set(value.map((entry) => entry.trim()).filter(Boolean))];
7173
+ return paths.length > 0 ? paths : null;
7174
+ }
7175
+ /** The string a choice is kept as. */
7176
+ function serializeColumnChoice(paths) {
7177
+ return JSON.stringify(paths);
7178
+ }
7179
+ /** The paths of a column list, in order. */
7180
+ function columnPaths(columns) {
7181
+ return columns.map((column) => column.path);
7182
+ }
7183
+ /** True when two path lists name the same columns in the same order. */
7184
+ function sameColumnPaths(a, b) {
7185
+ return a.length === b.length && a.every((path, at) => path === b[at]);
7186
+ }
7187
+ /** The paths a source with `fields` does not read yet. */
7188
+ function unreadPaths(fields, paths) {
7189
+ const read = new Set(fields);
7190
+ return paths.filter((path) => !read.has(path));
7191
+ }
7192
+ /** The known columns in the order `paths` names them. A path none of them carries is dropped. */
7193
+ function arrangeColumns(paths, known) {
7194
+ const byPath = /* @__PURE__ */ new Map();
7195
+ for (const column of known) if (!byPath.has(column.path)) byPath.set(column.path, column);
7196
+ return paths.flatMap((path) => {
7197
+ const column = byPath.get(path);
7198
+ return column ? [column] : [];
7199
+ });
7200
+ }
7201
+ /**
7202
+ * A choice as columns: the ones already resolved are kept as they are, the rest are
7203
+ * resolved from the schema, and a path the type does not have is skipped, so a
7204
+ * choice kept before a field was removed still opens.
7205
+ */
7206
+ async function resolveColumnChoice(schema, entityType, paths, known) {
7207
+ const have = new Set(known.map((column) => column.path));
7208
+ const missing = paths.filter((path) => !have.has(path));
7209
+ const resolved = await Promise.all(missing.map((path) => resolveColumns(schema, entityType, [path]).then((columns) => columns, () => [])));
7210
+ return arrangeColumns(paths, [...known, ...resolved.flat()]);
7211
+ }
7212
+ //#endregion
7015
7213
  //#region src/entity-card.ts
7016
7214
  const DEFAULT_IMAGE_PATH = "image";
7017
7215
  /**
@@ -7987,4 +8185,4 @@ function watchOverflow(list) {
7987
8185
  };
7988
8186
  }
7989
8187
  //#endregion
7990
- export { AppSessionError, COLOR_SENTINEL, DATA_TYPES, DEFAULT_FIELD_ICON, DISPLAY_NAME_FIELDS, ELLIPSIS_CHIPS, ERROR_LABEL, EVENT_LOG_FIELDS, FIELD_ICON_NAMES, FIELD_SCHEMA_OVERRIDES, FLOAT_PRECISION, HIERARCHY_LEAF_LIMIT, INT32_MAX, INT32_MIN, LOADING_LABEL, NAME_HUES, NATIVE_STATUSES, NEGATING_OPERATORS, NOTHING_CHOSEN_LABEL, NO_MATCH_LABEL, NO_ROWS_LABEL, OPERATORS, OPERATORS_BY_TYPE, OPERATOR_LABELS, OVERFLOW_END_VAR, OVERFLOW_START_VAR, PATH_SEPARATOR, PRESS_WINDOW_MS, PROJECT_PICKER_FIELDS, PROXY_METHODS, ProxyClient, RestClient, SCROLL_THRESHOLD, SEARCHING_LABEL, SEARCH_DEBOUNCE_MS, SEARCH_PAGE_SIZE, SORTABLE_HANDLE_ATTRIBUTE, SORTABLE_ID_ATTRIBUTE, STOCK_ICON_CELLS, STOCK_ICON_DATA_URLS, STOCK_ICON_KEYS, STOCK_SPRITE_PATH, SgApiError, THUMBNAIL_PENDING_PATH, TIME_UNITS, TIME_UNIT_LABELS, TREE_STATUS_FIELDS, UNRESOLVED_PATH_LABEL, USER_PICKER_FIELDS, VALUE_SHAPE, appendAt, applyPreset, asCollapseState, asFilterGroup, base64ToBytes, batchResults, breadcrumb, bytesToBase64, canLoadNext, cellValue, clearableForField, collapseAll, collapseStateFrom, collapsedKeys, collectionBottom, collectionView, colorToHex, condition, conditionArity, conditionList, conditionParts, conditionValues, contextFromClient, countActiveConditions, countConditions, countLine, createEntitySearch, createEntitySource, createProxyHandler, createQueryCache, createSchemaService, createSessionTokenAuth, createSgContext, createSortable, createSortableController, createStatusService, createTree, currentPlatform, currentType, defaultCondition, defaultValueFor, deriveFieldOptions, describeCondition, describeEntityCard, describePaging, displayNameOf, editorKindFor, editorNeedsContext, editorPlacementFor, emptyFilter, emptyValueFor, entityCardFields, entityCardSlot, entityDetailUrl, entityKey, entityTypeOptions, errorText, eventLogFilters, expandAll, facetCounts, facetLists, facetPresets, facetScopes, facetShape, facetValues, facetValuesFromGroups, fieldOperators, fieldPathOf, fieldSchemaOverride, fieldText, fileHref, fileNameFromUrl, filterEntityTypes, filterableFields, findCondition, findFacet, firstEnabledIndex, fitChips, flattenRow, focusChip, foregroundFor, formatCurrency, formatDate, formatDateTime, formatDuration, formatFloat, formatNumberInput, formatPercent, formatTimecode, friendlyFieldPath, fromApiDateTime, fromSortString, fromWire, group, groupKeyText, groupRows, groupRowsKeyed, hasFailedPage, hasMorePage, hierarchyEntity, hierarchyLoader, hierarchySearcher, hydrate, iconNameFor, idsForRefs, imageState, initialsOf, intersectStatuses, isBareRef, isBlankCondition, isCollapsed, isDataType, isEditableType, isEmptyFilter, isEmptyValue, isFilterable, isGroupingRefusal, isHiddenPath, isLinkType, isNativeStatus, isNumericType, isOperator, isParseError, isPinned, isProxyMethod, isSortable, isTemporalType, isValidListValue, isoDay, isoDayParts, listStatus, loadEntityCard, loadsOnArrowDown, markOverflow, matchRuns, matchesEveryWord, measureSortable, mergeFilters, moveAt, moveFieldPath, nameColorIndex, nameHue, nameSearchFilter, nativeStatus, nextEnabledIndex, nodeAt, normalizeEventLogEntry, normalizeField, normalizeFields, normalizeHierarchyNode, normalizeSiteUrl, numberDigits, numberDraft, numberSteps, numberWire, operatorLabel, operatorMenu, operatorsFor, overflowEdges, parseBgColor, parseColorInput, parseDurationInput, parseFloatInput, parseInteger, parseNumberInput, parseTextInput, parseTimecodeInput, parseUrlInput, pathLabel, pathOf, pathRefs, pathTypes, pickerKeyIntent, placeholderName, playSortableFlip, pollAppSession, preferencesOf, prependRecent, presetById, presetIdOf, presetsFor, pressGate, projectOfPath, projectPickerFilters, pruneFilterToFields, queryPlan, reachedEnd, referencedPaths, refsForIds, relativeFrom, relativeLuminance, relativeOperator, relativeValue, relativeWindow, removeAt, renderKindFor, replaceAt, requestAppSession, requestGate, resolveColumns, resolveFieldPathOptions, resolveRowFields, resolveTreeFields, rgbToCss, rowCode, rowFields, rowIdOf, rowIsDisabled, rowKey, rowSecondary, rowSubLabel, rowThumbnail, sameCollapse, sameFilters, sameIds, sameRefs, sameSort, scopeToProject, scrollHighlightedIntoView, searchFieldOptions, searchFieldPathOptions, searchKeyIntent, searchTypeMap, searchView, searchWords, secondaryType, selectableRefs, selectionState, serializeSort, setFacet, setFacetPreset, settleStep, shouldLoadNext, sortableAnnouncements, sortableDropIndex, sortableFields, sortableScrollStep, sortableStride, sourceModeFor, spriteStyle, stateLine, statusFieldFor, statusFieldNameFor, statusGlyph, statusLabel, statusPaint, stepNumber, stockIconSource, storedNumber, subLabelType, summariseSelection, supportsEmpty, supportsOperator, thumbnailField, timeUnitField, timeUnitLabel, timeZoneName, toApi3Hash, toApiDate, toApiDateTime, toApiFloat, toColumn, toFilterArray, toRef, toSearchHit, toSortKeys, toSortSpecs, toSortString, toWireGroup, toggleCollapsed, toggleFieldPath, toggleId, toggleRef, traversalTargets, undeclaredField, unformatNumberInput, urlLink, usableStatuses, userPickerFilters, userPickerSearchFields, userPickerSubLabel, userPickerTypes, userSearchFields, validateCondition, valueArity, valueEditorFor, walk, watchHighlight, watchOverflow, withAddedListValue, withListValue, withRelativeWindow, withSelectedPinned, withoutListValue, withoutPaths };
8188
+ export { AppSessionError, COLOR_SENTINEL, DATA_TYPES, DEFAULT_FIELD_ICON, DISPLAY_NAME_FIELDS, ELLIPSIS_CHIPS, ERROR_LABEL, EVENT_LOG_FIELDS, FIELD_ICON_NAMES, FIELD_SCHEMA_OVERRIDES, FLOAT_PRECISION, HIERARCHY_LEAF_LIMIT, INT32_MAX, INT32_MIN, LOADING_LABEL, NAME_HUES, NATIVE_STATUSES, NEGATING_OPERATORS, NOTHING_CHOSEN_LABEL, NO_MATCH_LABEL, NO_ROWS_LABEL, OPERATORS, OPERATORS_BY_TYPE, OPERATOR_LABELS, OVERFLOW_END_VAR, OVERFLOW_START_VAR, PATH_SEPARATOR, PRESS_WINDOW_MS, PROJECT_PICKER_FIELDS, PROXY_METHODS, ProxyClient, RestClient, SCROLL_THRESHOLD, SEARCHING_LABEL, SEARCH_DEBOUNCE_MS, SEARCH_PAGE_SIZE, SORTABLE_HANDLE_ATTRIBUTE, SORTABLE_ID_ATTRIBUTE, STOCK_ICON_CELLS, STOCK_ICON_DATA_URLS, STOCK_ICON_KEYS, STOCK_SPRITE_PATH, SgApiError, THUMBNAIL_PENDING_PATH, TIME_UNITS, TIME_UNIT_LABELS, TREE_STATUS_FIELDS, UNRESOLVED_PATH_LABEL, USER_PICKER_FIELDS, VALUE_SHAPE, appendAt, applyPreset, arrangeColumns, asCollapseState, asFilterGroup, base64ToBytes, batchResults, breadcrumb, bytesToBase64, canLoadNext, cellValue, clearableForField, collapseAll, collapseStateFrom, collapsedKeys, collectionBottom, collectionView, colorToHex, columnPaths, columnsStorageKey, condition, conditionArity, conditionList, conditionParts, conditionValues, contextFromClient, countActiveConditions, countConditions, countLine, createEntitySearch, createEntitySource, createProxyHandler, createQueryCache, createSchemaService, createSessionTokenAuth, createSgContext, createSortable, createSortableController, createStatusService, createTree, currentPlatform, currentType, defaultCondition, defaultValueFor, deriveFieldOptions, describeCondition, describeEntityCard, describePaging, displayNameOf, editorKindFor, editorNeedsContext, editorPlacementFor, emptyFilter, emptyValueFor, entityCardFields, entityCardSlot, entityDetailUrl, entityKey, entityTypeOptions, errorText, eventLogFilters, expandAll, extendByStep, extendRange, facetCounts, facetLists, facetPresets, facetScopes, facetShape, facetValues, facetValuesFromGroups, fieldOperators, fieldPathOf, fieldSchemaOverride, fieldText, fileHref, fileNameFromUrl, filterEntityTypes, filterableFields, findCondition, findFacet, firstEnabledIndex, fitChips, flattenRow, focusChip, foregroundFor, formatCurrency, formatDate, formatDateTime, formatDuration, formatFloat, formatNumberInput, formatPercent, formatTimecode, friendlyFieldPath, fromApiDateTime, fromSortString, fromWire, gestureOf, group, groupKeyText, groupRows, groupRowsKeyed, hasFailedPage, hasMorePage, hierarchyEntity, hierarchyLoader, hierarchySearcher, hydrate, iconNameFor, idsForRefs, imageState, initialsOf, intersectStatuses, isBareRef, isBlankCondition, isCollapsed, isDataType, isEditableType, isEmptyFilter, isEmptyValue, isFilterable, isGroupingRefusal, isHiddenPath, isLinkType, isNativeStatus, isNumericType, isOperator, isParseError, isPinned, isProxyMethod, isSortable, isTemporalType, isValidListValue, isoDay, isoDayParts, listStatus, loadEntityCard, loadsOnArrowDown, markOverflow, matchRuns, matchesEveryWord, matchingOffer, measureSortable, mergeFilters, moveAt, moveFieldPath, nameColorIndex, nameHue, nameSearchFilter, nativeStatus, nextEnabledIndex, nodeAt, normalizeEventLogEntry, normalizeField, normalizeFields, normalizeHierarchyNode, normalizeSiteUrl, numberDigits, numberDraft, numberSteps, numberWire, operatorLabel, operatorMenu, operatorsFor, overflowEdges, parseBgColor, parseColorInput, parseColumnChoice, parseDurationInput, parseFloatInput, parseInteger, parseNumberInput, parseTextInput, parseTimecodeInput, parseUrlInput, pathLabel, pathOf, pathRefs, pathTypes, pickerKeyIntent, placeholderName, playSortableFlip, pollAppSession, preferencesOf, prependRecent, presetById, presetIdOf, presetsFor, pressGate, projectOfPath, projectPickerFilters, pruneFilterToFields, queryPlan, reachedEnd, referencedPaths, refsForIds, relativeFrom, relativeLuminance, relativeOperator, relativeValue, relativeWindow, removeAt, renderKindFor, replaceAt, requestAppSession, requestGate, resolveColumnChoice, resolveColumns, resolveFieldPathOptions, resolveRowFields, resolveTreeFields, rgbToCss, rowCode, rowFields, rowIdOf, rowIsDisabled, rowKey, rowSecondary, rowSubLabel, rowThumbnail, sameCollapse, sameColumnPaths, sameFilters, sameIds, sameRefs, sameSort, scopeToProject, scrollHighlightedIntoView, searchFieldOptions, searchFieldPathOptions, searchKeyIntent, searchTypeMap, searchView, searchWords, secondaryType, selectableRefs, selectionKeyIntent, selectionState, serializeColumnChoice, serializeSort, setFacet, setFacetPreset, setRefs, settleStep, shouldLoadNext, sortableAnnouncements, sortableDropIndex, sortableFields, sortableScrollStep, sortableStride, sourceModeFor, spriteStyle, stateLine, statusFieldFor, statusFieldNameFor, statusGlyph, statusLabel, statusPaint, stepNumber, stockIconSource, storedNumber, subLabelType, summariseSelection, supportsEmpty, supportsOperator, thumbnailField, timeUnitField, timeUnitLabel, timeZoneName, toApi3Hash, toApiDate, toApiDateTime, toApiFloat, toColumn, toFilterArray, toRef, toSearchHit, toSortKeys, toSortSpecs, toSortString, toWireGroup, toggleCollapsed, toggleFieldPath, toggleId, toggleRef, toggleRow, traversalTargets, undeclaredField, unformatNumberInput, unreadPaths, urlLink, usableStatuses, userPickerFilters, userPickerSearchFields, userPickerSubLabel, userPickerTypes, userSearchFields, validateCondition, valueArity, valueEditorFor, walk, watchHighlight, watchOverflow, withAddedListValue, withListValue, withRelativeWindow, withSelectedPinned, withoutListValue, withoutPaths };
package/dist/mock.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as UploadFile, At as TextSearchFilter, D as TextSearchRow, H as StatusRecord, S as SummarizeResult, _ as SearchOptions, a as EntityTypeInfo, b as SgClient, c as EventLogResult, d as HierarchyPath, ft as FieldSchema, i as EntityRow, j as UploadResult, k as ThreadRow, l as FollowingOptions, n as BatchResult, s as EventLogOptions, t as BatchRequest, u as HierarchyNode, v as SearchResult, wt as EntityRef, x as SummarizeOptions } from "./client-B2PCySg9.mjs";
1
+ import { A as ThreadRow, C as SummarizeResult, M as UploadResult, O as TextSearchRow, S as SummarizeOptions, Tt as EntityRef, U as StatusRecord, a as EntityTypeInfo, c as EventLogResult, d as HierarchyPath, h as ReadOptions, i as EntityRow, j as UploadFile, jt as TextSearchFilter, l as FollowingOptions, n as BatchResult, pt as FieldSchema, s as EventLogOptions, t as BatchRequest, u as HierarchyNode, v as SearchOptions, x as SgClient, y as SearchResult } from "./client-CP9sWEVZ.mjs";
2
2
  //#region src/mock.d.ts
3
3
  /** What the next call should throw instead of answering. */
4
4
  export interface MockFailure {
@@ -38,6 +38,10 @@ export declare class MockClient implements SgClient {
38
38
  private readonly retired;
39
39
  /** Rows a batch created with no `project`: no read reaches them, a delete does (report 001). */
40
40
  private readonly unreadable;
41
+ /** What a Task delete did to other rows, by `Task:id`, for its revive to undo (089_task_delete_side_effects). */
42
+ private readonly cascades;
43
+ /** The highest id handed out per type, so an erased row's id is never reused. */
44
+ private readonly issued;
41
45
  private deletes;
42
46
  constructor(options?: MockClientOptions);
43
47
  /**
@@ -53,6 +57,7 @@ export declare class MockClient implements SgClient {
53
57
  fields(entityType: string, projectId?: number): Promise<Record<string, FieldSchema>>;
54
58
  fieldWithProject(entityType: string, field: string, projectId: number): Promise<FieldSchema>;
55
59
  search(entityType: string, options: SearchOptions): Promise<SearchResult>;
60
+ read(entityType: string, id: number, options?: ReadOptions): Promise<EntityRow>;
56
61
  textSearch(text: string, entityTypes: Record<string, TextSearchFilter>, page?: {
57
62
  size?: number;
58
63
  number?: number;
@@ -118,13 +123,50 @@ export declare class MockClient implements SgClient {
118
123
  private createRow;
119
124
  /**
120
125
  * Retire one row: reads skip it and a second delete is 404 (delete_entity_type_id).
121
- * The mock retires only the row; what a delete does to rows that link to it
122
- * (probe 060, 089_task_delete_side_effects) is not modelled.
126
+ * A Task takes its TaskDependency rows with it and leaves `Version.sg_task` and
127
+ * `PublishedFile.task` null until its revive (089_task_delete_side_effects), alone or
128
+ * in a batch (103_batch_delete_revive). A TaskTemplate retires its tasks
129
+ * (entity_types/TaskTemplate). What a Shot delete does to its Versions (probe 060)
130
+ * is not modelled.
123
131
  */
124
132
  delete(entityType: string, id: number): Promise<void>;
125
133
  private deleteRow;
126
- /** Bring a retired row back with its values; `false` for a row that is already live (post_entity_type_id). */
134
+ /**
135
+ * Bring a retired row back with its values; `false` for a row that is already live
136
+ * (post_entity_type_id). A Task gets back what its delete took (089_task_delete_side_effects).
137
+ * A TaskDependency whose pair is linked again refuses, the pair being a unique index
138
+ * (095_dependency_remove_undo). A TaskTemplate's tasks stay retired: unmeasured.
139
+ */
127
140
  revive(entityType: string, id: number): Promise<boolean>;
141
+ private retire;
142
+ private unretire;
143
+ /** Remove a row for good: no read reaches it and no revive brings it back. */
144
+ private erase;
145
+ private live;
146
+ /** The live TaskDependency rows with this Task at either end. */
147
+ private edgesOf;
148
+ /** Whether a live row already links this row's pair. */
149
+ private pairTaken;
150
+ /** Whether `from` depends on `target`, directly or through other Tasks. */
151
+ private dependsOn;
152
+ /**
153
+ * The checks a TaskDependency create makes: one of four types, one row per pair, and
154
+ * no loop of any length (085_task_dependency_types, 107_dependency_three_task_loop).
155
+ */
156
+ private checkEdge;
157
+ /**
158
+ * A write to `upstream_tasks` or `downstream_tasks`: a new neighbour gets a row of the
159
+ * default type and no offset, a dropped one's row is erased, not retired
160
+ * (086_batch_tasks_with_dependencies, 095_dependency_remove_undo).
161
+ */
162
+ private writeEdges;
163
+ /** Where the written field is one side of a two-sided link, make the other side agree. */
164
+ private mirror;
165
+ /**
166
+ * What the server derives from other rows: a Task's two edge lists from the
167
+ * TaskDependency rows, their ids and name, and a template's task count, a string.
168
+ */
169
+ private derive;
128
170
  /**
129
171
  * Apply the requests in order, and undo all of them when one fails (recipes/002).
130
172
  * A create or update row carries the record under `data`; a delete row is flat.
@@ -147,6 +189,13 @@ export declare class MockClient implements SgClient {
147
189
  * missing key (field_types/entity).
148
190
  */
149
191
  private checkLink;
192
+ /**
193
+ * Values the server checks beyond their shape. A status code must be in the site-wide
194
+ * `valid_values`, hidden ones included, and a create or any batch request wraps the
195
+ * refusal (field_types/status_list, recipes/002, 094_permission_preflight). A
196
+ * TaskTemplate's `entity_type` must name a type (entity_types/TaskTemplate).
197
+ */
198
+ private checkValue;
150
199
  /** The next free id of a type, which is what a create takes. */
151
200
  private nextId;
152
201
  /** The reverse view of a link the server fills in: a Reply lands in `Note.replies`. */