pict-section-form 1.3.3 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pict-section-form",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "Pict dynamic forms",
5
5
  "main": "source/Pict-Section-Form.js",
6
6
  "directories": {
@@ -1389,15 +1389,17 @@ class TabularLayout extends libPictSectionGroupLayout
1389
1389
  // Leading (non-data) columns that precede the data cells: row-select, row labels, left controls.
1390
1390
  let tmpLeadingColumnCount = (tmpRowSelectionEnabled ? 1 : 0) + tmpRowLabels.length + (tmpEditingLeft ? 1 : 0);
1391
1391
 
1392
- // When EditingControlsPosition isn't 'right' (the default), suppress the default
1393
- // extra-postfix slots by registering empty view-specific overrides. This keeps the
1394
- // existing template machinery intact for backwards compatibility -- consumers that
1395
- // don't opt in to the new behavior see identical output.
1396
- if (tmpEditingControlsPosition === 'left' || tmpEditingControlsPosition === 'hidden')
1397
- {
1398
- this.pict.TemplateProvider.addTemplate(pView.getViewSpecificTemplateHash('-TabularTemplate-Row-ExtraPostfix'), '');
1399
- this.pict.TemplateProvider.addTemplate(pView.getViewSpecificTemplateHash('-TabularTemplate-RowHeader-ExtraPostfix'), '');
1400
- }
1392
+ // When EditingControlsPosition isn't 'right' (the default), the right-side editing-
1393
+ // controls slots are suppressed PER GROUP by gating their emission on tmpEditingRight
1394
+ // below (the RowHeader-ExtraPostfix parity cell and the per-row Row-ExtraPostfix cell).
1395
+ //
1396
+ // We must NOT suppress by registering an empty view-specific override here:
1397
+ // getViewSpecificTemplateHash() is keyed by the view's formsTemplateSetPrefix, which is
1398
+ // shared by EVERY tabular group in the section. A single 'hidden'/'left' group registering
1399
+ // the empty override would shadow the default editing-controls template for sibling groups
1400
+ // that DO want controls ('right'), deleting their menu column from the DOM entirely. The
1401
+ // gate is the group's own EditingControlsPosition, so each group is independent and a
1402
+ // view-specific override (if a host registers one) still applies to the groups that emit.
1401
1403
 
1402
1404
  // The chooser bar sits ABOVE the group's table container (a div can't live
1403
1405
  // inside <table> without the browser foster-parenting it out anyway).
@@ -1542,7 +1544,12 @@ class TabularLayout extends libPictSectionGroupLayout
1542
1544
  tmpDataColumnCount++;
1543
1545
  }
1544
1546
 
1545
- tmpTemplate += tmpMetatemplateGenerator.getMetatemplateTemplateReference(pView, `-TabularTemplate-RowHeader-ExtraPostfix`, `getGroup("${pGroup.GroupIndex}")`);
1547
+ // Right-side editing-controls header parity cell -- only when this group keeps its
1548
+ // controls on the right. Gated per group (matches the extra-header-row parity above).
1549
+ if (tmpEditingRight)
1550
+ {
1551
+ tmpTemplate += tmpMetatemplateGenerator.getMetatemplateTemplateReference(pView, `-TabularTemplate-RowHeader-ExtraPostfix`, `getGroup("${pGroup.GroupIndex}")`);
1552
+ }
1546
1553
  tmpTemplate += tmpMetatemplateGenerator.getMetatemplateTemplateReference(pView, `-TabularTemplate-RowHeader-Postfix`, `getGroup("${pGroup.GroupIndex}")`);
1547
1554
 
1548
1555
  // Warn on header alignment mismatches (data-column count must equal each extra-header
@@ -1584,7 +1591,13 @@ class TabularLayout extends libPictSectionGroupLayout
1584
1591
  }
1585
1592
 
1586
1593
  tmpTemplateSetVirtualRowTemplate += `\n\n{~T:${pGroup.SectionTabularRowTemplateHash}:Record~}\n`;
1587
- tmpTemplateSetVirtualRowTemplate += tmpMetatemplateGenerator.getMetatemplateTemplateReferenceRaw(pView, `-TabularTemplate-Row-ExtraPostfix`, `Record`);
1594
+ // Right-side editing-controls cell (del/up/down) -- only when this group keeps its
1595
+ // controls on the right. Gated per group so a sibling group's 'hidden'/'left' setting
1596
+ // can't suppress this group's column. 'left' emits its controls via {~TEC:~} above.
1597
+ if (tmpEditingRight)
1598
+ {
1599
+ tmpTemplateSetVirtualRowTemplate += tmpMetatemplateGenerator.getMetatemplateTemplateReferenceRaw(pView, `-TabularTemplate-Row-ExtraPostfix`, `Record`);
1600
+ }
1588
1601
  tmpTemplateSetVirtualRowTemplate += tmpMetatemplateGenerator.getMetatemplateTemplateReference(pView, `-TabularTemplate-Row-Postfix`, `getGroup("${pGroup.GroupIndex}")`);
1589
1602
 
1590
1603
  // This is a custom template expression
@@ -1687,4 +1687,81 @@ suite('PictSectionForm Tabular Features', () =>
1687
1687
  }, fDone);
1688
1688
  });
1689
1689
  });
1690
+
1691
+ // ------------------------------------------------------------------------
1692
+ // Regression: editing controls are PER GROUP, not per section.
1693
+ // A 'hidden'/'left' tabular group used to register a view-shared empty
1694
+ // template override (keyed by formsTemplateSetPrefix, which every group in
1695
+ // the section shares), which deleted the right-side controls column of any
1696
+ // sibling 'right' group -- the column was absent from the DOM, not just
1697
+ // hidden. The fix gates the controls emission on the group's own
1698
+ // EditingControlsPosition instead of a shared override.
1699
+ // ------------------------------------------------------------------------
1700
+ suite('Editing controls position is per-group (no section-wide bleed)', () =>
1701
+ {
1702
+ function makeTwoGroupApplication(pGroupA, pGroupB)
1703
+ {
1704
+ let App = makeApplication(pGroupA);
1705
+ App.default_configuration.pict_configuration.DefaultFormManifest.Sections[0].Groups.push(JSON.parse(JSON.stringify(pGroupB)));
1706
+ return App;
1707
+ }
1708
+
1709
+ test("A sibling 'hidden' group does not suppress a 'right' group's controls column", (fDone) =>
1710
+ {
1711
+ let App = makeTwoGroupApplication(
1712
+ { Hash: 'Students', Layout: 'Tabular', RecordSetAddress: 'Students', RecordManifest: 'StudentEditor', EditingControlsPosition: 'hidden' },
1713
+ { Hash: 'Grades', Layout: 'Tabular', RecordSetAddress: 'Grades', RecordManifest: 'GradeRowEditor', EditingControlsPosition: 'right' }
1714
+ );
1715
+ bootstrap(App, (_Pict) =>
1716
+ {
1717
+ let tmpView = _Pict.views['PictSectionForm-Class'];
1718
+ let tmpLayout = _Pict.providers['Pict-Layout-Tabular'];
1719
+ let tmpHidden = tmpView.sectionDefinition.Groups[0];
1720
+ let tmpRight = tmpView.sectionDefinition.Groups[1];
1721
+
1722
+ // Bake in section order -- the 'hidden' group first, which is what used to
1723
+ // poison the section by registering the view-shared empty override.
1724
+ let tmpHiddenTemplate = tmpLayout.generateGroupLayoutTemplate(tmpView, tmpHidden);
1725
+ let tmpRightTemplate = tmpLayout.generateGroupLayoutTemplate(tmpView, tmpRight);
1726
+
1727
+ // (1) ROOT-CAUSE GUARD: a hidden/left group must NOT register a section-shared
1728
+ // empty override at the view-specific prefix (this is what shadowed the default
1729
+ // controls template for every other group in the section).
1730
+ Expect(tmpView.checkViewSpecificTemplate('-TabularTemplate-Row-ExtraPostfix')).to.equal(false, 'no section-shared per-row controls override registered');
1731
+ Expect(tmpView.checkViewSpecificTemplate('-TabularTemplate-RowHeader-ExtraPostfix')).to.equal(false, 'no section-shared header controls override registered');
1732
+
1733
+ // (2) The 'hidden' group itself emits no right-side controls (header parity or row cell).
1734
+ Expect(tmpHidden.SectionTabularRowVirtualTemplateHash).to.be.a('string');
1735
+ let tmpHiddenRow = _Pict.TemplateProvider.templates[tmpHidden.SectionTabularRowVirtualTemplateHash];
1736
+ Expect(tmpHiddenTemplate).to.not.contain('-TabularTemplate-RowHeader-ExtraPostfix', 'hidden group emits no header controls cell');
1737
+ Expect(tmpHiddenRow).to.not.contain('-TabularTemplate-Row-ExtraPostfix', 'hidden group emits no per-row controls cell');
1738
+
1739
+ // (3) The 'right' sibling KEEPS its controls (header parity + per-row cell).
1740
+ Expect(tmpRight.SectionTabularRowVirtualTemplateHash).to.be.a('string');
1741
+ let tmpRightRow = _Pict.TemplateProvider.templates[tmpRight.SectionTabularRowVirtualTemplateHash];
1742
+ Expect(tmpRightTemplate).to.contain('-TabularTemplate-RowHeader-ExtraPostfix', 'right group keeps its header controls cell');
1743
+ Expect(tmpRightRow).to.contain('-TabularTemplate-Row-ExtraPostfix', 'right group keeps its per-row controls cell');
1744
+
1745
+ // (4) ...and that per-row reference resolves to the REAL del/up/down control
1746
+ // (the default template is intact and reachable, not an empty override).
1747
+ let tmpDefaultControl = _Pict.TemplateProvider.templates[tmpView.defaultTemplatePrefix + '-TabularTemplate-Row-ExtraPostfix'];
1748
+ Expect(tmpDefaultControl).to.contain('deleteDynamicTableRow', 'default row-controls template still wired to the delete/move handlers');
1749
+ }, fDone);
1750
+ });
1751
+
1752
+ test("A lone 'right' (default) group keeps its controls column", (fDone) =>
1753
+ {
1754
+ let App = makeApplication({ Hash: 'Students', Layout: 'Tabular', RecordSetAddress: 'Students', RecordManifest: 'StudentEditor' });
1755
+ bootstrap(App, (_Pict) =>
1756
+ {
1757
+ let tmpView = _Pict.views['PictSectionForm-Class'];
1758
+ let tmpLayout = _Pict.providers['Pict-Layout-Tabular'];
1759
+ let tmpGroup = tmpView.sectionDefinition.Groups[0];
1760
+ let tmpTemplate = tmpLayout.generateGroupLayoutTemplate(tmpView, tmpGroup);
1761
+ let tmpRow = _Pict.TemplateProvider.templates[tmpGroup.SectionTabularRowVirtualTemplateHash];
1762
+ Expect(tmpTemplate).to.contain('-TabularTemplate-RowHeader-ExtraPostfix', 'default (right) group has its header controls cell');
1763
+ Expect(tmpRow).to.contain('-TabularTemplate-Row-ExtraPostfix', 'default (right) group has its per-row controls cell');
1764
+ }, fDone);
1765
+ });
1766
+ });
1690
1767
  });