Skip to content

Commit d36230f

Browse files
committed
refactoring menu maintenance
fix to SchemaSlotGroupMenu
1 parent 70c75f8 commit d36230f

3 files changed

Lines changed: 289 additions & 352 deletions

File tree

lib/AppContext.js

Lines changed: 42 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ export default class AppContext {
6666

6767
};
6868

69+
selectedTableRow(class_name) {
70+
const tab = this.dhs[class_name];
71+
return tab?.hot.getSelected()?.[0]?.[0] ?? -1; // -1 = undefined
72+
}
73+
6974
/**
7075
* Accessed by both a tabChange() but also by a #report_select_type change
7176
*/
@@ -74,8 +79,6 @@ export default class AppContext {
7479
let dh = this.getCurrentDataHarmonizer();
7580
let class_name = dh.template_name;
7681
let report_type = $('#report_select_type').val();
77-
const class_dh = this.dhs['Class'];
78-
const class_row = class_dh?.hot.getSelected()?.[0]?.[0] ?? -1; // -1 = undefined
7982

8083
//console.log("REFRESHTABDISPLAY", class_name, this.schemaEditor, report_type)
8184

@@ -91,9 +94,9 @@ export default class AppContext {
9194
//$('#slot_report_type, #slot_report_type_option')
9295
// .toggle(this.schemaEditor !== undefined && class_name === 'Slot');
9396

94-
// The Schema tab always displays a full list, even with "record(s) by selected key" option set in menu.
97+
// The Schema tab always displays a full list, even with "record(s) by
98+
// selected key" option set in menu.
9599
if (this.schemaEditor !== undefined && class_name === 'Schema') {
96-
// Report type override
97100
report_type = 'all';
98101
}
99102

@@ -114,30 +117,19 @@ export default class AppContext {
114117
this.slotTypeFilter(dh); // Done via hidden fields. no constraint (no keys)
115118
break;
116119

120+
/* Unused at moment
117121
// The following Display > menu is specific to the Field / Slots display
118122
case 'slot':
119123
//this.slotTypeFilter(dh, ['slot']);
120124
//dh.hot.getPlugin('multiColumnSorting').sort() ; //{ column: 3, sortOrder: 'asc' }
121125
break;
122126
123-
case 'attribute':
127+
// A class attribute" object has all the same fields as a class slot.
128+
// Hence they are all in the same report.
129+
case 'attribute':
124130
this.slotTypeFilter(dh, ['attribute']);
125131
break;
126-
127-
case 'slot_usage':
128-
this.slotTypeFilter(dh, ['slot','slot_usage']);
129-
// UNFINISHED CODE
130-
columnSorting.sort({
131-
column: dh.slot_name_column,
132-
sortOrder: 'asc'
133-
//compareFunctionFactory: function(sortOrder, columnMeta) {
134-
// return function(value, nextValue) {
135-
// return 0; // Custom compare function for the first column (don't sort)
136-
// }
137-
//}
138-
});
139-
140-
break;
132+
*/
141133

142134
// Records by selected key case
143135
case '':
@@ -146,13 +138,23 @@ export default class AppContext {
146138
let fkey_vals = this.dependent_rows.get(class_name).fkey_vals;
147139
// Some reports should show all class's entries if none selected in Class (Table) tab.
148140

149-
if (this.schemaEditor !== undefined && dh.template_name === 'UniqueKey') {
150-
// If no row is selected in the Class (Table) tab, remove the class_id
151-
// filter so all unique keys for the selected schema are shown.
152-
alert(class_row)
153-
if (class_row < 0) {
154-
delete fkey_vals['class_id'];
155-
//alert("here")
141+
if (this.schemaEditor !== undefined) {
142+
switch (dh.template_name) {
143+
case 'UniqueKey':
144+
case 'SlotGroup':
145+
case 'Slot':
146+
// If no row is selected in the Class (Table) tab, remove the class_id
147+
// filter so all unique keys for the selected schema are shown.
148+
if (this.selectedTableRow('Class') < 0) {
149+
delete fkey_vals['class_id'];
150+
}
151+
break;
152+
case 'PermissibleValue':
153+
case 'EnumSource':
154+
if (this.selectedTableRow('Enum') < 0) {
155+
delete fkey_vals['enum_id'];
156+
}
157+
break;
156158
}
157159
}
158160

@@ -185,101 +187,12 @@ export default class AppContext {
185187

186188
}
187189

188-
/** filterByKeys() SHOULD NOT BE APPLIED TO A schema's ROOT (top level) tab.
189-
* E.g. for SCHEMA EDITOR, on "Schema" TAB - we never want to filter selection
190-
* there unless there's a way of releasing that filter.
191-
*/
192-
async filterByKeys_UNUSED_UNUSED(dh, key_vals = {}) {
193-
194-
/* For Slot tab query, only foreign key at moment is schema_id.
195-
* However, if user has selected a table in Table/Class tab, we want
196-
* filter on class_name field.
197-
schema_id
198-
match to foreign keys:
199-
For every slot_id, class_id, name found, also include slot_id, name.
200-
alt: find slot_id, name, and class_id = key or NULL
201-
I.e. allow NULL to apply just to class_id field.
202-
*/
203-
/*
204-
if (class_name === 'Slot') {
205-
206-
let column = dh.slot_name_to_column[key_name];
207-
filtersPlugin.addCondition(column, 'eq', [value]); //
208-
// Get selected table/class, if any:
209-
const class_column = this.slot_name_to_column['class_name'];
210-
const class_dh = this.context.dhs['Class'];
211-
const focused_class_col = class_dh.slot_name_to_column['name'];
212-
const focused_class_row = class_dh.current_selection[0];
213-
const focused_class_name = (focused_class_row > -1) ? class_dh.hot.getDataAtCell(focused_class_row, focused_class_col) : '';
214-
// If user has clicked on a table, use that focus to constrain Field list
215-
if (focused_class_name > '') {
216-
filtersPlugin.addCondition(class_column, 'eq', [focused_class_name], 'disjunction');
217-
//filtersPlugin.addCondition(class_column, 'empty',[], 'disjunction');
218-
}
219-
// With no table selected, only show rows that DONT have a table/class mentioned
220-
else {
221-
filtersPlugin.addCondition(class_column, 'empty',[]);
222-
}
223-
}
224-
*/
225-
226-
227-
228-
// Special call to initialize highlight of schema library slots having 'slot_type' = 'field'.
229-
// Assumes crudFindAllRowsByKeyVals() will let in slots/fields with null values in order to
230-
// also bring in slots not associated with a class. (no class_name).
231-
232-
// let multiColumnSorting = dh.hot.getPlugin('multiColumnSorting');
233-
//const columnSorting = dh.hot.getPlugin('columnSorting');
234-
//columnSorting.clearSort(); // Reset sort so filter matches raw fields
235-
236-
const mode = $('#report_select_type').val();
237-
238-
switch (mode) {
239-
240-
// Just a list of schema fields:
241-
// sort by slot_group if any, then rank if any, then alphabetically
242-
// Slots and attributes are fully editable.
243-
case 'slot':
244-
245-
// Table-only fields. Sort as above.
246-
// NOTE: This shows attributes for ALL tables in schema.
247-
// One issue - possible naming collision with schema.slot name will cause schema slot attributes to overwrite slot.attributes slot values?
248-
case 'attribute':
249-
this.slotTypeFilter(dh, [mode]);
250-
// filtersPlugin.addCondition(dh.slot_type_column, 'eq', [mode]); //slot_type
251-
// filtersPlugin.filter();
252-
253-
/*
254-
multiColumnSorting.sort([
255-
{column: 5, sortOrder: 'asc'}, // slot_group
256-
{column: 4, sortOrder: 'asc'}, // rank
257-
{column: 1, sortOrder: 'asc'}, // slot.name
258-
]);
259-
*/
260-
break;
261-
262-
/**********************************************************/
263-
// Show all slot_usage fields. For each, show schema.slot if available.
264-
case 'slot_usage':
265-
266-
this.slotTypeFilter(dh, ['slot','slot_usage']);
267-
268190

269-
break;
270-
271-
default:
272-
//Show all types of field:
273-
this.slotTypeFilter(dh, ['slot','slot_usage','attribute']);
274-
}
275-
dh.render(); // Otherwise cells() implements meta and class stuff that isn't reflected
276-
277-
}
278-
279-
// Filtering has unpredictable results in terms of rendering, and in
280-
// conjunction with sorting, so using hiddenrowsplugin instead.
191+
// Using hiddenrowsplugin because filters plugin has unpredictable results
192+
// in terms of rendering, and in conjunction with sorting
281193
tabFilter(dh, key_vals) {
282194
dh.hot.suspendExecution(); // Recommended in handsontable example.
195+
// In case user has applied some filters, clears them:
283196
let filtersPlugin = dh.hot.getPlugin('filters');
284197
filtersPlugin.clearConditions();
285198

@@ -306,29 +219,9 @@ export default class AppContext {
306219
dh.render(); // Otherwise chunks of old html left with old visible rows
307220
};
308221

309-
/*
310-
tabFilter(dh, key_vals) {
311-
dh.hot.suspendExecution(); // Recommended in handsontable example.
312-
let filtersPlugin = dh.hot.getPlugin('filters');
313-
filtersPlugin.clearConditions();
314-
315-
Object.entries(key_vals).forEach(([key_name, value]) => {
316-
let column = dh.slot_name_to_column[key_name];
317-
//console.log('filter on', class_name, key_name, column, value); //foreign_key,
318-
if (column !== undefined) {
319-
// See https://handsontable.com/docs/javascript-data-grid/api/filters/
320-
filtersPlugin.addCondition(column, 'eq', [value]); //
321-
}
322-
else
323-
console.log(`ERROR: unable to find filter column "${key_name}" in "${dh.template_name}" table. Check DH_linkML unique_key_slots for this class`);
324-
});
325222

326-
filtersPlugin.filter();
327-
dh.hot.resumeExecution();
328-
};
329-
*/
330-
331-
// Controlling shown or hidden
223+
// Controlling shown or hidden rows. Much like above
224+
// Could be merged with above with additional parameter for selecting {[column name]: [acceptable values...] }
332225
slotTypeFilter(dh, show_type = null) {
333226
//dh.suspendExecution();
334227
// See https://handsontable.com/docs/javascript-data-grid/api/core/#suspendexecution
@@ -412,11 +305,6 @@ export default class AppContext {
412305
}
413306
}
414307

415-
// Ensure dynamic Enums are added so picklist source / range references are
416-
// detected and pulldown/multiselect menus are crafted; and validation works
417-
this.schemaEditor?.initMenus();
418-
419-
420308
// For all schemas, implement menu inheritance if any. Inheritance assembles
421309
// .inherits[enum1 name, enum2 name, ... , this enum], merging each in order
422310
// such that permissible value labels, descriptions and mappings can be
@@ -433,10 +321,17 @@ export default class AppContext {
433321
});
434322

435323
this.dhs = this.makeDHsFromRelations(schema, template_name);
436-
this.schemaEditor?.refreshMenus(); // requires classes Class, Enum to be built.
324+
437325
// this.currentDataHarmonizer is now set.
438326
this.crudGetDependentRows(this.current_data_harmonizer_name);
439327
this.crudUpdateRecordPath();
328+
329+
// Ensure dynamic Enums are added so picklist source / range references are
330+
// detected and pulldown/multiselect menus are crafted; and validation works
331+
this.schemaEditor?.initMenus();
332+
333+
this.schemaEditor?.refreshMenus(); // requires classes Class, Enum to be built.
334+
440335
this.refreshTabDisplay();
441336

442337
return this;

lib/DataHarmonizer.js

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -630,27 +630,6 @@ class DataHarmonizer {
630630
// If in schema editor mode, update or insert to name field (a
631631
// key field) of class, slot or enum (should cause update in
632632
// compiled enums and slot flatVocabularies.
633-
634-
if (self.context.schemaEditor) {
635-
switch (self.template_name) {
636-
case 'Schema':
637-
// For a schema name change (the only key in schema table),
638-
// update ALL related SchemaEditor Menus (classes, slots ...)
639-
// for that template.
640-
self.context.schemaEditor.refreshMenus();
641-
break;
642-
643-
case 'Slot':
644-
// A change in a Field/Slot table's row's schema
645-
self.context.schemaEditor.refreshMenus(['SchemaSlotMenu']);
646-
break;
647-
648-
case 'Type':
649-
case 'Class':
650-
case 'Enum':
651-
self.context.schemaEditor.refreshMenus([`Schema${self.template_name}Menu`]);
652-
}
653-
}
654633
}
655634
}
656635
},
@@ -695,22 +674,6 @@ class DataHarmonizer {
695674
// rows, if none, skip this.
696675
if (row_change) { // primary_key slot cell value change case handled in afterChange() event above.
697676
self.context.crudCalculateDependentKeys(self.template_name);
698-
699-
if (self.context.schemaEditor) { // Schema Editor specific function
700-
if (self.template_name === 'Schema') {
701-
self.context.schemaEditor.refreshMenus();
702-
}
703-
if (self.template_name === 'Class' || self.template_name === 'Slot') {
704-
// Have to update Slot > SlotUsage > slot_group menu for given Class.
705-
// (Currently not having Schema Class itself control slot_group.)
706-
// Find slot menu field and update source controlled vocab.
707-
// ISSUE: Menu won't work/validate if multiple classes are displayed.
708-
//const class_name = self.hot.getDataAtCell(
709-
// row, self.slot_name_to_column['name']
710-
//);
711-
self.context.schemaEditor.refreshMenus(['SchemaSlotMenu','SchemaSlotGroupMenu']);
712-
}
713-
}
714677
}
715678

716679
// - See if sidebar info is required for top column click.
@@ -847,7 +810,7 @@ class DataHarmonizer {
847810
for (let [dependent_name] of this.context.relations[class_name].dependents.entries()) {
848811

849812
let dependent_rep = this.context.dependent_rows.get(dependent_name);
850-
console.log("report for ", dependent_name, dependent_rep)
813+
//console.log("report for ", dependent_name, dependent_rep)
851814
dependent_report[dependent_name] = dependent_rep;
852815

853816
if (class_name != dependent_name && dependent_rep.count) {

0 commit comments

Comments
 (0)