From 91e97dbdf216885e7cecb61d1db749963ea80eea Mon Sep 17 00:00:00 2001 From: yu-i-i Date: Mon, 2 Feb 2026 17:05:02 +0100 Subject: [PATCH] Template Gallery: migration to 6.1.0 enable menu for editor redisign move frontend code to modules --- develop/docker-compose.yml | 2 +- .../Features/Templates/TemplatesManager.mjs | 80 +++++++++---------- services/web/app/src/router.mjs | 2 + .../template_gallery/template-gallery.pug | 18 ----- services/web/config/settings.defaults.js | 14 +++- .../stylesheets/pages/templates-v2.scss | 1 - .../app/src/TemplateGalleryController.mjs | 10 ++- .../app/src/TemplateGalleryHelper.mjs | 4 +- .../app/src/TemplateGalleryManager.mjs | 2 +- .../app/src/TemplateGalleryRouter.mjs | 2 +- .../src/models/{Template.js => Template.mjs} | 7 +- .../template_gallery/template-gallery.pug | 15 ++++ .../app/views/template_gallery/template.pug | 8 +- .../components/gallery-header-all.tsx | 0 .../components/gallery-header-tagged.tsx | 0 .../components/gallery-popular-tags.tsx | 0 .../components/gallery-search-sort-header.tsx | 0 .../components/pagination.tsx | 0 .../components/search-form.tsx | 2 +- .../components/sort/with-content.tsx | 0 .../components/template-gallery-entry.tsx | 2 +- .../components/template-gallery-root.tsx | 4 +- .../components/template-gallery.tsx | 0 .../context/template-gallery-context.tsx | 4 +- .../template-gallery/hooks/use-sort.ts | 2 +- .../js/features/template-gallery/types/api.ts | 2 +- .../js/features/template-gallery/util/api.ts | 2 +- .../template-gallery/util/sort-templates.ts | 4 +- .../components/actions-manage-template.tsx | 12 +-- .../components/delete-template-button.tsx | 0 .../components/edit-template-button.tsx | 0 .../components/form/form-field-input.tsx | 0 .../form/labeled-row-form-group.tsx | 0 .../components/form/template-form-fields.tsx | 0 .../editor-manage-template-modal-wrapper.tsx | 0 .../manage-template-modal-content.tsx | 0 .../manage-template-modal.tsx | 0 .../components/menubar-manage-template.tsx | 52 ++++++++++++ .../modals/delete-template-modal.tsx | 0 .../components/modals/edit-template-modal.tsx | 0 .../modals/template-action-modal.tsx | 0 .../components/settings/settings-language.tsx | 2 +- .../components/settings/settings-license.tsx | 0 .../settings/settings-menu-select.tsx | 0 .../settings/settings-template-category.tsx | 0 .../template/components/template-details.tsx | 4 +- .../template/components/template-preview.tsx | 0 .../template/components/template-root.tsx | 4 +- .../template/context/template-context.tsx | 0 .../features/template/hooks/use-focus-trap.ts | 0 .../frontend/js/features/template/util/api.ts | 0 .../frontend/js/pages/template-gallery.tsx | 7 -- .../frontend/js/pages/template.tsx | 7 -- .../template-gallery}/types/template.ts | 0 54 files changed, 161 insertions(+), 114 deletions(-) delete mode 100644 services/web/app/views/template_gallery/template-gallery.pug rename services/web/modules/template-gallery/app/src/models/{Template.js => Template.mjs} (77%) create mode 100644 services/web/modules/template-gallery/app/views/template_gallery/template-gallery.pug rename services/web/{ => modules/template-gallery}/app/views/template_gallery/template.pug (61%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/gallery-header-all.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/gallery-header-tagged.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/gallery-search-sort-header.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/pagination.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/search-form.tsx (95%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/sort/with-content.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/template-gallery-entry.tsx (91%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/template-gallery-root.tsx (93%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/components/template-gallery.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/context/template-gallery-context.tsx (97%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/hooks/use-sort.ts (88%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/types/api.ts (75%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/util/api.ts (84%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template-gallery/util/sort-templates.ts (87%) rename services/web/{frontend/js/features/editor-left-menu => modules/template-gallery/frontend/js/features/template}/components/actions-manage-template.tsx (82%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/delete-template-button.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/edit-template-button.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/form/form-field-input.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/form/labeled-row-form-group.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/form/template-form-fields.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/manage-template-modal/editor-manage-template-modal-wrapper.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/manage-template-modal/manage-template-modal-content.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/manage-template-modal/manage-template-modal.tsx (100%) create mode 100644 services/web/modules/template-gallery/frontend/js/features/template/components/menubar-manage-template.tsx rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/modals/delete-template-modal.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/modals/edit-template-modal.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/modals/template-action-modal.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/settings/settings-language.tsx (95%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/settings/settings-license.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/settings/settings-menu-select.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/settings/settings-template-category.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/template-details.tsx (95%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/template-preview.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/components/template-root.tsx (94%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/context/template-context.tsx (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/hooks/use-focus-trap.ts (100%) rename services/web/{ => modules/template-gallery}/frontend/js/features/template/util/api.ts (100%) rename services/web/{ => modules/template-gallery}/frontend/js/pages/template-gallery.tsx (55%) rename services/web/{ => modules/template-gallery}/frontend/js/pages/template.tsx (52%) rename services/web/{ => modules/template-gallery}/types/template.ts (100%) diff --git a/develop/docker-compose.yml b/develop/docker-compose.yml index a25dc11cb3..e2407da19d 100644 --- a/develop/docker-compose.yml +++ b/develop/docker-compose.yml @@ -138,7 +138,7 @@ services: dockerfile: services/real-time/Dockerfile env_file: - dev.env - + redis: image: redis:7 ports: diff --git a/services/web/app/src/Features/Templates/TemplatesManager.mjs b/services/web/app/src/Features/Templates/TemplatesManager.mjs index 0962f57ea6..66230a5963 100644 --- a/services/web/app/src/Features/Templates/TemplatesManager.mjs +++ b/services/web/app/src/Features/Templates/TemplatesManager.mjs @@ -32,8 +32,18 @@ const TemplatesManager = { templateVersionId, userId, imageName, - language + spellCheckLanguage ) { + + compiler = ProjectOptionsHandler.normalizeCompiler(compiler || 'pdflatex') + + try { + imageName = ProjectOptionsHandler.normalizeImageName(imageName) + } catch { + logger.warn( { templateId, imageName }, 'cannot use the image required by the template, using the default image') + imageName = null + } + const zipUrl = `${settings.apis.filestore.url}/template/${templateId}/v/${templateVersionId}/zip` const zipReq = await fetchStreamWithResponse(zipUrl, { signal: AbortSignal.timeout(TIMEOUT), @@ -42,8 +52,15 @@ const TemplatesManager = { const projectName = ProjectDetailsHandler.fixProjectName(templateName) const dumpPath = `${settings.path.dumpFolder}/${crypto.randomUUID()}_templates-manager` const writeStream = fs.createWriteStream(dumpPath) + try { - const attributes = {} + const attributes = { + compiler, + imageName, + spellCheckLanguage, + } + if (brandVariationId) attributes.brandVariationId = brandVariationId + await pipeline(zipReq.stream, writeStream) if (zipReq.response.status !== 200) { @@ -73,13 +90,22 @@ const TemplatesManager = { return undefined }) - await TemplatesManager._setCompiler(project._id, compiler) - await TemplatesManager._setImage(project._id, imageName) - await TemplatesManager._setMainFile(project._id, mainFile) - await TemplatesManager._setSpellCheckLanguage(project._id, language) - await TemplatesManager._setBrandVariationId(project._id, brandVariationId) + await TemplatesManager._setMainFile(project, mainFile) - await prepareClsiCacheInBackground + const found = await prepareClsiCacheInBackground + if (found === false && project.rootDoc_id) { + ClsiCacheManager.createTemplateClsiCache({ + templateVersionId, + project, + fileEntries, + docEntries, + }).catch(err => { + logger.error( + { err, templateVersionId }, + 'failed to create template clsi-cache' + ) + }) + } return project } finally { @@ -87,41 +113,15 @@ const TemplatesManager = { } }, - async _setCompiler(projectId, compiler) { - if (compiler == null) { - return - } - await ProjectOptionsHandler.setCompiler(projectId, compiler) - }, - - async _setImage(projectId, imageName) { - try { - await ProjectOptionsHandler.setImageName(projectId, imageName) - } catch { - logger.warn({ imageName: imageName }, 'not available') - await ProjectOptionsHandler.setImageName(projectId, settings.currentImageName) - } - }, - - async _setMainFile(projectId, mainFile) { + async _setMainFile(project, mainFile) { if (mainFile == null) { return } - await ProjectRootDocManager.setRootDocFromName(projectId, mainFile) - }, - - async _setSpellCheckLanguage(projectId, language) { - if (language == null) { - return - } - await ProjectOptionsHandler.setSpellCheckLanguage(projectId, language) - }, - - async _setBrandVariationId(projectId, brandVariationId) { - if (brandVariationId == null) { - return - } - await ProjectOptionsHandler.setBrandVariationId(projectId, brandVariationId) + const rootDocId = await ProjectRootDocManager.setRootDocFromName( + project._id, + mainFile + ) + if (rootDocId) project.rootDoc_id = rootDocId }, async fetchFromV1(templateId) { diff --git a/services/web/app/src/router.mjs b/services/web/app/src/router.mjs index e4aa8b9d79..264a56e281 100644 --- a/services/web/app/src/router.mjs +++ b/services/web/app/src/router.mjs @@ -309,6 +309,8 @@ async function initialize(webRouter, privateApiRouter, publicApiRouter) { TokenAccessRouter.apply(webRouter) HistoryRouter.apply(webRouter, privateApiRouter) + await Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter) + if (Settings.enableSubscriptions) { webRouter.get( '/user/bonus', diff --git a/services/web/app/views/template_gallery/template-gallery.pug b/services/web/app/views/template_gallery/template-gallery.pug deleted file mode 100644 index 3838d30606..0000000000 --- a/services/web/app/views/template_gallery/template-gallery.pug +++ /dev/null @@ -1,18 +0,0 @@ -extends ../layout-react - -block entrypointVar - - entrypoint = 'pages/template-gallery' - -block vars -block vars - - const suppressNavContentLinks = true - - const suppressNavbar = true - - const suppressFooter = true - - bootstrap5PageStatus = 'enabled' // One of 'disabled', 'enabled', and 'queryStringOnly' - - isWebsiteRedesign = false - -block append meta - meta(name="ol-templateCategory" data-type="string" content=category) - -block content - #template-gallery-root diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js index db64788b7f..01f2039731 100644 --- a/services/web/config/settings.defaults.js +++ b/services/web/config/settings.defaults.js @@ -1041,8 +1041,18 @@ module.exports = { importProjectFromGithubModalWrapper: [], importProjectFromGithubMenu: [], editorLeftMenuSync: [], - editorLeftMenuManageTemplate: ['@/features/editor-left-menu/components/actions-manage-template'], - menubarExtraComponents: [], + editorLeftMenuManageTemplate: [ + Path.resolve( + __dirname, + '../modules/template-gallery/frontend/js/features/template/components/actions-manage-template' + ), + ], + menubarExtraComponents: [ + Path.resolve( + __dirname, + '../modules/template-gallery/frontend/js/features/template/components/menubar-manage-template' + ), + ], oauth2Server: [], managedGroupSubscriptionEnrollmentNotification: [], managedGroupEnrollmentInvite: [], diff --git a/services/web/frontend/stylesheets/pages/templates-v2.scss b/services/web/frontend/stylesheets/pages/templates-v2.scss index 13fede40c9..2791812b0b 100644 --- a/services/web/frontend/stylesheets/pages/templates-v2.scss +++ b/services/web/frontend/stylesheets/pages/templates-v2.scss @@ -31,7 +31,6 @@ padding-top: 0px; padding-bottom: 0px; } - .gallery-header-sort-btn { font-size: var(--font-size-02); diff --git a/services/web/modules/template-gallery/app/src/TemplateGalleryController.mjs b/services/web/modules/template-gallery/app/src/TemplateGalleryController.mjs index 241c302daf..a5e01b9c58 100644 --- a/services/web/modules/template-gallery/app/src/TemplateGalleryController.mjs +++ b/services/web/modules/template-gallery/app/src/TemplateGalleryController.mjs @@ -1,12 +1,16 @@ +import Path from 'node:path' +import { fileURLToPath } from 'node:url' import logger from '@overleaf/logger' import ErrorController from '../../../../app/src/Features/Errors/ErrorController.mjs' import Errors from '../../../../app/src/Features/Errors/Errors.js' -import SessionManager from '../../../../app/src/Features/Authentication/SessionManager.js' +import SessionManager from '../../../../app/src/Features/Authentication/SessionManager.mjs' import TemplateGalleryManager from'./TemplateGalleryManager.mjs' import { getUserName } from './TemplateGalleryHelper.mjs' import { TemplateNameConflictError, RecompileRequiredError } from './TemplateErrors.mjs' import Settings from '@overleaf/settings' +const __dirname = Path.dirname(fileURLToPath(import.meta.url)) + async function createTemplateFromProject(req, res, next) { const t = req.i18n.translate try { @@ -108,7 +112,7 @@ async function templatesCategoryPage(req, res, next) { category = null title = t('templates_page_title') } - res.render('template_gallery/template-gallery', { + res.render(Path.resolve(__dirname, '../views/template_gallery/template-gallery'), { title, category, }) @@ -121,7 +125,7 @@ async function templateDetailsPage(req, res, next) { const t = req.i18n.translate try { const template = await TemplateGalleryManager.getTemplate('_id', req.params.template_id) - res.render('template_gallery/template', { + res.render(Path.resolve(__dirname, '../views/template_gallery/template'), { title: `${t('template')}: ${template.name}`, template: JSON.stringify(template), languages: Settings.languages, diff --git a/services/web/modules/template-gallery/app/src/TemplateGalleryHelper.mjs b/services/web/modules/template-gallery/app/src/TemplateGalleryHelper.mjs index cce1ef670e..ad3391cb2e 100644 --- a/services/web/modules/template-gallery/app/src/TemplateGalleryHelper.mjs +++ b/services/web/modules/template-gallery/app/src/TemplateGalleryHelper.mjs @@ -9,9 +9,9 @@ import ProjectZipStreamManager from '../../../../app/src/Features/Downloads/Proj import DocumentUpdaterHandler from '../../../../app/src/Features/DocumentUpdater/DocumentUpdaterHandler.mjs' import ClsiManager from '../../../../app/src/Features/Compile/ClsiManager.mjs' import CompileManager from '../../../../app/src/Features/Compile/CompileManager.mjs' -import UserGetter from '../../../../app/src/Features/User/UserGetter.js' +import UserGetter from '../../../../app/src/Features/User/UserGetter.mjs' import { fetchStreamWithResponse } from '@overleaf/fetch-utils' -import { Template } from './models/Template.js' +import { Template } from './models/Template.mjs' import { RecompileRequiredError } from './TemplateErrors.mjs' import { cleanHtml } from './CleanHtml.mjs' diff --git a/services/web/modules/template-gallery/app/src/TemplateGalleryManager.mjs b/services/web/modules/template-gallery/app/src/TemplateGalleryManager.mjs index f3993d6854..6325b841ec 100644 --- a/services/web/modules/template-gallery/app/src/TemplateGalleryManager.mjs +++ b/services/web/modules/template-gallery/app/src/TemplateGalleryManager.mjs @@ -3,7 +3,7 @@ import logger from '@overleaf/logger' import { Readable } from 'stream' import settings from '@overleaf/settings' import { OError } from '../../../../app/src/Features/Errors/Errors.js' -import { Template } from './models/Template.js' +import { Template } from './models/Template.mjs' import { validateTemplateInput, renderTemplateHtmlFields, diff --git a/services/web/modules/template-gallery/app/src/TemplateGalleryRouter.mjs b/services/web/modules/template-gallery/app/src/TemplateGalleryRouter.mjs index 422f075a68..de52e82ee1 100644 --- a/services/web/modules/template-gallery/app/src/TemplateGalleryRouter.mjs +++ b/services/web/modules/template-gallery/app/src/TemplateGalleryRouter.mjs @@ -2,7 +2,7 @@ import logger from '@overleaf/logger' import AuthenticationController from '../../../../app/src/Features/Authentication/AuthenticationController.mjs' import RateLimiterMiddleware from '../../../../app/src/Features/Security/RateLimiterMiddleware.mjs' -import { RateLimiter } from '../../../../app/src/infrastructure/RateLimiter.js' +import { RateLimiter } from '../../../../app/src/infrastructure/RateLimiter.mjs' import TemplateGalleryController from './TemplateGalleryController.mjs' const rateLimiterNewTemplate = new RateLimiter('create-template-from-project', { diff --git a/services/web/modules/template-gallery/app/src/models/Template.js b/services/web/modules/template-gallery/app/src/models/Template.mjs similarity index 77% rename from services/web/modules/template-gallery/app/src/models/Template.js rename to services/web/modules/template-gallery/app/src/models/Template.mjs index 79792f150e..8372b1944a 100644 --- a/services/web/modules/template-gallery/app/src/models/Template.js +++ b/services/web/modules/template-gallery/app/src/models/Template.mjs @@ -1,9 +1,9 @@ -const mongoose = require('../../../../../app/src/infrastructure/Mongoose') +import mongoose from '../../../../../app/src/infrastructure/Mongoose.mjs' const { Schema } = mongoose const { ObjectId } = Schema -const TemplateSchema = new Schema( +export const TemplateSchema = new Schema( { name: { type: String, required: true }, category: { type: String, required: true }, @@ -29,5 +29,4 @@ const TemplateSchema = new Schema( { minimize: false } ) -exports.Template = mongoose.model('Template', TemplateSchema) -exports.TemplateSchema = TemplateSchema +export const Template = mongoose.model('Template', TemplateSchema) diff --git a/services/web/modules/template-gallery/app/views/template_gallery/template-gallery.pug b/services/web/modules/template-gallery/app/views/template_gallery/template-gallery.pug new file mode 100644 index 0000000000..15b2ca0ae3 --- /dev/null +++ b/services/web/modules/template-gallery/app/views/template_gallery/template-gallery.pug @@ -0,0 +1,15 @@ +extends ../../../../../app/views/layout-react + +block entrypointVar + - entrypoint = 'modules/template-gallery/pages/template-gallery' + +block vars + - const suppressFooter = true + - const suppressPugCookieBanner = true + - isWebsiteRedesign = true + +block append meta + meta(name="ol-templateCategory" data-type="string" content=category) + +block content + #template-gallery-root diff --git a/services/web/app/views/template_gallery/template.pug b/services/web/modules/template-gallery/app/views/template_gallery/template.pug similarity index 61% rename from services/web/app/views/template_gallery/template.pug rename to services/web/modules/template-gallery/app/views/template_gallery/template.pug index e56fd8d2e5..81f3538492 100644 --- a/services/web/app/views/template_gallery/template.pug +++ b/services/web/modules/template-gallery/app/views/template_gallery/template.pug @@ -1,14 +1,12 @@ -extends ../layout-react +extends ../../../../../app/views/layout-react block entrypointVar - - entrypoint = 'pages/template' + - entrypoint = 'modules/template-gallery/pages/template' block vars - - const suppressNavContentLinks = true - const suppressNavbar = true - const suppressFooter = true - - bootstrap5PageStatus = 'enabled' // One of 'disabled', 'enabled', and 'queryStringOnly' - - isWebsiteRedesign = false + - isWebsiteRedesign = true block append meta meta(name="ol-template" data-type="json" content=template) diff --git a/services/web/frontend/js/features/template-gallery/components/gallery-header-all.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-header-all.tsx similarity index 100% rename from services/web/frontend/js/features/template-gallery/components/gallery-header-all.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-header-all.tsx diff --git a/services/web/frontend/js/features/template-gallery/components/gallery-header-tagged.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-header-tagged.tsx similarity index 100% rename from services/web/frontend/js/features/template-gallery/components/gallery-header-tagged.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-header-tagged.tsx diff --git a/services/web/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx similarity index 100% rename from services/web/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-popular-tags.tsx diff --git a/services/web/frontend/js/features/template-gallery/components/gallery-search-sort-header.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-search-sort-header.tsx similarity index 100% rename from services/web/frontend/js/features/template-gallery/components/gallery-search-sort-header.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/gallery-search-sort-header.tsx diff --git a/services/web/frontend/js/features/template-gallery/components/pagination.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/pagination.tsx similarity index 100% rename from services/web/frontend/js/features/template-gallery/components/pagination.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/pagination.tsx diff --git a/services/web/frontend/js/features/template-gallery/components/search-form.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/search-form.tsx similarity index 95% rename from services/web/frontend/js/features/template-gallery/components/search-form.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/search-form.tsx index f3f3f1ab11..ed287cf4c3 100644 --- a/services/web/frontend/js/features/template-gallery/components/search-form.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/search-form.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next' -import { MergeAndOverride } from '../../../../../types/utils' +import { MergeAndOverride } from '../../../../../../../types/utils' import OLForm from '@/shared/components/ol/ol-form' import OLFormControl from '@/shared/components/ol/ol-form-control' import MaterialIcon from '@/shared/components/material-icon' diff --git a/services/web/frontend/js/features/template-gallery/components/sort/with-content.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/sort/with-content.tsx similarity index 100% rename from services/web/frontend/js/features/template-gallery/components/sort/with-content.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/sort/with-content.tsx diff --git a/services/web/frontend/js/features/template-gallery/components/template-gallery-entry.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery-entry.tsx similarity index 91% rename from services/web/frontend/js/features/template-gallery/components/template-gallery-entry.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery-entry.tsx index 479b306b51..2a5964722a 100644 --- a/services/web/frontend/js/features/template-gallery/components/template-gallery-entry.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery-entry.tsx @@ -1,5 +1,5 @@ import { memo } from 'react' -import { cleanHtml } from '../../../../../modules/template-gallery/app/src/CleanHtml.mjs' +import { cleanHtml } from '../../../../../app/src/CleanHtml.mjs' function TemplateGalleryEntry({ template }) { return ( diff --git a/services/web/frontend/js/features/template-gallery/components/template-gallery-root.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery-root.tsx similarity index 93% rename from services/web/frontend/js/features/template-gallery/components/template-gallery-root.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery-root.tsx index dfb7cb9f2d..adf54e8d86 100644 --- a/services/web/frontend/js/features/template-gallery/components/template-gallery-root.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery-root.tsx @@ -1,7 +1,7 @@ import { TemplateGalleryProvider } from '../context/template-gallery-context' import { useTranslation } from 'react-i18next' -import useWaitForI18n from '../../../shared/hooks/use-wait-for-i18n' -import withErrorBoundary from '../../../infrastructure/error-boundary' +import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n' +import withErrorBoundary from '@/infrastructure/error-boundary' import { GenericErrorBoundaryFallback } from '@/shared/components/generic-error-boundary-fallback' import getMeta from '@/utils/meta' import DefaultNavbar from '@/shared/components/navbar/default-navbar' diff --git a/services/web/frontend/js/features/template-gallery/components/template-gallery.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery.tsx similarity index 100% rename from services/web/frontend/js/features/template-gallery/components/template-gallery.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/components/template-gallery.tsx diff --git a/services/web/frontend/js/features/template-gallery/context/template-gallery-context.tsx b/services/web/modules/template-gallery/frontend/js/features/template-gallery/context/template-gallery-context.tsx similarity index 97% rename from services/web/frontend/js/features/template-gallery/context/template-gallery-context.tsx rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/context/template-gallery-context.tsx index af67af534f..16e96b4cf5 100644 --- a/services/web/frontend/js/features/template-gallery/context/template-gallery-context.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/context/template-gallery-context.tsx @@ -9,8 +9,8 @@ import { } from 'react' import { Template } from '../../../../../types/template' import { GetTemplatesResponseBody, Sort } from '../types/api' -import getMeta from '../../../utils/meta' -import useAsync from '../../../shared/hooks/use-async' +import getMeta from '@/utils/meta' +import useAsync from '@/shared/hooks/use-async' import { getTemplates } from '../util/api' import sortTemplates from '../util/sort-templates' import { debugConsole } from '@/utils/debugging' diff --git a/services/web/frontend/js/features/template-gallery/hooks/use-sort.ts b/services/web/modules/template-gallery/frontend/js/features/template-gallery/hooks/use-sort.ts similarity index 88% rename from services/web/frontend/js/features/template-gallery/hooks/use-sort.ts rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/hooks/use-sort.ts index 675f052425..254398d156 100644 --- a/services/web/frontend/js/features/template-gallery/hooks/use-sort.ts +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/hooks/use-sort.ts @@ -1,6 +1,6 @@ import { useTemplateGalleryContext } from '../context/template-gallery-context' import { Sort } from '../types/api' -import { SortingOrder } from '../../../../../types/sorting-order' +import { SortingOrder } from '../../../../../../../types/sorting-order' const toggleSort = (order: SortingOrder): SortingOrder => { return order === 'asc' ? 'desc' : 'asc' diff --git a/services/web/frontend/js/features/template-gallery/types/api.ts b/services/web/modules/template-gallery/frontend/js/features/template-gallery/types/api.ts similarity index 75% rename from services/web/frontend/js/features/template-gallery/types/api.ts rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/types/api.ts index d2b19807a9..91ceb30bfc 100644 --- a/services/web/frontend/js/features/template-gallery/types/api.ts +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/types/api.ts @@ -1,4 +1,4 @@ -import { SortingOrder } from '../../../../../types/sorting-order' +import { SortingOrder } from '../../../../../../../types/sorting-order' import { Template } from '../../../../../types/template' export type Sort = { diff --git a/services/web/frontend/js/features/template-gallery/util/api.ts b/services/web/modules/template-gallery/frontend/js/features/template-gallery/util/api.ts similarity index 84% rename from services/web/frontend/js/features/template-gallery/util/api.ts rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/util/api.ts index 54704f187d..8e541479a0 100644 --- a/services/web/frontend/js/features/template-gallery/util/api.ts +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/util/api.ts @@ -1,5 +1,5 @@ import { GetTemplatesResponseBody, Sort } from '../types/api' -import { getJSON } from '../../../infrastructure/fetch-json' +import { getJSON } from '@/infrastructure/fetch-json' export function getTemplates(sortBy: Sort, category: string): Promise { const queryParams = new URLSearchParams({ diff --git a/services/web/frontend/js/features/template-gallery/util/sort-templates.ts b/services/web/modules/template-gallery/frontend/js/features/template-gallery/util/sort-templates.ts similarity index 87% rename from services/web/frontend/js/features/template-gallery/util/sort-templates.ts rename to services/web/modules/template-gallery/frontend/js/features/template-gallery/util/sort-templates.ts index 2315606514..1aec661fc5 100644 --- a/services/web/frontend/js/features/template-gallery/util/sort-templates.ts +++ b/services/web/modules/template-gallery/frontend/js/features/template-gallery/util/sort-templates.ts @@ -1,7 +1,7 @@ import { Sort } from '../types/api' import { Template } from '../../../../../types/template' -import { SortingOrder } from '../../../../../types/sorting-order' -import { Compare } from '../../../../../types/helpers/array/sort' +import { SortingOrder } from '../../../../../../../types/sorting-order' +import { Compare } from '../../../../../../../types/helpers/array/sort' const order = (order: SortingOrder, templates: Template[]) => { return order === 'asc' ? [...templates] : templates.reverse() diff --git a/services/web/frontend/js/features/editor-left-menu/components/actions-manage-template.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/actions-manage-template.tsx similarity index 82% rename from services/web/frontend/js/features/editor-left-menu/components/actions-manage-template.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/actions-manage-template.tsx index 0e28350877..2591dd7974 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/actions-manage-template.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template/components/actions-manage-template.tsx @@ -1,11 +1,11 @@ import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' -import * as eventTracking from '../../../infrastructure/event-tracking' -import getMeta from '../../../utils/meta' +import * as eventTracking from '@/infrastructure/event-tracking' +import getMeta from '@/utils/meta' import OLTooltip from '@/shared/components/ol/ol-tooltip' -import { useDetachCompileContext } from '../../../shared/context/detach-compile-context' -import EditorManageTemplateModalWrapper from '../../template/components/manage-template-modal/editor-manage-template-modal-wrapper' -import LeftMenuButton from './left-menu-button' +import { useDetachCompileContext } from '@/shared/context/detach-compile-context' +import EditorManageTemplateModalWrapper from './manage-template-modal/editor-manage-template-modal-wrapper' +import LeftMenuButton from '@/features/editor-left-menu/components/left-menu-button' type TemplateManageResponse = { template_id: string @@ -31,7 +31,7 @@ export default function ActionsManageTemplate() { ({ template_id: templateId }: TemplateManageResponse) => { location.assign(`/template/${templateId}`) }, - [location] + [] ) return ( diff --git a/services/web/frontend/js/features/template/components/delete-template-button.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/delete-template-button.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/delete-template-button.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/delete-template-button.tsx diff --git a/services/web/frontend/js/features/template/components/edit-template-button.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/edit-template-button.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/edit-template-button.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/edit-template-button.tsx diff --git a/services/web/frontend/js/features/template/components/form/form-field-input.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/form/form-field-input.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/form/form-field-input.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/form/form-field-input.tsx diff --git a/services/web/frontend/js/features/template/components/form/labeled-row-form-group.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/form/labeled-row-form-group.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/form/labeled-row-form-group.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/form/labeled-row-form-group.tsx diff --git a/services/web/frontend/js/features/template/components/form/template-form-fields.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/form/template-form-fields.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/form/template-form-fields.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/form/template-form-fields.tsx diff --git a/services/web/frontend/js/features/template/components/manage-template-modal/editor-manage-template-modal-wrapper.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/manage-template-modal/editor-manage-template-modal-wrapper.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/manage-template-modal/editor-manage-template-modal-wrapper.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/manage-template-modal/editor-manage-template-modal-wrapper.tsx diff --git a/services/web/frontend/js/features/template/components/manage-template-modal/manage-template-modal-content.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/manage-template-modal/manage-template-modal-content.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/manage-template-modal/manage-template-modal-content.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/manage-template-modal/manage-template-modal-content.tsx diff --git a/services/web/frontend/js/features/template/components/manage-template-modal/manage-template-modal.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/manage-template-modal/manage-template-modal.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/manage-template-modal/manage-template-modal.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/manage-template-modal/manage-template-modal.tsx diff --git a/services/web/modules/template-gallery/frontend/js/features/template/components/menubar-manage-template.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/menubar-manage-template.tsx new file mode 100644 index 0000000000..f6546812a7 --- /dev/null +++ b/services/web/modules/template-gallery/frontend/js/features/template/components/menubar-manage-template.tsx @@ -0,0 +1,52 @@ +import { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import getMeta from '@/utils/meta' +import { useDetachCompileContext as useCompileContext } from '@/shared/context/detach-compile-context' +import { useCommandProvider } from '@/features/ide-react/hooks/use-command-provider' +import EditorManageTemplateModalWrapper from './manage-template-modal/editor-manage-template-modal-wrapper' + +type TemplateManageResponse = { + template_id: string +} + +const MenubarManageTemplate = () => { + const { t } = useTranslation() + const { pdfUrl } = useCompileContext() + + const [showManageTemplateModal, setShowManageTemplateModal] = useState(false) + + const publishAsTemplateEnabled = + getMeta('ol-showTemplatesServerPro') && pdfUrl + + useCommandProvider( + () => [ + { + type: 'command', + id: 'manage-template', + label: t('publish_as_template'), + disabled: !publishAsTemplateEnabled, + handler: () => { + setShowManageTemplateModal(true) + }, + }, + ], + [t, publishAsTemplateEnabled] + ) + + const openTemplate = useCallback( + ({ template_id: templateId }: TemplateManageResponse) => { + location.assign(`/template/${templateId}`) + }, + [] + ) + + return ( + setShowManageTemplateModal(false)} + openTemplate={openTemplate} + /> + ) +} + +export default MenubarManageTemplate diff --git a/services/web/frontend/js/features/template/components/modals/delete-template-modal.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/modals/delete-template-modal.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/modals/delete-template-modal.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/modals/delete-template-modal.tsx diff --git a/services/web/frontend/js/features/template/components/modals/edit-template-modal.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/modals/edit-template-modal.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/modals/edit-template-modal.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/modals/edit-template-modal.tsx diff --git a/services/web/frontend/js/features/template/components/modals/template-action-modal.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/modals/template-action-modal.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/modals/template-action-modal.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/modals/template-action-modal.tsx diff --git a/services/web/frontend/js/features/template/components/settings/settings-language.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-language.tsx similarity index 95% rename from services/web/frontend/js/features/template/components/settings/settings-language.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-language.tsx index e9b7929617..82153bc08a 100644 --- a/services/web/frontend/js/features/template/components/settings/settings-language.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-language.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react' import { useTranslation } from 'react-i18next' -import getMeta from '../../../../utils/meta' +import getMeta from '@/utils/meta' import SettingsMenuSelect from './settings-menu-select' import type { Optgroup } from './settings-menu-select' diff --git a/services/web/frontend/js/features/template/components/settings/settings-license.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-license.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/settings/settings-license.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-license.tsx diff --git a/services/web/frontend/js/features/template/components/settings/settings-menu-select.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-menu-select.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/settings/settings-menu-select.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-menu-select.tsx diff --git a/services/web/frontend/js/features/template/components/settings/settings-template-category.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-template-category.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/settings/settings-template-category.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/settings/settings-template-category.tsx diff --git a/services/web/frontend/js/features/template/components/template-details.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/template-details.tsx similarity index 95% rename from services/web/frontend/js/features/template/components/template-details.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/template-details.tsx index 8c2bec5d40..ff2602137e 100644 --- a/services/web/frontend/js/features/template/components/template-details.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template/components/template-details.tsx @@ -3,8 +3,8 @@ import getMeta from '@/utils/meta' import OLCol from '@/shared/components/ol/ol-col' import OLRow from '@/shared/components/ol/ol-row' import OLTooltip from '@/shared/components/ol/ol-tooltip' -import { formatDate, fromNowDate } from '../../../utils/dates' -import { cleanHtml } from '../../../../../modules/template-gallery/app/src/CleanHtml.mjs' +import { formatDate, fromNowDate } from '@/utils/dates' +import { cleanHtml } from '../../../../../app/src/CleanHtml.mjs' import { useTemplateContext } from '../context/template-context' import DeleteTemplateButton from './delete-template-button' import EditTemplateButton from './edit-template-button' diff --git a/services/web/frontend/js/features/template/components/template-preview.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/template-preview.tsx similarity index 100% rename from services/web/frontend/js/features/template/components/template-preview.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/template-preview.tsx diff --git a/services/web/frontend/js/features/template/components/template-root.tsx b/services/web/modules/template-gallery/frontend/js/features/template/components/template-root.tsx similarity index 94% rename from services/web/frontend/js/features/template/components/template-root.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/components/template-root.tsx index c0961100cc..40e8800330 100644 --- a/services/web/frontend/js/features/template/components/template-root.tsx +++ b/services/web/modules/template-gallery/frontend/js/features/template/components/template-root.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next' -import useWaitForI18n from '../../../shared/hooks/use-wait-for-i18n' -import withErrorBoundary from '../../../infrastructure/error-boundary' +import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n' +import withErrorBoundary from '@/infrastructure/error-boundary' import { GenericErrorBoundaryFallback } from '@/shared/components/generic-error-boundary-fallback' import DefaultNavbar from '@/shared/components/navbar/default-navbar' import Footer from '@/shared/components/footer/footer' diff --git a/services/web/frontend/js/features/template/context/template-context.tsx b/services/web/modules/template-gallery/frontend/js/features/template/context/template-context.tsx similarity index 100% rename from services/web/frontend/js/features/template/context/template-context.tsx rename to services/web/modules/template-gallery/frontend/js/features/template/context/template-context.tsx diff --git a/services/web/frontend/js/features/template/hooks/use-focus-trap.ts b/services/web/modules/template-gallery/frontend/js/features/template/hooks/use-focus-trap.ts similarity index 100% rename from services/web/frontend/js/features/template/hooks/use-focus-trap.ts rename to services/web/modules/template-gallery/frontend/js/features/template/hooks/use-focus-trap.ts diff --git a/services/web/frontend/js/features/template/util/api.ts b/services/web/modules/template-gallery/frontend/js/features/template/util/api.ts similarity index 100% rename from services/web/frontend/js/features/template/util/api.ts rename to services/web/modules/template-gallery/frontend/js/features/template/util/api.ts diff --git a/services/web/frontend/js/pages/template-gallery.tsx b/services/web/modules/template-gallery/frontend/js/pages/template-gallery.tsx similarity index 55% rename from services/web/frontend/js/pages/template-gallery.tsx rename to services/web/modules/template-gallery/frontend/js/pages/template-gallery.tsx index 58a63be1ad..114ec01d06 100644 --- a/services/web/frontend/js/pages/template-gallery.tsx +++ b/services/web/modules/template-gallery/frontend/js/pages/template-gallery.tsx @@ -1,10 +1,3 @@ -import './../utils/meta' -import '../utils/webpack-public-path' -import './../infrastructure/error-reporter' -import '@/i18n' -import '../features/event-tracking' -import '../features/cookie-banner' -import '../features/link-helpers/slow-link' import ReactDOM from 'react-dom/client' import TemplateGalleryRoot from '../features/template-gallery/components/template-gallery-root' diff --git a/services/web/frontend/js/pages/template.tsx b/services/web/modules/template-gallery/frontend/js/pages/template.tsx similarity index 52% rename from services/web/frontend/js/pages/template.tsx rename to services/web/modules/template-gallery/frontend/js/pages/template.tsx index 02d29d04da..8fff6887c8 100644 --- a/services/web/frontend/js/pages/template.tsx +++ b/services/web/modules/template-gallery/frontend/js/pages/template.tsx @@ -1,10 +1,3 @@ -import './../utils/meta' -import '../utils/webpack-public-path' -import './../infrastructure/error-reporter' -import '@/i18n' -import '../features/event-tracking' -import '../features/cookie-banner' -import '../features/link-helpers/slow-link' import ReactDOM from 'react-dom/client' import TemplateRoot from '../features/template/components/template-root' diff --git a/services/web/types/template.ts b/services/web/modules/template-gallery/types/template.ts similarity index 100% rename from services/web/types/template.ts rename to services/web/modules/template-gallery/types/template.ts