mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-09 01:13:55 +00:00
feat: add user defined translations (#1756)
* feat: add user defined translations * add refetch key for translation (#1757) --------- Co-authored-by: Alex Christoffer Rasmussen <ac@omnivox.dk>
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import express from 'express';
|
||||
import type { Request, Response } from 'express';
|
||||
import type { ErrorResponse } from 'ontime-types';
|
||||
import { validatePostCss } from './assets.validation.js';
|
||||
import { readCssFile, writeCssFile } from './assets.service.js';
|
||||
import { RefetchKey, type ErrorResponse } from 'ontime-types';
|
||||
import { validatePostCss, validatePostTranslation } from './assets.validation.js';
|
||||
import { readCssFile, writeCssFile, writeUserTranslation } from './assets.service.js';
|
||||
import { getErrorMessage } from 'ontime-utils';
|
||||
import { defaultCss } from '../../user/styles/bundledCss.js';
|
||||
import { sendRefetch } from '../../adapters/WebsocketAdapter.js';
|
||||
|
||||
export const router = express.Router();
|
||||
|
||||
@@ -38,3 +39,21 @@ router.post('/css/restore', async (_req: Request, res: Response<string | ErrorRe
|
||||
res.status(500).send({ message });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/translations', validatePostTranslation, async (req: Request, res: Response<never | ErrorResponse>) => {
|
||||
const { translation } = req.body;
|
||||
|
||||
if (!translation) {
|
||||
res.status(400).send({ message: 'translation payload is required ' });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await writeUserTranslation(translation);
|
||||
sendRefetch(RefetchKey.Translation);
|
||||
res.status(204).send();
|
||||
} catch (error) {
|
||||
const message = getErrorMessage(error);
|
||||
res.status(500).send({ message });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { publicFiles } from '../../setup/index.js';
|
||||
import type { TranslationObject } from 'ontime-types';
|
||||
|
||||
import { existsSync } from 'node:fs';
|
||||
import { readFile, writeFile } from 'node:fs/promises';
|
||||
|
||||
import { publicFiles } from '../../setup/index.js';
|
||||
import { defaultCss } from '../../user/styles/bundledCss.js';
|
||||
|
||||
/**
|
||||
@@ -31,3 +34,13 @@ export async function writeCssFile(css: string) {
|
||||
|
||||
await writeFile(path, css, { encoding: 'utf8' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the user's custom translation file
|
||||
* @param translations the updated translations to write to file
|
||||
*/
|
||||
export async function writeUserTranslation(translations: TranslationObject) {
|
||||
const path = publicFiles.translationsFile;
|
||||
const translationsString = JSON.stringify(translations, null, 2);
|
||||
await writeFile(path, translationsString, { encoding: 'utf8' });
|
||||
}
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import { body } from 'express-validator';
|
||||
|
||||
import { requestValidationFunction } from '../validation-utils/validationFunction.js';
|
||||
|
||||
export const validatePostCss = [body('css').isString().trim(), requestValidationFunction];
|
||||
|
||||
export const validatePostTranslation = [
|
||||
body('translation')
|
||||
.custom((v) => v != null && typeof v === 'object' && !Array.isArray(v))
|
||||
.withMessage('translation must be an object (key -> string)')
|
||||
.bail(),
|
||||
body('translation.*').isString().trim().notEmpty(),
|
||||
requestValidationFunction,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user