spiderly 19.11.5 → 19.11.7

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
- import { AfterViewInit, EventEmitter, OnDestroy, OnInit, QueryList, TemplateRef } from '@angular/core';
1
+ import { AfterViewInit, EventEmitter, OnChanges, OnDestroy, OnInit, QueryList, TemplateRef } from '@angular/core';
2
2
  import { ActivatedRoute, Router } from '@angular/router';
3
3
  import { TranslocoService } from '@jsverse/transloco';
4
4
  import { SelectItem, SortMeta } from 'primeng/api';
@@ -14,7 +14,7 @@ import { ConfigServiceBase } from '../../services/config.service.base';
14
14
  import { SpiderlyMessageService } from '../../services/spiderly-message.service';
15
15
  import { SpiderlyFormControl } from '../spiderly-form-control/spiderly-form-control';
16
16
  import * as i0 from "@angular/core";
17
- export declare class SpiderlyDataTableComponent implements OnInit, AfterViewInit, OnDestroy {
17
+ export declare class SpiderlyDataTableComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {
18
18
  private router;
19
19
  private dialogService;
20
20
  private route;
@@ -38,6 +38,8 @@ export declare class SpiderlyDataTableComponent implements OnInit, AfterViewInit
38
38
  tableIcon: string;
39
39
  items: any[];
40
40
  rows: number;
41
+ /** Paginator page-size choices; merge rules and persistence: CLAUDE.md → "Rows-per-page". */
42
+ rowsPerPageOptions: number[];
41
43
  cols: Column[];
42
44
  /** Whether the paginator is shown. Pass only when `hasLazyLoad === false`. Defaults to `true`. */
43
45
  showPaginator: boolean;
@@ -63,6 +65,9 @@ export declare class SpiderlyDataTableComponent implements OnInit, AfterViewInit
63
65
  isAllSelected: boolean;
64
66
  fakeIsAllSelected: boolean;
65
67
  isFirstTimeLazyLoad: boolean;
68
+ /** Shift-range selection state — model and invariants: CLAUDE.md → "Shift-click range selection". */
69
+ private rangeAnchorId;
70
+ private pendingShift;
66
71
  onIsAllSelectedChange: EventEmitter<AllClickEvent>;
67
72
  selectedLazyLoadObservableMethod: (tableFilter: Filter) => Observable<LazyLoadSelectedIdsResult>;
68
73
  additionalFilterIdLong: number;
@@ -133,6 +138,16 @@ export declare class SpiderlyDataTableComponent implements OnInit, AfterViewInit
133
138
  */
134
139
  getCellTemplate(col: Column): TemplateRef<CellTemplateContext> | null;
135
140
  private setupRemovableSort;
141
+ /**
142
+ * A page size PrimeNG will actually apply but that is missing from `rowsPerPageOptions` leaves
143
+ * the paginator dropdown blank — so both the effective `rows` and the persisted pick (which
144
+ * `restoreState` applies after init) are merged in. Runs again on input changes because a
145
+ * consumer may resolve `[rows]` asynchronously. Storage is user-writable, hence the shape and
146
+ * ceiling check: a hand-edited `{"rows": 100000}` must not become an offered choice, since the
147
+ * backend `.Take`s whatever it is sent.
148
+ */
149
+ private mergeActivePageSizesIntoOptions;
150
+ ngOnChanges(): void;
136
151
  ngOnInit(): void;
137
152
  /**
138
153
  * User visibility choices (field → visible), holding only fields the user explicitly
@@ -224,7 +239,16 @@ export declare class SpiderlyDataTableComponent implements OnInit, AfterViewInit
224
239
  getColMatchMode(filterType: string): any;
225
240
  isDropOrMulti(filterType: string): boolean;
226
241
  navigateToDetails(rowId: number): void;
227
- onRowClick(row: any): void;
242
+ /**
243
+ * Handle row click event. Arbitration between "this click navigates the row" and "this click
244
+ * belongs to a control inside the row" happens HERE, once, rather than in each interactive
245
+ * surface: anything marked `.row-interactive` (the selection cell, the actions column, editable
246
+ * cells, opted-in `onCellClick` cells) owns its own click and never navigates. Per-surface
247
+ * `stopPropagation` used to be the mechanism and was structurally lossy — the actions column
248
+ * never had one, so a Delete click opened the dialog AND navigated away. Mark new interactive
249
+ * cells with the class; don't add another stop.
250
+ */
251
+ onRowClick(row: any, event: MouseEvent): void;
228
252
  onCellClick(col: Column, rowData: any, event: MouseEvent): void;
229
253
  private buildClickEvent;
230
254
  deleteObject(rowId: number): void;
@@ -246,13 +270,36 @@ export declare class SpiderlyDataTableComponent implements OnInit, AfterViewInit
246
270
  clear(table: Table): void;
247
271
  setFakeIsAllSelected(): void;
248
272
  selectAll(checked: boolean): void;
273
+ /**
274
+ * Captures the shift state for the checkbox change this press produces — id-paired so an
275
+ * aborted press can never leak into a later toggle (see CLAUDE.md). Also stops shift+click
276
+ * from extending the browser text selection, which starts at mousedown.
277
+ */
278
+ onSelectionCellMouseDown(event: MouseEvent, id: number): void;
279
+ /**
280
+ * The rows the user can currently see, in display order — PrimeNG's own answer, so it cannot
281
+ * drift from what the table paints (it applies `filteredValue` and the paginator slice, and
282
+ * caps lazy pages at `rows` even when the server overshoots). Resolving a range over raw
283
+ * `items` would sweep filtered-out or off-page rows sitting between two visually adjacent
284
+ * ones. An anchor outside this window misses and the shift-click degrades to a plain toggle.
285
+ */
286
+ private renderedRows;
249
287
  selectRow(id: number, index: number): void;
288
+ /** Single-row toggle — the plain-click path. */
289
+ private toggleRow;
290
+ /**
291
+ * Applies `select` to every row between the two positions in `rows` (inclusive), skipping rows
292
+ * already in the target state; each change goes through `toggleRow` so the delta model and
293
+ * per-row events stay identical to manual clicks (see CLAUDE.md). The event payload keeps
294
+ * `row.index` for parity with what the single-click template binding passes.
295
+ */
296
+ private applyRange;
250
297
  isRowSelected(id: number): boolean;
251
298
  rowSelect(id: number): void;
252
299
  rowUnselect(id: number): void;
253
300
  getFormArrayControlByIndex(formControlName: string, index: number): SpiderlyFormControl;
254
301
  static ɵfac: i0.ɵɵFactoryDeclaration<SpiderlyDataTableComponent, never>;
255
- static ɵcmp: i0.ɵɵComponentDeclaration<SpiderlyDataTableComponent, "spiderly-data-table", never, { "tableTitle": { "alias": "tableTitle"; "required": false; }; "tableIcon": { "alias": "tableIcon"; "required": false; }; "items": { "alias": "items"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "cols": { "alias": "cols"; "required": false; }; "showPaginator": { "alias": "showPaginator"; "required": false; }; "showCardWrapper": { "alias": "showCardWrapper"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "idField": { "alias": "idField"; "required": false; }; "getPaginatedListObservableMethod": { "alias": "getPaginatedListObservableMethod"; "required": false; }; "exportListToExcelObservableMethod": { "alias": "exportListToExcelObservableMethod"; "required": false; }; "deleteItemFromTableObservableMethod": { "alias": "deleteItemFromTableObservableMethod"; "required": false; }; "deleteListFromTableObservableMethod": { "alias": "deleteListFromTableObservableMethod"; "required": false; }; "newlySelectedItems": { "alias": "newlySelectedItems"; "required": false; }; "unselectedItems": { "alias": "unselectedItems"; "required": false; }; "selectionMode": { "alias": "selectionMode"; "required": false; }; "selectedLazyLoadObservableMethod": { "alias": "selectedLazyLoadObservableMethod"; "required": false; }; "additionalFilterIdLong": { "alias": "additionalFilterIdLong"; "required": false; }; "showAddButton": { "alias": "showAddButton"; "required": false; }; "showExportToExcelButton": { "alias": "showExportToExcelButton"; "required": false; }; "showReloadTableButton": { "alias": "showReloadTableButton"; "required": false; }; "getFormArrayItems": { "alias": "getFormArrayItems"; "required": false; }; "hasLazyLoad": { "alias": "hasLazyLoad"; "required": false; }; "stateKey": { "alias": "stateKey"; "required": false; }; "stateStorage": { "alias": "stateStorage"; "required": false; }; "defaultSortField": { "alias": "defaultSortField"; "required": false; }; "defaultSortOrder": { "alias": "defaultSortOrder"; "required": false; }; "getAlreadySelectedItemIds": { "alias": "getAlreadySelectedItemIds"; "required": false; }; "getAlreadySelectedItems": { "alias": "getAlreadySelectedItems"; "required": false; }; "getFormControl": { "alias": "getFormControl"; "required": false; }; "additionalIndexes": { "alias": "additionalIndexes"; "required": false; }; "navigateOnRowClick": { "alias": "navigateOnRowClick"; "required": false; }; "rowNavigationPath": { "alias": "rowNavigationPath"; "required": false; }; }, { "onTotalRecordsChange": "onTotalRecordsChange"; "onLazyLoad": "onLazyLoad"; "onIsAllSelectedChange": "onIsAllSelectedChange"; "onRowSelect": "onRowSelect"; "onRowUnselect": "onRowUnselect"; }, ["actionsTemplate", "cellTemplates"], never, true, never>;
302
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpiderlyDataTableComponent, "spiderly-data-table", never, { "tableTitle": { "alias": "tableTitle"; "required": false; }; "tableIcon": { "alias": "tableIcon"; "required": false; }; "items": { "alias": "items"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "rowsPerPageOptions": { "alias": "rowsPerPageOptions"; "required": false; }; "cols": { "alias": "cols"; "required": false; }; "showPaginator": { "alias": "showPaginator"; "required": false; }; "showCardWrapper": { "alias": "showCardWrapper"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "idField": { "alias": "idField"; "required": false; }; "getPaginatedListObservableMethod": { "alias": "getPaginatedListObservableMethod"; "required": false; }; "exportListToExcelObservableMethod": { "alias": "exportListToExcelObservableMethod"; "required": false; }; "deleteItemFromTableObservableMethod": { "alias": "deleteItemFromTableObservableMethod"; "required": false; }; "deleteListFromTableObservableMethod": { "alias": "deleteListFromTableObservableMethod"; "required": false; }; "newlySelectedItems": { "alias": "newlySelectedItems"; "required": false; }; "unselectedItems": { "alias": "unselectedItems"; "required": false; }; "selectionMode": { "alias": "selectionMode"; "required": false; }; "selectedLazyLoadObservableMethod": { "alias": "selectedLazyLoadObservableMethod"; "required": false; }; "additionalFilterIdLong": { "alias": "additionalFilterIdLong"; "required": false; }; "showAddButton": { "alias": "showAddButton"; "required": false; }; "showExportToExcelButton": { "alias": "showExportToExcelButton"; "required": false; }; "showReloadTableButton": { "alias": "showReloadTableButton"; "required": false; }; "getFormArrayItems": { "alias": "getFormArrayItems"; "required": false; }; "hasLazyLoad": { "alias": "hasLazyLoad"; "required": false; }; "stateKey": { "alias": "stateKey"; "required": false; }; "stateStorage": { "alias": "stateStorage"; "required": false; }; "defaultSortField": { "alias": "defaultSortField"; "required": false; }; "defaultSortOrder": { "alias": "defaultSortOrder"; "required": false; }; "getAlreadySelectedItemIds": { "alias": "getAlreadySelectedItemIds"; "required": false; }; "getAlreadySelectedItems": { "alias": "getAlreadySelectedItems"; "required": false; }; "getFormControl": { "alias": "getFormControl"; "required": false; }; "additionalIndexes": { "alias": "additionalIndexes"; "required": false; }; "navigateOnRowClick": { "alias": "navigateOnRowClick"; "required": false; }; "rowNavigationPath": { "alias": "rowNavigationPath"; "required": false; }; }, { "onTotalRecordsChange": "onTotalRecordsChange"; "onLazyLoad": "onLazyLoad"; "onIsAllSelectedChange": "onIsAllSelectedChange"; "onRowSelect": "onRowSelect"; "onRowUnselect": "onRowUnselect"; }, ["actionsTemplate", "cellTemplates"], never, true, never>;
256
303
  }
257
304
  export declare class Action {
258
305
  name?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spiderly",
3
- "version": "19.11.5",
3
+ "version": "19.11.7",
4
4
  "author": "Filip Trivan",
5
5
  "license": "MIT",
6
6
  "description": "Spiderly Angular Library to use in combination with Spiderly.",
@@ -73,6 +73,11 @@
73
73
  text-decoration: underline;
74
74
  }
75
75
 
76
+ // Belt to onSelectionCellMouseDown's preventDefault (shift+click text-selection suppression).
77
+ td.selection-cell {
78
+ user-select: none;
79
+ }
80
+
76
81
  ::ng-deep {
77
82
  .p-datatable-thead {
78
83
  position: unset !important;