@gridengine/angular-datagrid-enterprise 0.9.0 → 0.11.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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from '@gridengine/angular-datagrid';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, ChangeDetectionStrategy, Component, computed, effect, makeEnvironmentProviders, provideEnvironmentInitializer, output, inject, ElementRef, HostListener, Directive } from '@angular/core';
|
|
3
|
+
import { input, ChangeDetectionStrategy, Component, computed, effect, makeEnvironmentProviders, provideEnvironmentInitializer, signal, output, inject, ElementRef, HostListener, Directive } from '@angular/core';
|
|
4
4
|
import { validateLicense, resolveFeatures as resolveFeatures$1, TIER_FEATURES } from '@gridengine/license-core';
|
|
5
5
|
export { TIER_FEATURES } from '@gridengine/license-core';
|
|
6
6
|
import { DOCUMENT } from '@angular/common';
|
|
@@ -1380,6 +1380,92 @@ class TransactionEngine {
|
|
|
1380
1380
|
}
|
|
1381
1381
|
}
|
|
1382
1382
|
|
|
1383
|
+
/**
|
|
1384
|
+
* TransactionController — a reactive (signals) wrapper around `TransactionEngine`
|
|
1385
|
+
* for the open-source `<gd-data-grid>`. Bind `displayRows()` to `[rowData]` and
|
|
1386
|
+
* pipe `(cellValueChanged)` into `onCellValueChanged` to stage inline edits
|
|
1387
|
+
* without mutating the base data; then `commit()` / `rollback()`:
|
|
1388
|
+
*
|
|
1389
|
+
* ```html
|
|
1390
|
+
* <gd-data-grid [rowData]="txn.displayRows()" [columnDefs]="cols" [getRowId]="byId"
|
|
1391
|
+
* (cellValueChanged)="txn.onCellValueChanged($event)" />
|
|
1392
|
+
* <button [disabled]="!txn.isDirty()" (click)="txn.commit()">Save</button>
|
|
1393
|
+
* ```
|
|
1394
|
+
*
|
|
1395
|
+
* `displayRows()` returns shallow clones, so the grid's in-place cell edits
|
|
1396
|
+
* change the copy while the base stays clean (rollback restores it). Use a
|
|
1397
|
+
* field-based `getRowId` so row identity survives cloning.
|
|
1398
|
+
*/
|
|
1399
|
+
class TransactionController {
|
|
1400
|
+
_engine;
|
|
1401
|
+
_rowIdField;
|
|
1402
|
+
_version = signal(0, /* @ts-ignore */
|
|
1403
|
+
...(ngDevMode ? [{ debugName: "_version" }] : /* istanbul ignore next */ []));
|
|
1404
|
+
/** The current merged rows (base + staged changes) as shallow clones. */
|
|
1405
|
+
displayRows;
|
|
1406
|
+
/** Whether there are uncommitted staged changes. */
|
|
1407
|
+
isDirty;
|
|
1408
|
+
constructor(initialRows, options = {}) {
|
|
1409
|
+
this._rowIdField = options.rowIdField ?? 'id';
|
|
1410
|
+
this._engine = new TransactionEngine({
|
|
1411
|
+
initialRows,
|
|
1412
|
+
rowIdField: this._rowIdField,
|
|
1413
|
+
onTransactionCommit: options.onCommit,
|
|
1414
|
+
onTransactionRollback: options.onRollback,
|
|
1415
|
+
});
|
|
1416
|
+
this.displayRows = computed(() => {
|
|
1417
|
+
this._version();
|
|
1418
|
+
return this._engine.getDisplayRows().map((r) => ({ ...r }));
|
|
1419
|
+
}, /* @ts-ignore */
|
|
1420
|
+
...(ngDevMode ? [{ debugName: "displayRows" }] : /* istanbul ignore next */ []));
|
|
1421
|
+
this.isDirty = computed(() => {
|
|
1422
|
+
this._version();
|
|
1423
|
+
return this._engine.isDirty();
|
|
1424
|
+
}, /* @ts-ignore */
|
|
1425
|
+
...(ngDevMode ? [{ debugName: "isDirty" }] : /* istanbul ignore next */ []));
|
|
1426
|
+
}
|
|
1427
|
+
/** Stage an inline edit emitted by the grid's `(cellValueChanged)`. */
|
|
1428
|
+
onCellValueChanged(event) {
|
|
1429
|
+
if (!event.field)
|
|
1430
|
+
return;
|
|
1431
|
+
const id = event.row[this._rowIdField];
|
|
1432
|
+
this._engine.updateRows([{ [this._rowIdField]: id, [event.field]: event.newValue }]);
|
|
1433
|
+
this._bump();
|
|
1434
|
+
}
|
|
1435
|
+
addRows(rows) {
|
|
1436
|
+
this._engine.addRows(rows);
|
|
1437
|
+
this._bump();
|
|
1438
|
+
}
|
|
1439
|
+
updateRows(rows) {
|
|
1440
|
+
this._engine.updateRows(rows);
|
|
1441
|
+
this._bump();
|
|
1442
|
+
}
|
|
1443
|
+
removeRows(ids) {
|
|
1444
|
+
this._engine.removeRows(ids);
|
|
1445
|
+
this._bump();
|
|
1446
|
+
}
|
|
1447
|
+
/** All current staged changes, grouped by kind. */
|
|
1448
|
+
getDirtyRows() {
|
|
1449
|
+
return this._engine.getDirtyRows();
|
|
1450
|
+
}
|
|
1451
|
+
commit() {
|
|
1452
|
+
this._engine.commitTransaction();
|
|
1453
|
+
this._bump();
|
|
1454
|
+
}
|
|
1455
|
+
rollback() {
|
|
1456
|
+
this._engine.rollbackTransaction();
|
|
1457
|
+
this._bump();
|
|
1458
|
+
}
|
|
1459
|
+
/** Replace the base rows (e.g. after a server refresh); staged changes are kept. */
|
|
1460
|
+
resetRows(rows) {
|
|
1461
|
+
this._engine.resetRows(rows);
|
|
1462
|
+
this._bump();
|
|
1463
|
+
}
|
|
1464
|
+
_bump() {
|
|
1465
|
+
this._version.update((v) => v + 1);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1383
1469
|
class MasterDetailEngine {
|
|
1384
1470
|
_getDetailRowData;
|
|
1385
1471
|
_onExpand;
|
|
@@ -2465,11 +2551,13 @@ function toPdfColumns(columnDefs) {
|
|
|
2465
2551
|
* </div>
|
|
2466
2552
|
* ```
|
|
2467
2553
|
*
|
|
2468
|
-
* Drag across cells to select a block, then Ctrl/Cmd+C to copy it
|
|
2469
|
-
*
|
|
2470
|
-
*
|
|
2471
|
-
*
|
|
2472
|
-
*
|
|
2554
|
+
* Drag across cells to select a block, then Ctrl/Cmd+C to copy it as TSV
|
|
2555
|
+
* (paste-ready into Excel / Sheets). Ctrl/Cmd+V emits `(rangePaste)` with the
|
|
2556
|
+
* parsed matrix and Delete/Backspace emits `(rangeClear)` — the consumer writes
|
|
2557
|
+
* those back into its own data (one-way binding, like the grid's other events).
|
|
2558
|
+
* Cell coordinates come from the grid's ARIA attributes (`role="gridcell"` +
|
|
2559
|
+
* `aria-colindex`, and the row's `aria-rowindex`), so no base-grid changes are
|
|
2560
|
+
* needed. Selection state is driven by the Pro `RangeSelectionEngine`.
|
|
2473
2561
|
*/
|
|
2474
2562
|
const STYLE_ID = 'gd-range-selection-styles';
|
|
2475
2563
|
const SELECTED_CLASS = 'gd-range-selected';
|
|
@@ -2477,6 +2565,10 @@ const NON_DATA_ROW = ['gd-row--header', 'gd-row--filter', 'gd-row--group', 'gd-r
|
|
|
2477
2565
|
class RangeSelectionDirective {
|
|
2478
2566
|
/** Emits the copied cell matrix (rows × cols of displayed text) on Ctrl/Cmd+C. */
|
|
2479
2567
|
rangeCopy = output();
|
|
2568
|
+
/** Emits the parsed clipboard matrix on Ctrl/Cmd+V for the consumer to write back. */
|
|
2569
|
+
rangePaste = output();
|
|
2570
|
+
/** Emits the selected range on Delete/Backspace for the consumer to clear. */
|
|
2571
|
+
rangeClear = output();
|
|
2480
2572
|
_host = inject(ElementRef);
|
|
2481
2573
|
_doc = inject(DOCUMENT);
|
|
2482
2574
|
_engine = new RangeSelectionEngine({ onChange: () => this._paint() });
|
|
@@ -2506,9 +2598,18 @@ class RangeSelectionDirective {
|
|
|
2506
2598
|
this._engine.extendSelection(pos.row, pos.col);
|
|
2507
2599
|
}
|
|
2508
2600
|
onKeyDown(event) {
|
|
2509
|
-
|
|
2601
|
+
const mod = event.ctrlKey || event.metaKey;
|
|
2602
|
+
if (mod && (event.key === 'c' || event.key === 'C')) {
|
|
2603
|
+
if (this._engine.getSelection())
|
|
2604
|
+
event.preventDefault();
|
|
2510
2605
|
this._copy();
|
|
2511
2606
|
}
|
|
2607
|
+
else if (mod && (event.key === 'v' || event.key === 'V')) {
|
|
2608
|
+
this._paste();
|
|
2609
|
+
}
|
|
2610
|
+
else if (event.key === 'Delete' || event.key === 'Backspace') {
|
|
2611
|
+
this._clear(event);
|
|
2612
|
+
}
|
|
2512
2613
|
}
|
|
2513
2614
|
/** The current selection engine (for advanced consumers / testing). */
|
|
2514
2615
|
get engine() {
|
|
@@ -2560,6 +2661,28 @@ class RangeSelectionDirective {
|
|
|
2560
2661
|
void navigator.clipboard?.writeText?.(tsv);
|
|
2561
2662
|
this.rangeCopy.emit(matrix);
|
|
2562
2663
|
}
|
|
2664
|
+
_paste() {
|
|
2665
|
+
const read = navigator.clipboard?.readText?.();
|
|
2666
|
+
if (!read)
|
|
2667
|
+
return;
|
|
2668
|
+
void read.then((text) => {
|
|
2669
|
+
if (!text)
|
|
2670
|
+
return;
|
|
2671
|
+
const selection = this._engine.getSelection();
|
|
2672
|
+
this.rangePaste.emit({
|
|
2673
|
+
startRow: selection?.startRowIndex ?? 0,
|
|
2674
|
+
startCol: selection?.startColIndex ?? 0,
|
|
2675
|
+
data: parseTSV(text),
|
|
2676
|
+
});
|
|
2677
|
+
});
|
|
2678
|
+
}
|
|
2679
|
+
_clear(event) {
|
|
2680
|
+
const selection = this._engine.getSelection();
|
|
2681
|
+
if (!selection)
|
|
2682
|
+
return;
|
|
2683
|
+
event.preventDefault();
|
|
2684
|
+
this.rangeClear.emit(selection);
|
|
2685
|
+
}
|
|
2563
2686
|
_ensureStyles() {
|
|
2564
2687
|
if (this._doc.getElementById(STYLE_ID))
|
|
2565
2688
|
return;
|
|
@@ -2569,7 +2692,7 @@ class RangeSelectionDirective {
|
|
|
2569
2692
|
this._doc.head.appendChild(style);
|
|
2570
2693
|
}
|
|
2571
2694
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: RangeSelectionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2572
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: RangeSelectionDirective, isStandalone: true, selector: "[gdRangeSelection]", outputs: { rangeCopy: "rangeCopy" }, host: { listeners: { "mousedown": "onMouseDown($event)", "mousemove": "onMouseMove($event)", "keydown": "onKeyDown($event)" } }, ngImport: i0 });
|
|
2695
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: RangeSelectionDirective, isStandalone: true, selector: "[gdRangeSelection]", outputs: { rangeCopy: "rangeCopy", rangePaste: "rangePaste", rangeClear: "rangeClear" }, host: { listeners: { "mousedown": "onMouseDown($event)", "mousemove": "onMouseMove($event)", "keydown": "onKeyDown($event)" } }, ngImport: i0 });
|
|
2573
2696
|
}
|
|
2574
2697
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: RangeSelectionDirective, decorators: [{
|
|
2575
2698
|
type: Directive,
|
|
@@ -2577,7 +2700,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
|
|
|
2577
2700
|
selector: '[gdRangeSelection]',
|
|
2578
2701
|
standalone: true,
|
|
2579
2702
|
}]
|
|
2580
|
-
}], ctorParameters: () => [], propDecorators: { rangeCopy: [{ type: i0.Output, args: ["rangeCopy"] }], onMouseDown: [{
|
|
2703
|
+
}], ctorParameters: () => [], propDecorators: { rangeCopy: [{ type: i0.Output, args: ["rangeCopy"] }], rangePaste: [{ type: i0.Output, args: ["rangePaste"] }], rangeClear: [{ type: i0.Output, args: ["rangeClear"] }], onMouseDown: [{
|
|
2581
2704
|
type: HostListener,
|
|
2582
2705
|
args: ['mousedown', ['$event']]
|
|
2583
2706
|
}], onMouseMove: [{
|
|
@@ -2600,5 +2723,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
|
|
|
2600
2723
|
* Generated bundle index. Do not edit.
|
|
2601
2724
|
*/
|
|
2602
2725
|
|
|
2603
|
-
export { AuditTrailEngine, CellPermissionEngine, ClipboardEngine, DEFAULT_MASK, DataGridPro, ExcelImportEngine, FillHandleEngine, FilterPresetEngine, FormEditorEngine, FormulaEngine, GridLicenseWatermark, LicenseManager, MasterDetailEngine, PDFExportEngine, PRODUCT_ID, PURCHASE_URL, RangeSelectionDirective, RangeSelectionEngine, RowLockEngine, SSRMEngine, SavedViewsEngine, TransactionEngine, UndoRedoManager, applyCellPermissions, deserializeFilter, evaluateFilter, parseCSV, parseTSV, provideGridEngineLicense, serializeFilter, toNumber, toPdfColumns, toTimestamp };
|
|
2726
|
+
export { AuditTrailEngine, CellPermissionEngine, ClipboardEngine, DEFAULT_MASK, DataGridPro, ExcelImportEngine, FillHandleEngine, FilterPresetEngine, FormEditorEngine, FormulaEngine, GridLicenseWatermark, LicenseManager, MasterDetailEngine, PDFExportEngine, PRODUCT_ID, PURCHASE_URL, RangeSelectionDirective, RangeSelectionEngine, RowLockEngine, SSRMEngine, SavedViewsEngine, TransactionController, TransactionEngine, UndoRedoManager, applyCellPermissions, deserializeFilter, evaluateFilter, parseCSV, parseTSV, provideGridEngineLicense, serializeFilter, toNumber, toPdfColumns, toTimestamp };
|
|
2604
2727
|
//# sourceMappingURL=gridengine-angular-datagrid-enterprise.mjs.map
|