@lavalogic/scoria 0.38.2 → 0.38.4

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.
@@ -14,7 +14,7 @@
14
14
  import { Size } from '../../../Types/Internal/Size.js';
15
15
  import type { TabOption } from '../../../Types/Internal/TabOption.js';
16
16
  import { Variant } from '../../../Types/Internal/Variant.js';
17
- import { getContext } from 'svelte';
17
+ import { getContext, onMount } from 'svelte';
18
18
  import { TableContext } from '../Types/Context/TableContext.svelte.js';
19
19
  import type { Primitive } from '../Types/Context/TableInitOptions.js';
20
20
  import type { DatatableView } from '../Types/Persistence/DatatableView.js';
@@ -48,6 +48,10 @@
48
48
  // errors inline in its own body.
49
49
  let errorMessage = $state<string | null>(null);
50
50
 
51
+ // True while the open-time fetch of saved views is in flight, so the
52
+ // My-tab shows "Loading…" rather than the "nothing saved yet" message.
53
+ let loadingViews = $state(false);
54
+
51
55
  // Whether remote saved views are available at all. A table created
52
56
  // without `datatableUuid` / `remoteLayouts` opts out of remote views;
53
57
  // the modal then renders a graceful "unavailable" empty state and
@@ -88,11 +92,34 @@
88
92
  errorMessage = null;
89
93
  try {
90
94
  await action();
91
- } catch {
92
- errorMessage = failureMessage;
95
+ } catch (e) {
96
+ // Surface the underlying error rather than swallowing it: the
97
+ // generic message alone has made failures hard to diagnose. The
98
+ // full error (with stack) goes to the console; its message is
99
+ // appended to the banner so it is visible without devtools.
100
+ console.error('[TableConfigurationModal] action failed:', e);
101
+ errorMessage = e instanceof Error ? `${failureMessage} (${e.message})` : failureMessage;
93
102
  }
94
103
  }
95
104
 
105
+ // Fetch the saved views fresh every time the modal opens. The boot-time
106
+ // fetch can miss (it races table construction / auth readiness), so the
107
+ // modal cannot rely on `_viewState.savedViews` already being populated -
108
+ // it pulls `GET /datatable-state` itself on open. A failure surfaces in
109
+ // the inline error banner via `guard` rather than being swallowed.
110
+ onMount(() => {
111
+ if (!remoteAvailable) {
112
+ return;
113
+ }
114
+ loadingViews = true;
115
+ void guard(
116
+ () => tableContext.refreshSavedViews(),
117
+ 'Could not load saved layouts and filters. Please try again.'
118
+ ).finally(() => {
119
+ loadingViews = false;
120
+ });
121
+ });
122
+
96
123
  /** Apply a saved view to the live table. Pure local call - no await. */
97
124
  function applyView(view: DatatableView): void {
98
125
  errorMessage = null;
@@ -301,7 +328,9 @@
301
328
  {/if}
302
329
 
303
330
  {#if args.tab === 'mine'}
304
- {#if myViews.length === 0}
331
+ {#if loadingViews}
332
+ <p class="muted">Loading saved {sectionNounPlural.toLowerCase()}…</p>
333
+ {:else if myViews.length === 0}
305
334
  <p class="muted">
306
335
  You have not saved any {sectionNounPlural.toLowerCase()} yet. Use the "Save a new {sectionNoun}"
307
336
  tab to create one.
@@ -458,10 +487,6 @@
458
487
  }}
459
488
  />
460
489
  <Button
461
- type="submit"
462
- variant={Variant.Secondary}
463
- size={Size.MediumSmall}
464
- nowrap
465
490
  disabled={!newViewName.trim()}
466
491
  onclick={saveNewView}>Save Current</Button
467
492
  >
@@ -940,8 +940,10 @@ export declare class TableContext<T extends object, RowIdType extends Primitive>
940
940
  * against the now-known body of any persisted saved-view ref.
941
941
  *
942
942
  * No-op when remote saved views are disabled (`datatableUuid` /
943
- * `remoteLayouts` absent). An adapter rejection is routed to
944
- * `devCatch` and never breaks the table.
943
+ * `remoteLayouts` absent). An adapter rejection is propagated to the
944
+ * caller: the boot-time call site catches it with `devCatch`, while
945
+ * the Table Configuration modal routes it to its inline error banner
946
+ * so a failed fetch is visible rather than silently swallowed.
945
947
  */
946
948
  readonly refreshSavedViews: () => Promise<void>;
947
949
  /**
@@ -2439,8 +2439,10 @@ export class TableContext {
2439
2439
  * against the now-known body of any persisted saved-view ref.
2440
2440
  *
2441
2441
  * No-op when remote saved views are disabled (`datatableUuid` /
2442
- * `remoteLayouts` absent). An adapter rejection is routed to
2443
- * `devCatch` and never breaks the table.
2442
+ * `remoteLayouts` absent). An adapter rejection is propagated to the
2443
+ * caller: the boot-time call site catches it with `devCatch`, while
2444
+ * the Table Configuration modal routes it to its inline error banner
2445
+ * so a failed fetch is visible rather than silently swallowed.
2444
2446
  */
2445
2447
  refreshSavedViews = async () => {
2446
2448
  const adapter = this.remoteLayouts;
@@ -2448,18 +2450,13 @@ export class TableContext {
2448
2450
  if (!adapter || !datatableUuid) {
2449
2451
  return;
2450
2452
  }
2451
- try {
2452
- const views = await adapter.listViews(datatableUuid);
2453
- this._viewState.setSavedViews('layout', views.filter((view) => view.kind === 'layout'));
2454
- this._viewState.setSavedViews('filter', views.filter((view) => view.kind === 'filter'));
2455
- // A persisted saved-view ref restored at boot may have had an
2456
- // unknown body until now; reconcile both baselines against it.
2457
- this._reconcileBaselineForActiveView();
2458
- this._reconcileBaselineForActiveFilterView();
2459
- }
2460
- catch (e) {
2461
- devCatch(e);
2462
- }
2453
+ const views = await adapter.listViews(datatableUuid);
2454
+ this._viewState.setSavedViews('layout', views.filter((view) => view.kind === 'layout'));
2455
+ this._viewState.setSavedViews('filter', views.filter((view) => view.kind === 'filter'));
2456
+ // A persisted saved-view ref restored at boot may have had an
2457
+ // unknown body until now; reconcile both baselines against it.
2458
+ this._reconcileBaselineForActiveView();
2459
+ this._reconcileBaselineForActiveFilterView();
2463
2460
  };
2464
2461
  /**
2465
2462
  * Drop the persisted live-layout snapshot for this table. The next
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.38.2",
4
+ "version": "0.38.4",
5
5
  "publishConfig": {
6
6
  "access": "restricted"
7
7
  },