diff --git a/public/docs.html b/public/docs.html index 5f896394..93765d9a 100644 --- a/public/docs.html +++ b/public/docs.html @@ -38,10 +38,6 @@ - - - - diff --git a/public/js/components/document-cards.js b/public/js/components/document-cards.js index 7983a219..ffb4eb6c 100644 --- a/public/js/components/document-cards.js +++ b/public/js/components/document-cards.js @@ -41,6 +41,14 @@ class DocumentCards { practical: 'Guides pratiques', technical: 'Détails techniques', reference: 'Documentation de référence' + }, + mi: { + title: 'Aratohu Tae', + critical: 'Ngā wāhanga waipuke', + conceptual: 'Ngā whakamāramatanga ariā', + practical: 'Ngā aratohu whaihua', + technical: 'Ngā taipitopito hangarau', + reference: 'Ngā tuhinga tohutoro' } }; diff --git a/public/js/docs-app.js b/public/js/docs-app.js index f9a104fc..b33fc5f1 100644 --- a/public/js/docs-app.js +++ b/public/js/docs-app.js @@ -82,6 +82,32 @@ const UI_TRANSLATIONS = { 'advanced-topics': 'Sujets avancés', 'business-leadership': 'Business & Leadership' } + }, + mi: { + pageTitle: 'Ngā Tuhinga Anga', + pageSubtitle: 'Ngā tautukunga hangarau, ngā aratohu, me ngā rauemi tohutoro', + documentsHeading: 'Ngā Tuhinga', + searchButton: 'Rapu', + backToDocuments: 'Hoki ki ngā Tuhinga', + selectDocument: 'Kōwhiria he Tuhinga', + selectDocumentDesc: 'Kōwhiria he tuhinga mai i te taha ki te tīmata pānui', + loadingDocument: 'Kei te uta te tuhinga...', + errorLoadingDoc: 'He hapa i te utanga o te tuhinga', + tableOfContents: 'Rārangi Kaupapa', + downloadPdf: 'Tikiake PDF', + github: 'GitHub', + publicRepository: 'Pūtahi Tūmatanui', + publicRepositoryDesc: 'Waehere pūtake, tauira me ngā koha', + readmeQuickStart: 'README & Tīmata Tere', + readmeQuickStartDesc: 'Aratohu whakauru me te tīmata', + categories: { + 'getting-started': 'Tīmata', + 'resources': 'Ngā Rauemi', + 'research-theory': 'Rangahau & Ariā', + 'technical-reference': 'Tohutoro Hangarau', + 'advanced-topics': 'Kaupapa Matatau', + 'business-leadership': 'Pakihi & Hautūtanga' + } } }; @@ -95,17 +121,15 @@ function updatePageUI(lang = currentLanguage) { const t = getUITranslations(lang); // Update page header + const allPageTitles = Object.values(UI_TRANSLATIONS).map(t => t.pageTitle); const pageTitle = document.querySelector('h1'); - if (pageTitle && pageTitle.textContent === UI_TRANSLATIONS.en.pageTitle || - pageTitle.textContent === UI_TRANSLATIONS.de.pageTitle || - pageTitle.textContent === UI_TRANSLATIONS.fr.pageTitle) { + if (pageTitle && allPageTitles.includes(pageTitle.textContent)) { pageTitle.textContent = t.pageTitle; } + const allPageSubtitles = Object.values(UI_TRANSLATIONS).map(t => t.pageSubtitle); const pageSubtitle = document.querySelector('.text-gray-600.mt-2'); - if (pageSubtitle && (pageSubtitle.textContent === UI_TRANSLATIONS.en.pageSubtitle || - pageSubtitle.textContent === UI_TRANSLATIONS.de.pageSubtitle || - pageSubtitle.textContent === UI_TRANSLATIONS.fr.pageSubtitle)) { + if (pageSubtitle && allPageSubtitles.includes(pageSubtitle.textContent)) { pageSubtitle.textContent = t.pageSubtitle; } @@ -116,20 +140,17 @@ function updatePageUI(lang = currentLanguage) { } // Update sidebar Documents heading + const allDocsHeadings = Object.values(UI_TRANSLATIONS).map(t => t.documentsHeading); const docsHeading = document.querySelector('aside h3'); - if (docsHeading && (docsHeading.textContent === UI_TRANSLATIONS.en.documentsHeading || - docsHeading.textContent === UI_TRANSLATIONS.de.documentsHeading || - docsHeading.textContent === UI_TRANSLATIONS.fr.documentsHeading)) { + if (docsHeading && allDocsHeadings.includes(docsHeading.textContent)) { docsHeading.textContent = t.documentsHeading; } // Update GitHub section heading + const allGithubLabels = Object.values(UI_TRANSLATIONS).map(t => t.github); const githubHeadings = document.querySelectorAll('aside h3'); githubHeadings.forEach(heading => { - if (heading.textContent.trim() === UI_TRANSLATIONS.en.github || - heading.textContent.trim() === UI_TRANSLATIONS.de.github || - heading.textContent.trim() === UI_TRANSLATIONS.fr.github) { - // Keep the SVG icon, just update text + if (allGithubLabels.includes(heading.textContent.trim())) { const textNode = Array.from(heading.childNodes).find(node => node.nodeType === Node.TEXT_NODE); if (textNode) { textNode.textContent = t.github; @@ -138,31 +159,28 @@ function updatePageUI(lang = currentLanguage) { }); // Update GitHub links + const allRepoTitles = Object.values(UI_TRANSLATIONS).map(t => t.publicRepository); + const allReadmeTitles = Object.values(UI_TRANSLATIONS).map(t => t.readmeQuickStart); + const allRepoDescs = Object.values(UI_TRANSLATIONS).map(t => t.publicRepositoryDesc); + const allReadmeDescs = Object.values(UI_TRANSLATIONS).map(t => t.readmeQuickStartDesc); + const githubLinks = document.querySelectorAll('aside a[href*="github.com"]'); githubLinks.forEach(link => { const titleDiv = link.querySelector('.text-sm.font-medium'); const descDiv = link.querySelector('.text-xs.text-gray-500'); if (titleDiv) { - if (titleDiv.textContent === UI_TRANSLATIONS.en.publicRepository || - titleDiv.textContent === UI_TRANSLATIONS.de.publicRepository || - titleDiv.textContent === UI_TRANSLATIONS.fr.publicRepository) { + if (allRepoTitles.includes(titleDiv.textContent)) { titleDiv.textContent = t.publicRepository; - } else if (titleDiv.textContent === UI_TRANSLATIONS.en.readmeQuickStart || - titleDiv.textContent === UI_TRANSLATIONS.de.readmeQuickStart || - titleDiv.textContent === UI_TRANSLATIONS.fr.readmeQuickStart) { + } else if (allReadmeTitles.includes(titleDiv.textContent)) { titleDiv.textContent = t.readmeQuickStart; } } if (descDiv) { - if (descDiv.textContent === UI_TRANSLATIONS.en.publicRepositoryDesc || - descDiv.textContent === UI_TRANSLATIONS.de.publicRepositoryDesc || - descDiv.textContent === UI_TRANSLATIONS.fr.publicRepositoryDesc) { + if (allRepoDescs.includes(descDiv.textContent)) { descDiv.textContent = t.publicRepositoryDesc; - } else if (descDiv.textContent === UI_TRANSLATIONS.en.readmeQuickStartDesc || - descDiv.textContent === UI_TRANSLATIONS.de.readmeQuickStartDesc || - descDiv.textContent === UI_TRANSLATIONS.fr.readmeQuickStartDesc) { + } else if (allReadmeDescs.includes(descDiv.textContent)) { descDiv.textContent = t.readmeQuickStartDesc; } } diff --git a/src/controllers/documents.controller.js b/src/controllers/documents.controller.js index 92e7d635..f9889f42 100644 --- a/src/controllers/documents.controller.js +++ b/src/controllers/documents.controller.js @@ -30,6 +30,9 @@ async function listDocuments(req, res) { filter.audience = audience; } + // Use summary projection for list endpoint (returns ~7KB instead of ~7MB) + const summary = req.query.fields !== 'full'; + if (quadrant && !audience) { documents = await Document.findByQuadrant(quadrant, { limit: parseInt(limit), @@ -48,7 +51,8 @@ async function listDocuments(req, res) { documents = await Document.list({ limit: parseInt(limit), skip: parseInt(skip), - filter + filter, + summary }); total = await Document.count(filter); } diff --git a/src/models/Document.model.js b/src/models/Document.model.js index e1a39fcf..1193cf83 100644 --- a/src/models/Document.model.js +++ b/src/models/Document.model.js @@ -223,8 +223,8 @@ class Document { // Validate category is in allowed list const validCategories = [ - 'getting-started', 'technical-reference', 'research-theory', - 'advanced-topics', 'case-studies', 'business-leadership', 'archives' + 'getting-started', 'resources', 'research-theory', 'technical-reference', + 'advanced-topics', 'business-leadership', 'archives' ]; if (!validCategories.includes(category)) { return { @@ -310,13 +310,36 @@ class Document { /** * List all documents + * @param {object} options + * @param {boolean} options.summary - If true, return only summary fields (for sidebar/listing) */ static async list(options = {}) { const collection = await getCollection('documents'); - const { limit = 50, skip = 0, sort = { order: 1, 'metadata.date_created': -1 }, filter = {} } = options; + const { limit = 50, skip = 0, sort = { order: 1, 'metadata.date_created': -1 }, filter = {}, summary = false } = options; - return await collection - .find(filter) + const query = collection.find(filter); + + if (summary) { + query.project({ + title: 1, + slug: 1, + category: 1, + order: 1, + visibility: 1, + quadrant: 1, + persistence: 1, + audience: 1, + download_formats: 1, + 'metadata.date_created': 1, + 'metadata.date_updated': 1, + 'metadata.version': 1, + 'translations.de.title': 1, + 'translations.fr.title': 1, + 'translations.mi.title': 1 + }); + } + + return await query .sort(sort) .skip(skip) .limit(limit)