typo3-typescript-sources 13.4.20

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 (415) hide show
  1. package/.github/workflows/sync-and-publish.yml +265 -0
  2. package/.last-synced-tag +1 -0
  3. package/LICENSE.txt +339 -0
  4. package/README-TYPO3.md +166 -0
  5. package/README.md +28 -0
  6. package/adminpanel/admin-panel.ts +375 -0
  7. package/adminpanel/modules/cache.ts +27 -0
  8. package/adminpanel/modules/preview.ts +75 -0
  9. package/backend/action-button/abstract-action.ts +22 -0
  10. package/backend/action-button/deferred-action.ts +41 -0
  11. package/backend/action-button/immediate-action.ts +31 -0
  12. package/backend/action-dispatcher.ts +104 -0
  13. package/backend/ajax-data-handler/message-interface.ts +18 -0
  14. package/backend/ajax-data-handler/response-interface.ts +20 -0
  15. package/backend/ajax-data-handler.ts +214 -0
  16. package/backend/backend-exception.ts +22 -0
  17. package/backend/broadcast-message.ts +50 -0
  18. package/backend/broadcast-service.ts +52 -0
  19. package/backend/browse-database.ts +38 -0
  20. package/backend/clear-cache.ts +88 -0
  21. package/backend/clipboard-panel.ts +240 -0
  22. package/backend/close-current-window.ts +2 -0
  23. package/backend/code-editor/autocomplete/completion-result.ts +105 -0
  24. package/backend/code-editor/autocomplete/ts-code-completion.ts +142 -0
  25. package/backend/code-editor/autocomplete/ts-parser.ts +485 -0
  26. package/backend/code-editor/autocomplete/ts-ref.ts +164 -0
  27. package/backend/code-editor/element/code-mirror-element.ts +282 -0
  28. package/backend/code-editor/language/typoscript.ts +181 -0
  29. package/backend/code-editor/stream-parser/typoscript.ts +1600 -0
  30. package/backend/color-picker.ts +158 -0
  31. package/backend/color-scheme-switch.ts +179 -0
  32. package/backend/column-selector-button.ts +302 -0
  33. package/backend/context-help.ts +68 -0
  34. package/backend/context-menu-actions.ts +322 -0
  35. package/backend/context-menu.ts +751 -0
  36. package/backend/copy-to-clipboard.ts +79 -0
  37. package/backend/date-time-picker.ts +270 -0
  38. package/backend/document-save-actions.ts +159 -0
  39. package/backend/drag-tooltip.ts +285 -0
  40. package/backend/drag-uploader.ts +914 -0
  41. package/backend/element/alert-element.ts +116 -0
  42. package/backend/element/dispatch-modal-button.ts +50 -0
  43. package/backend/element/draggable-resizable-element.ts +249 -0
  44. package/backend/element/editable-page-title.ts +306 -0
  45. package/backend/element/icon-element.ts +84 -0
  46. package/backend/element/immediate-action-element.ts +89 -0
  47. package/backend/element/pagination.ts +59 -0
  48. package/backend/element/progress-bar-element.ts +172 -0
  49. package/backend/element/progress-tracker-element.ts +119 -0
  50. package/backend/element/pseudo-button.ts +58 -0
  51. package/backend/element/spinner-element.ts +51 -0
  52. package/backend/element/thumbnail-element.ts +80 -0
  53. package/backend/element-browser.ts +182 -0
  54. package/backend/enum/data-transfer-types.ts +21 -0
  55. package/backend/enum/icon-types.ts +31 -0
  56. package/backend/enum/key-types.ts +27 -0
  57. package/backend/enum/severity.ts +20 -0
  58. package/backend/enum/viewport/scaffold-identifier.ts +24 -0
  59. package/backend/event/client-request.ts +25 -0
  60. package/backend/event/consumable.ts +18 -0
  61. package/backend/event/consumer-scope.ts +54 -0
  62. package/backend/event/event-dispatcher.ts +26 -0
  63. package/backend/event/interaction-request-assignment.ts +24 -0
  64. package/backend/event/interaction-request-map.ts +75 -0
  65. package/backend/event/interaction-request.ts +48 -0
  66. package/backend/event/trigger-request.ts +56 -0
  67. package/backend/form/submit-interceptor.ts +66 -0
  68. package/backend/form-engine/container/files-control-container.ts +716 -0
  69. package/backend/form-engine/container/flex-form-container-container.ts +166 -0
  70. package/backend/form-engine/container/flex-form-section-container.ts +210 -0
  71. package/backend/form-engine/container/inline-control-container.ts +1230 -0
  72. package/backend/form-engine/container/site-language-container.ts +616 -0
  73. package/backend/form-engine/element/abstract-sortable-select-items.ts +186 -0
  74. package/backend/form-engine/element/category-element.ts +160 -0
  75. package/backend/form-engine/element/color-element.ts +81 -0
  76. package/backend/form-engine/element/datetime-element.ts +66 -0
  77. package/backend/form-engine/element/extra/char-counter.ts +112 -0
  78. package/backend/form-engine/element/extra/select-box-filter.ts +85 -0
  79. package/backend/form-engine/element/folder-element.ts +66 -0
  80. package/backend/form-engine/element/group-element.ts +47 -0
  81. package/backend/form-engine/element/json-element.ts +52 -0
  82. package/backend/form-engine/element/link-element.ts +121 -0
  83. package/backend/form-engine/element/mfa-info-element.ts +169 -0
  84. package/backend/form-engine/element/modifier/resizable.ts +27 -0
  85. package/backend/form-engine/element/modifier/tabbable.ts +29 -0
  86. package/backend/form-engine/element/online-media-form-element.ts +65 -0
  87. package/backend/form-engine/element/password-element.ts +71 -0
  88. package/backend/form-engine/element/select-multiple-side-by-side-element.ts +83 -0
  89. package/backend/form-engine/element/select-single-element.ts +82 -0
  90. package/backend/form-engine/element/select-tree-element.ts +148 -0
  91. package/backend/form-engine/element/select-tree-toolbar.ts +118 -0
  92. package/backend/form-engine/element/select-tree.ts +210 -0
  93. package/backend/form-engine/element/slug-element.ts +243 -0
  94. package/backend/form-engine/element/suggest/result-container.ts +118 -0
  95. package/backend/form-engine/element/suggest/result-item.ts +90 -0
  96. package/backend/form-engine/element/table-permission-element.ts +101 -0
  97. package/backend/form-engine/element/table-wizard-element.ts +427 -0
  98. package/backend/form-engine/element/text-element.ts +52 -0
  99. package/backend/form-engine/element/text-table-element.ts +31 -0
  100. package/backend/form-engine/field-control/add-record.ts +40 -0
  101. package/backend/form-engine/field-control/edit-popup.ts +64 -0
  102. package/backend/form-engine/field-control/insert-clipboard.ts +50 -0
  103. package/backend/form-engine/field-control/link-popup.ts +53 -0
  104. package/backend/form-engine/field-control/list-module.ts +40 -0
  105. package/backend/form-engine/field-control/password-generator.ts +102 -0
  106. package/backend/form-engine/field-control/reset-selection.ts +48 -0
  107. package/backend/form-engine/field-wizard/localization-state-selector.ts +67 -0
  108. package/backend/form-engine/field-wizard/value-picker.ts +123 -0
  109. package/backend/form-engine/field-wizard/value-slider.ts +86 -0
  110. package/backend/form-engine/inline-relation/ajax-dispatcher.ts +124 -0
  111. package/backend/form-engine/inline-relation/inline-response-interface.ts +41 -0
  112. package/backend/form-engine-link-browser-adapter.ts +129 -0
  113. package/backend/form-engine-review.ts +155 -0
  114. package/backend/form-engine-suggest.ts +133 -0
  115. package/backend/form-engine-validation.ts +686 -0
  116. package/backend/form-engine.ts +1391 -0
  117. package/backend/global-event-handler.ts +252 -0
  118. package/backend/grid-editor.ts +1077 -0
  119. package/backend/hashing/md5.ts +252 -0
  120. package/backend/helper.ts +24 -0
  121. package/backend/hotkeys/hotkey-storage.ts +63 -0
  122. package/backend/hotkeys.ts +216 -0
  123. package/backend/icons.ts +236 -0
  124. package/backend/image-manipulation.ts +885 -0
  125. package/backend/info-window.ts +46 -0
  126. package/backend/input/clearable.ts +128 -0
  127. package/backend/input/index.d.ts +8 -0
  128. package/backend/java-script-module-import-event-handler.ts +19 -0
  129. package/backend/key-bindings.ts +42 -0
  130. package/backend/layout-module/drag-drop.ts +359 -0
  131. package/backend/layout-module/paste.ts +165 -0
  132. package/backend/link-browser.ts +89 -0
  133. package/backend/live-search/element/backend-search.ts +34 -0
  134. package/backend/live-search/element/hint.ts +33 -0
  135. package/backend/live-search/element/provider/default-result-item.ts +52 -0
  136. package/backend/live-search/element/provider/page-provider-result-item.ts +52 -0
  137. package/backend/live-search/element/result/item/action/action-container.ts +135 -0
  138. package/backend/live-search/element/result/item/action/action.ts +56 -0
  139. package/backend/live-search/element/result/item/item-container.ts +224 -0
  140. package/backend/live-search/element/result/item/item.ts +74 -0
  141. package/backend/live-search/element/result/result-container.ts +110 -0
  142. package/backend/live-search/element/result/result-detail-container.ts +50 -0
  143. package/backend/live-search/element/result/result-pagination.ts +122 -0
  144. package/backend/live-search/element/search-option-item.ts +70 -0
  145. package/backend/live-search/live-search-configurator.ts +54 -0
  146. package/backend/live-search/live-search-shortcut.ts +29 -0
  147. package/backend/live-search/result-types/backend-module-result-type.ts +8 -0
  148. package/backend/live-search/result-types/default-result-type.ts +21 -0
  149. package/backend/live-search/result-types/page-result-type.ts +23 -0
  150. package/backend/localization.ts +390 -0
  151. package/backend/login-refresh.ts +525 -0
  152. package/backend/login.ts +179 -0
  153. package/backend/mail-link-handler.ts +45 -0
  154. package/backend/modal-interface.ts +19 -0
  155. package/backend/modal.ts +685 -0
  156. package/backend/module/iframe.ts +125 -0
  157. package/backend/module/router.ts +275 -0
  158. package/backend/module-menu.ts +550 -0
  159. package/backend/module.ts +133 -0
  160. package/backend/multi-record-selection-action.ts +44 -0
  161. package/backend/multi-record-selection-delete-action.ts +108 -0
  162. package/backend/multi-record-selection-edit-action.ts +56 -0
  163. package/backend/multi-record-selection.ts +468 -0
  164. package/backend/multi-step-wizard.ts +568 -0
  165. package/backend/new-content-element-wizard-button.ts +51 -0
  166. package/backend/new-multiple-pages.ts +108 -0
  167. package/backend/new-record-wizard.ts +680 -0
  168. package/backend/notification.ts +366 -0
  169. package/backend/offset.ts +40 -0
  170. package/backend/online-media.ts +110 -0
  171. package/backend/page-actions.ts +91 -0
  172. package/backend/page-link-handler.ts +51 -0
  173. package/backend/pagetsconfig/pagetsconfig-includes.ts +77 -0
  174. package/backend/popover.ts +165 -0
  175. package/backend/record-download-button.ts +104 -0
  176. package/backend/record-link-handler.ts +31 -0
  177. package/backend/record-search.ts +44 -0
  178. package/backend/recordlist.ts +230 -0
  179. package/backend/resource/resource.ts +35 -0
  180. package/backend/security/element/csp-reports.ts +406 -0
  181. package/backend/security/element/sudo-mode.ts +249 -0
  182. package/backend/security/sudo-mode-interceptor.ts +19 -0
  183. package/backend/settings/editor/editable-setting.ts +231 -0
  184. package/backend/settings/editor.ts +451 -0
  185. package/backend/settings/enum/settings-mode.enum.ts +24 -0
  186. package/backend/settings/type/base.ts +200 -0
  187. package/backend/settings/type/bool.ts +56 -0
  188. package/backend/settings/type/color.ts +64 -0
  189. package/backend/settings/type/int.ts +85 -0
  190. package/backend/settings/type/number.ts +61 -0
  191. package/backend/settings/type/page.ts +100 -0
  192. package/backend/settings/type/string.ts +77 -0
  193. package/backend/settings/type/stringlist.ts +87 -0
  194. package/backend/severity.ts +88 -0
  195. package/backend/site-inline-actions.ts +32 -0
  196. package/backend/sortable-table.ts +208 -0
  197. package/backend/storage/abstract-client-storage.ts +76 -0
  198. package/backend/storage/browser-session.ts +28 -0
  199. package/backend/storage/client.ts +28 -0
  200. package/backend/storage/module-state-storage.ts +118 -0
  201. package/backend/storage/persistent.ts +204 -0
  202. package/backend/switch-user.ts +82 -0
  203. package/backend/tabs.ts +72 -0
  204. package/backend/telephone-link-handler.ts +40 -0
  205. package/backend/tests/backend/storage/browser-storage-test.ts +87 -0
  206. package/backend/tests/backend/storage/client-test.ts +87 -0
  207. package/backend/tests/backend/utility/dom-helper-test.ts +51 -0
  208. package/backend/tests/backend-exception-test.ts +28 -0
  209. package/backend/tests/element/immediate-action-element-test.ts +81 -0
  210. package/backend/tests/form-engine-validation-test.ts +304 -0
  211. package/backend/tests/grid-editor-test.ts +29 -0
  212. package/backend/tests/hashing/md5Test.ts +28 -0
  213. package/backend/tests/icons-test.ts +23 -0
  214. package/backend/tests/notification-test.ts +161 -0
  215. package/backend/tests/popover-test.ts +83 -0
  216. package/backend/toolbar/clear-cache-menu.ts +88 -0
  217. package/backend/toolbar/live-search.ts +284 -0
  218. package/backend/toolbar/shortcut-menu.ts +254 -0
  219. package/backend/toolbar/system-information-menu.ts +161 -0
  220. package/backend/toolbar.ts +41 -0
  221. package/backend/tree/file-storage-browser.ts +194 -0
  222. package/backend/tree/file-storage-tree-container.ts +465 -0
  223. package/backend/tree/file-storage-tree.ts +42 -0
  224. package/backend/tree/page-browser.ts +272 -0
  225. package/backend/tree/page-tree-element.ts +602 -0
  226. package/backend/tree/page-tree.ts +152 -0
  227. package/backend/tree/tree-module-state.ts +159 -0
  228. package/backend/tree/tree-node-toggle.ts +31 -0
  229. package/backend/tree/tree-node.ts +97 -0
  230. package/backend/tree/tree-toolbar.ts +117 -0
  231. package/backend/tree/tree.ts +1595 -0
  232. package/backend/url-link-handler.ts +36 -0
  233. package/backend/user-pass-login.ts +255 -0
  234. package/backend/user-settings-manager.ts +189 -0
  235. package/backend/utility/collapse-state-persister.ts +205 -0
  236. package/backend/utility/collapse-state-search.ts +183 -0
  237. package/backend/utility/dom-helper.ts +91 -0
  238. package/backend/utility/drag-drop-utility.ts +47 -0
  239. package/backend/utility/message-utility.ts +45 -0
  240. package/backend/utility/top-level-module-import.ts +32 -0
  241. package/backend/utility.ts +194 -0
  242. package/backend/viewport/abstract-container.ts +22 -0
  243. package/backend/viewport/content-container.ts +98 -0
  244. package/backend/viewport/loader.ts +28 -0
  245. package/backend/viewport/navigation-container.ts +119 -0
  246. package/backend/viewport/resizable-navigation.ts +176 -0
  247. package/backend/viewport/toolbar.ts +27 -0
  248. package/backend/viewport/topbar.ts +39 -0
  249. package/backend/viewport.ts +46 -0
  250. package/backend/window-manager.ts +84 -0
  251. package/backend/wizard/move-content-element.ts +107 -0
  252. package/backend/wizard/move-page.ts +74 -0
  253. package/backend/wizard.ts +331 -0
  254. package/belog/backend-log.ts +88 -0
  255. package/beuser/backend-user-listing.ts +40 -0
  256. package/beuser/permissions.ts +291 -0
  257. package/core/ajax/ajax-request-types.ts +15 -0
  258. package/core/ajax/ajax-request.ts +202 -0
  259. package/core/ajax/ajax-response.ts +57 -0
  260. package/core/ajax/input-transformer.ts +92 -0
  261. package/core/ajax/simple-response-interface.ts +5 -0
  262. package/core/authentication/mfa-provider/totp.ts +54 -0
  263. package/core/cache/dedupe-async-task.ts +95 -0
  264. package/core/directive/markdown.ts +82 -0
  265. package/core/directive/nl2br.ts +16 -0
  266. package/core/document-service.ts +35 -0
  267. package/core/event/debounce-event.ts +40 -0
  268. package/core/event/event-interface.ts +24 -0
  269. package/core/event/regular-event.ts +58 -0
  270. package/core/event/request-animation-frame-event.ts +42 -0
  271. package/core/event/throttle-event.ts +54 -0
  272. package/core/java-script-item-handler.ts +29 -0
  273. package/core/java-script-item-processor.ts +171 -0
  274. package/core/lit-helper.ts +126 -0
  275. package/core/literals.ts +17 -0
  276. package/core/referrer-refresh.ts +2 -0
  277. package/core/security-utility.ts +89 -0
  278. package/core/tests/ajax/ajax-request-test.ts +290 -0
  279. package/core/tests/ajax/input-transformer-test.ts +64 -0
  280. package/core/tests/cache/dedupe-async-task-test.ts +152 -0
  281. package/core/tests/event/throttle-event-test.ts +47 -0
  282. package/core/tests/literals-test.ts +24 -0
  283. package/core/tests/security-utility-test.ts +50 -0
  284. package/core/utility/types.ts +9 -0
  285. package/dashboard/chart-initializer.ts +136 -0
  286. package/dashboard/dashboard.ts +1487 -0
  287. package/extensionmanager/distribution-image.ts +55 -0
  288. package/extensionmanager/main.ts +291 -0
  289. package/extensionmanager/repository.ts +195 -0
  290. package/extensionmanager/update.ts +118 -0
  291. package/extensionmanager/upload-form.ts +42 -0
  292. package/filelist/browse-files.ts +148 -0
  293. package/filelist/browse-folders.ts +94 -0
  294. package/filelist/context-menu-actions.ts +335 -0
  295. package/filelist/create-folder.ts +69 -0
  296. package/filelist/file-delete.ts +69 -0
  297. package/filelist/file-list-actions.ts +132 -0
  298. package/filelist/file-list-dragdrop.ts +139 -0
  299. package/filelist/file-list-rename-handler.ts +128 -0
  300. package/filelist/file-list-transfer-handler.ts +138 -0
  301. package/filelist/file-list.ts +396 -0
  302. package/filelist/file-replace.ts +37 -0
  303. package/filelist/linkbrowser-file-handler.ts +94 -0
  304. package/filelist/linkbrowser-folder-handler.ts +74 -0
  305. package/filelist/rename-file.ts +109 -0
  306. package/form/backend/form-editor/component/property-grid-editor.ts +340 -0
  307. package/form/backend/form-editor/core.ts +2104 -0
  308. package/form/backend/form-editor/helper.ts +226 -0
  309. package/form/backend/form-editor/inspector-component.ts +2323 -0
  310. package/form/backend/form-editor/mediator.ts +941 -0
  311. package/form/backend/form-editor/modals-component.ts +433 -0
  312. package/form/backend/form-editor/stage-component.ts +908 -0
  313. package/form/backend/form-editor/tree-component.ts +548 -0
  314. package/form/backend/form-editor/view-model.ts +1343 -0
  315. package/form/backend/form-editor.ts +846 -0
  316. package/form/backend/form-manager/main.ts +39 -0
  317. package/form/backend/form-manager/view-model.ts +789 -0
  318. package/form/backend/form-manager.ts +180 -0
  319. package/form/backend/helper.ts +60 -0
  320. package/form/frontend/date-picker.ts +38 -0
  321. package/frontend/default_frontend.ts +82 -0
  322. package/impexp/context-menu-actions.ts +50 -0
  323. package/impexp/import-export.ts +62 -0
  324. package/indexed-search/pagination.ts +26 -0
  325. package/indexed-search/statistics.ts +50 -0
  326. package/info/translation-status.ts +48 -0
  327. package/install/ajax/ajax-queue.ts +83 -0
  328. package/install/init-install.ts +2 -0
  329. package/install/init-installer.ts +2 -0
  330. package/install/install.ts +25 -0
  331. package/install/installer.ts +458 -0
  332. package/install/message-interface.ts +18 -0
  333. package/install/module/abstract-inline-module.ts +27 -0
  334. package/install/module/abstract-interactable-module.ts +107 -0
  335. package/install/module/environment/environment-check.ts +92 -0
  336. package/install/module/environment/folder-structure.ts +145 -0
  337. package/install/module/environment/image-processing.ts +141 -0
  338. package/install/module/environment/mail-test.ts +127 -0
  339. package/install/module/environment/php-info.ts +50 -0
  340. package/install/module/environment/system-information.ts +50 -0
  341. package/install/module/maintenance/cache.ts +59 -0
  342. package/install/module/maintenance/clear-tables.ts +134 -0
  343. package/install/module/maintenance/clear-typo3temp-files.ts +137 -0
  344. package/install/module/maintenance/create-admin.ts +126 -0
  345. package/install/module/maintenance/database-analyzer.ts +266 -0
  346. package/install/module/maintenance/dump-autoload.ts +58 -0
  347. package/install/module/maintenance/language-packs.ts +338 -0
  348. package/install/module/maintenance/reset-backend-user-uc.ts +58 -0
  349. package/install/module/password-strength.ts +56 -0
  350. package/install/module/settings/change-install-tool-password.ts +101 -0
  351. package/install/module/settings/extension-configuration.ts +224 -0
  352. package/install/module/settings/features.ts +102 -0
  353. package/install/module/settings/local-configuration.ts +316 -0
  354. package/install/module/settings/presets.ts +147 -0
  355. package/install/module/settings/system-maintainer.ts +111 -0
  356. package/install/module/upgrade/core-update.ts +255 -0
  357. package/install/module/upgrade/extension-compat-tester.ts +195 -0
  358. package/install/module/upgrade/extension-scanner.ts +381 -0
  359. package/install/module/upgrade/tca-ext-tables-check.ts +93 -0
  360. package/install/module/upgrade/tca-migrations-check.ts +101 -0
  361. package/install/module/upgrade/upgrade-docs.ts +310 -0
  362. package/install/module/upgrade/upgrade-wizards.ts +612 -0
  363. package/install/renderable/clearable.ts +113 -0
  364. package/install/renderable/flash-message.ts +64 -0
  365. package/install/renderable/info-box.ts +66 -0
  366. package/install/renderable/language-packs.ts +304 -0
  367. package/install/renderable/offset-group.ts +38 -0
  368. package/install/renderable/severity.ts +49 -0
  369. package/install/renderable/wrap-group.ts +36 -0
  370. package/install/router.ts +468 -0
  371. package/linkvalidator/linkvalidator-modal.ts +45 -0
  372. package/linkvalidator/linkvalidator.ts +101 -0
  373. package/lowlevel/query-generator.ts +132 -0
  374. package/lowlevel/reference-index.ts +44 -0
  375. package/opendocs/toolbar/opendocs-menu.ts +117 -0
  376. package/package.json +34 -0
  377. package/recycler/recycler.ts +539 -0
  378. package/redirects/event-handler.ts +108 -0
  379. package/redirects/form-engine-evaluation.ts +34 -0
  380. package/redirects/redirects-module.ts +58 -0
  381. package/rte-ckeditor/ckeditor5.ts +402 -0
  382. package/rte-ckeditor/css-prefixer.ts +94 -0
  383. package/rte-ckeditor/legacy/ckeditor5-bundle.ts +17 -0
  384. package/rte-ckeditor/legacy/ckeditor5-inspector.ts +2 -0
  385. package/rte-ckeditor/plugin/typo3-link.ts +810 -0
  386. package/rte-ckeditor/plugin/whitespace.ts +114 -0
  387. package/rte-ckeditor/rte-link-browser.ts +112 -0
  388. package/rte-ckeditor/tests/css-prefixer-test.ts +314 -0
  389. package/scheduler/scheduler-add-group.ts +119 -0
  390. package/scheduler/scheduler-editable-group-name.ts +307 -0
  391. package/scheduler/scheduler-sortable-groups.ts +59 -0
  392. package/scheduler/scheduler.ts +466 -0
  393. package/setup/setup-module.ts +122 -0
  394. package/styleguide/checkbox-demo.ts +5 -0
  395. package/styleguide/element/theme-switcher-element.ts +101 -0
  396. package/styleguide/filter.ts +22 -0
  397. package/styleguide/find-icons.ts +78 -0
  398. package/styleguide/processing-indicator.ts +78 -0
  399. package/styleguide/render-notifications.ts +64 -0
  400. package/sys-note/element/delete-button.ts +78 -0
  401. package/tstemplate/constant-editor.ts +64 -0
  402. package/tstemplate/information-module.ts +31 -0
  403. package/tstemplate/template-analyzer.ts +77 -0
  404. package/viewpage/main.ts +253 -0
  405. package/workspaces/backend.ts +979 -0
  406. package/workspaces/preview.ts +232 -0
  407. package/workspaces/renderable/comment-view.ts +79 -0
  408. package/workspaces/renderable/diff-view.ts +58 -0
  409. package/workspaces/renderable/history-view.ts +97 -0
  410. package/workspaces/renderable/record-information.ts +118 -0
  411. package/workspaces/renderable/record-table.ts +355 -0
  412. package/workspaces/renderable/send-to-stage-form.ts +108 -0
  413. package/workspaces/toolbar/workspaces-menu.ts +190 -0
  414. package/workspaces/utility/icon-helper.ts +57 -0
  415. package/workspaces/workspaces.ts +136 -0
@@ -0,0 +1,355 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ import { customElement, property } from 'lit/decorators';
15
+ import { html, LitElement, nothing, type TemplateResult } from 'lit';
16
+ import IconHelper from '@typo3/workspaces/utility/icon-helper';
17
+ import { classMap } from 'lit/directives/class-map';
18
+ import { ifDefined } from 'lit/directives/if-defined';
19
+ import { repeat } from 'lit/directives/repeat';
20
+ import '@typo3/backend/element/icon-element';
21
+
22
+ export type RecordData = {
23
+ table: string,
24
+ id: string,
25
+ uid: number,
26
+ Workspaces_Collection: number,
27
+ Workspaces_CollectionLevel: number,
28
+ Workspaces_CollectionParent: string,
29
+ Workspaces_CollectionCurrent: string,
30
+ Workspaces_CollectionChildren: number,
31
+ label_Workspace: string,
32
+ label_Stage: string,
33
+ value_nextStage: number,
34
+ value_prevStage: number,
35
+ path_Workspace: string,
36
+ lastChangedFormatted: string,
37
+ t3ver_wsid: number,
38
+ t3ver_oid: number,
39
+ livepid: number,
40
+ stage: number,
41
+ icon_Workspace: string,
42
+ icon_Workspace_Overlay: string,
43
+ language: {
44
+ icon: string,
45
+ title: string,
46
+ title_crop: string
47
+ },
48
+ allowedAction_publish: boolean,
49
+ allowedAction_delete: boolean,
50
+ allowedAction_view: boolean,
51
+ allowedAction_edit: boolean,
52
+ allowedAction_versionPageOpen: boolean,
53
+ state_Workspace: string,
54
+ hasChanges: boolean,
55
+ urlToPage: string,
56
+ expanded: boolean,
57
+ integrity: {
58
+ status: string,
59
+ messages: string
60
+ }
61
+ };
62
+
63
+ @customElement('typo3-workspaces-record-table')
64
+ export class RecordTableElement extends LitElement {
65
+ @property({ type: Array })
66
+ public results: RecordData[] = [];
67
+
68
+ private latestPath: string | null = null;
69
+
70
+ protected override createRenderRoot(): HTMLElement | ShadowRoot {
71
+ // @todo Switch to Shadow DOM once Bootstrap CSS style can be applied correctly
72
+ return this;
73
+ }
74
+
75
+ protected override render(): TemplateResult {
76
+ return html`
77
+ <div class="table-fit mb-0">
78
+ <table class="table table-striped">
79
+ <thead>
80
+ <tr>
81
+ <th>
82
+ <div class="btn-group dropdown">
83
+ <button type="button" class="dropdown-toggle dropdown-toggle-link t3js-multi-record-selection-check-actions-toggle" data-bs-toggle="dropdown" data-bs-boundary="window" aria-expanded="false" aria-label="${TYPO3.lang['labels.openSelectionOptions']}">
84
+ <typo3-backend-icon identifier="actions-selection" size="small"></typo3-backend-icon>
85
+ </button>
86
+ <ul class="dropdown-menu t3js-multi-record-selection-check-actions">
87
+ <li>
88
+ <button type="button" class="dropdown-item" disabled data-multi-record-selection-check-action="check-all" title=${TYPO3.lang['labels.checkAll']}>
89
+ <span class="dropdown-item-columns">
90
+ <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
91
+ <typo3-backend-icon identifier="actions-selection-elements-all" size="small"></typo3-backend-icon>
92
+ </span>
93
+ <span class="dropdown-item-column dropdown-item-column-title">
94
+ ${TYPO3.lang['labels.checkAll']}
95
+ </span>
96
+ </span>
97
+ </button>
98
+ </li>
99
+ <li>
100
+ <button type="button" class="dropdown-item" disabled data-multi-record-selection-check-action="check-none" title=${TYPO3.lang['labels.uncheckAll']}>
101
+ <span class="dropdown-item-columns">
102
+ <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
103
+ <typo3-backend-icon identifier="actions-selection-elements-none" size="small"></typo3-backend-icon>
104
+ </span>
105
+ <span class="dropdown-item-column dropdown-item-column-title">
106
+ ${TYPO3.lang['labels.uncheckAll']}
107
+ </span>
108
+ </span>
109
+ </button>
110
+ </li>
111
+ <li>
112
+ <button type="button" class="dropdown-item" data-multi-record-selection-check-action="toggle" title=${TYPO3.lang['labels.toggleSelection']}>
113
+ <span class="dropdown-item-columns">
114
+ <span class="dropdown-item-column dropdown-item-column-icon" aria-hidden="true">
115
+ <typo3-backend-icon identifier="actions-selection-elements-invert" size="small"></typo3-backend-icon>
116
+ </span>
117
+ <span class="dropdown-item-column dropdown-item-column-title">
118
+ ${TYPO3.lang['labels.toggleSelection']}
119
+ </span>
120
+ </span>
121
+ </button>
122
+ </li>
123
+ </ul>
124
+ </div>
125
+ </th>
126
+ <th class="col-min">${TYPO3.lang['column.wsTitle']}</th>
127
+ <th class="col-language">${TYPO3.lang['labels._LOCALIZATION_']}</th>
128
+ <th class="col-datetime">${TYPO3.lang['column.lastChangeOn']}</th>
129
+ <th class="col-state">${TYPO3.lang['column.wsStateAction']}</th>
130
+ <th class="col-state">${TYPO3.lang['column.integrity']}</th>
131
+ <th>${TYPO3.lang['column.stage']}</th>
132
+ <th class="col-control nowrap">
133
+ <span class="visually-hidden">${TYPO3.lang['labels._CONTROL_']}</span>
134
+ </th>
135
+ </tr>
136
+ </thead>
137
+ <tbody data-multi-record-selection-row-selection="true">
138
+ ${repeat(this.results, (result) => result.uid, (data: RecordData) => this.renderTableRow(data))}
139
+ </tbody>
140
+ </table>
141
+ </div>
142
+ `;
143
+ }
144
+
145
+ protected renderTableRow(data: RecordData): TemplateResult {
146
+ let parentItem = null;
147
+ let latestPathChanged = false;
148
+
149
+ if (this.latestPath !== data.path_Workspace) {
150
+ this.latestPath = data.path_Workspace;
151
+ latestPathChanged = true;
152
+ }
153
+
154
+ if (data.Workspaces_CollectionParent !== '') {
155
+ parentItem = this.results.find((element: any) => {
156
+ return element.Workspaces_CollectionCurrent === data.Workspaces_CollectionParent;
157
+ });
158
+ }
159
+
160
+ const wsState = data.state_Workspace;
161
+ let wsStateActionClass: string;
162
+ let wsStateActionLabel: string;
163
+
164
+ switch (wsState) {
165
+ case 'deleted':
166
+ wsStateActionClass = 'danger';
167
+ wsStateActionLabel = TYPO3.lang['column.wsStateAction.deleted'];
168
+ break;
169
+ case 'hidden':
170
+ wsStateActionClass = 'secondary';
171
+ wsStateActionLabel = TYPO3.lang['column.wsStateAction.hidden'];
172
+ break;
173
+ case 'modified':
174
+ wsStateActionClass = 'warning';
175
+ wsStateActionLabel = TYPO3.lang['column.wsStateAction.modified'];
176
+ break;
177
+ case 'moved':
178
+ wsStateActionClass = 'primary';
179
+ wsStateActionLabel = TYPO3.lang['column.wsStateAction.moved'];
180
+ break;
181
+ case 'new':
182
+ wsStateActionClass = 'success';
183
+ wsStateActionLabel = TYPO3.lang['column.wsStateAction.new'];
184
+ break;
185
+ default:
186
+ wsStateActionClass = 'secondary';
187
+ wsStateActionLabel = TYPO3.lang['column.wsStateAction.unchanged'];
188
+ }
189
+
190
+ return html`
191
+ ${latestPathChanged ? html`
192
+ <tr>
193
+ <th colspan="8" class="col-white-space-normal">
194
+ <a href=${data.urlToPage}>${data.path_Workspace}</a>
195
+ </th>
196
+ </tr>
197
+ ` : nothing}
198
+ <tr
199
+ class=${classMap({ collapse: data.Workspaces_CollectionParent !== '', show: parentItem?.expanded })}
200
+ data-uid=${data.uid}
201
+ data-pid=${data.livepid}
202
+ data-t3ver_oid=${data.t3ver_oid}
203
+ data-t3ver_wsid=${data.t3ver_wsid}
204
+ data-table=${data.table}
205
+ data-next-stage=${data.value_nextStage}
206
+ data-prev-stage=${data.value_prevStage}
207
+ data-stage=${data.stage}
208
+ data-multi-record-selection-element="true"
209
+ data-collection=${data.Workspaces_CollectionParent ? data.Workspaces_CollectionParent : nothing}
210
+ data-collection-current=${ifDefined(data.Workspaces_CollectionCurrent)}
211
+ >
212
+ <td class="col-checkbox">
213
+ <span class="form-check form-check-type-toggle">
214
+ <input type="checkbox" class="form-check-input t3js-multi-record-selection-check"/>
215
+ </span>
216
+ </td>
217
+ <td class="col-min t3js-title-workspace">
218
+ ${ data.Workspaces_CollectionLevel > 0 ? this.renderIndent(data.Workspaces_CollectionLevel) : nothing}
219
+ <span class="icon icon-size-small">
220
+ <typo3-backend-icon identifier=${IconHelper.getIconIdentifier(data.icon_Workspace)} overlay=${IconHelper.getIconIdentifier(data.icon_Workspace_Overlay)} size="small"></typo3-backend-icon>
221
+ </span>
222
+ <a href="#" data-action="changes">
223
+ ${data.label_Workspace}
224
+ </a>
225
+ </td>
226
+ <td class="col-language">
227
+ <span title="${data.language.title}" class="icon icon-size-small">
228
+ <typo3-backend-icon identifier=${IconHelper.getIconIdentifier(data.language.icon)} size="small"></typo3-backend-icon>
229
+ </span>
230
+ ${data.language.title_crop}
231
+ </td>
232
+ <td class="col-datetime">${data.lastChangedFormatted}</td>
233
+ <td class="col-state">
234
+ <span class="badge badge-${wsStateActionClass}">${wsStateActionLabel}</span>
235
+ </td>
236
+ <td class="col-state">${ data.integrity.messages !== '' ? html`
237
+ <span title="${data.integrity.messages}" class="icon icon-size-small">
238
+ <typo3-backend-icon identifier=${IconHelper.getIconIdentifier(data.integrity.status)} size="small"></typo3-backend-icon>
239
+ </span>
240
+ ` : nothing}</td>
241
+ <td>${data.label_Stage}</td>
242
+ <td class="col-control nowrap">
243
+ <div class="btn-group">${this.renderElementActions(data)}</div>
244
+ <div class="btn-group">${this.renderVersioningActions(data)}</div>
245
+ </td>
246
+ </tr>
247
+ `;
248
+ }
249
+
250
+ protected renderIndent(level: number) {
251
+ return html`<span class="indent indent-inline-block" style="--indent-level: ${level}"></span>`;
252
+ }
253
+
254
+ private renderElementActions(data: RecordData): TemplateResult[] {
255
+ return [
256
+ this.getAction(
257
+ data.allowedAction_view,
258
+ 'preview',
259
+ 'actions-version-workspace-preview',
260
+ {
261
+ 'title': TYPO3.lang['tooltip.viewElementAction']
262
+ }
263
+ ),
264
+ this.getAction(
265
+ data.allowedAction_edit && data.state_Workspace !== 'deleted',
266
+ 'open',
267
+ 'actions-open',
268
+ {
269
+ 'title': TYPO3.lang['tooltip.editElementAction']
270
+ }
271
+ ),
272
+ this.getAction(
273
+ data.allowedAction_versionPageOpen,
274
+ 'version',
275
+ 'actions-version-page-open',
276
+ {
277
+ 'title': TYPO3.lang['tooltip.openPage']
278
+ }
279
+ )
280
+ ];
281
+ }
282
+
283
+ private renderVersioningActions(data: RecordData): TemplateResult[] {
284
+ const hasSubitems = data.Workspaces_CollectionChildren > 0 && data.Workspaces_CollectionCurrent !== '';
285
+
286
+ return [
287
+ this.getAction(
288
+ hasSubitems,
289
+ 'expand',
290
+ (data.expanded ? 'actions-caret-down' : 'actions-caret-right'),
291
+ {
292
+ 'title': TYPO3.lang['tooltip.expand'],
293
+ 'data-bs-target': '[data-collection="' + data.Workspaces_CollectionCurrent + '"]',
294
+ 'aria-expanded': !hasSubitems || data.expanded ? 'true' : 'false',
295
+ 'data-bs-toggle': 'collapse',
296
+ }
297
+ ),
298
+ this.getAction(
299
+ data.hasChanges,
300
+ 'changes',
301
+ 'actions-document-info',
302
+ {
303
+ 'title': TYPO3.lang['tooltip.showChanges']
304
+ }
305
+ ),
306
+ this.getAction(
307
+ data.allowedAction_publish && data.Workspaces_CollectionParent === '',
308
+ 'publish',
309
+ 'actions-version-swap-version',
310
+ {
311
+ 'title': TYPO3.lang['tooltip.publish']
312
+ }
313
+ ),
314
+ this.getAction(
315
+ data.allowedAction_delete,
316
+ 'remove',
317
+ 'actions-delete',
318
+ {
319
+ 'title': TYPO3.lang['tooltip.discardVersion']
320
+ }
321
+ )
322
+ ];
323
+ }
324
+
325
+ /**
326
+ * Renders the action button based on the user's permission.
327
+ *
328
+ * @param {string} condition
329
+ * @param {string} action
330
+ * @param {string} iconIdentifier
331
+ * @param {object} additionalAttributes
332
+ * @return {JQuery}
333
+ */
334
+ private getAction(condition: boolean, action: string, iconIdentifier: string, additionalAttributes?: Record<string, string>): TemplateResult {
335
+ return html`
336
+ <button
337
+ type="button"
338
+ class="btn btn-default"
339
+ ?disabled=${condition ? nothing : ''}
340
+ data-action="${condition ? action : nothing}"
341
+ title=${ifDefined(additionalAttributes.title)}
342
+ data-bs-target=${ifDefined(additionalAttributes['data-bs-target'])}
343
+ data-bs-toggle=${ifDefined(additionalAttributes['data-bs-toggle'])}
344
+ aria-expanded=${ifDefined(additionalAttributes['aria-expanded'])}>
345
+ <typo3-backend-icon identifier=${IconHelper.getIconIdentifier((condition ? iconIdentifier : 'empty-empty'))} size="small"></typo3-backend-icon>
346
+ </button>
347
+ `;
348
+ }
349
+ }
350
+
351
+ declare global {
352
+ interface HTMLElementTagNameMap {
353
+ 'typo3-workspaces-record-table': RecordTableElement;
354
+ }
355
+ }
@@ -0,0 +1,108 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ import { customElement, property } from 'lit/decorators';
15
+ import { html, LitElement, nothing, type TemplateResult } from 'lit';
16
+
17
+ export type SendToStageResultData = {
18
+ sendMailTo?: SendToStageRecipient[],
19
+ additional?: {
20
+ type: string,
21
+ value: string
22
+ },
23
+ comments: {
24
+ type: string,
25
+ value: string
26
+ }
27
+ };
28
+
29
+ export type SendToStageRecipient = {
30
+ name: string,
31
+ value: string,
32
+ checked: boolean,
33
+ disabled: boolean,
34
+ label: string
35
+ };
36
+
37
+ @customElement('typo3-workspaces-send-to-stage-form')
38
+ export class SendToStageFormElement extends LitElement {
39
+ @property({ type: Object })
40
+ public data: SendToStageResultData | null = null;
41
+
42
+ @property({ type: Object })
43
+ public TYPO3lang: typeof TYPO3.lang | null = null;
44
+
45
+ protected override createRenderRoot(): HTMLElement | ShadowRoot {
46
+ // @todo Switch to Shadow DOM once Bootstrap CSS style can be applied correctly
47
+ return this;
48
+ }
49
+
50
+ protected override render(): TemplateResult {
51
+ return html`
52
+ <form>
53
+ ${this.data.sendMailTo !== undefined && this.data.sendMailTo.length > 0 ? html`
54
+ <label class="form-label">${this.TYPO3lang['window.sendToNextStageWindow.itemsWillBeSentTo']}</label>
55
+ ${this.renderRecipientCheckboxes()}
56
+ ` : nothing}
57
+ ${this.data.additional !== undefined ? html`
58
+ <div class="form-group">
59
+ <label for="additional" class="form-label">
60
+ ${this.TYPO3lang['window.sendToNextStageWindow.additionalRecipients']}
61
+ </label>
62
+ <textarea class="form-control" name="additional" id="additional">${this.data.additional.value}</textarea>
63
+ <div class="form-text">
64
+ ${this.TYPO3lang['window.sendToNextStageWindow.additionalRecipients.hint']}
65
+ </div>
66
+ </div>
67
+ ` : nothing}
68
+ <div class="form-group">
69
+ <label for="comments" class="form-label">
70
+ ${this.TYPO3lang['window.sendToNextStageWindow.comments']}
71
+ </label>
72
+ <textarea class="form-control" name="comments" id="comments">${this.data.comments.value}</textarea>
73
+ </div>
74
+ </form>
75
+ `;
76
+ }
77
+
78
+ private renderRecipientCheckboxes(): TemplateResult[] {
79
+ const renderResult: TemplateResult[] = [];
80
+
81
+ this.data.sendMailTo?.forEach((recipient: SendToStageRecipient) => {
82
+ renderResult.push(html`
83
+ <div class="form-check">
84
+ <input
85
+ type="checkbox"
86
+ name="recipients"
87
+ class="form-check-input t3js-workspace-recipient"
88
+ id=${recipient.name}
89
+ value=${recipient.value}
90
+ ?checked=${recipient.checked}
91
+ ?disabled=${recipient.disabled}
92
+ />
93
+ <label class="form-check-label" for=${recipient.name}>
94
+ ${recipient.label}
95
+ </label>
96
+ </div>
97
+ `);
98
+ });
99
+
100
+ return renderResult;
101
+ }
102
+ }
103
+
104
+ declare global {
105
+ interface HTMLElementTagNameMap {
106
+ 'typo3-workspaces-send-to-stage-form': SendToStageFormElement;
107
+ }
108
+ }
@@ -0,0 +1,190 @@
1
+ /*
2
+ * This file is part of the TYPO3 CMS project.
3
+ *
4
+ * It is free software; you can redistribute it and/or modify it under
5
+ * the terms of the GNU General Public License, either version 2
6
+ * of the License, or any later version.
7
+ *
8
+ * For the full copyright and license information, please read the
9
+ * LICENSE.txt file that was distributed with this source code.
10
+ *
11
+ * The TYPO3 project - inspiring people to share!
12
+ */
13
+
14
+ import AjaxRequest from '@typo3/core/ajax/ajax-request';
15
+ import ModuleMenu from '@typo3/backend/module-menu';
16
+ import Viewport from '@typo3/backend/viewport';
17
+ import RegularEvent from '@typo3/core/event/regular-event';
18
+ import { ModuleStateStorage } from '@typo3/backend/storage/module-state-storage';
19
+ import type { AjaxResponse } from '@typo3/core/ajax/ajax-response';
20
+
21
+ enum Identifiers {
22
+ scaffoldSelector = '.t3js-scaffold',
23
+ containerSelector = '#typo3-cms-workspaces-backend-toolbaritems-workspaceselectortoolbaritem',
24
+ activeMenuItemLinkSelector = '.t3js-workspaces-switchlink.active',
25
+ menuItemLinkSelector = '.t3js-workspaces-switchlink',
26
+ toolbarItemSelector = '.dropdown-toggle',
27
+ }
28
+
29
+ enum Classes {
30
+ workspaceBodyClass = 'scaffold-in-workspace',
31
+ workspacesTitleInToolbarClass = 'toolbar-item-name',
32
+ }
33
+
34
+ interface WorkspaceState {
35
+ id: number
36
+ title: string
37
+ inWorkspace: boolean
38
+ }
39
+
40
+ /**
41
+ * Module: @typo3/workspaces/toolbar/workspaces-menu
42
+ * toolbar menu for the workspaces functionality to switch between the workspaces
43
+ * and jump to the workspaces module
44
+ */
45
+ class WorkspacesMenu {
46
+ constructor() {
47
+ Viewport.Topbar.Toolbar.registerEvent((): void => {
48
+ this.initializeEvents();
49
+ WorkspacesMenu.updateBackendContext();
50
+ });
51
+
52
+ new RegularEvent('typo3:datahandler:process', (e: CustomEvent): void => {
53
+ const payload = e.detail.payload;
54
+ if (payload.table === 'sys_workspace' && payload.action === 'delete' && payload.hasErrors === false) {
55
+ Viewport.Topbar.refresh();
56
+ }
57
+ }).bindTo(document);
58
+ }
59
+
60
+ /**
61
+ * Refresh the page tree
62
+ */
63
+ private static refreshPageTree(): void {
64
+ document.dispatchEvent(new CustomEvent('typo3:pagetree:refresh'));
65
+ }
66
+
67
+ /**
68
+ * Get workspace state from the current active menu item
69
+ */
70
+ private static getWorkspaceState(): null|WorkspaceState {
71
+ const selectedWorkspaceLink: HTMLElement = document.querySelector(
72
+ [Identifiers.containerSelector, Identifiers.activeMenuItemLinkSelector].join(' ')
73
+ );
74
+ if (selectedWorkspaceLink === null) {
75
+ return null;
76
+ }
77
+ const workspaceId = parseInt(selectedWorkspaceLink.dataset.workspaceid || '0', 10);
78
+ return {
79
+ id: workspaceId,
80
+ title: selectedWorkspaceLink.innerText.trim(),
81
+ inWorkspace: workspaceId !== 0
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Adds the workspace title to the toolbar next to the username
87
+ * and adds the check icon to the currently active menu items.
88
+ *
89
+ * @param {WorkspaceState} workspaceState
90
+ */
91
+ private static updateTopBar(workspaceState: WorkspaceState): void {
92
+ const toolbarItemContainer = document.querySelector(Identifiers.containerSelector);
93
+
94
+ // Remove the workspace title in toolbar
95
+ toolbarItemContainer.querySelector(Identifiers.containerSelector + ' .' + Classes.workspacesTitleInToolbarClass)?.remove();
96
+
97
+ // If we are in a workspace, add the corresponding title to the toolbar - if available
98
+ if (workspaceState.inWorkspace && workspaceState.title) {
99
+ const titleElement = document.createElement('span');
100
+ titleElement.classList.add(Classes.workspacesTitleInToolbarClass);
101
+ titleElement.textContent = workspaceState.title;
102
+ toolbarItemContainer.querySelector(Identifiers.toolbarItemSelector).append(titleElement);
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Updates backend context, especially the topbar
108
+ */
109
+ private static updateBackendContext(workspaceState: WorkspaceState = null): void {
110
+ workspaceState ??= WorkspacesMenu.getWorkspaceState();
111
+ if (workspaceState === null) {
112
+ // If still no workspace state, return
113
+ return;
114
+ }
115
+
116
+ const topbar = document.querySelector(Identifiers.scaffoldSelector);
117
+ topbar.classList.toggle(Classes.workspaceBodyClass, workspaceState.inWorkspace);
118
+ if (workspaceState.inWorkspace && !workspaceState.title) {
119
+ workspaceState.title = TYPO3.lang['Workspaces.workspaceTitle'];
120
+ }
121
+
122
+ WorkspacesMenu.updateTopBar(workspaceState);
123
+ }
124
+
125
+ /**
126
+ * Changes the data in the module menu and the updates the backend context
127
+ */
128
+ private performWorkspaceSwitch(id: number, title: string): void {
129
+ const toolbarItemContainer = document.querySelector(Identifiers.containerSelector);
130
+ // remove "active" class
131
+ toolbarItemContainer.querySelector(Identifiers.activeMenuItemLinkSelector).classList.remove('active');
132
+
133
+ // add "active" class to currently selected workspace
134
+ toolbarItemContainer.querySelector(Identifiers.menuItemLinkSelector + '[data-workspaceid="' + id + '"]')?.classList.add('active');
135
+
136
+ // Initiate backend context update
137
+ WorkspacesMenu.updateBackendContext({ id: id, title: title, inWorkspace: id !== 0 });
138
+ }
139
+
140
+ private initializeEvents(): void {
141
+ const toolbarItemContainer = document.querySelector(Identifiers.containerSelector);
142
+
143
+ new RegularEvent('click', (e: Event, menuItem: HTMLAnchorElement): void => {
144
+ e.preventDefault();
145
+ this.switchWorkspace(parseInt(menuItem.dataset.workspaceid, 10));
146
+ }).delegateTo(toolbarItemContainer, Identifiers.menuItemLinkSelector);
147
+ }
148
+
149
+ private switchWorkspace(workspaceId: number): void {
150
+ (new AjaxRequest(TYPO3.settings.ajaxUrls.workspace_switch)).post({
151
+ workspaceId: workspaceId,
152
+ pageId: ModuleStateStorage.current('web').identifier
153
+ }).then(async (response: AjaxResponse): Promise<void> => {
154
+ const data = await response.resolve();
155
+ if (!data.workspaceId) {
156
+ data.workspaceId = 0;
157
+ }
158
+
159
+ this.performWorkspaceSwitch(data.workspaceId, data.title || '');
160
+
161
+ const currentModule = ModuleMenu.App.getCurrentModule();
162
+ // If a user has no view permission for the requested page, the first allowed page id from its rootline is
163
+ // returned which gets appended to the URL
164
+ if (data.pageId) {
165
+ let url = TYPO3.Backend.ContentContainer.getUrl();
166
+ url += (!url.includes('?') ? '?' : '&') + 'id=' + data.pageId;
167
+ Viewport.ContentContainer.setUrl(url);
168
+ } else if (currentModule === 'workspaces_admin') {
169
+ // Reload the workspace module and override the workspace id
170
+ ModuleMenu.App.showModule(currentModule, 'workspace=' + workspaceId);
171
+ } else if (currentModule?.startsWith('web_')) {
172
+ // when in web module reload, otherwise send the user to the page module
173
+ ModuleMenu.App.reloadFrames();
174
+ } else if (data.pageModule) {
175
+ ModuleMenu.App.showModule(data.pageModule);
176
+ }
177
+
178
+ // Refresh the pagetree if visible
179
+ WorkspacesMenu.refreshPageTree();
180
+ // reload the module menu
181
+ ModuleMenu.App.refreshMenu();
182
+ });
183
+ }
184
+ }
185
+
186
+ const workspacesMenu = new WorkspacesMenu();
187
+ // expose the module in a global object
188
+ TYPO3.WorkspacesMenu = workspacesMenu;
189
+
190
+ export default workspacesMenu;