@blokkli/editor 2.0.0-alpha.52 → 2.0.0-alpha.53

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 (373) hide show
  1. package/dist/chunks/tailwindConfig.mjs +3 -3
  2. package/dist/global/types/blockOptions.d.ts +18 -2
  3. package/dist/module.d.mts +2 -2
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +281 -18
  6. package/dist/modules/agent/index.d.mts +1 -1
  7. package/dist/modules/agent/runtime/app/composables/agentProvider.d.ts +1 -0
  8. package/dist/modules/agent/runtime/app/composables/agentProvider.js +7 -0
  9. package/dist/modules/agent/runtime/app/features/agent/Panel/DropHandler/index.d.vue.ts +2 -2
  10. package/dist/modules/agent/runtime/app/features/agent/Panel/DropHandler/index.vue +14 -49
  11. package/dist/modules/agent/runtime/app/features/agent/Panel/DropHandler/index.vue.d.ts +2 -2
  12. package/dist/modules/agent/runtime/app/features/agent/Panel/Feedback/index.d.vue.ts +10 -0
  13. package/dist/modules/agent/runtime/app/features/agent/Panel/Feedback/index.vue +102 -0
  14. package/dist/modules/agent/runtime/app/features/agent/Panel/Feedback/index.vue.d.ts +10 -0
  15. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.vue +8 -5
  16. package/dist/modules/agent/runtime/app/features/agent/Panel/ToolCard/index.d.vue.ts +3 -3
  17. package/dist/modules/agent/runtime/app/features/agent/Panel/ToolCard/index.vue +9 -5
  18. package/dist/modules/agent/runtime/app/features/agent/Panel/ToolCard/index.vue.d.ts +3 -3
  19. package/dist/modules/agent/runtime/app/features/agent/Panel/index.d.vue.ts +7 -0
  20. package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue +16 -2
  21. package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue.d.ts +7 -0
  22. package/dist/modules/agent/runtime/app/features/agent/index.vue +29 -0
  23. package/dist/modules/agent/runtime/app/features/agent/types.d.ts +16 -0
  24. package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Component.vue +3 -1
  25. package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/index.d.ts +2 -0
  26. package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/index.js +8 -1
  27. package/dist/modules/charts/index.d.mts +1 -1
  28. package/dist/modules/charts/index.mjs +2 -3
  29. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypePicker/index.vue +1 -1
  30. package/dist/modules/charts/runtime/features/charts/Editor/ColorDropdown/index.vue +1 -1
  31. package/dist/modules/drupal/graphql/base/fragment.paragraphsBlokkliEditState.graphql +16 -0
  32. package/dist/modules/drupal/graphql/base/query.pbConfig.graphql +9 -0
  33. package/dist/modules/drupal/graphql/features/agent.graphql +20 -0
  34. package/dist/modules/drupal/graphql/features/publishNew.graphql +14 -0
  35. package/dist/modules/drupal/graphql/features/referenced-entities.graphql +21 -0
  36. package/dist/modules/drupal/graphql/features/textFieldValues.graphql +20 -0
  37. package/dist/modules/drupal/graphql/features/workspace.graphql +23 -0
  38. package/dist/modules/drupal/graphql/mutations/bulk_translate_field_values.graphql +19 -0
  39. package/dist/modules/drupal/graphql/mutations/clear_outdated_translation.graphql +15 -0
  40. package/dist/modules/drupal/graphql/mutations/ignore_analyze.graphql +15 -0
  41. package/dist/modules/drupal/graphql/mutations/request_translation.graphql +10 -0
  42. package/dist/modules/drupal/graphql/mutations/unignore_analyze.graphql +15 -0
  43. package/dist/modules/drupal/index.d.mts +1 -1
  44. package/dist/modules/drupal/index.mjs +16 -0
  45. package/dist/modules/drupal/runtime/adapter/index.js +180 -11
  46. package/dist/modules/iframes/index.d.mts +31 -0
  47. package/dist/modules/iframes/index.mjs +52 -0
  48. package/dist/modules/iframes/runtime/components/BlokkliIframe/index.d.vue.ts +18 -0
  49. package/dist/modules/iframes/runtime/components/BlokkliIframe/index.vue +61 -0
  50. package/dist/modules/iframes/runtime/components/BlokkliIframe/index.vue.d.ts +18 -0
  51. package/dist/modules/iframes/runtime/components/index.d.ts +1 -0
  52. package/dist/modules/iframes/runtime/components/index.js +1 -0
  53. package/dist/modules/iframes/runtime/features/iframes/Editor/index.d.vue.ts +12 -0
  54. package/dist/modules/iframes/runtime/features/iframes/Editor/index.vue +220 -0
  55. package/dist/modules/iframes/runtime/features/iframes/Editor/index.vue.d.ts +12 -0
  56. package/dist/modules/iframes/runtime/types.d.ts +10 -0
  57. package/dist/modules/index.d.mts +1 -1
  58. package/dist/modules/table-of-contents/index.d.mts +1 -1
  59. package/dist/runtime/components/Blocks/NotImplemented/index.vue +57 -0
  60. package/dist/runtime/components/BlokkliEditable.vue +1 -1
  61. package/dist/runtime/editor/adapter/index.d.ts +8 -1
  62. package/dist/runtime/editor/components/Actions/Interactions/index.vue +77 -17
  63. package/dist/runtime/editor/components/Actions/{ItemDropdown.vue → ItemDropdown/index.vue} +9 -10
  64. package/dist/runtime/editor/components/Actions/index.vue +586 -23
  65. package/dist/runtime/editor/components/AnimationCanvas/index.vue +1 -0
  66. package/dist/runtime/editor/components/AppMenu/MenuButton.vue +185 -1
  67. package/dist/runtime/editor/components/AppMenu/index.vue +24 -10
  68. package/dist/runtime/editor/components/ArtboardTooltip/index.d.vue.ts +6 -2
  69. package/dist/runtime/editor/components/ArtboardTooltip/index.vue +223 -3
  70. package/dist/runtime/editor/components/ArtboardTooltip/index.vue.d.ts +6 -2
  71. package/dist/runtime/editor/components/AutoHeight/index.vue +23 -0
  72. package/dist/runtime/editor/components/Banner/Inner.d.vue.ts +30 -0
  73. package/dist/runtime/editor/components/Banner/Inner.vue +32 -0
  74. package/dist/runtime/editor/components/Banner/Inner.vue.d.ts +30 -0
  75. package/dist/runtime/editor/components/Banner/index.d.vue.ts +3 -13
  76. package/dist/runtime/editor/components/Banner/index.vue +2 -14
  77. package/dist/runtime/editor/components/Banner/index.vue.d.ts +3 -13
  78. package/dist/runtime/editor/components/BetaIndicator/index.d.vue.ts +6 -0
  79. package/dist/runtime/editor/components/BetaIndicator/index.vue +16 -0
  80. package/dist/runtime/editor/components/BetaIndicator/index.vue.d.ts +6 -0
  81. package/dist/runtime/editor/components/BlockPreviewItem/index.vue +51 -1
  82. package/dist/runtime/editor/components/BlockPreviewRenderer/index.vue +27 -1
  83. package/dist/runtime/editor/components/BlockProxy/index.vue +148 -1
  84. package/dist/runtime/editor/components/BlokkliRootErrorBoundary.vue +59 -0
  85. package/dist/runtime/editor/components/BundleSelector/index.vue +170 -20
  86. package/dist/runtime/editor/components/Dialog/index.d.vue.ts +2 -0
  87. package/dist/runtime/editor/components/Dialog/index.vue +341 -0
  88. package/dist/runtime/editor/components/Dialog/index.vue.d.ts +2 -0
  89. package/dist/runtime/editor/components/DiffApproval/Highlight/index.vue +117 -0
  90. package/dist/runtime/editor/components/DiffApproval/Toolbar/index.vue +224 -28
  91. package/dist/runtime/editor/components/DiffViewer/DiffValue.d.vue.ts +1 -0
  92. package/dist/runtime/editor/components/DiffViewer/DiffValue.vue +5 -1
  93. package/dist/runtime/editor/components/DiffViewer/DiffValue.vue.d.ts +1 -0
  94. package/dist/runtime/editor/components/DiffViewer/State.vue +319 -0
  95. package/dist/runtime/editor/components/DraggableList.vue +103 -0
  96. package/dist/runtime/editor/components/Dropdown/index.vue +84 -0
  97. package/dist/runtime/editor/components/EditProvider.vue +72 -15
  98. package/dist/runtime/editor/components/FileDropHandler/index.d.vue.ts +23 -0
  99. package/dist/runtime/editor/components/FileDropHandler/index.vue +108 -0
  100. package/dist/runtime/editor/components/FileDropHandler/index.vue.d.ts +23 -0
  101. package/dist/runtime/editor/components/FlexTextarea/index.vue +4 -2
  102. package/dist/runtime/editor/components/Form/Datepicker/index.vue +149 -0
  103. package/dist/runtime/editor/components/Form/Toggle/index.vue +205 -1
  104. package/dist/runtime/editor/components/FormOverlay/index.vue +90 -0
  105. package/dist/runtime/editor/components/Icon/index.vue +6 -0
  106. package/dist/runtime/editor/components/Indicators/index.vue +161 -0
  107. package/dist/runtime/editor/components/InfoBox/index.vue +65 -0
  108. package/dist/runtime/editor/components/Konami/index.vue +119 -0
  109. package/dist/runtime/editor/components/Loading/index.d.vue.ts +6 -3
  110. package/dist/runtime/editor/components/Loading/index.vue +10 -5
  111. package/dist/runtime/editor/components/Loading/index.vue.d.ts +6 -3
  112. package/dist/runtime/editor/components/Messages/index.vue +131 -0
  113. package/dist/runtime/editor/components/NestedEditorOverlay/index.d.vue.ts +1 -0
  114. package/dist/runtime/editor/components/NestedEditorOverlay/index.vue +246 -12
  115. package/dist/runtime/editor/components/NestedEditorOverlay/index.vue.d.ts +1 -0
  116. package/dist/runtime/editor/components/NotEditStateInfo/index.d.vue.ts +3 -0
  117. package/dist/runtime/editor/components/NotEditStateInfo/index.vue +19 -0
  118. package/dist/runtime/editor/components/NotEditStateInfo/index.vue.d.ts +3 -0
  119. package/dist/runtime/editor/components/Overlay/index.vue +84 -0
  120. package/dist/runtime/editor/components/Pagination/index.vue +41 -0
  121. package/dist/runtime/editor/components/PluginConfigForm/index.vue +23 -0
  122. package/dist/runtime/editor/components/PluginConfigFormInline/FilterSelect/index.vue +429 -0
  123. package/dist/runtime/editor/components/PluginConfigFormInline/index.d.vue.ts +22 -0
  124. package/dist/runtime/editor/components/PluginConfigFormInline/index.vue +150 -0
  125. package/dist/runtime/editor/components/PluginConfigFormInline/index.vue.d.ts +22 -0
  126. package/dist/runtime/editor/components/Popup/index.vue +77 -2
  127. package/dist/runtime/editor/components/PreviewProvider.vue +7 -0
  128. package/dist/runtime/editor/components/Resizable/index.vue +90 -1
  129. package/dist/runtime/editor/components/ScaleToFit/index.vue +30 -1
  130. package/dist/runtime/editor/components/SearchOverlay/index.d.vue.ts +43 -0
  131. package/dist/runtime/editor/components/SearchOverlay/index.vue +264 -0
  132. package/dist/runtime/editor/components/SearchOverlay/index.vue.d.ts +43 -0
  133. package/dist/runtime/editor/components/StatusIcon/index.vue +104 -0
  134. package/dist/runtime/editor/components/StatusIndicator/index.d.vue.ts +9 -0
  135. package/dist/runtime/editor/components/StatusIndicator/index.vue +16 -0
  136. package/dist/runtime/editor/components/StatusIndicator/index.vue.d.ts +9 -0
  137. package/dist/runtime/editor/components/SystemRequirements/index.vue +57 -0
  138. package/dist/runtime/editor/components/Tabs/index.d.vue.ts +30 -0
  139. package/dist/runtime/editor/components/Tabs/index.vue +32 -0
  140. package/dist/runtime/editor/components/Tabs/index.vue.d.ts +30 -0
  141. package/dist/runtime/editor/components/Toolbar/index.vue +214 -3
  142. package/dist/runtime/editor/components/Tooltip/Context.d.vue.ts +7 -0
  143. package/dist/runtime/editor/components/Tooltip/Context.vue +13 -0
  144. package/dist/runtime/editor/components/Tooltip/Context.vue.d.ts +7 -0
  145. package/dist/runtime/editor/components/Tooltip/Status.d.vue.ts +8 -0
  146. package/dist/runtime/editor/components/Tooltip/Status.vue +27 -0
  147. package/dist/runtime/editor/components/Tooltip/Status.vue.d.ts +8 -0
  148. package/dist/runtime/editor/components/Tooltip/index.d.vue.ts +27 -0
  149. package/dist/runtime/editor/components/Tooltip/index.vue +40 -0
  150. package/dist/runtime/editor/components/Tooltip/index.vue.d.ts +27 -0
  151. package/dist/runtime/editor/components/index.d.ts +59 -49
  152. package/dist/runtime/editor/components/index.js +59 -98
  153. package/dist/runtime/editor/composables/defineHighlight.d.ts +2 -0
  154. package/dist/runtime/editor/composables/defineHighlight.js +10 -0
  155. package/dist/runtime/editor/composables/index.d.ts +1 -0
  156. package/dist/runtime/editor/composables/index.js +1 -0
  157. package/dist/runtime/editor/composables/useBlockRegistration.js +8 -0
  158. package/dist/runtime/editor/composables/useStickyToolbar.d.ts +1 -0
  159. package/dist/runtime/editor/composables/useStickyToolbar.js +16 -0
  160. package/dist/runtime/editor/css/output.css +1 -1
  161. package/dist/runtime/editor/events/index.d.ts +10 -0
  162. package/dist/runtime/editor/features/add-list/Help/index.vue +193 -0
  163. package/dist/runtime/editor/features/add-list/index.vue +441 -0
  164. package/dist/runtime/editor/features/analyze/Ignored/index.d.vue.ts +7 -0
  165. package/dist/runtime/editor/features/analyze/Ignored/index.vue +35 -0
  166. package/dist/runtime/editor/features/analyze/Ignored/index.vue.d.ts +7 -0
  167. package/dist/runtime/editor/features/analyze/Main.vue +148 -24
  168. package/dist/runtime/editor/features/analyze/Results/Results.d.vue.ts +1 -9
  169. package/dist/runtime/editor/features/analyze/Results/Results.vue +0 -2
  170. package/dist/runtime/editor/features/analyze/Results/Results.vue.d.ts +1 -9
  171. package/dist/runtime/editor/features/analyze/Results/ResultsItem.d.vue.ts +1 -9
  172. package/dist/runtime/editor/features/analyze/Results/ResultsItem.vue +1 -2
  173. package/dist/runtime/editor/features/analyze/Results/ResultsItem.vue.d.ts +1 -9
  174. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodes.d.vue.ts +1 -9
  175. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodes.vue +11 -8
  176. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodes.vue.d.ts +1 -9
  177. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodesTarget.d.vue.ts +3 -10
  178. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodesTarget.vue +63 -25
  179. package/dist/runtime/editor/features/analyze/Results/ResultsItemNodesTarget.vue.d.ts +3 -10
  180. package/dist/runtime/editor/features/analyze/analyzers/altText.js +2 -0
  181. package/dist/runtime/editor/features/analyze/analyzers/headingStructure.js +3 -0
  182. package/dist/runtime/editor/features/analyze/analyzers/helpers/hashString.d.ts +7 -0
  183. package/dist/runtime/editor/features/analyze/analyzers/helpers/hashString.js +8 -0
  184. package/dist/runtime/editor/features/analyze/analyzers/readability.js +6 -12
  185. package/dist/runtime/editor/features/analyze/analyzers/types.d.ts +20 -0
  186. package/dist/runtime/editor/features/analyze/index.vue +458 -0
  187. package/dist/runtime/editor/features/analyze/types.d.ts +12 -0
  188. package/dist/runtime/editor/features/artboard/Overview/index.vue +37 -4
  189. package/dist/runtime/editor/features/artboard/Renderer.vue +79 -9
  190. package/dist/runtime/editor/features/artboard/Scrollbar/index.vue +84 -0
  191. package/dist/runtime/editor/features/block-scheduler/Dialog/index.vue +1 -1
  192. package/dist/runtime/editor/features/block-scheduler/index.vue +114 -0
  193. package/dist/runtime/editor/features/breadcrumbs/index.vue +150 -0
  194. package/dist/runtime/editor/features/changelog/Dialog/index.vue +62 -7
  195. package/dist/runtime/editor/features/changelog/changelog.json +9 -1
  196. package/dist/runtime/editor/features/clipboard/index.vue +153 -1
  197. package/dist/runtime/editor/features/command-palette/Palette/Item/index.vue +39 -16
  198. package/dist/runtime/editor/features/command-palette/Palette/index.vue +24 -130
  199. package/dist/runtime/editor/features/comments/index.vue +235 -0
  200. package/dist/runtime/editor/features/complex-options/index.vue +4 -1
  201. package/dist/runtime/editor/features/debug/Main.vue +1 -1
  202. package/dist/runtime/editor/features/debug/Section/Features.vue +2 -4
  203. package/dist/runtime/editor/features/debug/index.vue +168 -0
  204. package/dist/runtime/editor/features/dev-mode/index.vue +92 -27
  205. package/dist/runtime/editor/features/dragging-overlay/Renderer/index.vue +1 -1
  206. package/dist/runtime/editor/features/dragging-overlay/index.vue +330 -0
  207. package/dist/runtime/editor/features/edit/index.vue +15 -17
  208. package/dist/runtime/editor/features/edit-form/Frame/index.vue +21 -4
  209. package/dist/runtime/editor/features/editable-field/Overlay/Frame/index.d.vue.ts +9 -1
  210. package/dist/runtime/editor/features/editable-field/Overlay/Frame/index.vue +32 -3
  211. package/dist/runtime/editor/features/editable-field/Overlay/Frame/index.vue.d.ts +9 -1
  212. package/dist/runtime/editor/features/editable-field/Overlay/ReadabilityIndicator/ChunkOverlay.vue +77 -0
  213. package/dist/runtime/editor/features/editable-field/Overlay/ReadabilityIndicator/index.vue +55 -56
  214. package/dist/runtime/editor/features/editable-field/Overlay/index.vue +416 -8
  215. package/dist/runtime/editor/features/editable-mask/index.vue +9 -0
  216. package/dist/runtime/editor/features/entity-title/index.vue +40 -56
  217. package/dist/runtime/editor/features/fragments/Dialog/index.vue +90 -0
  218. package/dist/runtime/editor/features/help/Shortcuts/index.vue +71 -0
  219. package/dist/runtime/editor/features/help/index.vue +17 -0
  220. package/dist/runtime/editor/features/highlights/Renderer/fragment.glsl +89 -0
  221. package/dist/runtime/editor/features/highlights/Renderer/index.vue +408 -0
  222. package/dist/runtime/editor/features/highlights/Renderer/vertex.glsl +87 -0
  223. package/dist/runtime/editor/features/highlights/index.d.vue.ts +3 -0
  224. package/dist/runtime/editor/features/highlights/index.vue +20 -0
  225. package/dist/runtime/editor/features/highlights/index.vue.d.ts +3 -0
  226. package/dist/runtime/editor/features/history/List/index.vue +209 -0
  227. package/dist/runtime/editor/features/history/index.vue +0 -1
  228. package/dist/runtime/editor/features/hover/Renderer/index.vue +1 -1
  229. package/dist/runtime/editor/features/hover/Renderer/vertex.glsl +1 -1
  230. package/dist/runtime/editor/features/import-existing/Dialog/index.vue +18 -0
  231. package/dist/runtime/editor/features/media-library/Library/index.vue +10 -30
  232. package/dist/runtime/editor/features/media-library/index.vue +331 -0
  233. package/dist/runtime/editor/features/options/Form/Checkbox/index.vue +1 -1
  234. package/dist/runtime/editor/features/options/Form/Checkboxes/index.vue +1 -1
  235. package/dist/runtime/editor/features/options/Form/ComplexType/index.vue +6 -2
  236. package/dist/runtime/editor/features/options/Form/Item.vue +21 -18
  237. package/dist/runtime/editor/features/options/Form/Radios/index.d.vue.ts +6 -0
  238. package/dist/runtime/editor/features/options/Form/Radios/index.vue +25 -6
  239. package/dist/runtime/editor/features/options/Form/Radios/index.vue.d.ts +6 -0
  240. package/dist/runtime/editor/features/options/Form/index.vue +1 -4
  241. package/dist/runtime/editor/features/options/index.vue +729 -0
  242. package/dist/runtime/editor/features/ownership/Banner/index.vue +9 -8
  243. package/dist/runtime/editor/features/ownership/index.vue +1 -1
  244. package/dist/runtime/editor/features/preview-grant/QrCode/index.vue +8 -3
  245. package/dist/runtime/editor/features/publish/Dialog/Item.vue +18 -20
  246. package/dist/runtime/editor/features/publish/Dialog/index.vue +5 -1
  247. package/dist/runtime/editor/features/publish/index.vue +835 -0
  248. package/dist/runtime/editor/features/publish/types.d.ts +5 -1
  249. package/dist/runtime/editor/features/referenced-entities/List/Item/index.d.vue.ts +4 -0
  250. package/dist/runtime/editor/features/referenced-entities/List/Item/index.vue +81 -0
  251. package/dist/runtime/editor/features/referenced-entities/List/Item/index.vue.d.ts +4 -0
  252. package/dist/runtime/editor/features/referenced-entities/List/index.d.vue.ts +11 -0
  253. package/dist/runtime/editor/features/referenced-entities/List/index.vue +78 -0
  254. package/dist/runtime/editor/features/referenced-entities/List/index.vue.d.ts +11 -0
  255. package/dist/runtime/editor/features/referenced-entities/index.d.vue.ts +3 -0
  256. package/dist/runtime/editor/features/referenced-entities/index.vue +36 -0
  257. package/dist/runtime/editor/features/referenced-entities/index.vue.d.ts +3 -0
  258. package/dist/runtime/editor/features/referenced-entities/types.d.ts +13 -0
  259. package/dist/runtime/editor/features/responsive-preview/Frame/index.vue +188 -0
  260. package/dist/runtime/editor/features/search/Overlay/Results/Page/index.vue +1 -1
  261. package/dist/runtime/editor/features/search/index.vue +511 -0
  262. package/dist/runtime/editor/features/selection/AddButtons/Renderer/index.vue +58 -0
  263. package/dist/runtime/editor/features/selection/index.vue +47 -15
  264. package/dist/runtime/editor/features/settings/Dialog/FeatureSetting/index.vue +23 -0
  265. package/dist/runtime/editor/features/settings/Dialog/index.vue +5 -2
  266. package/dist/runtime/editor/features/settings/index.vue +152 -0
  267. package/dist/runtime/editor/features/structure/List/Item/index.vue +7 -0
  268. package/dist/runtime/editor/features/structure/index.vue +178 -0
  269. package/dist/runtime/editor/features/templates/ManageDialog/Item.vue +3 -3
  270. package/dist/runtime/editor/features/templates/ManageDialog/index.vue +24 -3
  271. package/dist/runtime/editor/features/theme/index.vue +94 -0
  272. package/dist/runtime/editor/features/touch-action-bar/Bar/index.vue +34 -0
  273. package/dist/runtime/editor/features/tour/Overlay/index.vue +243 -13
  274. package/dist/runtime/editor/features/transform/Dialog/index.vue +132 -1
  275. package/dist/runtime/editor/features/translations/Banner/index.d.vue.ts +14 -1
  276. package/dist/runtime/editor/features/translations/Banner/index.vue +139 -12
  277. package/dist/runtime/editor/features/translations/Banner/index.vue.d.ts +14 -1
  278. package/dist/runtime/editor/features/translations/CsvDialog/Export/index.d.vue.ts +3 -0
  279. package/dist/runtime/editor/features/translations/CsvDialog/Export/index.vue +272 -0
  280. package/dist/runtime/editor/features/translations/CsvDialog/Export/index.vue.d.ts +3 -0
  281. package/dist/runtime/editor/features/translations/CsvDialog/Import/index.d.vue.ts +10 -0
  282. package/dist/runtime/editor/features/translations/CsvDialog/Import/index.vue +382 -0
  283. package/dist/runtime/editor/features/translations/CsvDialog/Import/index.vue.d.ts +10 -0
  284. package/dist/runtime/editor/features/translations/CsvDialog/csv.d.ts +22 -0
  285. package/dist/runtime/editor/features/translations/CsvDialog/csv.js +50 -0
  286. package/dist/runtime/editor/features/translations/CsvDialog/index.d.vue.ts +10 -0
  287. package/dist/runtime/editor/features/translations/CsvDialog/index.vue +37 -0
  288. package/dist/runtime/editor/features/translations/CsvDialog/index.vue.d.ts +10 -0
  289. package/dist/runtime/editor/features/translations/CsvDialog/po.d.ts +7 -0
  290. package/dist/runtime/editor/features/translations/CsvDialog/po.js +36 -0
  291. package/dist/runtime/editor/features/translations/SelectionTable/index.d.vue.ts +37 -0
  292. package/dist/runtime/editor/features/translations/SelectionTable/index.vue +102 -0
  293. package/dist/runtime/editor/features/translations/SelectionTable/index.vue.d.ts +37 -0
  294. package/dist/runtime/editor/features/translations/TranslateDialog/index.d.vue.ts +7 -0
  295. package/dist/runtime/editor/features/translations/TranslateDialog/index.vue +294 -0
  296. package/dist/runtime/editor/features/translations/TranslateDialog/index.vue.d.ts +7 -0
  297. package/dist/runtime/editor/features/translations/index.vue +276 -6
  298. package/dist/runtime/editor/features/translations/types.d.ts +47 -0
  299. package/dist/runtime/editor/features/validations/Overlay/index.vue +130 -0
  300. package/dist/runtime/editor/features/validations/index.vue +41 -0
  301. package/dist/runtime/editor/features/{assistant → workspace}/Overlay/index.d.vue.ts +2 -4
  302. package/dist/runtime/editor/features/workspace/Overlay/index.vue +177 -0
  303. package/dist/runtime/editor/features/{assistant → workspace}/Overlay/index.vue.d.ts +2 -4
  304. package/dist/runtime/editor/features/workspace/index.d.vue.ts +3 -0
  305. package/dist/runtime/editor/features/workspace/index.vue +46 -0
  306. package/dist/runtime/editor/features/workspace/index.vue.d.ts +3 -0
  307. package/dist/runtime/editor/features/workspace/types.d.ts +59 -0
  308. package/dist/runtime/editor/features/workspace/types.js +0 -0
  309. package/dist/runtime/editor/icons/svg/spinner.svg +2 -2
  310. package/dist/runtime/editor/plugins/ContextMenu/Menu/index.vue +21 -7
  311. package/dist/runtime/editor/plugins/ContextMenu/index.vue +4 -0
  312. package/dist/runtime/editor/plugins/ItemAction/index.d.vue.ts +9 -2
  313. package/dist/runtime/editor/plugins/ItemAction/index.vue +26 -16
  314. package/dist/runtime/editor/plugins/ItemAction/index.vue.d.ts +9 -2
  315. package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue +24 -26
  316. package/dist/runtime/editor/plugins/Sidebar/index.vue +612 -27
  317. package/dist/runtime/editor/plugins/ToolbarButton/index.d.vue.ts +13 -84
  318. package/dist/runtime/editor/plugins/ToolbarButton/index.vue +36 -22
  319. package/dist/runtime/editor/plugins/ToolbarButton/index.vue.d.ts +13 -84
  320. package/dist/runtime/editor/plugins/ViewOption/index.vue +13 -14
  321. package/dist/runtime/editor/providers/blocks.js +1 -0
  322. package/dist/runtime/editor/providers/cache.d.ts +23 -0
  323. package/dist/runtime/editor/providers/cache.js +29 -0
  324. package/dist/runtime/editor/providers/directive.d.ts +25 -0
  325. package/dist/runtime/editor/providers/directive.js +20 -0
  326. package/dist/runtime/editor/providers/fieldValue.d.ts +5 -5
  327. package/dist/runtime/editor/providers/fieldValue.js +8 -7
  328. package/dist/runtime/editor/providers/plugin.d.ts +14 -0
  329. package/dist/runtime/editor/providers/plugin.js +9 -0
  330. package/dist/runtime/editor/providers/readability.js +1 -1
  331. package/dist/runtime/editor/providers/selection.js +1 -1
  332. package/dist/runtime/editor/providers/state.d.ts +1 -0
  333. package/dist/runtime/editor/providers/state.js +1 -0
  334. package/dist/runtime/editor/providers/texts.js +11 -1
  335. package/dist/runtime/editor/providers/ui.d.ts +11 -0
  336. package/dist/runtime/editor/providers/ui.js +5 -1
  337. package/dist/runtime/editor/translations/de.json +316 -56
  338. package/dist/runtime/editor/translations/fr.json +310 -50
  339. package/dist/runtime/editor/translations/gsw_CH.json +311 -51
  340. package/dist/runtime/editor/translations/it.json +310 -50
  341. package/dist/runtime/editor/types/app.d.ts +2 -0
  342. package/dist/runtime/editor/types/definitions.d.ts +8 -0
  343. package/dist/runtime/editor/types/field.d.ts +1 -0
  344. package/dist/runtime/editor/types/state.d.ts +10 -0
  345. package/dist/runtime/editor/types/ui.d.ts +3 -1
  346. package/dist/runtime/helpers/tw.d.ts +15 -0
  347. package/dist/runtime/helpers/tw.js +3 -0
  348. package/dist/runtime/types/field.d.ts +1 -0
  349. package/dist/shared/{editor.DsGJIlGn.d.mts → editor.BTOBvmaz.d.mts} +20 -3
  350. package/dist/types.d.mts +1 -1
  351. package/package.json +16 -3
  352. package/dist/runtime/editor/features/analyze/Renderer/fragment.glsl +0 -74
  353. package/dist/runtime/editor/features/analyze/Renderer/index.d.vue.ts +0 -24
  354. package/dist/runtime/editor/features/analyze/Renderer/index.vue +0 -330
  355. package/dist/runtime/editor/features/analyze/Renderer/index.vue.d.ts +0 -24
  356. package/dist/runtime/editor/features/analyze/Renderer/vertex.glsl +0 -94
  357. package/dist/runtime/editor/features/assistant/Overlay/ResultMarkup/index.d.vue.ts +0 -7
  358. package/dist/runtime/editor/features/assistant/Overlay/ResultMarkup/index.vue +0 -17
  359. package/dist/runtime/editor/features/assistant/Overlay/ResultMarkup/index.vue.d.ts +0 -7
  360. package/dist/runtime/editor/features/assistant/Overlay/index.vue +0 -108
  361. package/dist/runtime/editor/features/assistant/docs.md +0 -7
  362. package/dist/runtime/editor/features/assistant/index.vue +0 -66
  363. package/dist/runtime/editor/features/assistant/types.d.ts +0 -37
  364. package/dist/runtime/editor/features/media-library/Library/FilterSelect/index.vue +0 -168
  365. package/dist/runtime/editor/providers/fieldValueAdapterTypes.d.ts +0 -13
  366. /package/dist/{runtime/editor/features/assistant → modules/iframes/runtime}/types.js +0 -0
  367. /package/dist/runtime/editor/components/Actions/{ItemDropdown.d.vue.ts → ItemDropdown/index.d.vue.ts} +0 -0
  368. /package/dist/runtime/editor/components/Actions/{ItemDropdown.vue.d.ts → ItemDropdown/index.vue.d.ts} +0 -0
  369. /package/dist/runtime/editor/{features/media-library/Library → components/PluginConfigFormInline}/FilterSelect/index.d.vue.ts +0 -0
  370. /package/dist/runtime/editor/{features/media-library/Library → components/PluginConfigFormInline}/FilterSelect/index.vue.d.ts +0 -0
  371. /package/dist/runtime/editor/features/{assistant → highlights/Renderer}/index.d.vue.ts +0 -0
  372. /package/dist/runtime/editor/features/{assistant → highlights/Renderer}/index.vue.d.ts +0 -0
  373. /package/dist/runtime/editor/{providers/fieldValueAdapterTypes.js → features/referenced-entities/types.js} +0 -0
@@ -0,0 +1,272 @@
1
+ <template>
2
+ <div class="_bk_flex _bk_flex-col _bk_h-full">
3
+ <div v-if="isLoading" class="_bk_flex _bk_items-center _bk_gap-10 _bk_py-20">
4
+ <Loading />
5
+ </div>
6
+ <template v-else-if="exportRows.length">
7
+ <SelectionTable
8
+ v-model:only-outdated="onlyOutdated"
9
+ v-model:only-untranslated="onlyMissing"
10
+ show-filters
11
+ :total-count="filteredRows.length"
12
+ >
13
+ <template #toolbar>
14
+ <FormCheckboxes
15
+ id="export-languages"
16
+ v-model="selectedLanguages"
17
+ :label="$t('translationsCsvLanguages', 'Languages')"
18
+ :options="languageOptions"
19
+ inline
20
+ @update:model-value="loadExportData"
21
+ />
22
+ </template>
23
+ <template #header>
24
+ <th>Key</th>
25
+ <th>{{ sourceLangName }}</th>
26
+ <th v-for="lang in activeLanguages" :key="lang.id">
27
+ {{ lang.name }}
28
+ </th>
29
+ </template>
30
+ <template #body>
31
+ <tr v-for="row in filteredRows" :key="row.key">
32
+ <td class="_bk_text-mono-400" v-text="row.key" />
33
+ <td v-text="row.source" />
34
+ <td
35
+ v-for="lang in activeLanguages"
36
+ :key="lang.id"
37
+ :class="{
38
+ 'bk-is-empty': !row.translations[lang.id]
39
+ }"
40
+ v-text="row.translations[lang.id] || '\u2014'"
41
+ />
42
+ </tr>
43
+ </template>
44
+ </SelectionTable>
45
+ <div class="_bk_flex _bk_gap-10 _bk_flex-wrap _bk_pt-20">
46
+ <button class="bk-button" @click="downloadCsv">
47
+ <div
48
+ class="_bk_uppercase _bk_font-bold _bk_border-2 _bk_leading-none _bk_rounded-md _bk_px-3 _bk_py-2 _bk_-ml-5"
49
+ >
50
+ csv
51
+ </div>
52
+ <span>{{ $t("download", "Download") }}</span>
53
+ </button>
54
+ <button
55
+ v-for="lang in activeLanguages"
56
+ :key="lang.id"
57
+ class="bk-button"
58
+ @click="downloadPo(lang.id)"
59
+ >
60
+ <div
61
+ class="_bk_uppercase _bk_font-bold _bk_border-2 _bk_leading-none _bk_rounded-md _bk_px-3 _bk_py-2 _bk_-ml-5"
62
+ >
63
+ po
64
+ </div>
65
+ <span>{{
66
+ $t("downloadWithLabel", "Download @label").replace(
67
+ "@label",
68
+ lang.name
69
+ )
70
+ }}</span>
71
+ </button>
72
+ </div>
73
+ </template>
74
+ </div>
75
+ </template>
76
+
77
+ <script setup>
78
+ import { ref, computed, useBlokkli, onMounted } from "#imports";
79
+ import { itemEntityType } from "#blokkli-build/config";
80
+ import { Loading, FormCheckboxes } from "#blokkli/editor/components";
81
+ import { buildMultiLangCsv } from "../csv";
82
+ import { buildPo } from "../po";
83
+ import SelectionTable from "../../SelectionTable/index.vue";
84
+ const { adapter, $t, state, blocks, context, element, ui, directive } = useBlokkli();
85
+ const isLoading = ref(false);
86
+ const onlyOutdated = ref(false);
87
+ const onlyMissing = ref(false);
88
+ const exportRows = ref([]);
89
+ const selectedLanguages = ref([]);
90
+ const availableLanguages = computed(() => {
91
+ const source = state.translation.value.sourceLanguage;
92
+ return state.translation.value.availableLanguages?.filter(
93
+ (l) => l.id !== source
94
+ ) ?? [];
95
+ });
96
+ const languageOptions = computed(
97
+ () => availableLanguages.value.map((l) => ({ value: l.id, label: l.name }))
98
+ );
99
+ const activeLanguages = computed(
100
+ () => availableLanguages.value.filter(
101
+ (l) => selectedLanguages.value.includes(l.id)
102
+ )
103
+ );
104
+ const filteredRows = computed(() => {
105
+ let rows = exportRows.value;
106
+ if (onlyOutdated.value) {
107
+ const activeLangIds = activeLanguages.value.map((l) => l.id);
108
+ const outdatedUuids = new Set(
109
+ blocks.getAllBlocks().filter(
110
+ (b) => b.outdatedTranslations.some((lang) => activeLangIds.includes(lang))
111
+ ).map((b) => b.uuid)
112
+ );
113
+ rows = rows.filter((row) => {
114
+ if (row.entityType !== itemEntityType) return true;
115
+ const uuid = row.key.substring(0, row.key.indexOf(":"));
116
+ return outdatedUuids.has(uuid);
117
+ });
118
+ }
119
+ if (onlyMissing.value) {
120
+ const activeLangIds = activeLanguages.value.map((l) => l.id);
121
+ rows = rows.filter(
122
+ (row) => activeLangIds.some((lang) => {
123
+ const val = row.translations[lang];
124
+ return !val || val === row.source;
125
+ })
126
+ );
127
+ }
128
+ return rows;
129
+ });
130
+ const sourceLangName = computed(() => {
131
+ const id = state.translation.value.sourceLanguage;
132
+ return state.translation.value.availableLanguages?.find((l) => l.id === id)?.name ?? id;
133
+ });
134
+ function slugify(text) {
135
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
136
+ }
137
+ function buildTimestamp() {
138
+ const now = /* @__PURE__ */ new Date();
139
+ return [
140
+ now.getFullYear(),
141
+ String(now.getMonth() + 1).padStart(2, "0"),
142
+ String(now.getDate()).padStart(2, "0")
143
+ ].join("-") + "--" + [
144
+ String(now.getHours()).padStart(2, "0"),
145
+ String(now.getMinutes()).padStart(2, "0")
146
+ ].join("-");
147
+ }
148
+ function buildFilename(ext, langcode) {
149
+ const langPart = langcode ?? activeLanguages.value.map((l) => l.id).join("-");
150
+ const pageSlug = slugify(state.entity.value.label || "page");
151
+ return `${pageSlug}--${langPart}-${buildTimestamp()}.${ext}`;
152
+ }
153
+ function triggerDownload(content, filename, mimeType) {
154
+ const blob = new Blob([content], { type: mimeType });
155
+ const url = URL.createObjectURL(blob);
156
+ const a = document.createElement("a");
157
+ a.href = url;
158
+ a.download = filename;
159
+ a.click();
160
+ URL.revokeObjectURL(url);
161
+ }
162
+ function downloadCsv() {
163
+ const langIds = activeLanguages.value.map((l) => l.id);
164
+ const content = buildMultiLangCsv(filteredRows.value, langIds);
165
+ triggerDownload(content, buildFilename("csv"), "text/csv;charset=utf-8");
166
+ }
167
+ function downloadPo(langcode) {
168
+ const rows = filteredRows.value.map((row) => ({
169
+ key: row.key,
170
+ source: row.source,
171
+ translation: row.translations[langcode] ?? ""
172
+ }));
173
+ const content = buildPo(rows, langcode);
174
+ triggerDownload(
175
+ content,
176
+ buildFilename("po", langcode),
177
+ "text/x-gettext;charset=utf-8"
178
+ );
179
+ }
180
+ async function loadExportData() {
181
+ const sourceLanguage = state.translation.value.sourceLanguage;
182
+ if (!sourceLanguage) {
183
+ return;
184
+ }
185
+ const langIds = selectedLanguages.value.filter(
186
+ (id) => availableLanguages.value.some((l) => l.id === id)
187
+ );
188
+ if (!langIds.length) {
189
+ exportRows.value = [];
190
+ return;
191
+ }
192
+ isLoading.value = true;
193
+ try {
194
+ const sourceValues = await adapter.loadTextFieldValuesForLanguage(sourceLanguage);
195
+ const translationMaps = /* @__PURE__ */ new Map();
196
+ for (const langId of langIds) {
197
+ const values = await adapter.loadTextFieldValuesForLanguage(langId);
198
+ const map = /* @__PURE__ */ new Map();
199
+ for (const v of values) {
200
+ map.set(`${v.uuid}:${v.fieldName}`, v.value);
201
+ }
202
+ translationMaps.set(langId, map);
203
+ }
204
+ const hostFields = sourceValues.filter(
205
+ (sv) => sv.entityType !== itemEntityType
206
+ );
207
+ const blockFields = sourceValues.filter(
208
+ (sv) => sv.entityType === itemEntityType
209
+ );
210
+ const uuidOrder = element.queryAll(
211
+ ui.providerElement,
212
+ ".bk-field-list-item",
213
+ "getExportOrder",
214
+ (el) => el.dataset.bkUuid
215
+ );
216
+ const uuidIndexMap = /* @__PURE__ */ new Map();
217
+ for (let i = 0; i < uuidOrder.length; i++) {
218
+ const uuid = uuidOrder[i];
219
+ if (uuid && !uuidIndexMap.has(uuid)) {
220
+ uuidIndexMap.set(uuid, i);
221
+ }
222
+ }
223
+ const grouped = /* @__PURE__ */ new Map();
224
+ for (const sv of blockFields) {
225
+ let group = grouped.get(sv.uuid);
226
+ if (!group) {
227
+ group = [];
228
+ grouped.set(sv.uuid, group);
229
+ }
230
+ group.push(sv);
231
+ }
232
+ for (const [uuid, fields] of grouped) {
233
+ if (fields.length <= 1) continue;
234
+ const block = blocks.getBlock(uuid);
235
+ if (!block) continue;
236
+ const host = { uuid, type: itemEntityType, bundle: block.bundle };
237
+ fields.sort((a, b) => {
238
+ const elA = directive.findEditableElement(a.fieldName, host);
239
+ const elB = directive.findEditableElement(b.fieldName, host);
240
+ if (!elA || !elB) return 0;
241
+ const pos = elA.compareDocumentPosition(elB);
242
+ if (pos & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
243
+ if (pos & Node.DOCUMENT_POSITION_PRECEDING) return 1;
244
+ return 0;
245
+ });
246
+ }
247
+ const sortedBlockFields = [...grouped.entries()].sort((a, b) => {
248
+ const idxA = uuidIndexMap.get(a[0]) ?? Infinity;
249
+ const idxB = uuidIndexMap.get(b[0]) ?? Infinity;
250
+ return idxA - idxB;
251
+ }).flatMap(([, fields]) => fields);
252
+ const sortedValues = [...hostFields, ...sortedBlockFields];
253
+ exportRows.value = sortedValues.map((sv) => {
254
+ const key = `${sv.uuid}:${sv.fieldName}`;
255
+ const translations = {};
256
+ for (const langId of langIds) {
257
+ translations[langId] = translationMaps.get(langId)?.get(key) ?? "";
258
+ }
259
+ return { key, source: sv.value, entityType: sv.entityType, translations };
260
+ });
261
+ } finally {
262
+ isLoading.value = false;
263
+ }
264
+ }
265
+ onMounted(() => {
266
+ const currentLang = context.value.language;
267
+ if (availableLanguages.value.some((l) => l.id === currentLang)) {
268
+ selectedLanguages.value = [currentLang];
269
+ }
270
+ loadExportData();
271
+ });
272
+ </script>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,10 @@
1
+ type __VLS_Props = {
2
+ initialFiles?: File[] | null;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
5
+ close: () => any;
6
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
7
+ onClose?: (() => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,382 @@
1
+ <template>
2
+ <FileDropHandler
3
+ icon="bk_mdi_translate"
4
+ :label="$t('translationsDropToImport', 'Drop CSV or PO file to import')"
5
+ :accept="acceptTranslationFile"
6
+ class="_bk_flex _bk_flex-col _bk_h-full"
7
+ @drop="addFiles"
8
+ >
9
+ <div v-if="files.length" class="_bk_flex _bk_flex-wrap _bk_items-center _bk_gap-8 _bk_pb-20">
10
+ <div
11
+ v-for="(file, index) in files"
12
+ :key="index"
13
+ class="_bk_flex _bk_items-center _bk_gap-5 _bk_bg-mono-100 _bk_rounded-full _bk_pl-10 _bk_pr-5 _bk_py-3 _bk_text-sm _bk_text-mono-800"
14
+ >
15
+ <span>{{ file.name }}</span>
16
+ <button
17
+ class="_bk_rounded-full _bk_p-2 _bk_text-mono-400 _bk_hover:text-mono-900 _bk_hover:bg-mono-200"
18
+ @click="removeFile(file)"
19
+ >
20
+ <Icon name="bk_mdi_close" class="_bk_size-15" />
21
+ </button>
22
+ </div>
23
+ <button class="bk-button bk-is-small" @click.prevent="triggerFileDialog">
24
+ {{ $t("translationsAddFiles", "Add files...") }}
25
+ </button>
26
+ </div>
27
+ <div v-else class="_bk_mx-auto _bk_py-20">
28
+ <button
29
+ type="button"
30
+ class="bk-button"
31
+ @click.prevent="triggerFileDialog"
32
+ >
33
+ {{ $t("translationsSelectImportFile", "Select CSV or PO file") }}
34
+ </button>
35
+ </div>
36
+ <template v-if="files.length">
37
+ <div
38
+ v-if="changes && !changes.length"
39
+ class="_bk_py-20 _bk_text-center _bk_text-mono-500"
40
+ >
41
+ {{ $t("translationsCsvNoChanges", "No changes found") }}
42
+ </div>
43
+ <template v-else-if="changes && changes.length">
44
+ <SelectionTable
45
+ show-selection
46
+ :selected-count="selectedCount"
47
+ :total-count="changes.length"
48
+ :label="$t('translationsCsvChangesLabel', 'fields will be updated')"
49
+ @toggle-all="toggleAll"
50
+ >
51
+ <template #header>
52
+ <th>{{ sourceLangName }}</th>
53
+ <th v-if="!isMultiLang">
54
+ {{ $t("translationsCsvDiff", "Changes") }}
55
+ </th>
56
+ <th v-for="lang in languages" v-else :key="lang">
57
+ {{ langName(lang) }}
58
+ </th>
59
+ </template>
60
+ <template #body>
61
+ <tr v-for="row in rows" :key="row.key">
62
+ <td>
63
+ <div class="bk-checkbox">
64
+ <input
65
+ type="checkbox"
66
+ :checked="isRowSelected(row)"
67
+ @change="toggleRow(row)"
68
+ />
69
+ <span class="_bk_!mt-0 _bk_before:!mt-0" />
70
+ </div>
71
+ </td>
72
+ <td v-text="row.source" />
73
+ <template v-if="!isMultiLang">
74
+ <td>
75
+ <DiffValue
76
+ :before="singleLangChange(row).current"
77
+ :after="singleLangChange(row).imported"
78
+ :after-only="
79
+ !singleLangChange(row).current || singleLangChange(row).current === row.source
80
+ "
81
+ />
82
+ </td>
83
+ </template>
84
+ <template v-else>
85
+ <td v-for="lang in languages" :key="lang">
86
+ <div v-if="row.changes[lang]" class="_bk_flex _bk_items-start _bk_gap-8">
87
+ <div class="bk-checkbox _bk_shrink-0">
88
+ <input
89
+ v-model="selected[row.changes[lang].id]"
90
+ type="checkbox"
91
+ />
92
+ <span class="_bk_!mt-0 _bk_before:!mt-0" />
93
+ </div>
94
+ <DiffValue
95
+ :before="row.changes[lang].current"
96
+ :after="row.changes[lang].imported"
97
+ :after-only="
98
+ !row.changes[lang].current || row.changes[lang].current === row.source
99
+ "
100
+ />
101
+ </div>
102
+ <span v-else class="bk-is-empty">&mdash;</span>
103
+ </td>
104
+ </template>
105
+ </tr>
106
+ </template>
107
+ </SelectionTable>
108
+ <div class="_bk_flex _bk_items-center _bk_gap-10 _bk_mt-auto _bk_pt-20">
109
+ <button
110
+ class="bk-button bk-is-primary"
111
+ :disabled="!selectedCount"
112
+ @click="applyImport"
113
+ >
114
+ {{
115
+ $t("translationsCsvApply", "Import @count translations").replace(
116
+ "@count",
117
+ selectedCount.toString()
118
+ )
119
+ }}
120
+ </button>
121
+ <FormToggle
122
+ v-model="markUpToDate"
123
+ class="_bk_!h-auto"
124
+ :label="
125
+ $t('translationsMarkUpToDate', 'Mark translations as up to date')
126
+ "
127
+ />
128
+ </div>
129
+ </template>
130
+ </template>
131
+ <input
132
+ ref="fileInputEl"
133
+ type="file"
134
+ accept=".csv,.po,text/csv"
135
+ multiple
136
+ class="_bk_hidden"
137
+ @change="onFileSelected"
138
+ />
139
+ </FileDropHandler>
140
+ </template>
141
+
142
+ <script setup>
143
+ import { ref, computed, useBlokkli, useTemplateRef, onMounted } from "#imports";
144
+ import {
145
+ DiffValue,
146
+ FileDropHandler,
147
+ FormToggle,
148
+ Icon
149
+ } from "#blokkli/editor/components";
150
+ import { parseCsv } from "../csv";
151
+ import { parsePo } from "../po";
152
+ import SelectionTable from "../../SelectionTable/index.vue";
153
+ const props = defineProps({
154
+ initialFiles: { type: [Array, null], required: false }
155
+ });
156
+ const emit = defineEmits(["close"]);
157
+ const { adapter, $t, state, context } = useBlokkli();
158
+ const files = ref([]);
159
+ const changes = ref(null);
160
+ const languages = ref([]);
161
+ const isMultiLang = computed(() => languages.value.length > 1);
162
+ const selected = ref({});
163
+ const fileInputEl = useTemplateRef("fileInputEl");
164
+ const markUpToDate = ref(false);
165
+ const rows = computed(() => {
166
+ if (!changes.value) return [];
167
+ const map = /* @__PURE__ */ new Map();
168
+ for (const change of changes.value) {
169
+ let row = map.get(change.key);
170
+ if (!row) {
171
+ row = { key: change.key, source: change.source, changes: {} };
172
+ map.set(change.key, row);
173
+ }
174
+ row.changes[change.langcode] = change;
175
+ }
176
+ return [...map.values()];
177
+ });
178
+ const sourceLangName = computed(() => {
179
+ const id = state.translation.value.sourceLanguage;
180
+ return state.translation.value.availableLanguages?.find((l) => l.id === id)?.name ?? id;
181
+ });
182
+ function langName(langcode) {
183
+ return state.translation.value.availableLanguages?.find((l) => l.id === langcode)?.name ?? langcode;
184
+ }
185
+ const selectedCount = computed(
186
+ () => changes.value?.filter((c) => selected.value[c.id]).length ?? 0
187
+ );
188
+ function isRowSelected(row) {
189
+ const rowChanges = Object.values(row.changes);
190
+ return rowChanges.length > 0 && rowChanges.every((c) => selected.value[c.id]);
191
+ }
192
+ function toggleRow(row) {
193
+ const newValue = !isRowSelected(row);
194
+ for (const change of Object.values(row.changes)) {
195
+ selected.value[change.id] = newValue;
196
+ }
197
+ }
198
+ function singleLangChange(row) {
199
+ return Object.values(row.changes)[0];
200
+ }
201
+ function toggleAll() {
202
+ if (!changes.value) return;
203
+ const allSelected = changes.value.length > 0 && selectedCount.value === changes.value.length;
204
+ const newValue = !allSelected;
205
+ for (const change of changes.value) {
206
+ selected.value[change.id] = newValue;
207
+ }
208
+ }
209
+ async function loadCurrentValues(langcode) {
210
+ const map = /* @__PURE__ */ new Map();
211
+ const values = await adapter.loadTextFieldValuesForLanguage(langcode);
212
+ for (const v of values) {
213
+ map.set(`${v.uuid}:${v.fieldName}`, v.value);
214
+ }
215
+ return map;
216
+ }
217
+ async function addFiles(newFiles) {
218
+ const filtered = newFiles.filter(
219
+ (f) => f.name.endsWith(".csv") || f.name.endsWith(".po")
220
+ );
221
+ if (!filtered.length) return;
222
+ files.value = [...files.value, ...filtered];
223
+ await reprocess();
224
+ }
225
+ async function removeFile(file) {
226
+ files.value = files.value.filter((f) => f !== file);
227
+ selected.value = {};
228
+ if (!files.value.length) {
229
+ changes.value = null;
230
+ languages.value = [];
231
+ return;
232
+ }
233
+ await reprocess();
234
+ }
235
+ async function reprocess() {
236
+ selected.value = {};
237
+ await processFiles(files.value);
238
+ }
239
+ async function processFiles(allFiles) {
240
+ const poFiles = allFiles.filter((f) => f.name.endsWith(".po"));
241
+ const csvFiles = allFiles.filter((f) => f.name.endsWith(".csv"));
242
+ if (csvFiles.length) {
243
+ await processCsvFile(csvFiles[0]);
244
+ } else if (poFiles.length) {
245
+ await processPoFiles(poFiles);
246
+ }
247
+ }
248
+ async function processPoFiles(files2) {
249
+ const rowsByLang = /* @__PURE__ */ new Map();
250
+ const langs = [];
251
+ for (const file of files2) {
252
+ const text = await file.text();
253
+ const parsed = parsePo(text);
254
+ const lang = parsed.language || context.value.language;
255
+ if (!rowsByLang.has(lang)) {
256
+ langs.push(lang);
257
+ rowsByLang.set(lang, /* @__PURE__ */ new Map());
258
+ }
259
+ const langRows = rowsByLang.get(lang);
260
+ for (const row of parsed.rows) {
261
+ langRows.set(row.key, row);
262
+ }
263
+ }
264
+ const newChanges = [];
265
+ for (const lang of langs) {
266
+ const currentMap = await loadCurrentValues(lang);
267
+ for (const row of rowsByLang.get(lang).values()) {
268
+ const current = currentMap.get(row.key) ?? "";
269
+ if (row.translation !== current && row.translation !== "") {
270
+ const change = {
271
+ id: `${lang}:${row.key}`,
272
+ key: row.key,
273
+ langcode: lang,
274
+ source: row.source,
275
+ current,
276
+ imported: row.translation
277
+ };
278
+ newChanges.push(change);
279
+ selected.value[change.id] = true;
280
+ }
281
+ }
282
+ }
283
+ languages.value = langs;
284
+ changes.value = newChanges;
285
+ }
286
+ async function processCsvFile(file) {
287
+ const text = await file.text();
288
+ const parsed = parseCsv(text);
289
+ if (parsed.type === "single") {
290
+ const lang = context.value.language;
291
+ const currentMap = await loadCurrentValues(lang);
292
+ const newChanges = [];
293
+ for (const row of parsed.rows) {
294
+ const current = currentMap.get(row.key) ?? "";
295
+ if (row.translation !== current && row.translation !== "") {
296
+ const change = {
297
+ id: `${lang}:${row.key}`,
298
+ key: row.key,
299
+ langcode: lang,
300
+ source: row.source,
301
+ current,
302
+ imported: row.translation
303
+ };
304
+ newChanges.push(change);
305
+ selected.value[change.id] = true;
306
+ }
307
+ }
308
+ languages.value = [lang];
309
+ changes.value = newChanges;
310
+ } else {
311
+ const currentMaps = /* @__PURE__ */ new Map();
312
+ for (const lang of parsed.languages) {
313
+ currentMaps.set(lang, await loadCurrentValues(lang));
314
+ }
315
+ const newChanges = [];
316
+ for (const row of parsed.rows) {
317
+ for (const lang of parsed.languages) {
318
+ const translation = row.translations[lang] ?? "";
319
+ const current = currentMaps.get(lang)?.get(row.key) ?? "";
320
+ if (translation !== current && translation !== "") {
321
+ const change = {
322
+ id: `${lang}:${row.key}`,
323
+ key: row.key,
324
+ langcode: lang,
325
+ source: row.source,
326
+ current,
327
+ imported: translation
328
+ };
329
+ newChanges.push(change);
330
+ selected.value[change.id] = true;
331
+ }
332
+ }
333
+ }
334
+ languages.value = parsed.languages;
335
+ changes.value = newChanges;
336
+ }
337
+ }
338
+ async function onFileSelected(e) {
339
+ const fileList = e.target.files;
340
+ if (!fileList?.length) return;
341
+ await addFiles([...fileList]);
342
+ if (fileInputEl.value) {
343
+ fileInputEl.value.value = "";
344
+ }
345
+ }
346
+ async function applyImport() {
347
+ if (!changes.value) return;
348
+ const selectedChanges = changes.value.filter((c) => selected.value[c.id]);
349
+ if (!selectedChanges.length) return;
350
+ const items = selectedChanges.map((change) => {
351
+ const separatorIndex = change.key.indexOf(":");
352
+ return {
353
+ langcode: change.langcode,
354
+ uuid: change.key.substring(0, separatorIndex),
355
+ fieldName: change.key.substring(separatorIndex + 1),
356
+ fieldValue: change.imported
357
+ };
358
+ });
359
+ await state.mutateWithLoadingState(
360
+ () => adapter.importTranslationsBatched({
361
+ items,
362
+ markUpToDate: markUpToDate.value
363
+ })
364
+ );
365
+ emit("close");
366
+ }
367
+ function acceptTranslationFile(item) {
368
+ if (item.kind !== "file") return false;
369
+ if (item.type.startsWith("text/") || !item.type) return true;
370
+ return false;
371
+ }
372
+ function triggerFileDialog() {
373
+ fileInputEl.value?.click();
374
+ }
375
+ onMounted(() => {
376
+ if (props.initialFiles?.length) {
377
+ addFiles(props.initialFiles);
378
+ } else {
379
+ triggerFileDialog();
380
+ }
381
+ });
382
+ </script>
@@ -0,0 +1,10 @@
1
+ type __VLS_Props = {
2
+ initialFiles?: File[] | null;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
5
+ close: () => any;
6
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
7
+ onClose?: (() => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;