Skip to content

Commit e08b83d

Browse files
committed
updatees to fix ui issues
1 parent 7861608 commit e08b83d

9 files changed

Lines changed: 1328 additions & 530 deletions

File tree

docs/README_schema_editor.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,26 @@ The Schema Editor lets you copy one or more rows from any tab into a different s
129129
- Right-click **within the highlighted selection** to preserve the multi-row selection while opening the context menu.
130130
3. Right-click the selection and choose **Copy to schema**.
131131
4. In the dialog that appears:
132-
- Choose the **target schema** from the drop-down list. The schema(s) the selected rows belong to are shown as disabled and cannot be chosen as a target.
133-
- Review the **Dependencies** list, if shown. Any structural items that must accompany the selection (see below) are listed here.
132+
- Choose the **target schema** from the **Copy to schema** drop-down. The source schema(s) are shown as disabled and cannot be chosen as a target.
133+
- Review the three optional sections described below.
134134
5. Click **Copy**. The rows are appended to the appropriate tabs of the target schema, and a confirmation message reports how many rows were written.
135135

136+
#### Dialog sections
137+
138+
**Section 1 — Selected rows and their parents (always copied)**
139+
This section is always visible. The selected rows are listed first, grouped under their tab name. Below them, any structural items they depend on that are not yet present in the target schema (e.g. a Table row that a Field refers to, or a base slot that a slot_usage customises) are listed. Everything in this section is always copied and cannot be individually deselected.
140+
141+
**Section 2 — Dependent table records (optional)**
142+
Child records that belong to the selected rows — for example, Field rows that belong to a selected Table, or Enum value rows that belong to a selected Enum — are listed here. Uncheck the section to skip copying them entirely.
143+
144+
**Section 3 — Copy picklists and picklist choices (optional)**
145+
Enumerations (picklists) referenced by the `range` attribute of selected or subordinate fields are listed here. Each enumeration has its own checkbox; expanding an enumeration shows a checkbox for each individual permissible value. All items are checked by default.
146+
147+
- Uncheck an **enumeration** to skip that entire picklist and all its values.
148+
- Uncheck individual **permissible value** rows to copy the enumeration but exclude specific choices.
149+
150+
> **Note:** If you choose not to copy a picklist that one or more fields reference in their `range`, those fields will show a validation error on the Field tab (broken enumeration reference). This is expected — you can resolve it later by either copying the missing picklist separately or updating the field's `range` to point to a picklist that already exists in the target schema.
151+
136152
### What gets copied automatically (dependencies)
137153

138154
Before appending the selected rows, the editor checks whether any structural items they reference are already present in the target schema. Items that are missing are copied along automatically:

lib/AppContext.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,14 @@ export default class AppContext {
148148

149149
//console.log("REFRESHTABDISPLAY", class_name, this.schemaEditor, report_type)
150150

151-
// Display Focus path only if there is some path > 1 element.
152-
$("#record-hierarchy-div").toggle(Object.keys(this.dhs).length > 1);
151+
// Show Display menu and breadcrumb only when the current class has inter-table
152+
// relations (parent FK slots or child tables). A standalone class with neither
153+
// has no use for "Record(s) by selected key" filtering or a hierarchy path.
154+
const classRel = this.relations?.[class_name];
155+
const hasRelations = !!classRel
156+
&& (Object.keys(classRel.parent || {}).length > 0
157+
|| Object.keys(classRel.child || {}).length > 0);
158+
$("#record-hierarchy-div").toggle(hasRelations);
153159

154160
// Record hierarchy cookie crumbs on Display line at top of toolbar are
155161
// only shown for "Records by 1-many key"
@@ -591,8 +597,10 @@ export default class AppContext {
591597
this.dhs = this.makeDHsFromRelations(schema, template_name);
592598

593599
// this.currentDataHarmonizer is now set.
594-
this.crudGetDependentRows(this.current_data_harmonizer_name);
595-
this.crudUpdateRecordPath();
600+
// Use crudCalculateDependentKeys (not just crudGetDependentRows) so that
601+
// setDHTabStatus() is also called and tabs are correctly enabled/disabled
602+
// from the start — without requiring a user cell-click to trigger it.
603+
this.crudCalculateDependentKeys(this.current_data_harmonizer_name);
596604

597605
// Ensure dynamic Enums are added so picklist source / range references are
598606
// detected and pulldown/multiselect menus are crafted; and validation works
@@ -1559,9 +1567,13 @@ export default class AppContext {
15591567
// Presumes dependent_rows has been updated:
15601568
const domId = Object.keys(this.dhs).indexOf(class_name);
15611569
const state = this.dependent_rows.get(class_name).fkey_status;
1570+
// Disable when state < 2: state 0 = no FK satisfied, state 1 = partial
1571+
// (some FKs met, some not — e.g. schema_id known but class_id unknown).
1572+
// Enable when state 2 (no FKs) or 3 (all FKs satisfied).
1573+
const disabled = state < 2;
15621574
$('#tab-data-harmonizer-grid-' + domId)
1563-
.toggleClass('disabled',state === 0)
1564-
.parent().toggleClass('disabled',state === 0);
1575+
.toggleClass('disabled', disabled)
1576+
.parent().toggleClass('disabled', disabled);
15651577
}
15661578

15671579
/**

lib/DataHarmonizer.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ class DataHarmonizer {
218218
copyPaste: true,
219219
outsideClickDeselects: false, // for maintaining selection between tabs
220220
manualColumnResize: true,
221+
manualRowResize: false, // Note Handsontable has a bug according to Claude: What's happening: When the context menu opens (right-click), the ManualRowResize plugin's _onContextMenu handler tries to clean up its resize-guide DOM element by calling parent.removeChild(element). But a HOT re-render (triggered by, e.g., hidden-rows plugin recalculating, or switching selection across a tab with many rows) has already detached and re-created that DOM node, so the parent no longer holds the original node reference — causing the NotFoundError.
221222
//colWidths: [100], //Just fixes first column width
222223
minRows: 5,
223224
minSpareRows: 0,
@@ -363,6 +364,16 @@ class DataHarmonizer {
363364
},
364365
callback() { self.context.schemaEditor.previewSchema(); }
365366
},
367+
copy_to_schema: {
368+
name: 'Copy to schema',
369+
hidden() {
370+
const schema = self.context.dhs.Schema;
371+
return schema?.schema.name !== "DH_LinkML";
372+
},
373+
callback() {
374+
self.context.schemaEditor.openCopyToSchemaModal(self);
375+
}
376+
},
366377
// FUTURE Implementation
367378
// Issue is that this doesn't freeze the column user is on. It
368379
// freezes the first unfrozen column to left.
@@ -945,6 +956,14 @@ class DataHarmonizer {
945956
const wtHolder = self.hot.rootElement?.querySelector('.wtHolder');
946957
const scrollTop = wtHolder?.scrollTop ?? 0;
947958
self.hot.loadData(reordered);
959+
// loadData() resets the hiddenRows plugin, revealing all rows.
960+
// In "Records by selected key" mode, re-apply the tab filter so only
961+
// rows matching the current key selection remain visible.
962+
// In "All records" mode all rows were already visible, so no re-apply
963+
// is needed (and doing so would trigger unwanted cross-tab side effects).
964+
if (($('input[name="display-main-type"]:checked').val() ?? '') !== 'all') {
965+
self.context?.refreshTabDisplay();
966+
}
948967
setTimeout(() => {
949968
if (wtHolder) wtHolder.scrollTop = scrollTop;
950969
// Re-select exactly the moved rows without auto-scrolling the
@@ -1226,6 +1245,8 @@ class DataHarmonizer {
12261245
if (isEmpty(parents)) {
12271246
// Insert the new rows below the last existing row
12281247
this.hot.alter(row_where, startRowIndex, numRows);
1248+
// hot.alter() can reset HOT's hidden-columns plugin state; re-apply concise view.
1249+
if (this._conciseViewActive) this.context.toolbar?._applyConciseView(this);
12291250
return;
12301251
}
12311252

@@ -1257,6 +1278,8 @@ class DataHarmonizer {
12571278
});
12581279
}
12591280
});
1281+
// hot.alter() can reset HOT's hidden-columns plugin state; re-apply concise view.
1282+
if (this._conciseViewActive) this.context.toolbar?._applyConciseView(this);
12601283
}
12611284

12621285
/**

0 commit comments

Comments
 (0)