@elytracms/studio 0.0.41 → 0.0.43

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.
Files changed (151) hide show
  1. package/dist/components/assets/asset-detail.js +1 -1
  2. package/dist/components/assets/asset-detail.js.map +1 -1
  3. package/dist/components/assets/assets-module.js +19 -6
  4. package/dist/components/assets/assets-module.js.map +1 -1
  5. package/dist/components/assets/assets-store.d.ts +2 -1
  6. package/dist/components/assets/assets-store.js +4 -8
  7. package/dist/components/assets/assets-store.js.map +1 -1
  8. package/dist/components/assets/assets-view-preference.d.ts +0 -8
  9. package/dist/components/assets/assets-view-preference.js +12 -13
  10. package/dist/components/assets/assets-view-preference.js.map +1 -1
  11. package/dist/components/auth-context.d.ts +2 -1
  12. package/dist/components/auth-context.js +6 -8
  13. package/dist/components/auth-context.js.map +1 -1
  14. package/dist/components/builder/builder-store.d.ts +2 -2
  15. package/dist/components/builder/builder-store.js +4 -8
  16. package/dist/components/builder/builder-store.js.map +1 -1
  17. package/dist/components/builder/canvas.js +16 -2
  18. package/dist/components/builder/canvas.js.map +1 -1
  19. package/dist/components/cms/bulk-actions.js +2 -1
  20. package/dist/components/cms/bulk-actions.js.map +1 -1
  21. package/dist/components/cms/cell-edit.js +2 -1
  22. package/dist/components/cms/cell-edit.js.map +1 -1
  23. package/dist/components/cms/cms-composition-validators.d.ts +25 -0
  24. package/dist/components/cms/cms-composition-validators.js +75 -0
  25. package/dist/components/cms/cms-composition-validators.js.map +1 -0
  26. package/dist/components/cms/cms-labels.d.ts +15 -0
  27. package/dist/components/cms/cms-labels.js +27 -0
  28. package/dist/components/cms/cms-labels.js.map +1 -0
  29. package/dist/components/cms/cms-store.d.ts +23 -10
  30. package/dist/components/cms/cms-store.js +78 -154
  31. package/dist/components/cms/cms-store.js.map +1 -1
  32. package/dist/components/cms/collection-table.js +1 -1
  33. package/dist/components/cms/collection-table.js.map +1 -1
  34. package/dist/components/cms/detail-editor.js +67 -67
  35. package/dist/components/cms/detail-editor.js.map +1 -1
  36. package/dist/components/cms/details-pane.d.ts +11 -21
  37. package/dist/components/cms/details-pane.js +14 -31
  38. package/dist/components/cms/details-pane.js.map +1 -1
  39. package/dist/components/cms/discard-draft.d.ts +18 -0
  40. package/dist/components/cms/discard-draft.js +18 -0
  41. package/dist/components/cms/discard-draft.js.map +1 -1
  42. package/dist/components/cms/document-editor-context.d.ts +2 -1
  43. package/dist/components/cms/document-editor-context.js +4 -9
  44. package/dist/components/cms/document-editor-context.js.map +1 -1
  45. package/dist/components/cms/document-ref-utils.d.ts +33 -0
  46. package/dist/components/cms/document-ref-utils.js +47 -0
  47. package/dist/components/cms/document-ref-utils.js.map +1 -0
  48. package/dist/components/cms/document-url-path.d.ts +39 -0
  49. package/dist/components/cms/document-url-path.js +60 -0
  50. package/dist/components/cms/document-url-path.js.map +1 -0
  51. package/dist/components/cms/field-control.js +19 -13
  52. package/dist/components/cms/field-control.js.map +1 -1
  53. package/dist/components/cms/issues-pane.js +1 -1
  54. package/dist/components/cms/issues-pane.js.map +1 -1
  55. package/dist/components/cms/rich-text/block-commands.d.ts +36 -0
  56. package/dist/components/cms/rich-text/block-commands.js +47 -0
  57. package/dist/components/cms/rich-text/block-commands.js.map +1 -0
  58. package/dist/components/cms/rich-text/slash-command.js +25 -8
  59. package/dist/components/cms/rich-text/slash-command.js.map +1 -1
  60. package/dist/components/cms/rich-text/toolbar.js +3 -2
  61. package/dist/components/cms/rich-text/toolbar.js.map +1 -1
  62. package/dist/components/cms/version-compare.js +1 -1
  63. package/dist/components/cms/version-compare.js.map +1 -1
  64. package/dist/components/cms/versions-model.d.ts +31 -0
  65. package/dist/components/cms/versions-model.js +30 -0
  66. package/dist/components/cms/versions-model.js.map +1 -1
  67. package/dist/components/cms/view-bar.js +9 -6
  68. package/dist/components/cms/view-bar.js.map +1 -1
  69. package/dist/components/collab/collab-context.d.ts +2 -1
  70. package/dist/components/collab/collab-context.js +4 -8
  71. package/dist/components/collab/collab-context.js.map +1 -1
  72. package/dist/components/collection-view/collection-view-context.d.ts +9 -1
  73. package/dist/components/collection-view/collection-view-context.js +4 -9
  74. package/dist/components/collection-view/collection-view-context.js.map +1 -1
  75. package/dist/components/components/component-detail.js +2 -5
  76. package/dist/components/components/component-detail.js.map +1 -1
  77. package/dist/components/components/component-preview.js +8 -4
  78. package/dist/components/components/component-preview.js.map +1 -1
  79. package/dist/components/components/registry-browser.js +24 -5
  80. package/dist/components/components/registry-browser.js.map +1 -1
  81. package/dist/components/components/transfer-dialog.d.ts +10 -0
  82. package/dist/components/components/transfer-dialog.js +24 -8
  83. package/dist/components/components/transfer-dialog.js.map +1 -1
  84. package/dist/components/delivery-health-banner.d.ts +12 -6
  85. package/dist/components/delivery-health-banner.js +27 -29
  86. package/dist/components/delivery-health-banner.js.map +1 -1
  87. package/dist/components/dev-login-badge.d.ts +0 -2
  88. package/dist/components/dev-login-badge.js +1 -3
  89. package/dist/components/dev-login-badge.js.map +1 -1
  90. package/dist/components/inspector/inspector-sidebar.js +20 -3
  91. package/dist/components/inspector/inspector-sidebar.js.map +1 -1
  92. package/dist/components/playground-badge.d.ts +0 -2
  93. package/dist/components/playground-badge.js +0 -2
  94. package/dist/components/playground-badge.js.map +1 -1
  95. package/dist/components/project-list.js +2 -6
  96. package/dist/components/project-list.js.map +1 -1
  97. package/dist/components/project-session.d.ts +6 -2
  98. package/dist/components/project-session.js +32 -83
  99. package/dist/components/project-session.js.map +1 -1
  100. package/dist/components/project-switcher.js +2 -6
  101. package/dist/components/project-switcher.js.map +1 -1
  102. package/dist/components/redirects/redirects-store.d.ts +2 -1
  103. package/dist/components/redirects/redirects-store.js +4 -8
  104. package/dist/components/redirects/redirects-store.js.map +1 -1
  105. package/dist/components/studio-context.d.ts +2 -1
  106. package/dist/components/studio-context.js +4 -8
  107. package/dist/components/studio-context.js.map +1 -1
  108. package/dist/components/studio-shell.js +1 -1
  109. package/dist/components/studio-shell.js.map +1 -1
  110. package/dist/components/theme-context.d.ts +2 -1
  111. package/dist/components/theme-context.js +4 -8
  112. package/dist/components/theme-context.js.map +1 -1
  113. package/dist/components/use-hydration-phase.d.ts +65 -0
  114. package/dist/components/use-hydration-phase.js +64 -0
  115. package/dist/components/use-hydration-phase.js.map +1 -0
  116. package/dist/components/users/users-store.d.ts +2 -1
  117. package/dist/components/users/users-store.js +4 -8
  118. package/dist/components/users/users-store.js.map +1 -1
  119. package/dist/components/workspace-projects.d.ts +14 -0
  120. package/dist/components/workspace-projects.js +21 -0
  121. package/dist/components/workspace-projects.js.map +1 -1
  122. package/dist/lib/data/data-store.d.ts +2 -1
  123. package/dist/lib/data/data-store.js +4 -8
  124. package/dist/lib/data/data-store.js.map +1 -1
  125. package/dist/lib/delivery/instant-publish.d.ts +9 -13
  126. package/dist/lib/delivery/instant-publish.js +0 -7
  127. package/dist/lib/delivery/instant-publish.js.map +1 -1
  128. package/dist/lib/diff-view-preference.js +4 -4
  129. package/dist/lib/diff-view-preference.js.map +1 -1
  130. package/dist/lib/i18n/messages.en.js +7 -5
  131. package/dist/lib/i18n/messages.en.js.map +1 -1
  132. package/dist/lib/local-preference.d.ts +37 -0
  133. package/dist/lib/local-preference.js +36 -0
  134. package/dist/lib/local-preference.js.map +1 -1
  135. package/dist/lib/persistence/convex-adapter.d.ts +3 -1
  136. package/dist/lib/persistence/convex-adapter.js +20 -0
  137. package/dist/lib/persistence/convex-adapter.js.map +1 -1
  138. package/dist/lib/rail.js +7 -6
  139. package/dist/lib/rail.js.map +1 -1
  140. package/dist/lib/required-context.d.ts +24 -0
  141. package/dist/lib/required-context.js +28 -0
  142. package/dist/lib/required-context.js.map +1 -0
  143. package/dist/lib/theme.js +11 -4
  144. package/dist/lib/theme.js.map +1 -1
  145. package/dist/ui/index.d.ts +1 -0
  146. package/dist/ui/index.js +1 -0
  147. package/dist/ui/index.js.map +1 -1
  148. package/dist/ui/segmented-control.d.ts +46 -0
  149. package/dist/ui/segmented-control.js +13 -0
  150. package/dist/ui/segmented-control.js.map +1 -0
  151. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"collection-table.js","sourceRoot":"","sources":["../../../src/components/cms/collection-table.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAC9F,OAAO,EACL,SAAS,EACT,OAAO,EACP,eAAe,EACf,QAAQ,EACR,GAAG,EACH,MAAM,EACN,YAAY,EACZ,cAAc,EACd,MAAM,EACN,IAAI,EACJ,MAAM,EACN,MAAM,GACP,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,GAAG,EACH,SAAS,EACT,MAAM,EACN,KAAK,EACL,IAAI,GACL,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpF,OAAO,EACL,eAAe,EACf,WAAW,EACX,cAAc,EACd,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,cAAc,EACd,gBAAgB,GACjB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,4BAA4B,EAC5B,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,GACf,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAA;AAC1F,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAA;AAEtG,MAAM,UAAU,eAAe,CAAC,EAAE,SAAS,EAAE,YAAY,EAA+C;IACtG,iFAAiF;IACjF,iFAAiF;IACjF,MAAM,MAAM,GAAG,0BAA0B,CAAC,YAAY,CAAC,CAAA;IAEvD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CACL,cAAK,SAAS,EAAC,oCAAoC,YACjD,MAAC,IAAI,IAAC,IAAI,EAAC,OAAO,oCACG,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,YAAE,YAAY,GAAQ,SACtD,GACH,CACP,CAAA;IACH,CAAC;IAED,iFAAiF;IACjF,OAAO,CACL,KAAC,sBAAsB,IAAC,MAAM,EAAE,MAAM,YACpC,KAAC,qBAAqB,IAAoB,SAAS,EAAE,SAAS,IAAlC,YAAY,CAA0B,GAC3C,CAC1B,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,SAAS,EACT,YAAY,GASb;IACC,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAA;IAChC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAA;IACxC,6EAA6E;IAC7E,kDAAkD;IAClD,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC,CAAA;IACnF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAiB,eAAe,CAAC,CAAA;IAC3E,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAA;IACrE,4EAA4E;IAC5E,qEAAqE;IACrE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAGpC,IAAI,CAAC,CAAA;IAEf,4EAA4E;IAC5E,uEAAuE;IACvE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,CAAA;IACpC,6EAA6E;IAC7E,mEAAmE;IACnE,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;IACpD,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;IACxF,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;IAEzE,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,EAAE,CAAA;IAE/B,8EAA8E;IAC9E,iFAAiF;IACjF,gFAAgF;IAChF,+EAA+E;IAC/E,4EAA4E;IAC5E,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,uBAAuB,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAA;IAEhG,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,IAAI,IAAI,CAAA;IAE1D,MAAM,WAAW,GAAG,OAAO;IACzB,2EAA2E;IAC3E,uEAAuE;IACvE,GAAG,EAAE,CACH,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,YAAY,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CACvE,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CACpF,CAAC,IAAI,EACR,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,YAAY,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,CACtE,CAAA;IAED,4EAA4E;IAC5E,wEAAwE;IACxE,yEAAyE;IACzE,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,SAAS,CAAA;IAClD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAA;IACtD,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,EAAE,CAAC,CAAC,YAAY,IAAI,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAC1E,CAAC,YAAY,EAAE,QAAQ,EAAE,WAAW,CAAC,CACtC,CAAA;IACD,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;IAC3E,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EACtF,CAAC,QAAQ,CAAC,CACX,CAAA;IAED,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,YAAY,GAAG,CAAC,CAAA;IAC9E,MAAM,aAAa,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;IAClF,MAAM,UAAU,GACd,WAAW,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAChC,CAAC,CAAC,SAAS,CAAC,gBAAgB,EAAE;YAC1B,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,IAAI,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW;SACtD,CAAC;QACJ,CAAC,CAAC,SAAS,CAAC,wBAAwB,EAAE;YAClC,OAAO,EAAE,WAAW,CAAC,MAAM;YAC3B,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,IAAI,EAAE,WAAW;SAClB,CAAC,CAAA;IAER,yEAAyE;IACzE,+EAA+E;IAC/E,2EAA2E;IAC3E,8EAA8E;IAC9E,8EAA8E;IAC9E,MAAM,gBAAgB,GAAG,YAAY,KAAK,MAAM,CAAA;IAChD,8EAA8E;IAC9E,gFAAgF;IAChF,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAA;IAC/E,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACzC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAM;QAC/B,QAAQ,CAAC,EAAE,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;IAC9E,CAAC,CAAA;IACD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACnD,2EAA2E;IAC3E,gDAAgD;IAChD,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;IAC3D,6EAA6E;IAC7E,2EAA2E;IAC3E,0EAA0E;IAC1E,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,YAAY,CAAC,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAA;IAElH,SAAS,UAAU,CAAC,KAAa;QAC/B,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,MAAM,IAAI,GACR,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,KAAK;gBACxB,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE;gBACvB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK;oBACvB,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE;oBACxB,CAAC,CAAC,IAAI,CAAA;YACZ,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAA;QAC1B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,SAAS,CAAC,MAAkB;QACnC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAA;YACzC,OAAM;QACR,CAAC;QACD,kEAAkE;QAClE,8CAA8C;QAC9C,IAAI,MAAM,KAAK,WAAW;YAAE,OAAM;QAClC,oEAAoE;QACpE,qEAAqE;QACrE,cAAc,CAAC;YACb,MAAM;YACN,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;SACrE,CAAC,CAAA;IACJ,CAAC;IAED,wEAAwE;IACxE,wEAAwE;IACxE,wEAAwE;IACxE,4EAA4E;IAC5E,wEAAwE;IACxE,SAAS,eAAe,CAAC,MAAiB,EAAE,GAAgB;QAC1D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACzC,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAM;YAC/B,QAAQ,CAAC,EAAE,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAA;YAC5E,OAAM;QACR,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YACjC,OAAM;QACR,CAAC;QACD,uEAAuE;QACvE,uCAAuC;QACvC,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;IACjF,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,MAAkB,EAAE,KAAwB,EAAE,QAAuB;QAC7F,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,OAAM;QACxB,WAAW,CAAC,IAAI,CAAC,CAAA;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;YAC9D,aAAa,CAAC,MAAM,CAAC,CAAA;YACrB,oEAAoE;YACpE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;YAC/B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;YAChF,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACtB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACjE,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC,CAAA;QACL,CAAC;gBAAS,CAAC;YACT,WAAW,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IAED,SAAS,UAAU;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACxD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAA;QAC3D,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;QACrC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAA;QACZ,CAAC,CAAC,QAAQ,GAAG,GAAG,YAAY,OAAO,CAAA;QACnC,CAAC,CAAC,KAAK,EAAE,CAAA;QACT,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,8BAA8B,aAM3C,cAAK,SAAS,EAAC,mDAAmD,YAChE,MAAC,GAAG,IAAC,GAAG,EAAC,GAAG,EAAC,IAAI,mBAEf,KAAC,QAAQ,KAAG,EAGZ,KAAC,aAAa,IAAC,UAAU,EAAE,UAAU,GAAI,EAGzC,KAAC,SAAS,IAAC,WAAW,EAAC,UAAU,EAAC,SAAS,EAAC,iBAAiB,GAAG,EAChE,KAAC,IAAI,IACH,EAAE,EAAC,MAAM,EACT,IAAI,EAAC,IAAI,EACT,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,gCAAgC,iBAC9B,kBAAkB,YAE7B,UAAU,GACN,EAEP,KAAC,MAAM,KAAG,EAIT,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,KAAC,cAAc,KAAG,CAAC,CAAC,CAAC,IAAI,EACxD,KAAC,WAAW,IACV,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,WAAW,GACzB,EACD,SAAS,CAAC,CAAC,CAAC,CACX,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,SAAS,iBAAc,cAAc,aAC9D,KAAC,IAAI,KAAG,OAAE,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,IAC/E,CACV,CAAC,CAAC,CAAC,IAAI,EAIP,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAClC,MAAC,YAAY,eACX,KAAC,mBAAmB,IAAC,OAAO,kBAC1B,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,SAAS,gBACF,SAAS,CAAC,sBAAsB,CAAC,iBACjC,oBAAoB,YAEhC,KAAC,cAAc,KAAG,GACX,GACW,EACtB,MAAC,mBAAmB,IAAC,KAAK,EAAC,KAAK,aAC9B,MAAC,gBAAgB,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,iBAAc,eAAe,aAC/E,KAAC,MAAM,KAAG,OAAE,SAAS,CAAC,iBAAiB,CAAC,IACvB,EACnB,MAAC,gBAAgB,IACf,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,iBACf,eAAe,aAE3B,KAAC,QAAQ,KAAG,OAAE,SAAS,CAAC,iBAAiB,CAAC,IACzB,IACC,IACT,CAChB,CAAC,CAAC,CAAC,IAAI,EACP,YAAY,IACT,GACF,EAGN,KAAC,OAAO,IACN,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,WAAW,CAAC,MAAM,EACzB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,SAAS,EACnB,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,UAAU,CAAC,WAAW,EAAE,CAAC,GAAG,WAAW,CAAC,EAAE,QAAQ,CAAC,EAClF,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC,GAC7C,EACD,UAAU,CAAC,CAAC,CAAC,CACZ,KAAC,eAAe,IAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAI,CAC9E,CAAC,CAAC,CAAC,IAAI,EAGP,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,CACtB,KAAC,sBAAsB,IACrB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,WAAW,CAAC,MAAM,EAC1B,OAAO,EAAE,WAAW,CAAC,OAAO,EAC5B,IAAI,QACJ,IAAI,EAAE,QAAQ,EACd,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;oBACrB,IAAI,CAAC,IAAI;wBAAE,cAAc,CAAC,IAAI,CAAC,CAAA;gBACjC,CAAC,EACD,SAAS,EAAE,GAAG,EAAE;oBACd,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;oBACvC,cAAc,CAAC,IAAI,CAAC,CAAA;oBACpB,KAAK,UAAU,CACb,MAAM,EACN,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CACnC,CAAA;gBACH,CAAC,GACD,CACH,CAAC,CAAC,CAAC,IAAI,EAIP,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACxB,cACE,SAAS,EAAC,qEAAqE,iBACnE,qBAAqB,YAEjC,KAAC,KAAK,IAAC,GAAG,EAAC,GAAG,YACX,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAC7B,MAAC,GAAG,IAA4B,GAAG,EAAC,GAAG,EAAC,KAAK,EAAC,OAAO,aACnD,KAAC,aAAa,IAAC,SAAS,EAAC,uCAAuC,wBAAe,EAC/E,MAAC,KAAK,IAAC,GAAG,EAAC,MAAM,EAAC,SAAS,EAAC,SAAS,aACnC,MAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAC,UAAU,EAAC,IAAI,EAAC,SAAS,EAAC,KAAK,EAAE,KAAK,CAAC,IAAI,aAC/D,SAAS,CAAC,oBAAoB,CAAC,cAAK,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IACzD,EACP,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,YACzB,KAAK,CAAC,OAAO,GACT,IACD,KATA,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,EAAE,CAUxB,CACP,CAAC,GACI,GACJ,CACP,CAAC,CAAC,CAAC,IAAI,EAGR,cAAK,SAAS,EAAC,8BAA8B,YAC1C,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACnB,cAAK,SAAS,EAAC,oCAAoC,YACjD,MAAC,KAAK,IAAC,GAAG,EAAC,GAAG,EAAC,KAAK,EAAC,QAAQ,EAAC,SAAS,EAAC,aAAa,aACnD,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,YAAE,SAAS,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC,GAAQ,EAC/F,SAAS,CAAC,CAAC,CAAC,CACX,MAAC,MAAM,IAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,SAAS,aAClC,KAAC,IAAI,KAAG,EAAC,GAAG,EACX,gBAAgB;wCACf,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC;wCAC/B,CAAC,CAAC,SAAS,CAAC,mBAAmB,EAAE;4CAC7B,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC;yCACjE,CAAC,IACC,CACV,CAAC,CAAC,CAAC,IAAI,IACF,GACJ,CACP,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC7B,cAAK,SAAS,EAAC,oCAAoC,YACjD,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,iBAAa,gBAAgB,YAC5C,SAAS,CAAC,wBAAwB,CAAC,GAC/B,GACH,CACP,CAAC,CAAC,CAAC,CACF,KAAC,aAAa,IACZ,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,WAAW,EACvB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CACzB,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,EAEhE,WAAW,EAAE,GAAG,EAAE,CAChB,YAAY,CACV,WAAW,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;wBAC/D,CAAC,CAAC,cAAc,EAAE;wBAClB,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAC1B,EAEH,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,eAAe,GAC5B,CACH,GACG,EAEL,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAClC,KAAC,YAAY,IAAC,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,GAAI,CAC5F,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,EACrB,SAAS,EACT,UAAU,EACV,OAAO,EACP,eAAe,EACf,OAAO,EACP,UAAU,EACV,SAAS,EACT,UAAU,EACV,IAAI,EACJ,MAAM,EACN,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,WAAW,GAoBZ;IACC,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;IAClC,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,CAAA;IAClC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IACpF,6EAA6E;IAC7E,MAAM,cAAc,GAAG,MAAM,CAAC,YAAY,CAAC,UAAU;QACnD,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;YAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA;QACtF,CAAC,CAAC;QACJ,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAA;IAC9E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;IACrC,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,CAAA;IAErF,OAAO,CACL,cAAK,GAAG,EAAE,QAAQ,CAAC,YAAY,YAS7B,iBAAO,SAAS,EAAC,4CAA4C,aAC3D,+BACE,cAAK,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,yBAAyB,KAAK,EAAE,GAAI,EAC5D,cAAK,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,wBAAwB,KAAK,EAAE,GAAI,EAC1D,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACrB,cAAgB,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAjE,IAAI,CAAiE,CAChF,CAAC,EACF,cAAK,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,sBAAsB,KAAK,EAAE,GAAI,EACxD,UAAU,CAAC,CAAC,CAAC,cAAK,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,oBAAoB,KAAK,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,EAC3E,aAAa,CAAC,CAAC,CAAC,cAAK,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,4BAA4B,KAAK,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,IAC9E,EACX,gBAAO,SAAS,EAAC,iCAAiC,YAChD,cAAI,SAAS,EAAC,wBAAwB,aACpC,aAAI,SAAS,EAAC,qBAAqB,YACjC,KAAC,iBAAiB,IAChB,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,EACrD,KAAK,EAAE,SAAS,CAAC,oBAAoB,CAAC,EACtC,MAAM,EAAC,YAAY,EACnB,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,GAC7B,GACC,EACL,KAAC,UAAU,IACT,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,EACzF,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACd,EACD,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gCACpB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;gCAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,CACb,KAAC,UAAU,IAAY,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAvE,IAAI,CAAuE,CAC7F,CAAC,CAAC,CAAC,IAAI,CAAA;4BACV,CAAC,CAAC,EACF,KAAC,UAAU,IAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,uBAAuB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAI,EAExG,UAAU,CAAC,CAAC,CAAC,CACZ,aAAI,SAAS,EAAC,iEAAiE,YAAE,SAAS,CAAC,qBAAqB,CAAC,GAAM,CACxH,CAAC,CAAC,CAAC,IAAI,EACP,aAAa,CAAC,CAAC,CAAC,CACf,aAAI,SAAS,EAAC,sBAAsB,YAClC,eAAM,SAAS,EAAC,SAAS,YAAE,SAAS,CAAC,gCAAgC,CAAC,GAAQ,GAC3E,CACN,CAAC,CAAC,CAAC,IAAI,IACL,GACC,EACR,0BACG,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACvB,cAEE,SAAS,EAAE,EAAE,CACX,mDAAmD,EACnD,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,cAAc,CACvC,aAED,aAAI,SAAS,EAAC,wBAAwB,YACpC,KAAC,iBAAiB,IAChB,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAC7B,KAAK,EAAE,SAAS,CAAC,oBAAoB,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EACtD,MAAM,EAAE,cAAc,GAAG,CAAC,EAAE,EAAE,EAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,GAC/C,GACC,EACL,aAAI,SAAS,EAAC,wBAAwB,YACpC,KAAC,WAAW,IACV,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAClC,MAAM,EAAE,MAAM,CAAC,YAAY,EAC3B,MAAM,EAAE,MAAM,CAAC,YAAY,EAC3B,UAAU,EAAE,MAAM,CAAC,UAAU,GAC7B,GACC,EACJ,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gCACpB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;gCAC/B,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;gCAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;gCAC1B,OAAO,CACL,aAAe,SAAS,EAAC,wBAAwB,YAC9C,KAAK,CAAC,CAAC,CAAC,CACP,KAAC,YAAY,IACX,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,QAAQ,CAAC,SAAS,KAAK,GAAG,EACnC,IAAI,EAAE,QAAQ,CAAC,OAAO,KAAK,GAAG,EAC9B,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EACnC,WAAW,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EACxC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,GACpE,CACH,CAAC,CAAC,CAAC,IAAI,IAbD,IAAI,CAcR,CACN,CAAA;4BACH,CAAC,CAAC,EACF,aAAI,SAAS,EAAC,wBAAwB,YACpC,KAAC,aAAa,IACZ,SAAS,EACP,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,GAEnF,GACC,EACJ,UAAU,CAAC,CAAC,CAAC,CACZ,aAAI,SAAS,EAAC,wBAAwB,YACpC,KAAC,OAAO,IAAC,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAI,GACrC,CACN,CAAC,CAAC,CAAC,IAAI,EACP,aAAa,CAAC,CAAC,CAAC,CACf,aAAI,SAAS,EAAC,mCAAmC,YAC/C,KAAC,cAAc,IACb,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,EAC5F,aAAa,EAAE,MAAM,CAAC,UAAU,KAAK,SAAS,EAC9C,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9C,GACC,CACN,CAAC,CAAC,CAAC,IAAI,KArEH,GAAG,CAAC,EAAE,CAsER,CACN,CAAC,GACI,IACF,GACJ,CACP,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,EACtB,GAAG,EACH,SAAS,EACT,aAAa,EACb,QAAQ,GAMT;IACC,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAA;IAClC,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAA;IAC9F,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACrC,OAAO,CACL,MAAC,YAAY,eACX,KAAC,mBAAmB,IAAC,OAAO,kBAC1B,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,SAAS,gBACF,SAAS,CAAC,0BAA0B,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,iBACpD,eAAe,GAAG,CAAC,EAAE,EAAE,YAEpC,KAAC,cAAc,KAAG,GACX,GACW,EACtB,KAAC,mBAAmB,IAAC,KAAK,EAAC,KAAK,YAC7B,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,KAAC,aAAa,IAAc,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAxD,MAAM,CAAsD,CACjF,CAAC,GACkB,IACT,CAChB,CAAA;AACH,CAAC;AAED,SAAS,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAA+C;IACtF,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,CACL,MAAC,gBAAgB,IAAC,OAAO,EAAE,QAAQ,iBAAc,iBAAiB,aAChE,KAAC,MAAM,KAAG,OAAE,SAAS,CAAC,yBAAyB,CAAC,IAC/B,CACpB,CAAA;QACH,KAAK,SAAS;YACZ,OAAO,CACL,MAAC,gBAAgB,IAAC,OAAO,EAAE,QAAQ,iBAAc,oBAAoB,aACnE,KAAC,GAAG,KAAG,OAAE,SAAS,CAAC,uBAAuB,CAAC,IAC1B,CACpB,CAAA;QACH,KAAK,WAAW;YACd,OAAO,CACL,MAAC,gBAAgB,IAAC,OAAO,EAAE,QAAQ,iBAAc,sBAAsB,aACrE,KAAC,MAAM,KAAG,OAAE,SAAS,CAAC,yBAAyB,CAAC,IAC/B,CACpB,CAAA;QACH,KAAK,QAAQ;YACX,OAAO,CACL,MAAC,gBAAgB,IACf,OAAO,EAAC,aAAa,EACrB,OAAO,EAAE,QAAQ,iBACL,mBAAmB,aAE/B,KAAC,MAAM,KAAG,OAAE,SAAS,CAAC,eAAe,CAAC,IACrB,CACpB,CAAA;IACL,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,EACzB,OAAO,EACP,aAAa,GAAG,KAAK,EACrB,KAAK,EACL,MAAM,EACN,QAAQ,GAOT;IACC,OAAO,CACL,gBACE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE;YACV,IAAI,EAAE;gBAAE,EAAE,CAAC,aAAa,GAAG,aAAa,IAAI,CAAC,OAAO,CAAA;QACtD,CAAC,EACD,IAAI,EAAC,UAAU,EACf,SAAS,EAAC,mDAAmD,EAC7D,OAAO,EAAE,OAAO,EAChB,QAAQ,sBACI,KAAK,iBACJ,MAAM,EACnB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC5C,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;gBAC1B,KAAK,CAAC,cAAc,EAAE,CAAA;gBACtB,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YAC1B,CAAC;QACH,CAAC,EACD,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;YACrB,IAAI,KAAK,CAAC,QAAQ;gBAAE,KAAK,CAAC,cAAc,EAAE,CAAA;QAC5C,CAAC,GACD,CACH,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,EAClB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,MAAM,GAMP;IACC,MAAM,MAAM,GAAG,IAAI,EAAE,KAAK,KAAK,KAAK,CAAA;IACpC,OAAO,CACL,aAAI,SAAS,EAAC,iEAAiE,YAC7E,kBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAC,sDAAsD,aACjH,KAAK,EACL,MAAM,CAAC,CAAC,CAAC,CACR,IAAK,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CACpB,KAAC,OAAO,IAAC,SAAS,EAAC,QAAQ,GAAG,CAC/B,CAAC,CAAC,CAAC,CACF,KAAC,SAAS,IAAC,SAAS,EAAC,QAAQ,GAAG,CACjC,CACF,CAAC,CAAC,CAAC,IAAI,IACD,GACN,CACN,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,EACnB,SAAS,EACT,UAAU,EACV,GAAG,EACH,OAAO,EACP,KAAK,GAAG,CAAC,EACT,MAAM,EACN,MAAM,EACN,UAAU,GAYX;IACC,gFAAgF;IAChF,2EAA2E;IAC3E,kFAAkF;IAClF,gFAAgF;IAChF,MAAM,KAAK,GAAG,oBAAoB,CAChC,UAAU,EACV,wBAAwB,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EACzD,GAAG,CAAC,EAAE,CACP,CAAA;IACD,MAAM,QAAQ,GACZ,OAAO,UAAU,CAAC,UAAU,KAAK,UAAU;QACzC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,qBAAqB,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAA;IAC9E,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAClC,OAAO,CACL,MAAC,GAAG,IAAC,GAAG,EAAC,GAAG,EAAC,KAAK,EAAC,QAAQ,EAAC,SAAS,EAAC,SAAS,EAAC,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,GAAG,EAAE,EAAE,aAC/E,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CACX,KAAC,eAAe,IAAC,SAAS,EAAC,yCAAyC,wBAAe,CACpF,CAAC,CAAC,CAAC,IAAI,EAIP,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAC,cAAc,IAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,GAAI,CAAC,CAAC,CAAC,IAAI,EACpF,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACrB,KAAC,IAAI,IACH,EAAE,EAAE,oBAAoB,EACxB,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EACpC,SAAS,EAAC,yEAAyE,YAElF,KAAK,GACD,CACR,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,EAAE,EAAC,MAAM,EAAC,SAAS,EAAC,sCAAsC,YAC7D,KAAK,GACD,CACR,EACD,KAAC,YAAY,IAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,iBAAiB,GAAG,CAAC,EAAE,IAAI,OAAO,EAAE,GAAI,IAC9E,CACP,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,EAAE,OAAO,EAAE,GAAG,EAAoC;IACxE,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IACtC,OAAO,KAAC,UAAU,IAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAC,iBAAiB,GAAG,CAAA;AAC7E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,OAAO,CAAC,EAAE,GAAG,EAAyB;IAC7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CACL,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,QAAQ,uBAEtB,CACR,CAAA;IACH,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,OAAO,CACL,aACE,IAAI,EAAE,GAAG,CAAC,IAAI,EACd,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,YAAY,EAChB,KAAK,EAAE,GAAG,CAAC,IAAI,EACf,SAAS,EAAC,oHAAoH,aAE9H,eAAM,SAAS,EAAC,UAAU,YAAE,GAAG,CAAC,IAAI,GAAQ,EAC5C,KAAC,YAAY,IAAC,SAAS,EAAC,iBAAiB,wBAAe,IACtD,CACL,CAAA;IACH,CAAC;IACD,OAAO,CACL,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,wBAAwB,EAAC,KAAK,EAAE,GAAG,CAAC,IAAI,YAC5E,GAAG,CAAC,IAAI,GACJ,CACR,CAAA;AACH,CAAC","sourcesContent":["import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router'\nimport {\n ArrowDown,\n ArrowUp,\n CornerDownRight,\n Download,\n Eye,\n EyeOff,\n ExternalLink,\n MoreHorizontal,\n Pencil,\n Plus,\n Trash2,\n Upload,\n} from 'lucide-react'\nimport { useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { CmsDocument, CollectionDef, DocumentUrl, FieldDef, Locale, LocaleConfig } from '@elytracms/core/cms-core'\nimport {\n orderHierarchically,\n resolveDocumentForLocale,\n resolveDocumentTitle,\n validateCollectionShape,\n} from '@elytracms/core/cms-core'\nimport {\n Button,\n Code,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Row,\n Separator,\n Spacer,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { localizedLabel, translate } from '@elytracms/studio/lib/i18n'\nimport { LocaleSwitcher, resolveDisplayedValue } from '@elytracms/studio/lib/locale'\nimport {\n EMPTY_SELECTION,\n STATE_FIELD,\n applyViewState,\n clearSelection,\n primaryColumn,\n selectAll,\n toggleRow,\n visibleColumns,\n visibleSelection,\n} from '@elytracms/studio/lib/cms-views'\nimport type { SelectionState, ViewSort } from '@elytracms/studio/lib/cms-views'\nimport { cellEditKind, cellKey } from './cell-edit'\nimport { FallbackChip } from './cell'\nimport { EditableCell } from './editable-cell'\nimport { useCellEdit } from './use-cell-edit'\nimport { ImportDialog } from './import-export'\nimport { AssetThumb, useAssetRecord } from '../assets/asset-thumb'\nimport { fieldLabel } from './cms-store'\nimport { cmsIssueLabel } from '@elytracms/studio/lib/persona/labels'\nimport { TriangleAlert } from 'lucide-react'\nimport type { BulkAction, BulkReport, BulkSetField } from './bulk-actions'\nimport { BulkBar, BulkReportPanel } from './bulk-bar'\nimport { rowActionsFor } from './row-actions'\nimport type { RowAction } from './row-actions'\nimport {\n CHECKBOX_COLUMN_WIDTH_REM,\n PRIMARY_COLUMN_WIDTH_REM,\n ROW_ACTIONS_COLUMN_WIDTH_REM,\n STATE_COLUMN_WIDTH_REM,\n URL_COLUMN_WIDTH_REM,\n columnWidthRem,\n} from './column-width'\nimport { ReferenceConfirmDialog } from './reference-confirm'\nimport { FilterControl } from './filter-builder'\nimport { DisplayMenu, ViewTabs } from './view-bar'\nimport { DocStateBadge } from './doc-state'\nimport { useSetBreadcrumb } from '../breadcrumb-context'\nimport { useCmsCollectionViewSource } from '../collection-view/cms-collection-view-source'\nimport { CollectionViewProvider, useCollectionView } from '../collection-view/collection-view-context'\n\nexport function CollectionTable({ projectId, collectionId }: { projectId: string; collectionId: string }) {\n // AD-19: render over the portable CollectionViewSource, not `useCms()` directly,\n // so the SAME list surface serves the users rail (EC-240), redirects (EC-303), …\n const source = useCmsCollectionViewSource(collectionId)\n\n if (!source) {\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\">\n Unknown collection <Code tone=\"muted\">{collectionId}</Code>.\n </Text>\n </div>\n )\n }\n\n // Keyed per collection so selection/report state never leaks across collections.\n return (\n <CollectionViewProvider source={source}>\n <LoadedCollectionTable key={collectionId} projectId={projectId} />\n </CollectionViewProvider>\n )\n}\n\n/**\n * The portable list surface (AD-19). Renders entirely over the ambient\n * {@link useCollectionView} source — no `useCms`, no `CmsProvider` required — so\n * any rail (the users rail, redirects, …) reuses it by wrapping it in a\n * {@link CollectionViewProvider} over its own source. `CollectionTable` is just\n * the CMS entry point that builds a CMS source and mounts this.\n */\nexport function LoadedCollectionTable({\n projectId,\n toolbarExtra,\n}: {\n projectId: string\n /**\n * A rail-owned action rendered at the tail of the header toolbar (EC-319) —\n * e.g. the assets rail's Upload button + grid/list toggle. Absent for every\n * other rail today (users, redirects, CMS), so their toolbar is unchanged.\n */\n toolbarExtra?: ReactNode\n}) {\n const source = useCollectionView()\n const collection = source.schema\n const navigate = useNavigate()\n const collectionId = source.collectionId\n // EC-214: the collection is the active record — the global header breadcrumb\n // names it, replacing the per-view title heading.\n useSetBreadcrumb([{ label: localizedLabel(collection.form?.label, collectionId) }])\n const [importOpen, setImportOpen] = useState(false)\n const [selection, setSelection] = useState<SelectionState>(EMPTY_SELECTION)\n const [bulkBusy, setBulkBusy] = useState(false)\n const [bulkReport, setBulkReport] = useState<BulkReport | null>(null)\n // EC-173: bulk unpublish/delete go through the reference-aware confirmation\n // with a snapshot of the selection taken when the action was raised.\n const [pendingBulk, setPendingBulk] = useState<{\n action: 'unpublish' | 'delete'\n targets: { collection: string; id: string }[]\n } | null>(null)\n\n // The working view state (EC-169): filters + sort + columns, possibly dirty\n // against the active saved view. The table renders exactly this state.\n const viewState = source.viewState()\n // EC-213: the title/link column is the first visible column; the rest follow\n // in the view's column order. No separate primary-column selector.\n const primary = primaryColumn(collection, viewState)\n const columns = visibleColumns(collection, viewState).filter((name) => name !== primary)\n const primaryFieldDef = collection.fields.find((f) => f.name === primary)\n\n const docs = source.documents()\n\n // EC-274/EC-284: collection-shape drift (a singleton with > 1 document; later\n // duplicate/unknown/unfilled aliases). When the data has drifted from the lens's\n // expected shape the studio shows this list instead of skipping — surfacing the\n // conflicts here as a \"for review\" banner so an editor resolves them without a\n // developer (keep/delete the outliers), after which the lens applies again.\n const shapeIssues = useMemo(() => validateCollectionShape(collection, docs), [collection, docs])\n\n // EC-216 + EC-205 (\"live = published\"): each routable document's LIVE URL,\n // derived from the PUBLISHED pool (never draft rows), memoised inside the\n // source. `null` when the collection is not routable → the column is hidden.\n const urlByDocId = source.publishing?.liveUrls?.() ?? null\n\n const visibleDocs = useMemo(\n // EC-224: the `$state` filter/sort sources published-ness from the version\n // POINTER (`source.publishing.isPublished`), not a flat `state` field.\n () =>\n applyViewState(collection, docs, source.localeConfig, viewState, (doc) =>\n source.publishing?.isPublished({ collection: doc.collection, id: doc.id }) ?? false,\n ).docs,\n [collection, docs, source.localeConfig, viewState, source.publishing],\n )\n\n // EC-218: a collection with a `parent` self-relation can render as a nested\n // tree (parents above their children, indented). Tree mode reorders the\n // already-filtered rows depth-first — filters/sort still order siblings.\n const hierarchical = source.capabilities.hierarchy\n const [treeMode, setTreeMode] = useState(hierarchical)\n const treeRows = useMemo(\n () => (hierarchical && treeMode ? orderHierarchically(visibleDocs) : null),\n [hierarchical, treeMode, visibleDocs],\n )\n const orderedDocs = treeRows ? treeRows.map((row) => row.doc) : visibleDocs\n const depthById = useMemo(\n () => (treeRows ? new Map(treeRows.map((row) => [row.doc.id, row.depth])) : undefined),\n [treeRows],\n )\n\n // EC-246a header derivations. The count reads with the collection's own noun\n // (pluralized via the config labels), not a bare number or the generic kind.\n const pluralLabel = localizedLabel(collection.form?.label, `${collectionId}s`)\n const singularLabel = localizedLabel(collection.form?.labelSingular, collectionId)\n const countLabel =\n visibleDocs.length === docs.length\n ? translate('cms.list.count', {\n count: docs.length,\n noun: docs.length === 1 ? singularLabel : pluralLabel,\n })\n : translate('cms.list.countFiltered', {\n visible: visibleDocs.length,\n total: docs.length,\n noun: pluralLabel,\n })\n\n // EC-246d: New creates an empty draft and opens its editor directly — no\n // interstitial modal, for pages or any other collection. Id is auto-generated;\n // the slug/title (and, for pages, the parent) are typed in the form, and a\n // missing/duplicate slug surfaces as a Publish-gating issue, never blocks the\n // draft. Routes are config-sourced (EC-207), so nothing else is written here.\n const isPageCollection = collectionId === 'page'\n // Creation is a capability (a credential rail like users mints identities via\n // sign-up, not here), and the detail route is rail-owned (never the CMS route).\n const canCreate = source.capabilities.create && source.detailPath !== undefined\n const handleNew = () => {\n const ref = source.create()\n const splat = source.detailPath?.(ref.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n }\n const visibleIds = orderedDocs.map((doc) => doc.id)\n // Selection is always read against the current view — rows the filters hid\n // are never silently included in a bulk action.\n const selectedIds = visibleSelection(selection, visibleIds)\n // EC-316: the right-edge row menu is a capability-gated column — a rail with\n // no detail surface AND no publish/remove capability offers nothing (users\n // rail today has remove, so this is rarely empty; kept honest for AD-19).\n const hasRowActions = source.detailPath !== undefined || source.capabilities.publish || source.capabilities.remove\n\n function toggleSort(field: string) {\n source.setViewState((prev) => {\n const sort: ViewSort | null =\n prev.sort?.field !== field\n ? { field, dir: 'asc' }\n : prev.sort.dir === 'asc'\n ? { field, dir: 'desc' }\n : null\n return { ...prev, sort }\n })\n }\n\n function raiseBulk(action: BulkAction) {\n if (action === 'publish') {\n void handleBulk(action, [...selectedIds])\n return\n }\n // Set-field is composed + raised through the bulk bar's own panel\n // (onSetField), never this state-action path.\n if (action === 'set-field') return\n // Unpublish/delete first enumerate inbound references (EC-173): the\n // dialog shows the aggregate \"N documents, M references will break\".\n setPendingBulk({\n action,\n targets: selectedIds.map((id) => ({ collection: collectionId, id })),\n })\n }\n\n // EC-316: the row `⋮` menu dispatches through the SAME machinery as the\n // toolbar's bulk actions — one document is just a selection of one — so\n // there is exactly one write path for publish/unpublish/delete, never a\n // parallel one. `open` is the row menu's own affordance (the primary-column\n // link already offers it; this is the keyboard/menu-driven equivalent).\n function handleRowAction(action: RowAction, doc: CmsDocument) {\n if (action === 'open') {\n const splat = source.detailPath?.(doc.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n return\n }\n if (action === 'publish') {\n void handleBulk(action, [doc.id])\n return\n }\n // unpublish/delete: the same reference-aware confirmation the bulk bar\n // raises, scoped to this one document.\n setPendingBulk({ action, targets: [{ collection: collectionId, id: doc.id }] })\n }\n\n async function handleBulk(action: BulkAction, acted: readonly string[], setField?: BulkSetField) {\n if (!source.bulk) return\n setBulkBusy(true)\n try {\n const report = await source.bulk([...acted], action, setField)\n setBulkReport(report)\n // Succeeded items deselect; failed items stay selected for a retry.\n const actedSet = new Set(acted)\n const failed = new Set(report.results.filter((r) => !r.ok).map((r) => r.ref.id))\n setSelection((prev) => ({\n ids: prev.ids.filter((id) => !actedSet.has(id) || failed.has(id)),\n anchorId: null,\n }))\n } finally {\n setBulkBusy(false)\n }\n }\n\n function exportJson() {\n const data = JSON.stringify(source.documents(), null, 2)\n const blob = new Blob([data], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${collectionId}.json`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n {/* Header (EC-246a redesign). One toolbar: identity + refine on the left,\n lens + actions on the right; a transient filter bar drops below only\n while refining. The header breadcrumb (EC-214) names the collection —\n no title here. Locale is a lens; column/layout config lives behind the\n far-right Display control; shared views are config-as-code (EC-246b). */}\n <div className=\"shrink-0 border-b border-border px-4 py-3 sm:px-6\">\n <Row gap=\"2\" wrap>\n {/* Left — which view (only when >1), then the transient refine. */}\n <ViewTabs />\n {/* Transient ad-hoc refine — a chip beside the view tabs, editor in a\n popover (EC-246b); the chip's ✕ clears it, so no separate Reset. */}\n <FilterControl collection={collection} />\n {/* The working-set count is the RESULT of the view + filter above, so it\n reads last, set off by a divider and sized like its neighbours. */}\n <Separator orientation=\"vertical\" className=\"h-5 self-center\" />\n <Text\n as=\"span\"\n size=\"xs\"\n tone=\"muted\"\n className=\"whitespace-nowrap tabular-nums\"\n data-testid=\"collection-count\"\n >\n {countLabel}\n </Text>\n\n <Spacer />\n\n {/* Right — the ambient locale lens (EC-176; hidden for single-locale AND\n for a non-localized rail like users), then display config + write actions. */}\n {source.capabilities.locales ? <LocaleSwitcher /> : null}\n <DisplayMenu\n collection={collection}\n hierarchical={hierarchical}\n treeMode={treeMode}\n onToggleTree={setTreeMode}\n />\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew} data-testid=\"new-document\">\n <Plus /> {isPageCollection ? translate('cms.list.newPage') : translate('cms.list.new')}\n </Button>\n ) : null}\n {/* EC-213: import/export fold into one action menu, off the header.\n AD-19: a capability — absent on credential rails (users), so identity\n records are never dumped to / loaded from raw JSON. */}\n {source.capabilities.importExport ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.moreActions')}\n data-testid=\"collection-actions\"\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setImportOpen(true)} data-testid=\"action-import\">\n <Upload /> {translate('cms.list.import')}\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={exportJson}\n disabled={docs.length === 0}\n data-testid=\"action-export\"\n >\n <Download /> {translate('cms.list.export')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n {toolbarExtra}\n </Row>\n </div>\n\n {/* Bulk actions over the selection (EC-169) */}\n <BulkBar\n collection={collection}\n count={selectedIds.length}\n busy={bulkBusy}\n onAction={raiseBulk}\n onSetField={(setField) => void handleBulk('set-field', [...selectedIds], setField)}\n onClear={() => setSelection(clearSelection())}\n />\n {bulkReport ? (\n <BulkReportPanel report={bulkReport} onDismiss={() => setBulkReport(null)} />\n ) : null}\n\n {/* Reference-aware bulk unpublish/delete confirmation (EC-173). */}\n {pendingBulk !== null ? (\n <ReferenceConfirmDialog\n projectId={projectId}\n action={pendingBulk.action}\n targets={pendingBulk.targets}\n open\n busy={bulkBusy}\n onOpenChange={(open) => {\n if (!open) setPendingBulk(null)\n }}\n onConfirm={() => {\n const { action, targets } = pendingBulk\n setPendingBulk(null)\n void handleBulk(\n action,\n targets.map((target) => target.id),\n )\n }}\n />\n ) : null}\n\n {/* EC-274/EC-284: \"for review\" lane — the collection has drifted from its\n lens's expected shape; surface each conflict so an editor can resolve it. */}\n {shapeIssues.length > 0 ? (\n <div\n className=\"shrink-0 border-b border-warning/30 bg-warning/10 px-4 py-2 sm:px-6\"\n data-testid=\"shape-review-banner\"\n >\n <Stack gap=\"1\">\n {shapeIssues.map((issue, i) => (\n <Row key={`${issue.code}:${i}`} gap=\"2\" align=\"start\">\n <TriangleAlert className=\"mt-0.5 size-3.5 shrink-0 text-warning\" aria-hidden />\n <Stack gap=\"none\" className=\"min-w-0\">\n <Text size=\"xs\" weight=\"semibold\" tone=\"default\" title={issue.code}>\n {translate('cms.list.forReview')} · {cmsIssueLabel(issue.code)}\n </Text>\n <Text size=\"xs\" tone=\"muted\">\n {issue.message}\n </Text>\n </Stack>\n </Row>\n ))}\n </Stack>\n </div>\n ) : null}\n\n {/* Table */}\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {docs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Stack gap=\"2\" align=\"center\" className=\"text-center\">\n <Text tone=\"muted\">{translate('cms.list.emptyNone', { noun: pluralLabel.toLowerCase() })}</Text>\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew}>\n <Plus />{' '}\n {isPageCollection\n ? translate('cms.list.newPage')\n : translate('cms.list.newNamed', {\n noun: localizedLabel(collection.form?.labelSingular, 'document'),\n })}\n </Button>\n ) : null}\n </Stack>\n </div>\n ) : visibleDocs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\" data-testid=\"empty-filtered\">\n {translate('cms.list.emptyFiltered')}\n </Text>\n </div>\n ) : (\n <DocumentsGrid\n projectId={projectId}\n collection={collection}\n primary={primary}\n primaryFieldDef={primaryFieldDef}\n columns={columns}\n sortedDocs={orderedDocs}\n depthById={depthById}\n urlByDocId={urlByDocId}\n sort={viewState.sort}\n onSort={toggleSort}\n selectedIds={selectedIds}\n onToggleRow={(id, shift) =>\n setSelection((prev) => toggleRow(prev, visibleIds, id, shift))\n }\n onToggleAll={() =>\n setSelection(\n selectedIds.length === visibleIds.length && visibleIds.length > 0\n ? clearSelection()\n : selectAll(visibleIds),\n )\n }\n hasRowActions={hasRowActions}\n onRowAction={handleRowAction}\n />\n )}\n </div>\n\n {source.capabilities.importExport ? (\n <ImportDialog collectionId={collectionId} open={importOpen} onOpenChange={setImportOpen} />\n ) : null}\n </div>\n )\n}\n\n/**\n * The documents table with inline cell editing (EC-168). Cells edit in place\n * (text/number/boolean/select/date) or open pickers (relation/asset); each\n * commit is one operations command via the cell-edit controller, with\n * rollback + inline cell errors on rejection. Row checkboxes (EC-169) live in\n * their own column, so selection clicks never collide with cell editing.\n */\nfunction DocumentsGrid({\n projectId,\n collection,\n primary,\n primaryFieldDef,\n columns,\n sortedDocs,\n depthById,\n urlByDocId,\n sort,\n onSort,\n selectedIds,\n onToggleRow,\n onToggleAll,\n hasRowActions,\n onRowAction,\n}: {\n projectId: string\n collection: CollectionDef\n primary: string\n primaryFieldDef: FieldDef | undefined\n columns: string[]\n sortedDocs: CmsDocument[]\n /** EC-218: nesting depth per doc id when rendering the hierarchy (tree mode). */\n depthById?: Map<string, number>\n /** EC-216: each routable doc's derived URL; `null` hides the URL column. */\n urlByDocId?: Map<string, DocumentUrl> | null\n sort: ViewSort | null\n onSort: (field: string) => void\n selectedIds: readonly string[]\n onToggleRow: (id: string, shift: boolean) => void\n onToggleAll: () => void\n /** EC-316: whether the right-edge row `⋮` menu has anything to offer at all. */\n hasRowActions: boolean\n onRowAction: (action: RowAction, doc: CmsDocument) => void\n}) {\n const source = useCollectionView()\n const collectionId = collection.id\n const fieldByName = (name: string) => collection.fields.find((f) => f.name === name)\n // Inline editing is a capability: a read-only rail yields no editable cells.\n const editableFields = source.capabilities.inlineEdit\n ? columns.filter((name) => {\n const field = fieldByName(name)\n return field ? cellEditKind(field, source.isFieldReadOnly(field)) !== 'none' : false\n })\n : []\n const cellEdit = useCellEdit({ collection, docs: sortedDocs, editableFields })\n const selected = new Set(selectedIds)\n const allSelected = sortedDocs.length > 0 && selectedIds.length === sortedDocs.length\n\n return (\n <div ref={cellEdit.containerRef}>\n {/* EC-316: `table-fixed` + an explicit `<colgroup>` fix every column's\n width from the SCHEMA alone, before any row renders. Under the\n browser's default `table-layout: auto` a cell's INTRINSIC content\n width feeds back into its column — so swapping a cell's rendered\n value for its inline editor (a wider `<input>`) reflowed the whole\n grid. Fixed layout makes a column's width immune to its cells'\n content; `columnWidthRem` only sets relative proportions, so the\n grid still scales naturally with the container (never with a cell). */}\n <table className=\"w-full table-fixed border-collapse text-sm\">\n <colgroup>\n <col style={{ width: `${CHECKBOX_COLUMN_WIDTH_REM}rem` }} />\n <col style={{ width: `${PRIMARY_COLUMN_WIDTH_REM}rem` }} />\n {columns.map((name) => (\n <col key={name} style={{ width: `${columnWidthRem(fieldByName(name))}rem` }} />\n ))}\n <col style={{ width: `${STATE_COLUMN_WIDTH_REM}rem` }} />\n {urlByDocId ? <col style={{ width: `${URL_COLUMN_WIDTH_REM}rem` }} /> : null}\n {hasRowActions ? <col style={{ width: `${ROW_ACTIONS_COLUMN_WIDTH_REM}rem` }} /> : null}\n </colgroup>\n <thead className=\"sticky top-0 z-10 bg-background\">\n <tr className=\"border-b border-border\">\n <th className=\"px-3 py-2 text-left\">\n <SelectionCheckbox\n checked={allSelected}\n indeterminate={selectedIds.length > 0 && !allSelected}\n label={translate('cms.list.selectAll')}\n testId=\"select-all\"\n onToggle={() => onToggleAll()}\n />\n </th>\n <HeaderCell\n field={primary}\n label={primaryFieldDef ? fieldLabel(primaryFieldDef) : translate('cms.list.column.title')}\n sort={sort}\n onSort={onSort}\n />\n {columns.map((name) => {\n const field = fieldByName(name)\n return field ? (\n <HeaderCell key={name} field={name} label={fieldLabel(field)} sort={sort} onSort={onSort} />\n ) : null\n })}\n <HeaderCell field={STATE_FIELD} label={translate('cms.list.column.state')} sort={sort} onSort={onSort} />\n {/* EC-216: derived URL — not a field, so not sortable. */}\n {urlByDocId ? (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">{translate('cms.list.column.url')}</th>\n ) : null}\n {hasRowActions ? (\n <th className=\"px-2 py-2 text-right\">\n <span className=\"sr-only\">{translate('cms.list.rowActionsColumnLabel')}</span>\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody>\n {sortedDocs.map((doc) => (\n <tr\n key={doc.id}\n className={cn(\n 'group border-b border-border/60 hover:bg-muted/40',\n selected.has(doc.id) && 'bg-primary/5',\n )}\n >\n <td className=\"px-3 py-2 align-middle\">\n <SelectionCheckbox\n checked={selected.has(doc.id)}\n label={translate('cms.list.selectRow', { id: doc.id })}\n testId={`select-row-${doc.id}`}\n onToggle={(shift) => onToggleRow(doc.id, shift)}\n />\n </td>\n <td className=\"px-3 py-2 align-middle\">\n <PrimaryCell\n projectId={projectId}\n collection={collection}\n doc={doc}\n primary={primary}\n depth={depthById?.get(doc.id) ?? 0}\n locale={source.activeLocale}\n config={source.localeConfig}\n detailPath={source.detailPath}\n />\n </td>\n {columns.map((name) => {\n const field = fieldByName(name)\n const coord = { docId: doc.id, field: name }\n const key = cellKey(coord)\n return (\n <td key={name} className=\"px-3 py-2 align-middle\">\n {field ? (\n <EditableCell\n collection={collection}\n doc={doc}\n field={field}\n editing={cellEdit.activeKey === key}\n busy={cellEdit.busyKey === key}\n errorMessage={cellEdit.errorOf(key)}\n onStartEdit={() => cellEdit.start(coord)}\n onCancel={() => cellEdit.cancel(coord)}\n onCommit={(value, advance) => cellEdit.commit(coord, value, advance)}\n />\n ) : null}\n </td>\n )\n })}\n <td className=\"px-3 py-2 align-middle\">\n <DocStateBadge\n published={\n source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false\n }\n />\n </td>\n {urlByDocId ? (\n <td className=\"px-3 py-2 align-middle\">\n <UrlCell url={urlByDocId.get(doc.id)} />\n </td>\n ) : null}\n {hasRowActions ? (\n <td className=\"px-2 py-2 text-right align-middle\">\n <RowActionsMenu\n doc={doc}\n published={source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false}\n hasDetailPath={source.detailPath !== undefined}\n onAction={(action) => onRowAction(action, doc)}\n />\n </td>\n ) : null}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * The right-edge row `⋮` menu (EC-316): the SAME action vocabulary as the\n * toolbar's bulk actions (`rowActionsFor`), gated by the SAME capabilities —\n * so it degrades exactly like the rest of the list for a rail without\n * publish/remove (AD-19). Renders nothing when the gate leaves zero actions.\n */\nfunction RowActionsMenu({\n doc,\n published,\n hasDetailPath,\n onAction,\n}: {\n doc: CmsDocument\n published: boolean\n hasDetailPath: boolean\n onAction: (action: RowAction) => void\n}) {\n const source = useCollectionView()\n const actions = rowActionsFor({ capabilities: source.capabilities, hasDetailPath, published })\n if (actions.length === 0) return null\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.rowActionsLabel', { id: doc.id })}\n data-testid={`row-actions-${doc.id}`}\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {actions.map((action) => (\n <RowActionItem key={action} action={action} onSelect={() => onAction(action)} />\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction RowActionItem({ action, onSelect }: { action: RowAction; onSelect: () => void }) {\n switch (action) {\n case 'open':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-open\">\n <Pencil /> {translate('cms.list.rowAction.open')}\n </DropdownMenuItem>\n )\n case 'publish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-publish\">\n <Eye /> {translate('cms.list.bulk.publish')}\n </DropdownMenuItem>\n )\n case 'unpublish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-unpublish\">\n <EyeOff /> {translate('cms.list.bulk.unpublish')}\n </DropdownMenuItem>\n )\n case 'delete':\n return (\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={onSelect}\n data-testid=\"row-action-delete\"\n >\n <Trash2 /> {translate('common.delete')}\n </DropdownMenuItem>\n )\n }\n}\n\n/**\n * A selection checkbox (row or select-all). Its own column and focus target —\n * it never participates in the cell-edit keyboard flow. Shift-click selects\n * the anchor→row range (the mousedown guard stops text selection).\n */\nfunction SelectionCheckbox({\n checked,\n indeterminate = false,\n label,\n testId,\n onToggle,\n}: {\n checked: boolean\n indeterminate?: boolean\n label: string\n testId: string\n onToggle: (shift: boolean) => void\n}) {\n return (\n <input\n ref={(el) => {\n if (el) el.indeterminate = indeterminate && !checked\n }}\n type=\"checkbox\"\n className=\"size-4 cursor-pointer accent-primary align-middle\"\n checked={checked}\n readOnly\n aria-label={label}\n data-testid={testId}\n onClick={(event) => onToggle(event.shiftKey)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n onToggle(event.shiftKey)\n }\n }}\n onMouseDown={(event) => {\n if (event.shiftKey) event.preventDefault()\n }}\n />\n )\n}\n\nfunction HeaderCell({\n field,\n label,\n sort,\n onSort,\n}: {\n field: string\n label: string\n sort: ViewSort | null\n onSort: (field: string) => void\n}) {\n const active = sort?.field === field\n return (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">\n <button type=\"button\" onClick={() => onSort(field)} className=\"inline-flex items-center gap-1 hover:text-foreground\">\n {label}\n {active ? (\n sort!.dir === 'asc' ? (\n <ArrowUp className=\"size-3\" />\n ) : (\n <ArrowDown className=\"size-3\" />\n )\n ) : null}\n </button>\n </th>\n )\n}\n\n/**\n * The primary (title) column cell: the document link, resolved in the\n * ambient active locale with a visible fallback chip when the shown title is\n * untranslated (EC-176).\n */\nfunction PrimaryCell({\n projectId,\n collection,\n doc,\n primary,\n depth = 0,\n locale,\n config,\n detailPath,\n}: {\n projectId: string\n collection: CollectionDef\n doc: CmsDocument\n primary: string\n /** EC-218: nesting depth in the hierarchy (tree mode) — indents the title. */\n depth?: number\n locale: Locale\n config: LocaleConfig\n /** Rail-owned detail route splat (AD-19); absent ⇒ the rail has no detail surface. */\n detailPath?: (id: string) => string\n}) {\n // EC-242: the title cell renders the document identity (resolveDocumentTitle) —\n // a string `titleField` or a function pattern — over the fallback-resolved\n // values, NOT the raw `primary` column value. The untranslated-title chip applies\n // only to a field-backed title (a function pattern has no single source field).\n const title = resolveDocumentTitle(\n collection,\n resolveDocumentForLocale(collection, doc, locale, config),\n doc.id,\n )\n const fallback =\n typeof collection.titleField === 'function'\n ? null\n : resolveDisplayedValue(collection, doc, primary, locale, config).fallback\n const splat = detailPath?.(doc.id)\n return (\n <Row gap=\"2\" align=\"center\" className=\"min-w-0\" style={{ paddingLeft: depth * 20 }}>\n {depth > 0 ? (\n <CornerDownRight className=\"size-3.5 shrink-0 text-muted-foreground\" aria-hidden />\n ) : null}\n {/* 0.0.39: assets get a leading, fixed-size preview in the filename column —\n an image thumbnail (object-cover) for image assets, the file-type placeholder\n otherwise. Fixed box, so it never reflows the EC-316 fixed column widths. */}\n {collection.kind === 'asset' ? <AssetThumbCell assetId={doc.id} alt={title} /> : null}\n {splat !== undefined ? (\n <Link\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: splat }}\n className=\"truncate font-medium text-foreground hover:text-primary hover:underline\"\n >\n {title}\n </Link>\n ) : (\n <Text as=\"span\" className=\"truncate font-medium text-foreground\">\n {title}\n </Text>\n )}\n <FallbackChip fallback={fallback} testId={`cell-fallback-${doc.id}-${primary}`} />\n </Row>\n )\n}\n\n/**\n * The leading asset preview in the filename column (0.0.39). Resolves the asset\n * record from the ambient library and renders {@link AssetThumb} — an image preview\n * for image assets, the file-type placeholder for the rest. Mounted only for\n * `kind:'asset'` collections (which are always under an `<AssetsProvider>`), so the\n * `useAssetRecord` hook is never called on a rail without a library.\n */\nfunction AssetThumbCell({ assetId, alt }: { assetId: string; alt: string }) {\n const record = useAssetRecord(assetId)\n return <AssetThumb record={record} alt={alt} className=\"size-8 shrink-0\" />\n}\n\n/**\n * The read-only URL column cell (EC-216): the document's LIVE (published) path,\n * linking to the absolute live URL when a `frontendUrl` is configured. Only\n * published documents have a `url` here (the URL is derived from the published\n * pool, EC-205), so an unpublished document — having no live page — shows a dash.\n * The URL is always derived, never stored.\n */\nfunction UrlCell({ url }: { url?: DocumentUrl }) {\n if (!url) {\n return (\n <Text size=\"xs\" tone=\"subtle\">\n —\n </Text>\n )\n }\n if (url.href) {\n return (\n <a\n href={url.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n title={url.href}\n className=\"inline-flex max-w-[18rem] items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground\"\n >\n <span className=\"truncate\">{url.path}</span>\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden />\n </a>\n )\n }\n return (\n <Text size=\"xs\" tone=\"muted\" className=\"max-w-[18rem] truncate\" title={url.path}>\n {url.path}\n </Text>\n )\n}\n\nexport type { FieldDef }\n"]}
1
+ {"version":3,"file":"collection-table.js","sourceRoot":"","sources":["../../../src/components/cms/collection-table.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router'\nimport {\n ArrowDown,\n ArrowUp,\n CornerDownRight,\n Download,\n Eye,\n EyeOff,\n ExternalLink,\n MoreHorizontal,\n Pencil,\n Plus,\n Trash2,\n Upload,\n} from 'lucide-react'\nimport { useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { CmsDocument, CollectionDef, DocumentUrl, FieldDef, Locale, LocaleConfig } from '@elytracms/core/cms-core'\nimport {\n orderHierarchically,\n resolveDocumentForLocale,\n resolveDocumentTitle,\n validateCollectionShape,\n} from '@elytracms/core/cms-core'\nimport {\n Button,\n Code,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Row,\n Separator,\n Spacer,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { localizedLabel, translate } from '@elytracms/studio/lib/i18n'\nimport { LocaleSwitcher, resolveDisplayedValue } from '@elytracms/studio/lib/locale'\nimport {\n EMPTY_SELECTION,\n STATE_FIELD,\n applyViewState,\n clearSelection,\n primaryColumn,\n selectAll,\n toggleRow,\n visibleColumns,\n visibleSelection,\n} from '@elytracms/studio/lib/cms-views'\nimport type { SelectionState, ViewSort } from '@elytracms/studio/lib/cms-views'\nimport { cellEditKind, cellKey } from './cell-edit'\nimport { FallbackChip } from './cell'\nimport { EditableCell } from './editable-cell'\nimport { useCellEdit } from './use-cell-edit'\nimport { ImportDialog } from './import-export'\nimport { AssetThumb, useAssetRecord } from '../assets/asset-thumb'\nimport { fieldLabel } from './cms-labels'\nimport { cmsIssueLabel } from '@elytracms/studio/lib/persona/labels'\nimport { TriangleAlert } from 'lucide-react'\nimport type { BulkAction, BulkReport, BulkSetField } from './bulk-actions'\nimport { BulkBar, BulkReportPanel } from './bulk-bar'\nimport { rowActionsFor } from './row-actions'\nimport type { RowAction } from './row-actions'\nimport {\n CHECKBOX_COLUMN_WIDTH_REM,\n PRIMARY_COLUMN_WIDTH_REM,\n ROW_ACTIONS_COLUMN_WIDTH_REM,\n STATE_COLUMN_WIDTH_REM,\n URL_COLUMN_WIDTH_REM,\n columnWidthRem,\n} from './column-width'\nimport { ReferenceConfirmDialog } from './reference-confirm'\nimport { FilterControl } from './filter-builder'\nimport { DisplayMenu, ViewTabs } from './view-bar'\nimport { DocStateBadge } from './doc-state'\nimport { useSetBreadcrumb } from '../breadcrumb-context'\nimport { useCmsCollectionViewSource } from '../collection-view/cms-collection-view-source'\nimport { CollectionViewProvider, useCollectionView } from '../collection-view/collection-view-context'\n\nexport function CollectionTable({ projectId, collectionId }: { projectId: string; collectionId: string }) {\n // AD-19: render over the portable CollectionViewSource, not `useCms()` directly,\n // so the SAME list surface serves the users rail (EC-240), redirects (EC-303), …\n const source = useCmsCollectionViewSource(collectionId)\n\n if (!source) {\n return (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\">\n Unknown collection <Code tone=\"muted\">{collectionId}</Code>.\n </Text>\n </div>\n )\n }\n\n // Keyed per collection so selection/report state never leaks across collections.\n return (\n <CollectionViewProvider source={source}>\n <LoadedCollectionTable key={collectionId} projectId={projectId} />\n </CollectionViewProvider>\n )\n}\n\n/**\n * The portable list surface (AD-19). Renders entirely over the ambient\n * {@link useCollectionView} source — no `useCms`, no `CmsProvider` required — so\n * any rail (the users rail, redirects, …) reuses it by wrapping it in a\n * {@link CollectionViewProvider} over its own source. `CollectionTable` is just\n * the CMS entry point that builds a CMS source and mounts this.\n */\nexport function LoadedCollectionTable({\n projectId,\n toolbarExtra,\n}: {\n projectId: string\n /**\n * A rail-owned action rendered at the tail of the header toolbar (EC-319) —\n * e.g. the assets rail's Upload button + grid/list toggle. Absent for every\n * other rail today (users, redirects, CMS), so their toolbar is unchanged.\n */\n toolbarExtra?: ReactNode\n}) {\n const source = useCollectionView()\n const collection = source.schema\n const navigate = useNavigate()\n const collectionId = source.collectionId\n // EC-214: the collection is the active record — the global header breadcrumb\n // names it, replacing the per-view title heading.\n useSetBreadcrumb([{ label: localizedLabel(collection.form?.label, collectionId) }])\n const [importOpen, setImportOpen] = useState(false)\n const [selection, setSelection] = useState<SelectionState>(EMPTY_SELECTION)\n const [bulkBusy, setBulkBusy] = useState(false)\n const [bulkReport, setBulkReport] = useState<BulkReport | null>(null)\n // EC-173: bulk unpublish/delete go through the reference-aware confirmation\n // with a snapshot of the selection taken when the action was raised.\n const [pendingBulk, setPendingBulk] = useState<{\n action: 'unpublish' | 'delete'\n targets: { collection: string; id: string }[]\n } | null>(null)\n\n // The working view state (EC-169): filters + sort + columns, possibly dirty\n // against the active saved view. The table renders exactly this state.\n const viewState = source.viewState()\n // EC-213: the title/link column is the first visible column; the rest follow\n // in the view's column order. No separate primary-column selector.\n const primary = primaryColumn(collection, viewState)\n const columns = visibleColumns(collection, viewState).filter((name) => name !== primary)\n const primaryFieldDef = collection.fields.find((f) => f.name === primary)\n\n const docs = source.documents()\n\n // EC-274/EC-284: collection-shape drift (a singleton with > 1 document; later\n // duplicate/unknown/unfilled aliases). When the data has drifted from the lens's\n // expected shape the studio shows this list instead of skipping — surfacing the\n // conflicts here as a \"for review\" banner so an editor resolves them without a\n // developer (keep/delete the outliers), after which the lens applies again.\n const shapeIssues = useMemo(() => validateCollectionShape(collection, docs), [collection, docs])\n\n // EC-216 + EC-205 (\"live = published\"): each routable document's LIVE URL,\n // derived from the PUBLISHED pool (never draft rows), memoised inside the\n // source. `null` when the collection is not routable → the column is hidden.\n const urlByDocId = source.publishing?.liveUrls?.() ?? null\n\n const visibleDocs = useMemo(\n // EC-224: the `$state` filter/sort sources published-ness from the version\n // POINTER (`source.publishing.isPublished`), not a flat `state` field.\n () =>\n applyViewState(collection, docs, source.localeConfig, viewState, (doc) =>\n source.publishing?.isPublished({ collection: doc.collection, id: doc.id }) ?? false,\n ).docs,\n [collection, docs, source.localeConfig, viewState, source.publishing],\n )\n\n // EC-218: a collection with a `parent` self-relation can render as a nested\n // tree (parents above their children, indented). Tree mode reorders the\n // already-filtered rows depth-first — filters/sort still order siblings.\n const hierarchical = source.capabilities.hierarchy\n const [treeMode, setTreeMode] = useState(hierarchical)\n const treeRows = useMemo(\n () => (hierarchical && treeMode ? orderHierarchically(visibleDocs) : null),\n [hierarchical, treeMode, visibleDocs],\n )\n const orderedDocs = treeRows ? treeRows.map((row) => row.doc) : visibleDocs\n const depthById = useMemo(\n () => (treeRows ? new Map(treeRows.map((row) => [row.doc.id, row.depth])) : undefined),\n [treeRows],\n )\n\n // EC-246a header derivations. The count reads with the collection's own noun\n // (pluralized via the config labels), not a bare number or the generic kind.\n const pluralLabel = localizedLabel(collection.form?.label, `${collectionId}s`)\n const singularLabel = localizedLabel(collection.form?.labelSingular, collectionId)\n const countLabel =\n visibleDocs.length === docs.length\n ? translate('cms.list.count', {\n count: docs.length,\n noun: docs.length === 1 ? singularLabel : pluralLabel,\n })\n : translate('cms.list.countFiltered', {\n visible: visibleDocs.length,\n total: docs.length,\n noun: pluralLabel,\n })\n\n // EC-246d: New creates an empty draft and opens its editor directly — no\n // interstitial modal, for pages or any other collection. Id is auto-generated;\n // the slug/title (and, for pages, the parent) are typed in the form, and a\n // missing/duplicate slug surfaces as a Publish-gating issue, never blocks the\n // draft. Routes are config-sourced (EC-207), so nothing else is written here.\n const isPageCollection = collectionId === 'page'\n // Creation is a capability (a credential rail like users mints identities via\n // sign-up, not here), and the detail route is rail-owned (never the CMS route).\n const canCreate = source.capabilities.create && source.detailPath !== undefined\n const handleNew = () => {\n const ref = source.create()\n const splat = source.detailPath?.(ref.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n }\n const visibleIds = orderedDocs.map((doc) => doc.id)\n // Selection is always read against the current view — rows the filters hid\n // are never silently included in a bulk action.\n const selectedIds = visibleSelection(selection, visibleIds)\n // EC-316: the right-edge row menu is a capability-gated column — a rail with\n // no detail surface AND no publish/remove capability offers nothing (users\n // rail today has remove, so this is rarely empty; kept honest for AD-19).\n const hasRowActions = source.detailPath !== undefined || source.capabilities.publish || source.capabilities.remove\n\n function toggleSort(field: string) {\n source.setViewState((prev) => {\n const sort: ViewSort | null =\n prev.sort?.field !== field\n ? { field, dir: 'asc' }\n : prev.sort.dir === 'asc'\n ? { field, dir: 'desc' }\n : null\n return { ...prev, sort }\n })\n }\n\n function raiseBulk(action: BulkAction) {\n if (action === 'publish') {\n void handleBulk(action, [...selectedIds])\n return\n }\n // Set-field is composed + raised through the bulk bar's own panel\n // (onSetField), never this state-action path.\n if (action === 'set-field') return\n // Unpublish/delete first enumerate inbound references (EC-173): the\n // dialog shows the aggregate \"N documents, M references will break\".\n setPendingBulk({\n action,\n targets: selectedIds.map((id) => ({ collection: collectionId, id })),\n })\n }\n\n // EC-316: the row `⋮` menu dispatches through the SAME machinery as the\n // toolbar's bulk actions — one document is just a selection of one — so\n // there is exactly one write path for publish/unpublish/delete, never a\n // parallel one. `open` is the row menu's own affordance (the primary-column\n // link already offers it; this is the keyboard/menu-driven equivalent).\n function handleRowAction(action: RowAction, doc: CmsDocument) {\n if (action === 'open') {\n const splat = source.detailPath?.(doc.id)\n if (splat === undefined) return\n navigate({ to: STUDIO_PROJECT_ROUTE, params: { projectId, _splat: splat } })\n return\n }\n if (action === 'publish') {\n void handleBulk(action, [doc.id])\n return\n }\n // unpublish/delete: the same reference-aware confirmation the bulk bar\n // raises, scoped to this one document.\n setPendingBulk({ action, targets: [{ collection: collectionId, id: doc.id }] })\n }\n\n async function handleBulk(action: BulkAction, acted: readonly string[], setField?: BulkSetField) {\n if (!source.bulk) return\n setBulkBusy(true)\n try {\n const report = await source.bulk([...acted], action, setField)\n setBulkReport(report)\n // Succeeded items deselect; failed items stay selected for a retry.\n const actedSet = new Set(acted)\n const failed = new Set(report.results.filter((r) => !r.ok).map((r) => r.ref.id))\n setSelection((prev) => ({\n ids: prev.ids.filter((id) => !actedSet.has(id) || failed.has(id)),\n anchorId: null,\n }))\n } finally {\n setBulkBusy(false)\n }\n }\n\n function exportJson() {\n const data = JSON.stringify(source.documents(), null, 2)\n const blob = new Blob([data], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `${collectionId}.json`\n a.click()\n URL.revokeObjectURL(url)\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n {/* Header (EC-246a redesign). One toolbar: identity + refine on the left,\n lens + actions on the right; a transient filter bar drops below only\n while refining. The header breadcrumb (EC-214) names the collection —\n no title here. Locale is a lens; column/layout config lives behind the\n far-right Display control; shared views are config-as-code (EC-246b). */}\n <div className=\"shrink-0 border-b border-border px-4 py-3 sm:px-6\">\n <Row gap=\"2\" wrap>\n {/* Left — which view (only when >1), then the transient refine. */}\n <ViewTabs />\n {/* Transient ad-hoc refine — a chip beside the view tabs, editor in a\n popover (EC-246b); the chip's ✕ clears it, so no separate Reset. */}\n <FilterControl collection={collection} />\n {/* The working-set count is the RESULT of the view + filter above, so it\n reads last, set off by a divider and sized like its neighbours. */}\n <Separator orientation=\"vertical\" className=\"h-5 self-center\" />\n <Text\n as=\"span\"\n size=\"xs\"\n tone=\"muted\"\n className=\"whitespace-nowrap tabular-nums\"\n data-testid=\"collection-count\"\n >\n {countLabel}\n </Text>\n\n <Spacer />\n\n {/* Right — the ambient locale lens (EC-176; hidden for single-locale AND\n for a non-localized rail like users), then display config + write actions. */}\n {source.capabilities.locales ? <LocaleSwitcher /> : null}\n <DisplayMenu\n collection={collection}\n hierarchical={hierarchical}\n treeMode={treeMode}\n onToggleTree={setTreeMode}\n />\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew} data-testid=\"new-document\">\n <Plus /> {isPageCollection ? translate('cms.list.newPage') : translate('cms.list.new')}\n </Button>\n ) : null}\n {/* EC-213: import/export fold into one action menu, off the header.\n AD-19: a capability — absent on credential rails (users), so identity\n records are never dumped to / loaded from raw JSON. */}\n {source.capabilities.importExport ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.moreActions')}\n data-testid=\"collection-actions\"\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setImportOpen(true)} data-testid=\"action-import\">\n <Upload /> {translate('cms.list.import')}\n </DropdownMenuItem>\n <DropdownMenuItem\n onClick={exportJson}\n disabled={docs.length === 0}\n data-testid=\"action-export\"\n >\n <Download /> {translate('cms.list.export')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n {toolbarExtra}\n </Row>\n </div>\n\n {/* Bulk actions over the selection (EC-169) */}\n <BulkBar\n collection={collection}\n count={selectedIds.length}\n busy={bulkBusy}\n onAction={raiseBulk}\n onSetField={(setField) => void handleBulk('set-field', [...selectedIds], setField)}\n onClear={() => setSelection(clearSelection())}\n />\n {bulkReport ? (\n <BulkReportPanel report={bulkReport} onDismiss={() => setBulkReport(null)} />\n ) : null}\n\n {/* Reference-aware bulk unpublish/delete confirmation (EC-173). */}\n {pendingBulk !== null ? (\n <ReferenceConfirmDialog\n projectId={projectId}\n action={pendingBulk.action}\n targets={pendingBulk.targets}\n open\n busy={bulkBusy}\n onOpenChange={(open) => {\n if (!open) setPendingBulk(null)\n }}\n onConfirm={() => {\n const { action, targets } = pendingBulk\n setPendingBulk(null)\n void handleBulk(\n action,\n targets.map((target) => target.id),\n )\n }}\n />\n ) : null}\n\n {/* EC-274/EC-284: \"for review\" lane — the collection has drifted from its\n lens's expected shape; surface each conflict so an editor can resolve it. */}\n {shapeIssues.length > 0 ? (\n <div\n className=\"shrink-0 border-b border-warning/30 bg-warning/10 px-4 py-2 sm:px-6\"\n data-testid=\"shape-review-banner\"\n >\n <Stack gap=\"1\">\n {shapeIssues.map((issue, i) => (\n <Row key={`${issue.code}:${i}`} gap=\"2\" align=\"start\">\n <TriangleAlert className=\"mt-0.5 size-3.5 shrink-0 text-warning\" aria-hidden />\n <Stack gap=\"none\" className=\"min-w-0\">\n <Text size=\"xs\" weight=\"semibold\" tone=\"default\" title={issue.code}>\n {translate('cms.list.forReview')} · {cmsIssueLabel(issue.code)}\n </Text>\n <Text size=\"xs\" tone=\"muted\">\n {issue.message}\n </Text>\n </Stack>\n </Row>\n ))}\n </Stack>\n </div>\n ) : null}\n\n {/* Table */}\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {docs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Stack gap=\"2\" align=\"center\" className=\"text-center\">\n <Text tone=\"muted\">{translate('cms.list.emptyNone', { noun: pluralLabel.toLowerCase() })}</Text>\n {canCreate ? (\n <Button size=\"sm\" onClick={handleNew}>\n <Plus />{' '}\n {isPageCollection\n ? translate('cms.list.newPage')\n : translate('cms.list.newNamed', {\n noun: localizedLabel(collection.form?.labelSingular, 'document'),\n })}\n </Button>\n ) : null}\n </Stack>\n </div>\n ) : visibleDocs.length === 0 ? (\n <div className=\"grid h-full place-items-center p-8\">\n <Text tone=\"muted\" data-testid=\"empty-filtered\">\n {translate('cms.list.emptyFiltered')}\n </Text>\n </div>\n ) : (\n <DocumentsGrid\n projectId={projectId}\n collection={collection}\n primary={primary}\n primaryFieldDef={primaryFieldDef}\n columns={columns}\n sortedDocs={orderedDocs}\n depthById={depthById}\n urlByDocId={urlByDocId}\n sort={viewState.sort}\n onSort={toggleSort}\n selectedIds={selectedIds}\n onToggleRow={(id, shift) =>\n setSelection((prev) => toggleRow(prev, visibleIds, id, shift))\n }\n onToggleAll={() =>\n setSelection(\n selectedIds.length === visibleIds.length && visibleIds.length > 0\n ? clearSelection()\n : selectAll(visibleIds),\n )\n }\n hasRowActions={hasRowActions}\n onRowAction={handleRowAction}\n />\n )}\n </div>\n\n {source.capabilities.importExport ? (\n <ImportDialog collectionId={collectionId} open={importOpen} onOpenChange={setImportOpen} />\n ) : null}\n </div>\n )\n}\n\n/**\n * The documents table with inline cell editing (EC-168). Cells edit in place\n * (text/number/boolean/select/date) or open pickers (relation/asset); each\n * commit is one operations command via the cell-edit controller, with\n * rollback + inline cell errors on rejection. Row checkboxes (EC-169) live in\n * their own column, so selection clicks never collide with cell editing.\n */\nfunction DocumentsGrid({\n projectId,\n collection,\n primary,\n primaryFieldDef,\n columns,\n sortedDocs,\n depthById,\n urlByDocId,\n sort,\n onSort,\n selectedIds,\n onToggleRow,\n onToggleAll,\n hasRowActions,\n onRowAction,\n}: {\n projectId: string\n collection: CollectionDef\n primary: string\n primaryFieldDef: FieldDef | undefined\n columns: string[]\n sortedDocs: CmsDocument[]\n /** EC-218: nesting depth per doc id when rendering the hierarchy (tree mode). */\n depthById?: Map<string, number>\n /** EC-216: each routable doc's derived URL; `null` hides the URL column. */\n urlByDocId?: Map<string, DocumentUrl> | null\n sort: ViewSort | null\n onSort: (field: string) => void\n selectedIds: readonly string[]\n onToggleRow: (id: string, shift: boolean) => void\n onToggleAll: () => void\n /** EC-316: whether the right-edge row `⋮` menu has anything to offer at all. */\n hasRowActions: boolean\n onRowAction: (action: RowAction, doc: CmsDocument) => void\n}) {\n const source = useCollectionView()\n const collectionId = collection.id\n const fieldByName = (name: string) => collection.fields.find((f) => f.name === name)\n // Inline editing is a capability: a read-only rail yields no editable cells.\n const editableFields = source.capabilities.inlineEdit\n ? columns.filter((name) => {\n const field = fieldByName(name)\n return field ? cellEditKind(field, source.isFieldReadOnly(field)) !== 'none' : false\n })\n : []\n const cellEdit = useCellEdit({ collection, docs: sortedDocs, editableFields })\n const selected = new Set(selectedIds)\n const allSelected = sortedDocs.length > 0 && selectedIds.length === sortedDocs.length\n\n return (\n <div ref={cellEdit.containerRef}>\n {/* EC-316: `table-fixed` + an explicit `<colgroup>` fix every column's\n width from the SCHEMA alone, before any row renders. Under the\n browser's default `table-layout: auto` a cell's INTRINSIC content\n width feeds back into its column — so swapping a cell's rendered\n value for its inline editor (a wider `<input>`) reflowed the whole\n grid. Fixed layout makes a column's width immune to its cells'\n content; `columnWidthRem` only sets relative proportions, so the\n grid still scales naturally with the container (never with a cell). */}\n <table className=\"w-full table-fixed border-collapse text-sm\">\n <colgroup>\n <col style={{ width: `${CHECKBOX_COLUMN_WIDTH_REM}rem` }} />\n <col style={{ width: `${PRIMARY_COLUMN_WIDTH_REM}rem` }} />\n {columns.map((name) => (\n <col key={name} style={{ width: `${columnWidthRem(fieldByName(name))}rem` }} />\n ))}\n <col style={{ width: `${STATE_COLUMN_WIDTH_REM}rem` }} />\n {urlByDocId ? <col style={{ width: `${URL_COLUMN_WIDTH_REM}rem` }} /> : null}\n {hasRowActions ? <col style={{ width: `${ROW_ACTIONS_COLUMN_WIDTH_REM}rem` }} /> : null}\n </colgroup>\n <thead className=\"sticky top-0 z-10 bg-background\">\n <tr className=\"border-b border-border\">\n <th className=\"px-3 py-2 text-left\">\n <SelectionCheckbox\n checked={allSelected}\n indeterminate={selectedIds.length > 0 && !allSelected}\n label={translate('cms.list.selectAll')}\n testId=\"select-all\"\n onToggle={() => onToggleAll()}\n />\n </th>\n <HeaderCell\n field={primary}\n label={primaryFieldDef ? fieldLabel(primaryFieldDef) : translate('cms.list.column.title')}\n sort={sort}\n onSort={onSort}\n />\n {columns.map((name) => {\n const field = fieldByName(name)\n return field ? (\n <HeaderCell key={name} field={name} label={fieldLabel(field)} sort={sort} onSort={onSort} />\n ) : null\n })}\n <HeaderCell field={STATE_FIELD} label={translate('cms.list.column.state')} sort={sort} onSort={onSort} />\n {/* EC-216: derived URL — not a field, so not sortable. */}\n {urlByDocId ? (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">{translate('cms.list.column.url')}</th>\n ) : null}\n {hasRowActions ? (\n <th className=\"px-2 py-2 text-right\">\n <span className=\"sr-only\">{translate('cms.list.rowActionsColumnLabel')}</span>\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody>\n {sortedDocs.map((doc) => (\n <tr\n key={doc.id}\n className={cn(\n 'group border-b border-border/60 hover:bg-muted/40',\n selected.has(doc.id) && 'bg-primary/5',\n )}\n >\n <td className=\"px-3 py-2 align-middle\">\n <SelectionCheckbox\n checked={selected.has(doc.id)}\n label={translate('cms.list.selectRow', { id: doc.id })}\n testId={`select-row-${doc.id}`}\n onToggle={(shift) => onToggleRow(doc.id, shift)}\n />\n </td>\n <td className=\"px-3 py-2 align-middle\">\n <PrimaryCell\n projectId={projectId}\n collection={collection}\n doc={doc}\n primary={primary}\n depth={depthById?.get(doc.id) ?? 0}\n locale={source.activeLocale}\n config={source.localeConfig}\n detailPath={source.detailPath}\n />\n </td>\n {columns.map((name) => {\n const field = fieldByName(name)\n const coord = { docId: doc.id, field: name }\n const key = cellKey(coord)\n return (\n <td key={name} className=\"px-3 py-2 align-middle\">\n {field ? (\n <EditableCell\n collection={collection}\n doc={doc}\n field={field}\n editing={cellEdit.activeKey === key}\n busy={cellEdit.busyKey === key}\n errorMessage={cellEdit.errorOf(key)}\n onStartEdit={() => cellEdit.start(coord)}\n onCancel={() => cellEdit.cancel(coord)}\n onCommit={(value, advance) => cellEdit.commit(coord, value, advance)}\n />\n ) : null}\n </td>\n )\n })}\n <td className=\"px-3 py-2 align-middle\">\n <DocStateBadge\n published={\n source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false\n }\n />\n </td>\n {urlByDocId ? (\n <td className=\"px-3 py-2 align-middle\">\n <UrlCell url={urlByDocId.get(doc.id)} />\n </td>\n ) : null}\n {hasRowActions ? (\n <td className=\"px-2 py-2 text-right align-middle\">\n <RowActionsMenu\n doc={doc}\n published={source.publishing?.isPublished({ collection: collectionId, id: doc.id }) ?? false}\n hasDetailPath={source.detailPath !== undefined}\n onAction={(action) => onRowAction(action, doc)}\n />\n </td>\n ) : null}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\n/**\n * The right-edge row `⋮` menu (EC-316): the SAME action vocabulary as the\n * toolbar's bulk actions (`rowActionsFor`), gated by the SAME capabilities —\n * so it degrades exactly like the rest of the list for a rail without\n * publish/remove (AD-19). Renders nothing when the gate leaves zero actions.\n */\nfunction RowActionsMenu({\n doc,\n published,\n hasDetailPath,\n onAction,\n}: {\n doc: CmsDocument\n published: boolean\n hasDetailPath: boolean\n onAction: (action: RowAction) => void\n}) {\n const source = useCollectionView()\n const actions = rowActionsFor({ capabilities: source.capabilities, hasDetailPath, published })\n if (actions.length === 0) return null\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={translate('cms.list.rowActionsLabel', { id: doc.id })}\n data-testid={`row-actions-${doc.id}`}\n >\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {actions.map((action) => (\n <RowActionItem key={action} action={action} onSelect={() => onAction(action)} />\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\nfunction RowActionItem({ action, onSelect }: { action: RowAction; onSelect: () => void }) {\n switch (action) {\n case 'open':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-open\">\n <Pencil /> {translate('cms.list.rowAction.open')}\n </DropdownMenuItem>\n )\n case 'publish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-publish\">\n <Eye /> {translate('cms.list.bulk.publish')}\n </DropdownMenuItem>\n )\n case 'unpublish':\n return (\n <DropdownMenuItem onClick={onSelect} data-testid=\"row-action-unpublish\">\n <EyeOff /> {translate('cms.list.bulk.unpublish')}\n </DropdownMenuItem>\n )\n case 'delete':\n return (\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={onSelect}\n data-testid=\"row-action-delete\"\n >\n <Trash2 /> {translate('common.delete')}\n </DropdownMenuItem>\n )\n }\n}\n\n/**\n * A selection checkbox (row or select-all). Its own column and focus target —\n * it never participates in the cell-edit keyboard flow. Shift-click selects\n * the anchor→row range (the mousedown guard stops text selection).\n */\nfunction SelectionCheckbox({\n checked,\n indeterminate = false,\n label,\n testId,\n onToggle,\n}: {\n checked: boolean\n indeterminate?: boolean\n label: string\n testId: string\n onToggle: (shift: boolean) => void\n}) {\n return (\n <input\n ref={(el) => {\n if (el) el.indeterminate = indeterminate && !checked\n }}\n type=\"checkbox\"\n className=\"size-4 cursor-pointer accent-primary align-middle\"\n checked={checked}\n readOnly\n aria-label={label}\n data-testid={testId}\n onClick={(event) => onToggle(event.shiftKey)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n onToggle(event.shiftKey)\n }\n }}\n onMouseDown={(event) => {\n if (event.shiftKey) event.preventDefault()\n }}\n />\n )\n}\n\nfunction HeaderCell({\n field,\n label,\n sort,\n onSort,\n}: {\n field: string\n label: string\n sort: ViewSort | null\n onSort: (field: string) => void\n}) {\n const active = sort?.field === field\n return (\n <th className=\"px-3 py-2 text-left text-xs font-semibold text-muted-foreground\">\n <button type=\"button\" onClick={() => onSort(field)} className=\"inline-flex items-center gap-1 hover:text-foreground\">\n {label}\n {active ? (\n sort!.dir === 'asc' ? (\n <ArrowUp className=\"size-3\" />\n ) : (\n <ArrowDown className=\"size-3\" />\n )\n ) : null}\n </button>\n </th>\n )\n}\n\n/**\n * The primary (title) column cell: the document link, resolved in the\n * ambient active locale with a visible fallback chip when the shown title is\n * untranslated (EC-176).\n */\nfunction PrimaryCell({\n projectId,\n collection,\n doc,\n primary,\n depth = 0,\n locale,\n config,\n detailPath,\n}: {\n projectId: string\n collection: CollectionDef\n doc: CmsDocument\n primary: string\n /** EC-218: nesting depth in the hierarchy (tree mode) — indents the title. */\n depth?: number\n locale: Locale\n config: LocaleConfig\n /** Rail-owned detail route splat (AD-19); absent ⇒ the rail has no detail surface. */\n detailPath?: (id: string) => string\n}) {\n // EC-242: the title cell renders the document identity (resolveDocumentTitle) —\n // a string `titleField` or a function pattern — over the fallback-resolved\n // values, NOT the raw `primary` column value. The untranslated-title chip applies\n // only to a field-backed title (a function pattern has no single source field).\n const title = resolveDocumentTitle(\n collection,\n resolveDocumentForLocale(collection, doc, locale, config),\n doc.id,\n )\n const fallback =\n typeof collection.titleField === 'function'\n ? null\n : resolveDisplayedValue(collection, doc, primary, locale, config).fallback\n const splat = detailPath?.(doc.id)\n return (\n <Row gap=\"2\" align=\"center\" className=\"min-w-0\" style={{ paddingLeft: depth * 20 }}>\n {depth > 0 ? (\n <CornerDownRight className=\"size-3.5 shrink-0 text-muted-foreground\" aria-hidden />\n ) : null}\n {/* 0.0.39: assets get a leading, fixed-size preview in the filename column —\n an image thumbnail (object-cover) for image assets, the file-type placeholder\n otherwise. Fixed box, so it never reflows the EC-316 fixed column widths. */}\n {collection.kind === 'asset' ? <AssetThumbCell assetId={doc.id} alt={title} /> : null}\n {splat !== undefined ? (\n <Link\n to={STUDIO_PROJECT_ROUTE}\n params={{ projectId, _splat: splat }}\n className=\"truncate font-medium text-foreground hover:text-primary hover:underline\"\n >\n {title}\n </Link>\n ) : (\n <Text as=\"span\" className=\"truncate font-medium text-foreground\">\n {title}\n </Text>\n )}\n <FallbackChip fallback={fallback} testId={`cell-fallback-${doc.id}-${primary}`} />\n </Row>\n )\n}\n\n/**\n * The leading asset preview in the filename column (0.0.39). Resolves the asset\n * record from the ambient library and renders {@link AssetThumb} — an image preview\n * for image assets, the file-type placeholder for the rest. Mounted only for\n * `kind:'asset'` collections (which are always under an `<AssetsProvider>`), so the\n * `useAssetRecord` hook is never called on a rail without a library.\n */\nfunction AssetThumbCell({ assetId, alt }: { assetId: string; alt: string }) {\n const record = useAssetRecord(assetId)\n return <AssetThumb record={record} alt={alt} className=\"size-8 shrink-0\" />\n}\n\n/**\n * The read-only URL column cell (EC-216): the document's LIVE (published) path,\n * linking to the absolute live URL when a `frontendUrl` is configured. Only\n * published documents have a `url` here (the URL is derived from the published\n * pool, EC-205), so an unpublished document — having no live page — shows a dash.\n * The URL is always derived, never stored.\n */\nfunction UrlCell({ url }: { url?: DocumentUrl }) {\n if (!url) {\n return (\n <Text size=\"xs\" tone=\"subtle\">\n —\n </Text>\n )\n }\n if (url.href) {\n return (\n <a\n href={url.href}\n target=\"_blank\"\n rel=\"noreferrer\"\n title={url.href}\n className=\"inline-flex max-w-[18rem] items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground\"\n >\n <span className=\"truncate\">{url.path}</span>\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden />\n </a>\n )\n }\n return (\n <Text size=\"xs\" tone=\"muted\" className=\"max-w-[18rem] truncate\" title={url.path}>\n {url.path}\n </Text>\n )\n}\n\nexport type { FieldDef }\n"]}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Link, STUDIO_PROJECT_ROUTE, studioPath, useNavigate } from '@elytracms/studio/router';
3
- import { Check, ChevronDown, CircleAlert, CircleCheck, ExternalLink, Eye, EyeOff, GitCompareArrows, History, Loader2, Lock, MoreHorizontal, RotateCcw, Save, Tag, Trash2, X, } from 'lucide-react';
3
+ import { Check, ChevronDown, CircleAlert, CircleCheck, Eye, EyeOff, GitCompareArrows, History, Loader2, Lock, MoreHorizontal, RotateCcw, Save, Tag, Trash2, X, } from 'lucide-react';
4
4
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { FIELD_WIDTH_SPANS, SIDEBAR_FIELD_GROUP, clearHiddenValues, documentKey, groupOrder, groupSectionOf, hasAliases, hiddenGroupNames, isBlocksField, isFieldHidden, isFieldLocalized, isSingleton, resolveDocumentForLocale, resolveDocumentTitle, resolveField, sidebarFields, tabDescriptorOf, tabOrder, titleFieldOf, staticFieldHidden, urlForDocument, } from '@elytracms/core/cms-core';
6
6
  import { blockRootsOf } from '@elytracms/core/project-graph';
@@ -18,7 +18,7 @@ import { FieldControl } from './field-control';
18
18
  // EC-322: the lazy-wrapped page builder — the heavy canvas subtree code-splits out
19
19
  // of the detail-view critical path and downloads only when a `blocks` field opens.
20
20
  import { CompositionFieldEditor } from '../builder/composition-field-editor-lazy';
21
- import { fieldLabel } from './cms-store';
21
+ import { fieldLabel } from './cms-labels';
22
22
  import { useCmsCollectionViewSource } from '../collection-view/cms-collection-view-source';
23
23
  import { CollectionViewProvider, useCollectionView } from '../collection-view/collection-view-context';
24
24
  import { resolveFieldAccess } from '@elytracms/studio/lib/collection-view/collection-view-source';
@@ -33,9 +33,11 @@ import { VersionsPane } from './versions-pane';
33
33
  // critical path and loads only when the Compare tab opens.
34
34
  import { VersionCompare } from './version-compare-lazy';
35
35
  import { useDocumentVersionsQuery } from './use-document-versions';
36
- import { discardDraftStatus } from './discard-draft';
36
+ import { discardDraftStatus, flushDirtyDraft } from './discard-draft';
37
+ import { derivePublishedSnapshot, publishedVersionSnapshot } from './versions-model';
37
38
  import { IssuesPane } from './issues-pane';
38
39
  import { DetailsPane } from './details-pane';
40
+ import { DocumentUrlPath } from './document-url-path';
39
41
  // 0.0.41: selection-driven embed inspector. Both modules are deliberately TipTap-free
40
42
  // so the editor runtime stays behind rich-text/lazy (EC-322) — see their doc comments.
41
43
  import { EmbedInspectorProvider } from './rich-text/embed-inspector-context';
@@ -118,58 +120,43 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
118
120
  // meaningful when the document is published.
119
121
  const published = source.publishing?.isPublished(ref) ?? false;
120
122
  const [perspective, setPerspective] = useState('draft');
121
- const [publishedSnapshot, setPublishedSnapshot] = useState({ status: 'loading' });
122
123
  // Snap back to Draft if the document is unpublished while viewing Published.
123
124
  useEffect(() => {
124
125
  if (!published)
125
126
  setPerspective('draft');
126
127
  }, [published]);
127
- // Load the pinned published snapshot when viewing Published (fresh each switch,
128
- // so it reflects the current pin after a re-publish). `loadDocumentVersions` is
129
- // a stable callback, so this only re-runs on a perspective/ref change.
130
- const loadVersions = source.versioning?.load;
131
- useEffect(() => {
132
- if (perspective !== 'published')
133
- return;
134
- if (!loadVersions)
135
- return;
136
- let cancelled = false;
137
- setPublishedSnapshot({ status: 'loading' });
138
- void (async () => {
139
- const view = await loadVersions(ref);
140
- if (cancelled)
141
- return;
142
- const pinned = view.publishedVersion !== undefined
143
- ? view.versions.find((v) => v.version === view.publishedVersion)?.snapshot
144
- : undefined;
145
- setPublishedSnapshot(pinned ? { status: 'ready', doc: pinned } : { status: 'missing' });
146
- })();
147
- return () => {
148
- cancelled = true;
149
- };
150
- }, [perspective, ref, loadVersions]);
128
+ // EC-316/EC-325 — "Discard changes" gating AND the Published-perspective
129
+ // snapshot share ONE query (AD-17: the one operations-backed cache,
130
+ // `use-document-versions.ts` — no raw `source.versioning.load` call
131
+ // anywhere in this component). Both need exactly the same
132
+ // `versions`/`publishedVersion` shape, so a second bespoke fetch on
133
+ // perspective switch would just re-read what this already has. Gated the
134
+ // same way the Discard-draft menu item always was: a publishing + versioned
135
+ // rail AND a published document (never a wasted fetch on e.g. the users
136
+ // rail or a never-published draft) — in every real `CollectionViewSource`
137
+ // `capabilities.publish`/`capabilities.versions` are set identically, so
138
+ // this is also exactly when the Published perspective is reachable.
139
+ const canDiscard = canPublish && canVersions;
140
+ const { versionsQuery, versionKey } = useDocumentVersionsQuery(ref, {
141
+ enabled: canDiscard && published,
142
+ });
143
+ const versionsView = versionsQuery.data ?? null;
144
+ const publishedVersionNumber = versionsView?.publishedVersion;
145
+ const publishedSnapshotDoc = publishedVersionSnapshot(versionsView);
146
+ // The Published-perspective snapshot (EC-226), derived from the query
147
+ // above — no second fetch, and `derivePublishedSnapshot` guards a
148
+ // disabled/not-yet-resolved query by reading as 'loading' (never a false
149
+ // 'missing').
150
+ const publishedSnapshot = derivePublishedSnapshot(versionsView);
151
151
  // The whole fieldset is read-only when viewing Published. The form/canvas
152
152
  // render the pinned snapshot ONLY once it has loaded — never the draft, which
153
153
  // must not be presented as published; until then the body shows a placeholder.
154
154
  const viewReadOnly = perspective === 'published';
155
155
  const viewDoc = viewReadOnly && publishedSnapshot.status === 'ready' ? publishedSnapshot.doc : draft;
156
156
  const publishedPending = viewReadOnly && publishedSnapshot.status !== 'ready';
157
- // EC-316 — "Discard changes": revert the draft to exactly the published
158
- // content. Only meaningful for a publishing + versioned rail AND a published
159
- // document, so the history query is gated off otherwise (never a wasted
160
- // fetch on e.g. the users rail or a never-published draft).
161
- const canDiscard = canPublish && canVersions;
162
- const { versionsQuery: discardVersionsQuery, versionKey: discardVersionKey } = useDocumentVersionsQuery(ref, {
163
- enabled: canDiscard && published,
164
- });
165
157
  const discardCache = useOperationCache();
166
158
  const [discardConfirm, setDiscardConfirm] = useState(false);
167
159
  const [discardBusy, setDiscardBusy] = useState(false);
168
- const discardView = discardVersionsQuery.data ?? null;
169
- const publishedVersionNumber = discardView?.publishedVersion;
170
- const publishedSnapshotForDiscard = publishedVersionNumber !== undefined
171
- ? discardView?.versions.find((v) => v.version === publishedVersionNumber)?.snapshot
172
- : undefined;
173
160
  // One pure decision (tested in discard-draft.test.ts): hidden / disabled-
174
161
  // with-reason / ready. Its semantic equality is the SAME comparator the
175
162
  // Versions pane's publish gate uses, so the two never contradict (EC-298).
@@ -177,7 +164,7 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
177
164
  canDiscard,
178
165
  published,
179
166
  viewReadOnly,
180
- publishedSnapshot: publishedSnapshotForDiscard,
167
+ publishedSnapshot: publishedSnapshotDoc,
181
168
  collection,
182
169
  draft,
183
170
  });
@@ -196,10 +183,15 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
196
183
  return;
197
184
  setDiscardBusy(true);
198
185
  try {
186
+ // EC-325: flush a dirty in-memory buffer FIRST, mirroring the Versions
187
+ // pane's/Compare view's own restores — `documents.restore` snapshots
188
+ // whatever is currently PERSISTED, so an edit still sitting in the
189
+ // autosave debounce window would otherwise be silently unrecoverable.
190
+ flushDirtyDraft({ dirty, save });
199
191
  const restored = await source.versioning?.restore(ref, publishedVersionNumber, { kind: 'all' });
200
192
  if (restored)
201
193
  replaceDraft(restored);
202
- await discardCache.invalidate(discardVersionKey);
194
+ await discardCache.invalidate(versionKey);
203
195
  }
204
196
  finally {
205
197
  setDiscardBusy(false);
@@ -486,25 +478,23 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
486
478
  // memoized: its render closes over per-render edit state (draft, highlight,
487
479
  // field errors) via `renderFieldRow`, and the inspector re-renders with the rest
488
480
  // of the editor anyway, so a stable pane identity would buy nothing here.
489
- // 0.0.39: whether a deployment route addresses this collection — gates the header's
490
- // "View live" AND the Details pane's document-level URL row (EC-315 hybrid split).
491
- // A cheap synchronous accessor, resolved on every render (NOT frozen in a `useMemo`
492
- // with a static dep — the same first-paint-empty-routes trap the SlugField fix
493
- // removed: routes arrive after the workspace/config loads).
481
+ // 0.0.42 (round 3): whether a deployment route addresses this collection — gates the
482
+ // header's composed-URL row (which carries the live-page affordance, EC-315 hybrid
483
+ // split). A cheap synchronous accessor, resolved on every render (NOT frozen in a
484
+ // `useMemo` with a static dep — the same first-paint-empty-routes trap the SlugField
485
+ // fix removed: routes arrive after the workspace/config loads).
494
486
  const routableCollection = resolveDeploymentRoutes().some((route) => route.document?.collection === collection.id);
495
- const detailsPane = hasAliases(collection) || visibleSidebarFields.length > 0 || routableCollection
487
+ // The composed URL moved OUT of this pane and up to the header (round 3): a lone URL
488
+ // row on an otherwise-empty pane looked odd. So the Details pane exists only for slots
489
+ // and/or sidebar fields — never merely because the collection is routable (that would
490
+ // resurrect the empty-pane problem). A routable page keeps its pane via its slug
491
+ // sidebar field; a routable collection with neither has no pane (URL is in the header).
492
+ const detailsPane = hasAliases(collection) || visibleSidebarFields.length > 0
496
493
  ? {
497
494
  id: 'details',
498
495
  label: translate('cms.editor.detailsPane'),
499
496
  icon: _jsx(Tag, { className: "size-3.5" }),
500
- render: () => (_jsx(DetailsPane, { collection: collection, doc: draft, siblings: source.documents(), readOnly: viewReadOnly, fields: visibleSidebarFields, renderField: renderFieldRow, urlContext: routableCollection
501
- ? {
502
- projectId,
503
- routes: resolveDeploymentRoutes(),
504
- localeConfig: source.localeConfig,
505
- locale,
506
- }
507
- : undefined, onAliasChange: (alias) => setDraft((d) => {
497
+ render: () => (_jsx(DetailsPane, { collection: collection, doc: draft, siblings: source.documents(), readOnly: viewReadOnly, fields: visibleSidebarFields, renderField: renderFieldRow, onAliasChange: (alias) => setDraft((d) => {
508
498
  const next = { ...d };
509
499
  if (alias === undefined)
510
500
  delete next.alias;
@@ -655,10 +645,24 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
655
645
  localeConfig: source.localeConfig,
656
646
  }, collection, published, { siblings: [...publishedDocs.byId.values()], locale });
657
647
  }, [publishedDocs, collection, doc.id, locale, source.localeConfig]);
658
- // EC-246d/EC-315: the DRAFT composed path moved INTO the slug control itself
659
- // (`SlugField`), which derives + decomposes it from the same routes; the editor no
660
- // longer computes a separate `draftUrl`. `liveUrl` (published) still gates the
661
- // header's "View live" button — the sole open-live, so draft never links out.
648
+ // 0.0.42 (round 3): the composed URL row lives in the header under the title; its
649
+ // LEAF segment carries the open-live affordance, mirroring the retired "View live"
650
+ // button's gating EXACTLY. `href` present (published + frontendUrl) → the leaf opens
651
+ // the live page in a new tab; absent → a muted, non-interactive icon with the same
652
+ // reason tooltip (loading / publish-first / set-frontendUrl). The draft-derived path
653
+ // itself still updates as you type — only the OPEN-live action is published-gated, so
654
+ // the draft/live distinction is preserved.
655
+ const headerLive = routableCollection
656
+ ? liveUrl?.href
657
+ ? { href: liveUrl.href, title: translate('cms.editor.openLiveUrl', { path: liveUrl.path }) }
658
+ : {
659
+ title: publishedDocs.status === 'loading'
660
+ ? translate('cms.editor.loadingLiveUrl')
661
+ : !published
662
+ ? translate('cms.editor.publishToViewLive')
663
+ : translate('cms.editor.setFrontendUrlHint'),
664
+ }
665
+ : undefined;
662
666
  // EC-240: hide the tab bar when there is nothing to navigate — a single content
663
667
  // tab with no References/Compare (the users rail). When framework tabs ARE
664
668
  // present we KEEP the content tab(s) so there is always a way back to the form;
@@ -696,7 +700,7 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
696
700
  setCompareBase,
697
701
  setCompareTarget,
698
702
  exitCompare,
699
- }, children: _jsx(EmbedInspectorProvider, { value: embedInspectorApi, children: _jsxs("div", { className: cn('flex h-full min-h-0 flex-col', viewReadOnly && 'bg-info/[0.04]'), children: [_jsxs("div", { className: "shrink-0 border-b border-border px-4 py-3 sm:px-6", children: [_jsxs(Row, { gap: "3", children: [_jsxs(Row, { gap: "2", align: "center", className: "min-w-0", children: [_jsx(Heading, { level: 1, size: "h2", className: "truncate", children: singleton ? localizedLabel(collection.form?.label, collection.id) : title || doc.id }), singleton ? null : _jsx(FallbackChip, { fallback: titleFallback, testId: "doc-title-fallback" })] }), _jsx(Spacer, {}), _jsx(Text, { size: "xs", tone: "muted", className: "whitespace-nowrap", "data-testid": "autosave-status", children: source.lastError
703
+ }, children: _jsx(EmbedInspectorProvider, { value: embedInspectorApi, children: _jsxs("div", { className: cn('flex h-full min-h-0 flex-col', viewReadOnly && 'bg-info/[0.04]'), children: [_jsxs("div", { className: "shrink-0 border-b border-border px-4 py-3 sm:px-6", children: [_jsxs(Row, { gap: "3", align: "start", children: [_jsxs(Stack, { gap: "1", className: "min-w-0", children: [_jsxs(Row, { gap: "2", align: "center", className: "min-w-0", children: [_jsx(Heading, { level: 1, size: "h2", className: "truncate", children: singleton ? localizedLabel(collection.form?.label, collection.id) : title || doc.id }), singleton ? null : _jsx(FallbackChip, { fallback: titleFallback, testId: "doc-title-fallback" })] }), routableCollection ? (_jsx(DocumentUrlPath, { projectId: projectId, collection: collection, doc: draft, siblings: source.documents(), routes: resolveDeploymentRoutes(), localeConfig: source.localeConfig, locale: locale, live: headerLive })) : null] }), _jsx(Spacer, {}), _jsx(Text, { size: "xs", tone: "muted", className: "whitespace-nowrap", "data-testid": "autosave-status", children: source.lastError
700
704
  ? translate('cms.editor.saveFailed')
701
705
  : explicitSave
702
706
  ? dirty
@@ -704,11 +708,7 @@ function EditorBody({ projectId, collection, doc, focusPath, }) {
704
708
  : translate('cms.editor.saved')
705
709
  : dirty
706
710
  ? translate('cms.editor.saving')
707
- : translate('cms.editor.saved') }), canPublish ? _jsx(DocStateBadge, { published: published }) : null, routableCollection ? (liveUrl?.href ? (_jsx(Button, { asChild: true, variant: "outline", size: "sm", title: translate('cms.editor.openLiveUrl', { path: liveUrl.path }), children: _jsxs("a", { href: liveUrl.href, target: "_blank", rel: "noreferrer", "data-testid": "view-live", children: [_jsx(ExternalLink, {}), " ", translate('cms.editor.viewLive')] }) })) : (_jsxs(Button, { variant: "outline", size: "sm", disabled: true, "data-testid": "view-live-disabled", title: publishedDocs.status === 'loading'
708
- ? translate('cms.editor.loadingLiveUrl')
709
- : !published
710
- ? translate('cms.editor.publishToViewLive')
711
- : translate('cms.editor.setFrontendUrlHint'), children: [_jsx(ExternalLink, {}), " ", translate('cms.editor.viewLive')] }))) : null, canPublish ? (_jsxs(Row, { gap: "px", align: "center", children: [_jsx(Button, { size: "sm", onClick: handlePublish, disabled: publishDisabled, title: publishTitle, className: canPublishClose ? 'rounded-r-none' : undefined, "data-testid": "doc-publish", children: publishButtonLabel }), canPublishClose ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "sm", disabled: publishDisabled, "aria-label": translate('cms.editor.publishActions'), "data-testid": "doc-publish-actions", className: "rounded-l-none border-l border-primary-foreground/25 px-1.5", children: _jsx(ChevronDown, { className: "size-3.5" }) }) }), _jsx(DropdownMenuContent, { align: "end", children: _jsxs(DropdownMenuItem, { onClick: handlePublishAndClose, "data-testid": "doc-publish-and-close", children: [_jsx(Save, {}), " ", translate('cms.editor.publishAndClose')] }) })] })) : null] })) : null, explicitSave ? (_jsxs(Button, { size: "sm", onClick: save, disabled: !dirty, "data-testid": "doc-save", children: [_jsx(Check, {}), " ", translate('common.save')] })) : null, published || !singleton ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": translate('cms.editor.moreActions'), children: _jsx(MoreHorizontal, {}) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [discardStatus !== 'hidden' ? (_jsxs(DropdownMenuItem, { "data-testid": "doc-discard-draft", disabled: discardStatus !== 'ready', title: discardDisabledReason, onClick: () => setDiscardConfirm(true), children: [_jsx(RotateCcw, {}), " ", translate('cms.editor.discardDraft')] })) : null, published ? (_jsxs(DropdownMenuItem, { onClick: () => setConfirmAction('unpublish'), children: [_jsx(EyeOff, {}), " ", translate('cms.editor.unpublish')] })) : null, singleton ? null : (_jsxs(DropdownMenuItem, { "data-testid": "doc-delete", className: "text-destructive", onClick: () => setConfirmAction('delete'), children: [_jsx(Trash2, {}), " ", translate('common.delete')] }))] })] })) : null] }), showLensRow ? (_jsxs(Row, { gap: "3", className: "mt-3", wrap: true, children: [_jsxs(Row, { gap: "1", align: "center", children: [showContentTabs ? tabs.map((tab) => renderContentTab(tab)) : null, showReferences ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": true }), renderContentTab(REFERENCES_TAB)] })) : null, compare ? (_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium transition-colors', activeTab === COMPARE_TAB
711
+ : translate('cms.editor.saved') }), canPublish ? _jsx(DocStateBadge, { published: published }) : null, canPublish ? (_jsxs(Row, { gap: "px", align: "center", children: [_jsx(Button, { size: "sm", onClick: handlePublish, disabled: publishDisabled, title: publishTitle, className: canPublishClose ? 'rounded-r-none' : undefined, "data-testid": "doc-publish", children: publishButtonLabel }), canPublishClose ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { size: "sm", disabled: publishDisabled, "aria-label": translate('cms.editor.publishActions'), "data-testid": "doc-publish-actions", className: "rounded-l-none border-l border-primary-foreground/25 px-1.5", children: _jsx(ChevronDown, { className: "size-3.5" }) }) }), _jsx(DropdownMenuContent, { align: "end", children: _jsxs(DropdownMenuItem, { onClick: handlePublishAndClose, "data-testid": "doc-publish-and-close", children: [_jsx(Save, {}), " ", translate('cms.editor.publishAndClose')] }) })] })) : null] })) : null, explicitSave ? (_jsxs(Button, { size: "sm", onClick: save, disabled: !dirty, "data-testid": "doc-save", children: [_jsx(Check, {}), " ", translate('common.save')] })) : null, published || !singleton ? (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "icon-sm", "aria-label": translate('cms.editor.moreActions'), children: _jsx(MoreHorizontal, {}) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [discardStatus !== 'hidden' ? (_jsxs(DropdownMenuItem, { "data-testid": "doc-discard-draft", disabled: discardStatus !== 'ready', title: discardDisabledReason, onClick: () => setDiscardConfirm(true), children: [_jsx(RotateCcw, {}), " ", translate('cms.editor.discardDraft')] })) : null, published ? (_jsxs(DropdownMenuItem, { onClick: () => setConfirmAction('unpublish'), children: [_jsx(EyeOff, {}), " ", translate('cms.editor.unpublish')] })) : null, singleton ? null : (_jsxs(DropdownMenuItem, { "data-testid": "doc-delete", className: "text-destructive", onClick: () => setConfirmAction('delete'), children: [_jsx(Trash2, {}), " ", translate('common.delete')] }))] })] })) : null] }), showLensRow ? (_jsxs(Row, { gap: "3", className: "mt-3", wrap: true, children: [_jsxs(Row, { gap: "1", align: "center", children: [showContentTabs ? tabs.map((tab) => renderContentTab(tab)) : null, showReferences ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": true }), renderContentTab(REFERENCES_TAB)] })) : null, compare ? (_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium transition-colors', activeTab === COMPARE_TAB
712
712
  ? 'bg-accent text-accent-foreground'
713
713
  : 'text-muted-foreground hover:bg-muted'), children: [_jsxs("button", { type: "button", onClick: () => setActiveTab(COMPARE_TAB), "aria-pressed": activeTab === COMPARE_TAB, className: "inline-flex items-center gap-1", children: [_jsx(GitCompareArrows, { className: "size-3", "aria-hidden": true }), " ", translate('cms.version.compare')] }), _jsx("button", { type: "button", onClick: exitCompare, "aria-label": translate('cms.version.closeCompare'), className: "ml-0.5 rounded p-0.5 hover:bg-background/40", children: _jsx(X, { className: "size-3" }) })] })) : null] }), _jsx(Spacer, {}), canLocales ? _jsx(LocaleSwitcher, {}) : null, canPublish ? (_jsxs(Row, { gap: "px", className: "rounded-md bg-muted/60 p-0.5", children: [_jsx(PerspectiveButton, { label: translate('cms.editor.draftState'), active: perspective === 'draft', onClick: () => setPerspective('draft') }), _jsx(PerspectiveButton, { label: translate('cms.editor.publishedState'), active: perspective === 'published', accent: "info", disabled: !published, title: published ? undefined : translate('cms.editor.publishToViewPublished'), onClick: () => setPerspective('published') })] })) : null] })) : null] }), viewReadOnly ? (_jsxs(Row, { gap: "2", className: "shrink-0 border-b border-info/30 bg-info/10 px-4 py-1.5 text-info sm:px-6", "data-testid": "published-view-banner", children: [_jsx(Lock, { className: "size-3.5 shrink-0", "aria-hidden": true }), _jsx(Text, { size: "xs", className: "text-info", children: translate('cms.editor.publishedReadOnlyBanner') }), _jsx(Spacer, {}), _jsx("button", { type: "button", onClick: () => setPerspective('draft'), className: "text-xs font-medium underline-offset-2 hover:underline", children: translate('cms.editor.switchToDraft') })] })) : null, publishedPending ? (_jsx("div", { className: "grid min-h-0 flex-1 place-items-center p-8", children: _jsx(Text, { size: "sm", tone: "muted", children: publishedSnapshot.status === 'loading'
714
714
  ? translate('cms.editor.loadingPublishedVersion')