@@ -2,6 +2,7 @@ import '@selectize/selectize';
2
2
import Handsontable from 'handsontable' ;
3
3
import SheetClip from 'sheetclip' ;
4
4
import $ from 'jquery' ;
5
+ import { range as arrayRange } from 'lodash' ;
5
6
import 'jquery-ui-bundle' ;
6
7
import 'jquery-ui/dist/themes/base/jquery-ui.css' ;
7
8
@@ -751,11 +752,25 @@ class DataHarmonizer {
751
752
}
752
753
} ,
753
754
afterSelection : ( row , column , row2 , column2 ) => {
755
+ // A change in selected row
756
+ if ( self . current_selection [ 0 ] != row ) {
757
+ // Possibly focused key has changed child table's filter.
758
+ // Issue: need to cascade this down immediately to any
759
+ // subordinate table, otherwise if doing on-demand from a table's
760
+ // perspective, then if such a table depends on an intermediate that
761
+ // hasn't been refreshed, we'll get a wrong display.
762
+
763
+ Object . entries ( this . context . getDependents ( this . template_name ) )
764
+ . forEach ( ( [ child_name , child ] ) => {
765
+ // Dependent tables determine what parent foreign key values they
766
+ // need to filter view by
767
+ console . log ( "showing" , child_name )
768
+ this . showRowsByKeyVals ( child_name ) ;
769
+ } ) ;
770
+ } ;
771
+
754
772
self . current_selection = [ row , column , row2 , column2 ] ;
755
- // Two possible actions:
756
- // - For each subordinate table send a message to refilter
757
773
// - See if sidebar info is required for top column click.
758
-
759
774
if ( this . helpSidebar ) {
760
775
if ( column > - 1 ) {
761
776
const field = self . slots [ column ] ;
@@ -834,24 +849,48 @@ class DataHarmonizer {
834
849
if ( startRowIndex === false )
835
850
startRowIndex = this . hot . countRows ( ) ;
836
851
837
- console . log ( "menu" , this . template_name , this . context . relations ?. [ this . template_name ] ?. parent )
838
-
852
+ let parents = this . context . getParents ( this . template_name ) ;
839
853
// If this has no foreign key parent table(s) then go ahead and add x rows.
840
- if ( ! this . context . relations ?. [ this . template_name ] ?. parent ) {
854
+ if ( ! parents ) {
841
855
// Insert the new rows below the last existing row
842
856
this . hot . alter ( row_where , startRowIndex , numRows ) ;
843
857
return ;
844
858
}
845
859
846
- // Here we deal with adding rows that need foreign keys.
847
- // Locate each foreign key and fetch its focused value, and copy into new
848
- // records below.
849
- // If missing key value(s), prompt user to focus appropriate tab(s) row
850
- // and try again.
860
+ let [ required_selections , errors ] = this . getForeignKeyValues ( parents ) ;
861
+
862
+ if ( errors ) {
863
+ // Prompt user to select appropriate parent table row(s) first.
864
+ $ ( '#empty-parent-key-modal-info' ) . html ( errors ) ;
865
+ $ ( '#empty-parent-key-modal' ) . modal ( 'show' ) ;
866
+ return ;
867
+ }
868
+
869
+ this . hot . alter ( row_where , startRowIndex , numRows ) ;
851
870
871
+ // Populate new rows with selected foreign key value(s)
872
+ this . hot . batch ( ( ) => {
873
+ for ( let row = startRowIndex ; row < startRowIndex + numRows ; row ++ ) {
874
+ Object . entries ( required_selections ) . forEach ( ( [ slot_name , value ] ) => {
875
+ const col = this . getColumnIndexByFieldName ( slot_name ) ;
876
+ this . hot . setDataAtCell ( row , col , value ) ;
877
+ } ) ;
878
+ } ;
879
+ } ) ;
880
+
881
+ }
882
+
883
+
884
+
885
+ // Here we deal with adding rows that need foreign keys.
886
+ // Locate each foreign key and fetch its focused value, and copy into new
887
+ // records below.
888
+ // If missing key value(s), prompt user to focus appropriate tab(s) row
889
+ // and try again.
890
+ getForeignKeyValues ( parents ) {
852
891
let required_selections = { } ;
853
- let selection_error = '' ;
854
- Object . entries ( this . context . relations ?. [ this . template_name ] ?. parent )
892
+ let errors = '' ;
893
+ Object . entries ( parents )
855
894
. forEach ( ( [ parent_name , parent ] ) => {
856
895
Object . entries ( parent )
857
896
. forEach ( ( [ slot_name , foreign_slot_name ] ) => {
@@ -871,33 +910,14 @@ class DataHarmonizer {
871
910
}
872
911
if ( ! selected ) {
873
912
//required_selections[slot_name] = {source: parent_name};
874
- selection_error += `<li> <b>${ parent_name } </b> (${ foreign_slot_name } )</li>` ;
913
+ errors += `<li> <b>${ parent_name } </b> (${ foreign_slot_name } )</li>` ;
875
914
}
876
915
else {
877
916
required_selections [ slot_name ] = slot_value ;
878
917
}
879
918
} ) ;
880
919
} ) ;
881
-
882
- if ( selection_error ) {
883
- // Prompt user to select appropriate parent table row(s) first.
884
- $ ( '#empty-parent-key-modal-info' ) . html ( selection_error ) ;
885
- $ ( '#empty-parent-key-modal' ) . modal ( 'show' ) ;
886
- return ;
887
- }
888
-
889
- this . hot . alter ( row_where , startRowIndex , numRows ) ;
890
-
891
- // Populate new rows with selected value(s)
892
- this . hot . batch ( ( ) => {
893
- for ( let row = startRowIndex ; row < startRowIndex + numRows ; row ++ ) {
894
- Object . entries ( required_selections ) . forEach ( ( [ slot_name , value ] ) => {
895
- const col = this . getColumnIndexByFieldName ( slot_name ) ;
896
- this . hot . setDataAtCell ( row , col , value ) ;
897
- } ) ;
898
- } ;
899
- } ) ;
900
-
920
+ return [ required_selections , errors ]
901
921
}
902
922
903
923
getColumnIndexByFieldName ( slot_name ) {
@@ -910,6 +930,7 @@ class DataHarmonizer {
910
930
return - 1 ;
911
931
}
912
932
933
+
913
934
/*
914
935
// Function to find the nearest index after the last non-empty value
915
936
findNearestIndexAfterLastNonEmpty(column) {
@@ -1066,33 +1087,30 @@ class DataHarmonizer {
1066
1087
filtersPlugin . filter ( ) ;
1067
1088
}
1068
1089
1069
- hideMatchingRows ( columnIndex , valueToMatch = null ) {
1070
- function resetHiddenRows ( hotInstance ) {
1071
- const hiddenRowsPlugin = hotInstance . getPlugin ( 'hiddenRows' ) ;
1072
- hiddenRowsPlugin . showRows ( hiddenRowsPlugin . getHiddenRows ( ) ) ; // Reset any previously hidden rows
1073
- }
1074
-
1075
- function getAllRowIndices ( hotInstance ) {
1076
- const totalRows = hotInstance . countRows ( ) ;
1077
- return Array . from ( { length : totalRows } , ( _ , i ) => i ) ; // Return array of row indices [0, 1, 2, ..., totalRows - 1]
1078
- }
1079
-
1080
- const hotInstance = this . hot ;
1090
+ /* For given template name, show only rows that conform to that class's
1091
+ * foreign key-value constraints;
1092
+ */
1093
+ showRowsByKeyVals ( template_name ) {
1094
+ const hotInstance = this . context . dhs [ template_name ] . hot ;
1081
1095
const hiddenRowsPlugin = hotInstance . getPlugin ( 'hiddenRows' ) ;
1082
- resetHiddenRows ( hotInstance ) ; // Reset any previously hidden rows
1083
1096
1084
- let rowsToHide ;
1085
-
1086
- if ( valueToMatch === null || isEmptyUnitVal ( columnIndex ) ) {
1087
- // Hide all rows if no valueToMatch is provided
1088
- rowsToHide = getAllRowIndices ( hotInstance ) ;
1089
- } else {
1090
- // Hide rows that do not match the value at the given columnIndex
1091
- rowsToHide = getAllRowIndices ( hotInstance ) . filter ( ( row ) => {
1092
- const cellValue = hotInstance . getDataAtCell ( row , columnIndex ) ;
1093
- return cellValue !== valueToMatch ;
1094
- } ) ;
1095
- }
1097
+ // Ensure all rows are visible
1098
+ hiddenRowsPlugin . showRows ( hiddenRowsPlugin . getHiddenRows ( ) ) ;
1099
+
1100
+ //Fetch key-values to match
1101
+ let parents = this . context . getParents ( template_name ) ;
1102
+ let [ required_selections , errors ] = this . getForeignKeyValues ( parents ) ;
1103
+ // arrayRange() makes [0, ... n]
1104
+ let rowsToHide = arrayRange ( 0 , hotInstance . countRows ( ) )
1105
+ . filter ( ( row ) => {
1106
+ for ( let [ slot_name , value ] of Object . entries ( required_selections ) ) {
1107
+ const col = this . context . dhs [ template_name ] . getColumnIndexByFieldName ( slot_name ) ;
1108
+ const cellValue = hotInstance . getDataAtCell ( row , col ) ;
1109
+ console . log ( template_name , row , slot_name , col , cellValue , value )
1110
+ if ( cellValue != value )
1111
+ return true ;
1112
+ }
1113
+ } ) ;
1096
1114
1097
1115
hiddenRowsPlugin . hideRows ( rowsToHide ) ; // Hide the calculated rows
1098
1116
hotInstance . render ( ) ; // Render the table to apply changes
0 commit comments