Skip to content

Commit a4daedf

Browse files
committed
finishing touches on DH create row(s)
1 parent 9593e72 commit a4daedf

File tree

3 files changed

+71
-23
lines changed

3 files changed

+71
-23
lines changed

lib/AppContext.js

+27-12
Original file line numberDiff line numberDiff line change
@@ -412,14 +412,7 @@ export default class AppContext {
412412

413413
Object.entries(schema.classes)
414414
// Container class is only used in input and output file coordination.
415-
.filter(([class_name]) =>
416-
// If given template_name found, build it
417-
class_name == template_name
418-
// Or given class is a child of template
419-
|| this.relations[class_name]?.parent?.[template_name]
420-
// Or given class is a child of child of template etc.
421-
// ...
422-
)
415+
.filter(([class_name]) => this.isAncestor([class_name], template_name))
423416
.forEach((obj, index) => {
424417
if (obj.length > 0) {
425418
const [class_name, tree_obj] = obj;
@@ -450,7 +443,7 @@ export default class AppContext {
450443
schema: schema, // assign during constructor so validator can init on it.
451444
hot_override_settings: {
452445
minRows: is_child ? 0 : 10,
453-
minSpareRows: is_child ? 0 : 10,
446+
minSpareRows: 0,
454447
height: is_child ? '40vh' : '75vh',
455448
// TODO: Workaround, possibly due to too small section column on child tables
456449
// colWidths: is_child ? 256 : undefined,
@@ -463,8 +456,11 @@ export default class AppContext {
463456
dh.validator.useTargetClass(class_name);
464457

465458
if (is_child) {
466-
// Initialization of each child table is to hide all rows until
467-
// parent primary key record is selected as a foreign key index.
459+
/* Initialization of each child table is to hide all rows until
460+
* parent primary key record is selected as a foreign key index.
461+
* Note: user cut and paste of records doesn't change read-only
462+
* fields.
463+
**/
468464
dh.filterAll();
469465
// All foreign key fields must be read-only. Their contents are
470466
// controlled by dependent create and update actions.
@@ -484,7 +480,9 @@ export default class AppContext {
484480
* WRT rows which are foreign keys to other tables, a user:
485481
* - Can update or delete a key field which then cascades to
486482
* other child table(s). This might trigger violation of unique_keys!
487-
*
483+
*
484+
* Note: user cut and paste of records doesn't change read-only
485+
* fields.
488486
*/
489487

490488
}
@@ -499,6 +497,23 @@ export default class AppContext {
499497
return data_harmonizers;
500498
}
501499

500+
// Determine if parent relationships link class_name to given ancestor
501+
isAncestor(class_names, ancestor_name) {
502+
let subject_name = class_names.shift();
503+
if (!subject_name)
504+
return false;
505+
if (subject_name == ancestor_name)
506+
return true;
507+
if (this.relations[subject_name]?.parent) {
508+
if (this.relations[subject_name].parent[ancestor_name])
509+
return true;
510+
// Ancestor wasn't one of parents, so try search on all ancestors.
511+
//console.log(this.relations[subject_name].parent, Object.values(this.relations[subject_name].parent))
512+
class_names.push(Object.values(this.relations[subject_name].parent));
513+
}
514+
return this.isAncestor(class_names, ancestor_name)
515+
}
516+
502517
/*
503518
Return initialized, rendered dataHarmonizer instances rendered in order.
504519
If a template name is provided, only include that one in its schema, and any underlings.

lib/DataHarmonizer.js

+43-10
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,31 @@ class DataHarmonizer {
685685
colHeaders: true,
686686
rowHeaders: true,
687687
copyPaste: true,
688-
contextMenu: ['remove_row', 'row_above', 'row_below'],
688+
contextMenu: [
689+
690+
{
691+
key: 'remove_row',
692+
name: 'Remove row',
693+
callback: function () {
694+
//Enables removal of a row and all subordinate rows in other DH tables.
695+
self.hot.alter('remove_row', self.hot.getSelected()[0][0]); //, numRows
696+
},
697+
},
698+
{
699+
key: 'row_above',
700+
name: 'Insert row above',
701+
callback: function () {
702+
self.addRows('insert_row_above', 1, self.hot.getSelected()[0][0]);
703+
},
704+
},
705+
{
706+
key: 'row_below',
707+
name: 'Insert row below',
708+
callback: function () {
709+
self.addRows('insert_row_above', 1, parseInt(self.hot.getSelected()[0][0])+1);
710+
},
711+
},
712+
],
689713
outsideClickDeselects: false, // for maintaining selection between tabs
690714
manualColumnResize: true,
691715
//colWidths: [100], //Just fixes first column width
@@ -728,13 +752,18 @@ class DataHarmonizer {
728752
},
729753
afterSelection: (row, column, row2, column2) => {
730754
self.current_selection = [row, column, row2, column2];
755+
// Two possible actions:
756+
// - For each subordinate table send a message to refilter
757+
// - See if sidebar info is required for top column click.
758+
731759
if (this.helpSidebar) {
732760
if (column > -1) {
733761
const field = self.slots[column];
734762
const helpContent = self.getComment(field);
735763
self.helpSidebar.setContent(helpContent);
736764
} else self.helpSidebar.close();
737765
}
766+
return false;
738767
},
739768
// Bit of a hackey way to RESTORE classes to secondary headers. They are
740769
// removed by Handsontable when re-rendering main table.
@@ -791,22 +820,26 @@ class DataHarmonizer {
791820
this.hot.updateSettings({ columns: currentColumns });
792821
}
793822

794-
/* Currently only called via Footer.js
795-
* numRows is (usually) user specified number of rows to add at bottom
796-
* of current dh table. However, if table has foreign key(s) to another
797-
* table, the other table's focused row will control foreign key values
798-
* added to this table.
823+
/* Called via Footer.js, and also in right click menu DH contextMenu click
824+
* row_above, row_below.
825+
* numRows is specified number of rows to add to current dh table. If table
826+
* has foreign key(s) to another table, the other table's focused row will
827+
* control foreign key values added to this table.
828+
* row_where = 'insert_row_below' | 'insert_row_above'
799829
*/
800-
addRowsToBottom(numRows) {
830+
addRows(row_where, numRows, startRowIndex = false) {
801831

802832
numRows = parseInt(numRows); // Coming from form string input.
803833
// Get the starting row index where the new rows will be added
804-
const startRowIndex = this.hot.countRows();
834+
if (startRowIndex === false)
835+
startRowIndex = this.hot.countRows();
836+
837+
console.log("menu",this.template_name, this.context.relations?.[this.template_name]?.parent)
805838

806839
// If this has no foreign key parent table(s) then go ahead and add x rows.
807840
if (! this.context.relations?.[this.template_name]?.parent) {
808841
// Insert the new rows below the last existing row
809-
this.hot.alter('insert_row_below', startRowIndex, numRows);
842+
this.hot.alter(row_where, startRowIndex, numRows);
810843
return;
811844
}
812845

@@ -853,7 +886,7 @@ class DataHarmonizer {
853886
return;
854887
}
855888

856-
this.hot.alter('insert_row_below', startRowIndex, numRows);
889+
this.hot.alter(row_where, startRowIndex, numRows);
857890

858891
// Populate new rows with selected value(s)
859892
this.hot.batch(() => {

lib/Footer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Footer {
2626

2727
this.root.find('.add-rows-button').on('click', () => {
2828
const numRows = this.root.find('.add-rows-input').val();
29-
context.getCurrentDataHarmonizer().addRowsToBottom(numRows);
29+
context.getCurrentDataHarmonizer().addRows('insert_row_below', numRows);
3030
});
3131
}
3232
}

0 commit comments

Comments
 (0)