Commit 5f631379 by jhrabal

gui

parent 58b208b0
const fs = require('fs');
const path = require("path");
const jsonApi = require('really-relaxed-json');
const minimist = require('minimist');
const tag = new Date().getTime();
const MESSAGE_CATALOG_PATH = '../frontend/message_catalog.json';
const LANGS = ["cs"];
const INPUT_DIR = '../frontend/app/';
const OUTPUT_DIR = '../frontend/app/';
const TRANSLATIONS_DIR = '../frontend/app/translations/';
const DEFAULT_LANG = "en";
//const OUTPUT_DIR = './output/';
//const TRANSLATIONS_DIR = './output/translations/';
function emptyDelta() {
return {
changed: {},
translated: {}
};
}
function walkSync(dir, filelist) {
var
files = fs.readdirSync(dir);
filelist = filelist || [];
files.forEach(function(file) {
if (fs.statSync(dir + file).isDirectory()) {
filelist = walkSync(dir + file + '/', filelist);
} else if ("messages.js" == file) {
filelist.push(dir + file);
}
});
return filelist;
};
function readFile(file) {
let str = fs.readFileSync(file, 'utf8');
var regex = /^\s*export\s*default\s*/;
str = str.replace(regex, "");
regex = /\}\s*;\s*$/;
str = str.replace(regex, "}");
str = str.trim();
let data = str ? JSON.parse(jsonApi.toJson(str)) : null;
if (!data) {
return null;
}
return data;
}
function deltaFileName(file, lang) {
let
dirname = path.dirname(file),
basename = path.basename(file, ".js"),
filename = dirname + "/" + basename + "-" + lang + ".json";
return OUTPUT_DIR + filename;
}
function readDelta(deltaFilename) {
if (!fs.existsSync(deltaFilename)) {
return emptyDelta();
}
let str = fs.readFileSync(deltaFilename, 'utf8');
if (!str) {
return emptyDelta();
}
try {
let delta = JSON.parse(jsonApi.toJson(str));
return delta || emptyDelta();
} catch (e) {
console.log("Could not parse '" + deltaFilename + "'");
return emptyDelta();
}
}
function writeDelta(deltaFilename, data) {
try {
fs.mkdirSync(path.dirname(deltaFilename), { recursive: true });
} catch (e) {
//TODO
}
fs.writeFileSync(deltaFilename, JSON.stringify(data, null, 4));
}
function checkMetadata() {
return !fs.existsSync(MESSAGE_CATALOG_PATH);
}
function readMetadata() {
if (checkMetadata()) {
return {};
}
let str = fs.readFileSync(MESSAGE_CATALOG_PATH, 'utf8');
if (!str) {
return {};
}
return JSON.parse(jsonApi.toJson(str));
}
function writeMetadata(metadata) {
fs.writeFileSync(MESSAGE_CATALOG_PATH, JSON.stringify(metadata, null, 4));
}
function writeTranslationFile(list, lang) {
try {
fs.mkdirSync(TRANSLATIONS_DIR, { recursive: true });
} catch (e) {
//TODO
}
fs.writeFileSync(TRANSLATIONS_DIR + lang + ".js", "module.exports = " + JSON.stringify(list, null, 4));
}
function constructMetadata(files) {
let shouldWrite = checkMetadata();
let metadata = readMetadata(MESSAGE_CATALOG_PATH);
let result = {};
files.forEach((file) => {
let data = readFile(file);
if (!data) {
return;
}
for (let key in data) {
let message = data[key];
let item = {
id: message.id,
defaultMessage: message.defaultMessage,
langs: {},
//version: tag,
source: {
key,
file: path.relative(INPUT_DIR, file).replace(/\\/g, '/'),
}
};
let m = metadata[item.id];
if (m) {
if (m.defaultMessage == item.defaultMessage) {
result[item.id] = m;
} else {
result[item.id] = { ...item, langs: m.langs };
}
} else {
result[item.id] = item;
}
}
});
//if (shouldWrite) {
writeMetadata(result);
//}
return result;
}
function pullDelta() {
let metadata = constructMetadata(walkSync(INPUT_DIR));
//writeMetadata(metadata);
let files = {};
for (let key in metadata) {
let item = metadata[key];
let fname = item.source.file;
let file = files[fname];
if (!file) {
file = {};
files[fname] = file;
}
file[item.source.key] = {
id: item.id,
defaultMessage: item.defaultMessage,
//version: item.version
};
}
for (let lang of LANGS) {
for (let filename in files) {
let
deltaFilename = deltaFileName(filename, lang),
deltaFile = readDelta(deltaFilename),
delta = emptyDelta(),
file = files[filename];
for (let key in file) {
let item = file[key];
let m = metadata[item.id];
let l = m.langs[lang];
if (l) {
let df = deltaFile.translated[key];
if (df && (df.defaultMessage == m.defaultMessage || !df.defaultMessage)) {
delta.translated[key] = df;
} else {
delta.changed[key] = {
id: item.id,
message: l || item.defaultMessage,
defaultMessage: item.defaultMessage,
//version: tag
}
}
} else {
//not in metadata, check whether it is already translated...?
l = deltaFile.translated[key];
if (l) {
delta.translated[key] = l;
} else {
delta.changed[key] = {
id: item.id,
message: item.defaultMessage,
defaultMessage: item.defaultMessage,
//version: m.version
}
}
}
//deltaFile[key] = file[key];
}
writeDelta(deltaFilename, delta);
}
}
}
function pushDelta() {
let metadata = readMetadata(MESSAGE_CATALOG_PATH);
//construct paths
let paths = {};
for (let mk in metadata) {
let m = metadata[mk];
if (m.source && m.source.file) {
paths[m.source.file] = true;
}
}
//read delta files as well
let files = walkSync(INPUT_DIR);
files = files.map(file => path.relative(INPUT_DIR, file).replace(/\\/g, '/'));
files.forEach(file => paths[file] = true);
let outputLangs = {};
for (let lang of LANGS) {
outputLangs[lang] = [];
let ids = {};
for (let p in paths) {
let dfp = deltaFileName(p, lang);
let delta = readDelta(dfp);
for (let key in delta.translated) {
let l = delta.translated[key];
let m = metadata[l.id];
if (!m) {
m = {
id: l.id,
defaultMessage: l.defaultMessage,
langs: {},
//version: tag,
source: {
key,
file: p,
}
};
metadata[l.id] = m;
}
delete m.version;
ids[l.id] = true;
m.langs[lang] = l.message;
outputLangs[lang].push({
id: l.id,
defaultMessage: l.message
});
}
}
for (let id in metadata) {
let m = metadata[id];
if (m.langs[lang] && !ids[id]) {
outputLangs[lang].push({
id: id,
defaultMessage: m.langs[lang]
});
}
}
}
//write translations
for (let lang of LANGS) {
writeTranslationFile(outputLangs[lang], lang);
}
outputLangs[DEFAULT_LANG] = [];
for (let key in metadata) {
let m = metadata[key];
outputLangs[DEFAULT_LANG].push({
id: m.id,
defaultMessage: m.defaultMessage
});
}
writeTranslationFile(outputLangs[DEFAULT_LANG], DEFAULT_LANG);
writeMetadata(metadata);
}
let args = minimist(process.argv.slice(2));
if (!args._.length) {
process.exit(0);
}
let action = args._[0];
if (action == "pull") {
pullDelta();
} else if (action == "push") {
pushDelta();
}
{
"name": "frontend-tools",
"version": "0.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"really-relaxed-json": {
"version": "0.2.24",
"resolved": "https://registry.npmjs.org/really-relaxed-json/-/really-relaxed-json-0.2.24.tgz",
"integrity": "sha512-YaY9fR3c+wKOJFSv5dXsPQGtp7zvuOKlmdzUvQvNI/+Hk1/S0eiH+/Pwj9eMRpxlC59lt/szUAG3BLoJaz8JnQ=="
}
}
}
{
"name": "frontend-tools",
"version": "0.0.1",
"author": "",
"scripts": {
"start": "node ./app.js",
"translate": "gtranslate cs en,de,nl,fr,es,fi,sk,pl app/translations"
},
"keywords": [],
"license": "ISC",
"dependencies": {
"minimist": "^1.2.0",
"really-relaxed-json": "^0.2.24"
}
}
{
"changed": {
},
"translated": {
"emptyListMain": {
"id": "components.FetchedContent.emptyListMain",
"message": "Prázdný seznam",
"defaultMessage": "This list is empty"
},
"emptyListSecondary": {
"id": "components.FetchedContent.emptyListSecondary",
"message": "Nemáme zde co zobrazit. Chcete přidat nějaké položky?",
"defaultMessage": "We have nothing to display here. Do you want to add some items?"
},
"errorMain": {
"id": "components.FetchedContent.errorMain",
"message": "Něco se pokazilo",
"defaultMessage": "Something went wrong"
},
"errorSecondary": {
"id": "components.FetchedContent.errorSecondary",
"message": "Nemůžeme získat data",
"defaultMessage": "We were unable to fetch the data"
},
"errorTryAgainButton": {
"id": "components.FetchedContent.errorTryAgainButton",
"message": "Zkusit znova",
"defaultMessage": "Try again"
}
}
}
\ No newline at end of file
{
"changed": {
},
"translated": {
"title": {
"id": "components.RatingBarChart.title",
"message": "Hodnocení {rating}",
"defaultMessage": "Rating {rating}"
},
"value": {
"id": "components.RatingBarChart.value",
"message": "Počet: {count}",
"defaultMessage": "Count: {count}"
}
}
}
\ No newline at end of file
{
"changed": {
},
"translated": {
"rating": {
"id": "components.StatusChart.rating",
"message": "Hodnocení {rating}",
"defaultMessage": "Rating {rating}"
}
}
}
\ No newline at end of file
{
"changed": {
},
"translated": {
"emailSent": {
"id": "component.Toast.emailSent",
"message": "Email byl odeslán",
"defaultMessage": "Email was sent"
},
"validationErrors": {
"id": "component.Toast.validationErrors",
"message": "Formulář obsahuje chyby",
"defaultMessage": "Validation failed"
}
}
}
\ No newline at end of file
{
"changed": {
},
"translated": {
"homeMenu": {
"id": "containers.App.homeMenu",
"message": "Přehled",
"defaultMessage": "Overview"
},
"logoutMenu": {
"id": "containers.App.logoutMenu",
"message": "Odhlásit",
"defaultMessage": "Logout"
}
}
}
\ No newline at end of file
{
"changed": {
},
"translated": {
"pageTitle": {
"id": "containers.Home.pageTitle",
"message": "Přehled",
"defaultMessage": "Overview"
},
"ratingsCount": {
"id": "containers.Home.ratingsCount",
"message": "Počet hodnocení",
"defaultMessage": "Ratings"
},
"averageRating": {
"id": "containers.Home.averageRating",
"message": "Průměrné hodnocení",
"defaultMessage": "Average rating"
},
"refreshButton": {
"id": "containers.Home.refreshButton",
"message": "Obnovit",
"defaultMessage": "Refresh"
}
}
}
\ No newline at end of file
......@@ -18,7 +18,7 @@ let initialState = {
status: 'pending',
fresh: true,
paging: {
pageSize: 15
pageSize: 20
},
data: []
},
......
......@@ -53,7 +53,7 @@ $menu-box-shadow: 0px 0px 4px 4px rgba(0,0,0,0.45);
width:100%;
height: $top-menu-bar-height;
color: $menu-color;
background-color:$menu-background-color;
background-color:$theme-main-color;
list-style-type: none;
overflow-y:hidden;
}
......
{
"changed": {
"buttonCancel": {
"id": "common.button.cancel",
"message": "Storno",
"defaultMessage": "Cancel"
},
"buttonSave": {
"id": "common.button.save",
"message": "Uložit",
"defaultMessage": "Save"
},
"buttonYes": {
"id": "common.button.yes",
"message": "Ano",
"defaultMessage": "Yes"
},
"buttonNo": {
"id": "common.button.no",
"message": "Ne",
"defaultMessage": "No"
},
"buttonBack": {
"id": "common.button.back",
"message": "Zpět",
"defaultMessage": "Back"
},
"buttonDelete": {
"id": "common.button.delete",
"message": "Smazat",
"defaultMessage": "Delete"
},
"buttonSend": {
"id": "common.button.send",
"message": "Odeslat",
"defaultMessage": "Send"
},
"buttonClose": {
"id": "common.button.close",
"message": "Zavřít",
"defaultMessage": "Close"
},
"buttonRefresh": {
"id": "common.button.refresh",
"message": "Obnovit",
"defaultMessage": "Refresh"
},
"buttonSubmit": {
"id": "common.button.submit",
"message": "Odeslat",
"defaultMessage": "Submit"
},
"buttonNext": {
"id": "common.button.next",
"message": "Další",
"defaultMessage": "Next"
},
"buttonPrevious": {
"id": "common.button.previous",
"message": "Předchozí",
"defaultMessage": "Previous"
},
"buttonFinish": {
"id": "common.button.finish",
"message": "Dokončit",
"defaultMessage": "Finish"
},
"yes": {
"id": "common.yes",
"message": "Ano",
"defaultMessage": "Yes"
},
"no": {
"id": "common.no",
"message": "Ne",
"defaultMessage": "No"
},
"validationFieldRequired": {
"id": "common.validation.requiredField",
"message": "Pole je povinné",
"defaultMessage": "Field is required"
},
"validationFieldDecimal": {
"id": "common.validation.decimalField",
"message": "Je požadováno číslo",
"defaultMessage": "Decimal field"
},
"validationInvalidEmail": {
"id": "common.validation.invalidEmail",
"message": "Neplatný email",
"defaultMessage": "Invalid email"
},
"notificationSaved": {
"id": "common.notification.saved",
"message": "Uloženo",
"defaultMessage": "Saved"
},
"notificationDeleted": {
"id": "common.notification.deleted",
"message": "Smazáno",
"defaultMessage": "Deleted"
},
"notificationError": {
"id": "common.notification.error",
"message": "Chyba",
"defaultMessage": "Error"
},
"homeMenu": {
"id": "home.menu",
"message": "Přehled",
"defaultMessage": "Overview"
},
"logoutMenu": {
"id": "layout.logoutAction",
"message": "Odhlásit",
"defaultMessage": "Logout"
}
},
"translated": {}
}
\ No newline at end of file
module.exports = [
{
"id": "components.FetchedContent.emptyListMain",
"defaultMessage": "Prázdný seznam"
},
{
"id": "components.FetchedContent.emptyListSecondary",
"defaultMessage": "Nemáme zde co zobrazit. Chcete přidat nějaké položky?"
},
{
"id": "components.FetchedContent.errorMain",
"defaultMessage": "Něco se pokazilo"
},
{
"id": "components.FetchedContent.errorSecondary",
"defaultMessage": "Nemůžeme získat data"
},
{
"id": "components.FetchedContent.errorTryAgainButton",
"defaultMessage": "Zkusit znova"
},
{
"id": "components.RatingBarChart.title",
"defaultMessage": "Hodnocení {rating}"
},
{
"id": "components.RatingBarChart.value",
"defaultMessage": "Počet: {count}"
},
{
"id": "components.StatusChart.rating",
"defaultMessage": "Hodnocení {rating}"
},
{
"id": "component.Toast.emailSent",
"defaultMessage": "Email byl odeslán"
},
{
"id": "component.Toast.validationErrors",
"defaultMessage": "Formulář obsahuje chyby"
},
{
"id": "containers.App.homeMenu",
"defaultMessage": "Přehled"
},
{
"id": "containers.App.logoutMenu",
"defaultMessage": "Odhlásit"
},
{
"id": "containers.Home.pageTitle",
"defaultMessage": "Přehled"
},
{
"id": "containers.Home.ratingsCount",
"defaultMessage": "Počet hodnocení"
},
{
"id": "containers.Home.averageRating",
"defaultMessage": "Průměrné hodnocení"
},
{
"id": "containers.Home.refreshButton",
"defaultMessage": "Obnovit"
},
{
"id": "common.button.cancel",
"defaultMessage": "Storno"
},
{
"id": "common.button.save",
"defaultMessage": "Uložit"
},
{
"id": "common.button.yes",
"defaultMessage": "Ano"
},
{
"id": "common.button.no",
"defaultMessage": "Ne"
},
{
"id": "common.button.back",
"defaultMessage": "Zpět"
},
{
"id": "common.button.delete",
"defaultMessage": "Smazat"
},
{
"id": "common.button.send",
"defaultMessage": "Odeslat"
},
{
"id": "common.button.close",
"defaultMessage": "Zavřít"
},
{
"id": "common.button.refresh",
"defaultMessage": "Obnovit"
},
{
"id": "common.button.submit",
"defaultMessage": "Odeslat"
},
{
"id": "common.button.next",
"defaultMessage": "Další"
},
{
"id": "common.button.previous",
"defaultMessage": "Předchozí"
},
{
"id": "common.button.finish",
"defaultMessage": "Dokončit"
},
{
"id": "common.yes",
"defaultMessage": "Ano"
},
{
"id": "common.no",
"defaultMessage": "Ne"
},
{
"id": "common.validation.requiredField",
"defaultMessage": "Pole je povinné"
},
{
"id": "common.validation.decimalField",
"defaultMessage": "Je požadováno číslo"
},
{
"id": "common.validation.invalidEmail",
"defaultMessage": "Neplatný email"
},
{
"id": "common.notification.saved",
"defaultMessage": "Uloženo"
},
{
"id": "common.notification.deleted",
"defaultMessage": "Smazáno"
},
{
"id": "common.notification.error",
"defaultMessage": "Chyba"
},
{
"id": "home.menu",
"defaultMessage": "Přehled"
},
{
"id": "layout.logoutAction",
"defaultMessage": "Odhlásit"
}
]
\ No newline at end of file
module.exports = [
{
"id": "components.FetchedContent.emptyListMain",
"defaultMessage": "This list is empty"
},
{
"id": "components.FetchedContent.emptyListSecondary",
"defaultMessage": "We have nothing to display here. Do you want to add some items?"
},
{
"id": "components.FetchedContent.errorMain",
"defaultMessage": "Something went wrong"
},
{
"id": "components.FetchedContent.errorSecondary",
"defaultMessage": "We were unable to fetch the data"
},
{
"id": "components.FetchedContent.errorTryAgainButton",
"defaultMessage": "Try again"
},
{
"id": "components.RatingBarChart.title",
"defaultMessage": "Rating {rating}"
},
{
"id": "components.RatingBarChart.value",
"defaultMessage": "Count: {count}"
},
{
"id": "components.StatusChart.rating",
"defaultMessage": "Rating {rating}"
},
{
"id": "component.Toast.emailSent",
"defaultMessage": "Email was sent"
},
{
"id": "component.Toast.validationErrors",
"defaultMessage": "Validation failed"
},
{
"id": "containers.App.homeMenu",
"defaultMessage": "Overview"
},
{
"id": "containers.App.logoutMenu",
"defaultMessage": "Logout"
},
{
"id": "containers.Home.pageTitle",
"defaultMessage": "Overview"
},
{
"id": "containers.Home.ratingsCount",
"defaultMessage": "Ratings"
},
{
"id": "containers.Home.averageRating",
"defaultMessage": "Average rating"
},
{
"id": "containers.Home.refreshButton",
"defaultMessage": "Refresh"
},
{
"id": "attachments.title",
"defaultMessage": "Attachments"
},
{
"id": "attachments.hint",
"defaultMessage": "Drop files here to attach them"
},
{
"id": "attachments.hint2",
"defaultMessage": "or click here to browse files"
},
{
"id": "attachments.delete",
"defaultMessage": "Delete attachment"
},
{
"id": "attachments.edit",
"defaultMessage": "Edit"
},
{
"id": "attachments.download",
"defaultMessage": "Download file"
},
{
"id": "notifications.title",
"defaultMessage": "Notifications"
},
{
"id": "notifications.enableButton",
"defaultMessage": "Enable"
},
{
"id": "notifications.disableButton",
"defaultMessage": "Disable"
},
{
"id": "notifications.googleTitle",
"defaultMessage": "Google calendar"
},
{
"id": "notifications.googleDescription",
"defaultMessage": "Lorem ipsum dolor sit elit"
},
{
"id": "tags.title",
"defaultMessage": "Tags"
},
{
"id": "common.button.cancel",
"defaultMessage": "Cancel"
},
{
"id": "common.button.save",
"defaultMessage": "Save"
},
{
"id": "common.button.yes",
"defaultMessage": "Yes"
},
{
"id": "common.button.no",
"defaultMessage": "No"
},
{
"id": "common.button.back",
"defaultMessage": "Back"
},
{
"id": "common.button.delete",
"defaultMessage": "Delete"
},
{
"id": "common.button.send",
"defaultMessage": "Send"
},
{
"id": "common.button.close",
"defaultMessage": "Close"
},
{
"id": "common.button.refresh",
"defaultMessage": "Refresh"
},
{
"id": "common.button.submit",
"defaultMessage": "Submit"
},
{
"id": "common.button.next",
"defaultMessage": "Next"
},
{
"id": "common.button.previous",
"defaultMessage": "Previous"
},
{
"id": "common.button.finish",
"defaultMessage": "Finish"
},
{
"id": "common.yes",
"defaultMessage": "Yes"
},
{
"id": "common.no",
"defaultMessage": "No"
},
{
"id": "common.validation.requiredField",
"defaultMessage": "Field is required"
},
{
"id": "common.validation.decimalField",
"defaultMessage": "Decimal field"
},
{
"id": "common.validation.invalidEmail",
"defaultMessage": "Invalid email"
},
{
"id": "common.notification.saved",
"defaultMessage": "Saved"
},
{
"id": "common.notification.deleted",
"defaultMessage": "Deleted"
},
{
"id": "common.notification.error",
"defaultMessage": "Error"
},
{
"id": "home.menu",
"defaultMessage": "Overview"
},
{
"id": "layout.logoutAction",
"defaultMessage": "Logout"
}
]
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment