@lavalogic/scoria 0.22.4 → 0.22.6

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.
@@ -1,4 +1,4 @@
1
1
  import type { DimensionInputProps } from './DimensionInputProps.js';
2
- declare const DimensionInput: import("svelte").Component<DimensionInputProps, {}, "x" | "z" | "y" | "inputRef">;
2
+ declare const DimensionInput: import("svelte").Component<DimensionInputProps, {}, "x" | "y" | "z" | "inputRef">;
3
3
  type DimensionInput = ReturnType<typeof DimensionInput>;
4
4
  export default DimensionInput;
@@ -1,6 +1,9 @@
1
1
  <svelte:options runes />
2
2
 
3
- <script lang="ts" module>
3
+ <script
4
+ lang="ts"
5
+ module
6
+ >
4
7
  interface QuerySelectPropsAsObjectCommonProps<V extends object, VP extends ValueProp<V>> {
5
8
  labelProp: NonNullableKey<V>;
6
9
  valueProp: VP;
@@ -25,7 +28,7 @@
25
28
 
26
29
  export interface QuerySelectPropsAsObject<
27
30
  V extends object,
28
- VP extends ValueProp<V>
31
+ VP extends ValueProp<V>,
29
32
  > extends QuerySelectPropsAsObjectCommonProps<V, VP> {
30
33
  valueAsObject: true;
31
34
  value: V | null;
@@ -33,11 +36,10 @@
33
36
 
34
37
  export interface QuerySelectPropsAsPrimitive<
35
38
  V extends object,
36
- VP extends ValueProp<V>
39
+ VP extends ValueProp<V>,
37
40
  > extends QuerySelectPropsAsObjectCommonProps<V, VP> {
38
41
  valueAsObject: false;
39
42
  value: V[VP] | null;
40
- options: Array<V>;
41
43
  }
42
44
 
43
45
  export type QuerySelectProps<V extends object, VP extends ValueProp<V>> =
@@ -46,7 +48,10 @@
46
48
  </script>
47
49
 
48
50
  <!-- #region Script -->
49
- <script lang="ts" generics="V extends object, VP extends ValueProp<V>">
51
+ <script
52
+ lang="ts"
53
+ generics="V extends object, VP extends ValueProp<V>"
54
+ >
50
55
  import { ToastContext } from '../Contexts/ToastContext.svelte.js';
51
56
 
52
57
  import { dev } from '$app/environment';
@@ -77,7 +82,7 @@
77
82
  options = $bindable<Array<V>>([]),
78
83
  isValid,
79
84
  onchange,
80
- onfocus
85
+ onfocus,
81
86
  }: QuerySelectProps<V, VP> = $props();
82
87
 
83
88
  export function forceQuery() {
@@ -120,7 +125,7 @@
120
125
  //best-effort solution. Not a good one
121
126
  // eslint-disable-next-line @typescript-eslint/no-base-to-string
122
127
  [labelProp]: selectedValue.toString(),
123
- [valueProp]: selectedValue
128
+ [valueProp]: selectedValue,
124
129
  } as V);
125
130
  }
126
131
  }
@@ -372,7 +377,7 @@
372
377
  }}
373
378
  icon={{
374
379
  name: 'close-menu-cross',
375
- colour: Colour['$ui-blue-9']
380
+ colour: Colour['$ui-blue-9'],
376
381
  }}
377
382
  />
378
383
  {/if}
@@ -384,7 +389,7 @@
384
389
  size={Size.Small}
385
390
  icon={{
386
391
  name: isExpanded ? 'chevron-up' : 'chevron-down',
387
- colour: Colour['$ui-blue-9']
392
+ colour: Colour['$ui-blue-9'],
388
393
  }}
389
394
  />
390
395
  </div>
@@ -24,7 +24,6 @@ export interface QuerySelectPropsAsObject<V extends object, VP extends ValueProp
24
24
  export interface QuerySelectPropsAsPrimitive<V extends object, VP extends ValueProp<V>> extends QuerySelectPropsAsObjectCommonProps<V, VP> {
25
25
  valueAsObject: false;
26
26
  value: V[VP] | null;
27
- options: Array<V>;
28
27
  }
29
28
  export type QuerySelectProps<V extends object, VP extends ValueProp<V>> = QuerySelectPropsAsObject<V, VP> | QuerySelectPropsAsPrimitive<V, VP>;
30
29
  import type { NonNullableKey, ValueProp } from '../Types/Internal/Misc.js';
@@ -1,12 +1,12 @@
1
1
  import type { Pixels } from '../../../../../Types/Internal/Misc.js';
2
2
  import type { SelectOption } from '../../../../../Types/Internal/SelectOption.js';
3
3
  import type { Snippet } from 'svelte';
4
+ import type { MemoryColumnIndex } from '../../Coordinates/ColumnIndices.js';
4
5
  import type { FilterFn } from '../../Filtering/FilterFn.js';
5
6
  import type { FilterValueType } from '../../Filtering/FilterValueType.js';
6
7
  import { ColumnType } from '../ColumnType.js';
7
8
  import type { AccessorFn } from './AccessorFn.js';
8
9
  import type { ValidationFn } from './ValidationFn.js';
9
- import type { MemoryColumnIndex } from '../../Coordinates/ColumnIndices.js';
10
10
  export interface ColumnDefProps<T extends object, in FilterFnType, out OptionsType> {
11
11
  id: string;
12
12
  header: string | Snippet;
@@ -56,9 +56,15 @@ export declare abstract class ColumnDef<T extends object, in FilterFnType = neve
56
56
  get filterValueType(): FilterValueType | undefined;
57
57
  set filterValueType(v: FilterValueType | undefined);
58
58
  readonly getDisplayValue: ((item: T, index: number) => string | null | Promise<string | null>) | undefined;
59
- toJSON(): object;
59
+ toJSON(): ColumnJSONRepresentation;
60
60
  readonly isEditable: (item: T, index: number) => Promise<boolean>;
61
61
  readonly resizable: boolean;
62
62
  readonly header: string | Snippet;
63
63
  readonly getOptions?: () => Array<SelectOption<OptionsType>> | Promise<Array<SelectOption<OptionsType>>>;
64
64
  }
65
+ export interface ColumnJSONRepresentation {
66
+ columnType: ColumnType;
67
+ id: string;
68
+ header: string;
69
+ filterValueType: FilterValueType | undefined;
70
+ }
@@ -66,7 +66,7 @@ export class ColumnDef {
66
66
  console.warn(`Column ${this.id} is not sortable`);
67
67
  return;
68
68
  }
69
- this._isResizing = v;
69
+ this._visible = v;
70
70
  }
71
71
  _filterValueType;
72
72
  get filterValueType() {
@@ -77,7 +77,12 @@ export class ColumnDef {
77
77
  }
78
78
  getDisplayValue;
79
79
  toJSON() {
80
- return { columnType: this.columnType, id: this.id, header: this.header };
80
+ return {
81
+ columnType: this.columnType,
82
+ id: this.id,
83
+ header: this.header.toString(),
84
+ filterValueType: this.filterValueType,
85
+ };
81
86
  }
82
87
  isEditable;
83
88
  resizable;
@@ -1,11 +1,11 @@
1
1
  import type { SortingState } from '../../DataRepository/SortingState.js';
2
2
  import type { JSONColumnPinningState } from '../JSONColumnPinningState.js';
3
3
  import type { VisibilityState } from '../VisibilityState.js';
4
- import type { ColumnDef } from './ColumnDef.svelte.js';
5
- export interface JSONColumnDefSet<T extends object> {
4
+ import type { ColumnJSONRepresentation } from './ColumnDef.svelte.js';
5
+ export interface JSONColumnDefSet {
6
6
  name: string;
7
7
  sortingState: SortingState;
8
8
  visibilityState: VisibilityState;
9
9
  columnPinningState: JSONColumnPinningState;
10
- columnDefs: Array<ColumnDef<T>>;
10
+ columnDefs: Array<ColumnJSONRepresentation>;
11
11
  }
@@ -1,6 +1,9 @@
1
1
  import type { TableCell } from '../Columns/TableCell.js';
2
2
  export interface Row<T extends object> {
3
- getValue: (columnId: string) => Promise<unknown>;
3
+ getValue: {
4
+ <K extends keyof T>(columnId: K): T[K] | Promise<T[K]>;
5
+ (columnId: string): unknown | Promise<unknown>;
6
+ };
4
7
  original: T;
5
8
  visibleIndex: number;
6
9
  originalIndex: number;
@@ -1,5 +1,5 @@
1
1
  import { browser, dev } from '$app/environment';
2
- import { asyncAll, asyncForEach, asyncMap, devCatch, getCanvasContext, } from '../../../../Helpers/Helpers.svelte.js';
2
+ import { asyncAll, asyncForEach, asyncMap, devCatch, getCanvasContext, isKeyOf, } from '../../../../Helpers/Helpers.svelte.js';
3
3
  import { tick, untrack } from 'svelte';
4
4
  import { SvelteMap } from 'svelte/reactivity';
5
5
  import { ColumnType } from '../Columns/ColumnType.js';
@@ -345,6 +345,9 @@ export class TableContext {
345
345
  if (presets[0] && areDefsEquivalent(defs, presets[0].columnDefs)) {
346
346
  return this.reassignDefsToPresets(presets).then((p) => p);
347
347
  }
348
+ else if (dev && presets[0]) {
349
+ console.warn(`invalid presets:`, presets);
350
+ }
348
351
  }
349
352
  }
350
353
  return null;
@@ -1163,7 +1166,7 @@ export class TableContext {
1163
1166
  }
1164
1167
  };
1165
1168
  resetSelectedItems = () => {
1166
- this._selectedItems = new SvelteMap();
1169
+ this._selectedItems.clear();
1167
1170
  };
1168
1171
  selectAllInCurrentPage = async () => {
1169
1172
  void this.paginationRepo?.pageStartIndex;
@@ -1173,18 +1176,20 @@ export class TableContext {
1173
1176
  ? Math.min(this.paginationRepo.pageEndIndexExclusive, sortedData.length)
1174
1177
  : sortedData.length;
1175
1178
  // Will be doing one full reassignment to this.selectedItems to avoid svelteMap redraws
1176
- const cloned = new SvelteMap(this.selectedItems);
1179
+ // const cloned = new SvelteMap(this.selectedItems);
1180
+ const sel = this.selectedItems; // HACK: keep the same svelteMap going so that we can support setSelectionMap()
1181
+ // if this is deemed problematic, we'll need to find another way to ask for a new map from the context consumer
1177
1182
  const pending = [];
1178
1183
  if (this.allSelectedInCurrentPage) {
1179
1184
  for (let i = pageStartIndex; i < pageEndIndexExclusive; i++) {
1180
1185
  const raw = this._cachedKey(sortedData[i]);
1181
1186
  if (raw instanceof Promise) {
1182
1187
  pending.push(raw.then((key) => {
1183
- cloned.delete(key);
1188
+ sel.delete(key);
1184
1189
  }));
1185
1190
  }
1186
1191
  else {
1187
- cloned.delete(raw);
1192
+ sel.delete(raw);
1188
1193
  }
1189
1194
  }
1190
1195
  }
@@ -1202,10 +1207,10 @@ export class TableContext {
1202
1207
  const raw = this._cachedKey(item);
1203
1208
  if (raw instanceof Promise) {
1204
1209
  return raw.then((key) => {
1205
- cloned.set(key, item);
1210
+ sel.set(key, item);
1206
1211
  });
1207
1212
  }
1208
- cloned.set(raw, item);
1213
+ sel.set(raw, item);
1209
1214
  };
1210
1215
  const r = s instanceof Promise ? s.then(doSet) : doSet(s);
1211
1216
  if (r instanceof Promise) {
@@ -1219,11 +1224,11 @@ export class TableContext {
1219
1224
  const raw = this._cachedKey(item);
1220
1225
  if (raw instanceof Promise) {
1221
1226
  pending.push(raw.then((key) => {
1222
- cloned.set(key, item);
1227
+ sel.set(key, item);
1223
1228
  }));
1224
1229
  }
1225
1230
  else {
1226
- cloned.set(raw, item);
1231
+ sel.set(raw, item);
1227
1232
  }
1228
1233
  }
1229
1234
  }
@@ -1231,7 +1236,8 @@ export class TableContext {
1231
1236
  if (pending.length > 0) {
1232
1237
  await Promise.all(pending);
1233
1238
  }
1234
- this._selectedItems = cloned;
1239
+ // HACK
1240
+ // this._selectedItems = cloned;
1235
1241
  };
1236
1242
  onHighlightAll = () => {
1237
1243
  if (this.allHighlighted) {
@@ -1956,6 +1962,9 @@ export class TableContext {
1956
1962
  const jsonFriendly = newPresets.map((preset) => {
1957
1963
  return {
1958
1964
  ...preset,
1965
+ columnDefs: preset.columnDefs.map((it) => {
1966
+ return { ...it.toJSON(), header: it.header.toString() };
1967
+ }),
1959
1968
  columnPinningState: {
1960
1969
  left: [...(preset.columnPinningState.left?.entries() ?? [])],
1961
1970
  right: [...(preset.columnPinningState.right?.entries() ?? [])],
@@ -1978,12 +1987,15 @@ export class TableContext {
1978
1987
  // #region private methods
1979
1988
  createRow(item, index, unsortedIndex) {
1980
1989
  const row = {
1981
- getValue: async (key) => {
1982
- const gotValue = await this.columnDefsById.get(key)?.accessorFn?.(item, unsortedIndex);
1990
+ getValue: (key) => {
1991
+ const gotValue = this.columnDefsById.get(key)?.accessorFn?.(item, unsortedIndex);
1983
1992
  if (gotValue !== undefined) {
1984
1993
  return gotValue;
1985
1994
  }
1986
- return item[key];
1995
+ if (isKeyOf(key, item)) {
1996
+ return item[key];
1997
+ }
1998
+ throw new Error(`Row had neither an accessor function or an id that can index the item object`);
1987
1999
  },
1988
2000
  original: item,
1989
2001
  visibleIndex: index,
@@ -2516,14 +2528,14 @@ export class TableContext {
2516
2528
  return {
2517
2529
  ...preset,
2518
2530
  columnPinningState: adaptJSONPinningState(preset.columnPinningState),
2519
- columnDefs: preset.columnDefs.map((def, index) => {
2531
+ columnDefs: preset.columnDefs.map((def) => {
2520
2532
  const realDef = def.columnType == ColumnType.RowSelect || def.columnType == ColumnType.Actions
2521
2533
  ? adjustedDefs.find((it) => it.columnType === def.columnType)
2522
2534
  : asMap.get(def.id);
2523
2535
  if (!realDef) {
2524
2536
  throw new Error('Could not find equivalent column def:', { cause: def });
2525
2537
  }
2526
- return (preset.columnDefs[index] = realDef);
2538
+ return realDef;
2527
2539
  }),
2528
2540
  };
2529
2541
  });
@@ -211,16 +211,16 @@ export class LocalTableDataRepository extends TableDataRepository {
211
211
  numberFilter = async (row, columnId, // & keyof T,
212
212
  values) => {
213
213
  const columnValue = await row.getValue(columnId);
214
- const filterType = this.filterModes.get(columnId) ?? NumberDateFilterMode.In;
214
+ const mode = this.filterModes.get(columnId) ?? NumberDateFilterMode.In;
215
215
  const isValueInvalid = columnValue == null || typeof columnValue != 'number' || isNaN(columnValue);
216
- if (filterType == NumberDateFilterMode.null) {
216
+ if (mode == NumberDateFilterMode.null) {
217
217
  // TODO test
218
218
  return isValueInvalid;
219
219
  }
220
220
  if (isValueInvalid || typeof columnValue != 'number') {
221
- return inclusiveFilterModes.has(filterType);
221
+ return inclusiveFilterModes.has(mode);
222
222
  }
223
- switch (filterType) {
223
+ switch (mode) {
224
224
  case NumberDateFilterMode.Equals: {
225
225
  const [min] = TableDataRepository.getMinMax(values);
226
226
  return min == undefined || columnValue === min;
@@ -1,3 +1,6 @@
1
+ import type { DefsWrapper } from '../Components/Table/Types/Columns/DefsWrapper.js';
2
+ import { TableContext } from '../Components/Table/Types/Context/TableContext.svelte.js';
3
+ import type { Primitive } from '../Components/Table/Types/Context/TableInitOptions.js';
1
4
  import type { CustomFilter } from '../Components/Table/Types/Filtering/CustomFilter.js';
2
5
  import type { InputDate, InputDateWithTime, SQLDate } from '../Types/Internal/Misc.js';
3
6
  import type { RefWrapper } from '../Types/Internal/RefWrapper.js';
@@ -52,3 +55,12 @@ export declare function isDateTuple(value: unknown): value is [Date | null, Date
52
55
  export declare function isNumericArray(value: unknown): value is Array<number | null>;
53
56
  export declare function isValidityTuple(v: Validity | ValidityWrapper | undefined): v is ValidityWrapper;
54
57
  export declare const loadingText = "loading\u2026";
58
+ export declare function isKeyOf<T extends object>(key: string, obj: T): key is string & keyof T;
59
+ export interface ICreateTableArgs<T extends object, RowIdType extends Primitive> {
60
+ name: string;
61
+ defs: DefsWrapper<T>;
62
+ data: RefWrapper<Array<T>>;
63
+ getUserId: () => string | undefined;
64
+ selectionExtractor: (item: T) => RowIdType | Promise<RowIdType>;
65
+ }
66
+ export declare function createLocalTable<T extends object, RowIdType extends Primitive>(args: ICreateTableArgs<T, RowIdType>): TableContext<T, RowIdType>;
@@ -1,4 +1,6 @@
1
1
  import { dev } from '$app/environment';
2
+ import { TableContext } from '../Components/Table/Types/Context/TableContext.svelte.js';
3
+ import { LocalTableDataRepository } from '../Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.js';
2
4
  import { CustomFilterType } from '../Components/Table/Types/Filtering/CustomFilterType.js';
3
5
  import { Sizing } from '../scss/sizing.js';
4
6
  import { untrack } from 'svelte';
@@ -75,10 +77,12 @@ export function SQLFriendly(date) {
75
77
  }
76
78
  export function SQLFriendlyWithLocalTime(date, timeDate) {
77
79
  if (typeof date === 'string') {
78
- date = new SvelteDate(date);
80
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
81
+ date = new Date(date);
79
82
  }
80
83
  if (typeof timeDate === 'string') {
81
- timeDate = new SvelteDate(date);
84
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
85
+ timeDate = new Date(timeDate);
82
86
  }
83
87
  return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date
84
88
  .getDate()
@@ -407,3 +411,13 @@ export function isValidityTuple(v) {
407
411
  return v != null && typeof v == 'object';
408
412
  }
409
413
  export const loadingText = 'loading…';
414
+ export function isKeyOf(key, obj) {
415
+ return key in obj;
416
+ }
417
+ export function createLocalTable(args) {
418
+ const localRepo = new LocalTableDataRepository(args.name, args.data, args.getUserId);
419
+ return TableContext.init(args.defs, args.name, localRepo, {
420
+ selectionExtractor: args.selectionExtractor,
421
+ getUserId: args.getUserId,
422
+ });
423
+ }
package/dist/index.d.ts CHANGED
@@ -132,7 +132,7 @@ export { TooltipContext } from './Contexts/TooltipContext.svelte.js';
132
132
  export { UntypedInputContext } from './Contexts/UntypedInputContext.svelte.js';
133
133
  export { Delay } from './Delay/Delay.js';
134
134
  export { DATAMatrix } from './Helpers/Datamatrix.js';
135
- export { asyncAll, asyncEvery, asyncFilter, asyncFilterIndices, asyncFlatMap, asyncForEach, asyncMap, asyncSleep, asyncSome, autoPluralise, devCatch, generateShortUUID, generateUUID, getCanvasContext, getErrorMessage, gridItem, isDateTuple, isNumericArray, isValidEmailAddress, loadingText, localTimeFormat, passthrough, refWrapper, SQLFriendly, SQLFriendlyWithLocalTime, vowels, } from './Helpers/Helpers.svelte.js';
135
+ export { asyncAll, asyncEvery, asyncFilter, asyncFilterIndices, asyncFlatMap, asyncForEach, asyncMap, asyncSleep, asyncSome, autoPluralise, createLocalTable, devCatch, generateShortUUID, generateUUID, getCanvasContext, getErrorMessage, gridItem, isDateTuple, isNumericArray, isValidEmailAddress, loadingText, localTimeFormat, passthrough, refWrapper, SQLFriendly, SQLFriendlyWithLocalTime, vowels, type ICreateTableArgs, } from './Helpers/Helpers.svelte.js';
136
136
  export { type INamed } from './Helpers/INamed.js';
137
137
  export { AttributeOperation } from './Types/Internal/AttributeOperation.js';
138
138
  export { type BigRadioOption } from './Types/Internal/BigRadioOption.js';
package/dist/index.js CHANGED
@@ -132,7 +132,7 @@ export { TooltipContext } from './Contexts/TooltipContext.svelte.js';
132
132
  export { UntypedInputContext } from './Contexts/UntypedInputContext.svelte.js';
133
133
  export { Delay } from './Delay/Delay.js';
134
134
  export { DATAMatrix } from './Helpers/Datamatrix.js';
135
- export { asyncAll, asyncEvery, asyncFilter, asyncFilterIndices, asyncFlatMap, asyncForEach, asyncMap, asyncSleep, asyncSome, autoPluralise, devCatch, generateShortUUID, generateUUID, getCanvasContext, getErrorMessage, gridItem, isDateTuple, isNumericArray, isValidEmailAddress, loadingText, localTimeFormat, passthrough, refWrapper, SQLFriendly, SQLFriendlyWithLocalTime, vowels, } from './Helpers/Helpers.svelte.js';
135
+ export { asyncAll, asyncEvery, asyncFilter, asyncFilterIndices, asyncFlatMap, asyncForEach, asyncMap, asyncSleep, asyncSome, autoPluralise, createLocalTable, devCatch, generateShortUUID, generateUUID, getCanvasContext, getErrorMessage, gridItem, isDateTuple, isNumericArray, isValidEmailAddress, loadingText, localTimeFormat, passthrough, refWrapper, SQLFriendly, SQLFriendlyWithLocalTime, vowels, } from './Helpers/Helpers.svelte.js';
136
136
  export {} from './Helpers/INamed.js';
137
137
  export { AttributeOperation } from './Types/Internal/AttributeOperation.js';
138
138
  export {} from './Types/Internal/BigRadioOption.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lavalogic/scoria",
3
3
  "description": "Svelte components used for the FloWMS Web Frontend",
4
- "version": "0.22.4",
4
+ "version": "0.22.6",
5
5
  "publishConfig": {
6
6
  "access": "restricted"
7
7
  },