From d1259c6c133796c6b2991f2252d1dec274de183e Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Sun, 2 Mar 2025 15:02:17 +0100 Subject: [PATCH 1/8] start refactor deleted state, to make it easier for user to have control --- packages/grid/src/datasource/dataContainer.ts | 52 +++++++++++++------ packages/grid/src/datasource/entityHandler.ts | 20 ++++++- samples/grid01/gridConfig.ts | 11 ++++ 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/packages/grid/src/datasource/dataContainer.ts b/packages/grid/src/datasource/dataContainer.ts index 5e054a5a..18dba164 100644 --- a/packages/grid/src/datasource/dataContainer.ts +++ b/packages/grid/src/datasource/dataContainer.ts @@ -14,7 +14,6 @@ export const getNextKey = function () { */ export class DataContainer { private __collection: Entity[] = []; - private __markedForDeletion: Entity[] = []; private __keyAttribute = ''; private EntityHandler = EntityHandler; /** @@ -66,16 +65,20 @@ export class DataContainer { * @returns */ public getMarkedForDeletion() { - return this.__markedForDeletion; + return this.__collection.filter((e) => e.__controller.__isDeleted); } /** - * resets data, all edits are resets and marked for deletetion if returned + * resets data, all edits are resets/tags are reset + * new entities are removed */ public resetData() { const newEntities: Entity[] = []; - this.setData(this.__markedForDeletion, true); + this.__collection.forEach((row) => { + if (row.__controller.__isDeleted) { + row.__controller.__isDeleted = false; + } if (row.__controller.__isNew) { newEntities.push(row); } @@ -88,8 +91,6 @@ export class DataContainer { } }); this.removeData(newEntities); - - this.__markedForDeletion = []; } /** @@ -98,9 +99,13 @@ export class DataContainer { */ public getChanges() { const newEntities: Entity[] = []; - const deletedEntities: Entity[] = this.__markedForDeletion.slice(); + const deletedEntities: Entity[] = []; const modifiedEntities: Entity[] = []; this.__collection.forEach((row) => { + if (row.__controller.__isDeleted) { + deletedEntities.push(row); + return; + } if (row.__controller.__isNew) { newEntities.push(row); return; @@ -129,25 +134,36 @@ export class DataContainer { */ public markForDeletion(data: Entity | Entity[], all = false) { if (all) { - const removed = this.__collection.slice(); - this.__collection = []; - this.__markedForDeletion = removed; + this.__collection.forEach((e) => { + if (e.__controller.__isNew) { + const i = this.__collection.indexOf(e); + this.__collection.splice(i, 1)[0]; + } else { + e.__controller.__isDeleted = true; + } + }); } if (data) { if (Array.isArray(data)) { - const removed: Entity[] = []; data.forEach((d) => { const i = this.__collection.indexOf(d); if (i !== -1) { - removed.push(this.__collection.splice(i, 1)[0]); + if (this.__collection[i]?.__controller.__isNew) { + this.__collection.splice(i, 1)[0]; + } else { + this.__collection[i].__controller.__isDeleted = true; + } } }); - this.__markedForDeletion = this.__markedForDeletion.concat(removed); } else { const i = this.__collection.indexOf(data); if (i !== -1) { - this.__markedForDeletion.push(this.__collection.splice(i, 1)[0]); + if (this.__collection[i]?.__controller.__isNew) { + this.__collection.splice(i, 1)[0]; + } else { + this.__collection[i].__controller.__isDeleted = true; + } } } } @@ -157,7 +173,12 @@ export class DataContainer { * */ public clearMarkedForDeletion() { - this.__markedForDeletion = []; + this.__collection.forEach((e) => { + if (e.__controller.__isDeleted) { + const i = this.__collection.indexOf(e); + this.__collection.splice(i, 1)[0]; + } + }); } /** @@ -203,7 +224,6 @@ export class DataContainer { */ public setData(data: any[], add = false, tagAsNew = false): Entity[] | void { if (!add) { - this.__markedForDeletion = []; this.__collection = []; } diff --git a/packages/grid/src/datasource/entityHandler.ts b/packages/grid/src/datasource/entityHandler.ts index 04244e73..67350fe7 100644 --- a/packages/grid/src/datasource/entityHandler.ts +++ b/packages/grid/src/datasource/entityHandler.ts @@ -12,7 +12,8 @@ export class EntityHandler { __currentValues?: Record = {}; __newprops?: Record = {}; __isNew? = false; - __edited? = false; + __isDeleted? = false; + __edited? = false; // change to isModified? __controller?: EntityHandler; __KEY?: string | number; __KEYSTRING?: string | number; @@ -36,6 +37,7 @@ export class EntityHandler { if ( [ '__KEY', + '__rowState', '__group', '__groupID', '__groupName', @@ -49,9 +51,22 @@ export class EntityHandler { if (this.__KEYSTRING) { return target[this.__KEYSTRING]; } + } else if (prop === '__rowState') { + if (this.__isDeleted) { + return 'D'; + } + if (this.__isNew) { + return 'N'; + } + + if (this.__edited) { + return 'M'; + } } + return this[prop]; } + return target[prop]; } @@ -63,6 +78,7 @@ export class EntityHandler { if ( [ '__KEY', + '__rowState', '__group', '__groupID', '__groupName', @@ -78,6 +94,8 @@ export class EntityHandler { } else { this[prop] = value; } + } else if (prop === '__rowState') { + // nothing } else { this[prop] = value; } diff --git a/samples/grid01/gridConfig.ts b/samples/grid01/gridConfig.ts index 0c8eda36..1cacade6 100644 --- a/samples/grid01/gridConfig.ts +++ b/samples/grid01/gridConfig.ts @@ -31,6 +31,13 @@ export const gridConfig: GridConfig = { }, ], */ columnsCenter: [ + { + // you almost need to include this now + // N = new, D = deleted, M=modified + rows: ['__rowState'], + + width: 100 + }, { rows: ['company', 'country'], width: 200 @@ -106,6 +113,10 @@ export const gridConfig: GridConfig = { } ], attributes: [ + { + attribute:'__rowState', // N = new, D = deleted, M=modified + label: "RS" + }, { attribute: 'isActive', type: 'boolean' From 66628cfd60c088d37e7200716050156631aac1ba Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Sun, 2 Mar 2025 20:10:11 +0100 Subject: [PATCH 2/8] fix clear marked for selection, update demo, improve reloadDatasource --- packages/grid/src/datasource/dataContainer.ts | 8 +++++++- packages/grid/src/datasource/dataSource.ts | 5 ++++- samples/grid01/gridConfig.ts | 4 ++-- samples/grid01/index.ts | 6 ++++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/grid/src/datasource/dataContainer.ts b/packages/grid/src/datasource/dataContainer.ts index 18dba164..c8a27ffb 100644 --- a/packages/grid/src/datasource/dataContainer.ts +++ b/packages/grid/src/datasource/dataContainer.ts @@ -173,9 +173,15 @@ export class DataContainer { * */ public clearMarkedForDeletion() { + const tempArr: Entity[] = []; this.__collection.forEach((e) => { if (e.__controller.__isDeleted) { - const i = this.__collection.indexOf(e); + tempArr.push(e); + } + }); + tempArr.forEach((e) => { + const i = this.__collection.indexOf(e); + if (i !== -1) { this.__collection.splice(i, 1)[0]; } }); diff --git a/packages/grid/src/datasource/dataSource.ts b/packages/grid/src/datasource/dataSource.ts index 4a3a44cc..4df2d338 100644 --- a/packages/grid/src/datasource/dataSource.ts +++ b/packages/grid/src/datasource/dataSource.ts @@ -772,7 +772,10 @@ export class Datasource { public reloadDatasource() { this.__collectionFiltered = this.getAllData(); - this.__internalUpdate(true); + const eventTriggered = this.__internalUpdate(true); + if (!eventTriggered) { + this.__callSubscribers('collection-filtered', { info: 'filter' }); + } } public getFilterString(ctx?: Grid) { diff --git a/samples/grid01/gridConfig.ts b/samples/grid01/gridConfig.ts index 1cacade6..2e1cc3bf 100644 --- a/samples/grid01/gridConfig.ts +++ b/samples/grid01/gridConfig.ts @@ -35,7 +35,6 @@ export const gridConfig: GridConfig = { // you almost need to include this now // N = new, D = deleted, M=modified rows: ['__rowState'], - width: 100 }, { @@ -115,7 +114,8 @@ export const gridConfig: GridConfig = { attributes: [ { attribute:'__rowState', // N = new, D = deleted, M=modified - label: "RS" + label: "RS", + readonly: true }, { attribute: 'isActive', diff --git a/samples/grid01/index.ts b/samples/grid01/index.ts index bff99838..d66f16b9 100644 --- a/samples/grid01/index.ts +++ b/samples/grid01/index.ts @@ -220,6 +220,12 @@ createButton('get changes (ses console)', () => { console.log(datasource.getChanges()); }); +createButton('remove marked for deleted (no undo)', () => { + + datasource.getDataContainer().clearMarkedForDeletion(); + datasource.reloadDatasource(); +}); + createButton('use init config', () => { gridInterface.loadConfig(gridConfig); }); From 99bbc027a0f6c4a5f69f0c89aca0157614ed3339 Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Mon, 3 Mar 2025 21:21:28 +0100 Subject: [PATCH 3/8] improve resize, to small when sort icon is on --- packages/grid/src/grid/gridFunctions/autoResizeColumns.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grid/src/grid/gridFunctions/autoResizeColumns.ts b/packages/grid/src/grid/gridFunctions/autoResizeColumns.ts index 5193ca80..5cc5a9e3 100644 --- a/packages/grid/src/grid/gridFunctions/autoResizeColumns.ts +++ b/packages/grid/src/grid/gridFunctions/autoResizeColumns.ts @@ -77,7 +77,7 @@ export function autoResizeColumns(ctx: Grid, onlyResizeAttribute?: string) { if (attributeKeys.indexOf(rowAttribute) !== -1) { const xx = widths[attributeKeys.indexOf(rowAttribute)]; if (xx > x) { - x = getTextWidth(ctx, text[attributeKeys.indexOf(rowAttribute)]) + 5; + x = getTextWidth(ctx, text[attributeKeys.indexOf(rowAttribute)]) + 15; } } } From 8a0ab21c93dde31c7ed786c97b237d2939f37a39 Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Mon, 3 Mar 2025 21:33:13 +0100 Subject: [PATCH 4/8] add color classees to row number to show modification --- packages/grid/src/grid.css | 18 +++++++++++++++ .../gridFunctions/rebuildHeaderColumns.ts | 4 ++-- .../grid/gridFunctions/renderRowSelector.ts | 23 ++++++++++++++++++- samples/grid01/gridConfig.ts | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/grid/src/grid.css b/packages/grid/src/grid.css index a481b11f..ab29cbf0 100644 --- a/packages/grid/src/grid.css +++ b/packages/grid/src/grid.css @@ -760,6 +760,24 @@ input { filter: opacity(0.5); } +.simple-html-selector-text.row-is-modified { + color: yellow; + filter: opacity(1); + font-weight: bolder; +} + +.simple-html-selector-text.row-is-new { + color: rgb(154, 154, 238); + filter: opacity(1); + font-weight: bolder; +} + +.simple-html-selector-text.row-is-deleted { + color: rgb(226, 86, 86); + filter: opacity(1); + font-weight: bolder; +} + .simple-html-grid-col-resize { position: absolute; bottom: 0; diff --git a/packages/grid/src/grid/gridFunctions/rebuildHeaderColumns.ts b/packages/grid/src/grid/gridFunctions/rebuildHeaderColumns.ts index 5c77c6a4..f5194414 100644 --- a/packages/grid/src/grid/gridFunctions/rebuildHeaderColumns.ts +++ b/packages/grid/src/grid/gridFunctions/rebuildHeaderColumns.ts @@ -204,8 +204,8 @@ export function rebuildHeaderColumns(ctx: Grid) { col.width = originalWidth + (event.clientX - clientX); } - if (col.width < 50) { - col.width = 50; + if (col.width < 25) { + col.width = 25; } ctx.gridInterface.__parseConfig(); updateMainElementSizes(ctx); diff --git a/packages/grid/src/grid/gridFunctions/renderRowSelector.ts b/packages/grid/src/grid/gridFunctions/renderRowSelector.ts index 39c5e657..b10db657 100644 --- a/packages/grid/src/grid/gridFunctions/renderRowSelector.ts +++ b/packages/grid/src/grid/gridFunctions/renderRowSelector.ts @@ -47,8 +47,29 @@ export function renderRowSelector( } }} > - ${row + 1} +
+ ${row + 1} +
`, cell as any ); } + +// helper to add class so we can override color when row is modified +function isModified(rowData: Entity) { + if (rowData.__controller.__isDeleted) { + return 'row-is-deleted '; + } + + if (rowData.__controller.__isNew) { + return 'row-is-new '; + } + + if (rowData.__controller.__edited) { + return 'row-is-modified '; + } + + return ''; +} diff --git a/samples/grid01/gridConfig.ts b/samples/grid01/gridConfig.ts index 2e1cc3bf..db6b3166 100644 --- a/samples/grid01/gridConfig.ts +++ b/samples/grid01/gridConfig.ts @@ -35,7 +35,7 @@ export const gridConfig: GridConfig = { // you almost need to include this now // N = new, D = deleted, M=modified rows: ['__rowState'], - width: 100 + width: 20 }, { rows: ['company', 'country'], From 563658419b145e53123ff4df5ffb400fc3524354 Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Mon, 3 Mar 2025 21:53:02 +0100 Subject: [PATCH 5/8] improve coloring --- packages/grid/src/grid.css | 6 +++--- samples/grid01/toggelDarkGrid.ts | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/grid/src/grid.css b/packages/grid/src/grid.css index ab29cbf0..c45cf0ef 100644 --- a/packages/grid/src/grid.css +++ b/packages/grid/src/grid.css @@ -761,19 +761,19 @@ input { } .simple-html-selector-text.row-is-modified { - color: yellow; + color: blue; filter: opacity(1); font-weight: bolder; } .simple-html-selector-text.row-is-new { - color: rgb(154, 154, 238); + color: green; filter: opacity(1); font-weight: bolder; } .simple-html-selector-text.row-is-deleted { - color: rgb(226, 86, 86); + color: red; filter: opacity(1); font-weight: bolder; } diff --git a/samples/grid01/toggelDarkGrid.ts b/samples/grid01/toggelDarkGrid.ts index 550e5f90..bd2c5715 100644 --- a/samples/grid01/toggelDarkGrid.ts +++ b/samples/grid01/toggelDarkGrid.ts @@ -47,6 +47,22 @@ export function toggelDarkGrid() { border-top: 0px; } + + + .simple-html-selector-text.row-is-modified { + color: #9595f1; + } + + .simple-html-selector-text.row-is-new { + color: #5ff95f; + } + + .simple-html-selector-text.row-is-deleted { + color: red; + } + + + .simple-html-grid .filter-dialog-bottom-row button{ border: 1px solid #515458; } From 592a8ca9a52df2255e441440e296bf361bdc7fa2 Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Mon, 3 Mar 2025 22:31:20 +0100 Subject: [PATCH 6/8] reset selection --- packages/grid/src/datasource/dataContainer.ts | 35 +++++++++++++++++++ packages/grid/src/datasource/dataSource.ts | 11 ++++++ samples/grid01/index.ts | 4 +++ 3 files changed, 50 insertions(+) diff --git a/packages/grid/src/datasource/dataContainer.ts b/packages/grid/src/datasource/dataContainer.ts index c8a27ffb..1a61d1ab 100644 --- a/packages/grid/src/datasource/dataContainer.ts +++ b/packages/grid/src/datasource/dataContainer.ts @@ -68,6 +68,41 @@ export class DataContainer { return this.__collection.filter((e) => e.__controller.__isDeleted); } + /** + * for selected rows only + * resets data, all edits are resets/tags are reset + * new entities are removed + */ + public resetDataSelection(data: Entity[]) { + const newEntities: Entity[] = []; + + if (data) { + if (Array.isArray(data)) { + data.forEach((d) => { + const i = this.__collection.indexOf(d); + if (i !== -1 && this.__collection[i]) { + const row = this.__collection[i]; + if (row.__controller.__isDeleted) { + row.__controller.__isDeleted = false; + } + if (row.__controller.__isNew) { + newEntities.push(row); + } + if (row.__controller.__edited) { + for (const k in row.__controller.__originalValues) { + row[k] = row.__controller.__originalValues[k]; + } + row.__controller.__editedProps = {}; + row.__controller.__edited = false; + } + } + }); + } + } + + this.removeData(newEntities); + } + /** * resets data, all edits are resets/tags are reset * new entities are removed diff --git a/packages/grid/src/datasource/dataSource.ts b/packages/grid/src/datasource/dataSource.ts index 4df2d338..c77e9e22 100644 --- a/packages/grid/src/datasource/dataSource.ts +++ b/packages/grid/src/datasource/dataSource.ts @@ -153,6 +153,17 @@ export class Datasource { } } + /** + * resets all edited data and brings back marked for deletion + */ + public resetDataSelectionOnly() { + this.__dataContainer.resetDataSelection(this.getSelectedRows()); + const eventTriggered = this.__internalUpdate(true); + if (!eventTriggered) { + this.__callSubscribers('collection-filtered', { info: 'resetData' }); + } + } + /** * returns copy of all modified, new or marked for deletion * changes to these do not edit anything in grid diff --git a/samples/grid01/index.ts b/samples/grid01/index.ts index d66f16b9..974fdd2e 100644 --- a/samples/grid01/index.ts +++ b/samples/grid01/index.ts @@ -216,6 +216,10 @@ createButton('reset data/changes', () => { datasource.resetData(); }); +createButton('reset data/changes -selection', () => { + datasource.resetDataSelectionOnly(); +}); + createButton('get changes (ses console)', () => { console.log(datasource.getChanges()); }); From 50eb61b223733a34e8c759570f4e2bffc6dca35d Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Wed, 5 Mar 2025 21:21:14 +0100 Subject: [PATCH 7/8] just add class to modified/new and deleted --- packages/grid/src/grid.css | 17 ----------------- .../src/grid/gridFunctions/renderRowSelector.ts | 10 +++++----- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/packages/grid/src/grid.css b/packages/grid/src/grid.css index c45cf0ef..2e6fece5 100644 --- a/packages/grid/src/grid.css +++ b/packages/grid/src/grid.css @@ -760,23 +760,6 @@ input { filter: opacity(0.5); } -.simple-html-selector-text.row-is-modified { - color: blue; - filter: opacity(1); - font-weight: bolder; -} - -.simple-html-selector-text.row-is-new { - color: green; - filter: opacity(1); - font-weight: bolder; -} - -.simple-html-selector-text.row-is-deleted { - color: red; - filter: opacity(1); - font-weight: bolder; -} .simple-html-grid-col-resize { position: absolute; diff --git a/packages/grid/src/grid/gridFunctions/renderRowSelector.ts b/packages/grid/src/grid/gridFunctions/renderRowSelector.ts index b10db657..ea43763c 100644 --- a/packages/grid/src/grid/gridFunctions/renderRowSelector.ts +++ b/packages/grid/src/grid/gridFunctions/renderRowSelector.ts @@ -47,8 +47,8 @@ export function renderRowSelector( } }} > -
- + ${row + 1}
@@ -60,15 +60,15 @@ export function renderRowSelector( // helper to add class so we can override color when row is modified function isModified(rowData: Entity) { if (rowData.__controller.__isDeleted) { - return 'row-is-deleted '; + return 'row-is-deleted'; } if (rowData.__controller.__isNew) { - return 'row-is-new '; + return 'row-is-new'; } if (rowData.__controller.__edited) { - return 'row-is-modified '; + return 'row-is-modified'; } return ''; From 032860e11aa9f40d4c38f19d667d5ab476d6f9bb Mon Sep 17 00:00:00 2001 From: Vegar Ringdal Date: Fri, 7 Mar 2025 22:33:57 +0100 Subject: [PATCH 8/8] fix --- packages/grid/src/grid/gridFunctions/renderRowSelector.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grid/src/grid/gridFunctions/renderRowSelector.ts b/packages/grid/src/grid/gridFunctions/renderRowSelector.ts index ea43763c..612dac71 100644 --- a/packages/grid/src/grid/gridFunctions/renderRowSelector.ts +++ b/packages/grid/src/grid/gridFunctions/renderRowSelector.ts @@ -59,15 +59,15 @@ export function renderRowSelector( // helper to add class so we can override color when row is modified function isModified(rowData: Entity) { - if (rowData.__controller.__isDeleted) { + if (rowData?.__controller?.__isDeleted) { return 'row-is-deleted'; } - if (rowData.__controller.__isNew) { + if (rowData?.__controller?.__isNew) { return 'row-is-new'; } - if (rowData.__controller.__edited) { + if (rowData?.__controller?.__edited) { return 'row-is-modified'; }