1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-01-11 18:13:52 +02:00

Addining initial 18n support

This commit is contained in:
Jesús Espino 2020-10-23 13:40:39 +02:00
parent b6e65eb0c8
commit 48e4d8b569
10 changed files with 539 additions and 64 deletions

11
webapp/i18n/en.json Normal file
View File

@ -0,0 +1,11 @@
{
"Sidebar.add-board": "+ Add Board",
"Sidebar.delete-board": "Delete Board",
"Sidebar.export-archive": "Export Archive",
"Sidebar.import-archive": "Import Archive",
"Sidebar.set-english-language": "Set English Language",
"Sidebar.set-spanish-language": "Set Spanish Language",
"Sidebar.settings": "Settings",
"Sidebar.untitled-board": "(Untitled Board)",
"Sidebar.untitled-view": "(Untitled View)"
}

11
webapp/i18n/es.json Normal file
View File

@ -0,0 +1,11 @@
{
"Sidebar.add-board": "+ Añadir Panel",
"Sidebar.delete-board": "Borrar Panel",
"Sidebar.export-archive": "Exportar Archivo",
"Sidebar.import-archive": "Importar Archivo",
"Sidebar.set-english-language": "Usar idioma Inglés",
"Sidebar.set-spanish-language": "Usar idioma Español",
"Sidebar.settings": "Configuración",
"Sidebar.untitled-board": "(Panel sin titulo)",
"Sidebar.untitled-view": "(Vista sin titulo)"
}

337
webapp/package-lock.json generated
View File

@ -462,6 +462,157 @@
}
}
},
"@formatjs/cli": {
"version": "2.13.2",
"resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-2.13.2.tgz",
"integrity": "sha512-o0jY7AmaXIHugiV35xhKeNYQ9pzTi0O+stfZqY0+Sqb3MFk6oLz/K5ExvnXHvf3soiCOat4UhzAxHSR9T0QWwQ==",
"dev": true,
"requires": {
"@formatjs/ts-transformer": "^2.11.3",
"@types/json-stable-stringify": "^1.0.32",
"@types/lodash": "^4.14.150",
"@types/loud-rejection": "^2.0.0",
"@types/node": "14",
"chalk": "^4.0.0",
"commander": "^6.1.0",
"fast-glob": "^3.2.4",
"fs-extra": "^9.0.0",
"intl-messageformat-parser": "^6.0.10",
"json-stable-stringify": "^1.0.1",
"lodash": "^4.17.15",
"loud-rejection": "^2.2.0",
"tslib": "^2.0.1",
"typescript": "^4.0"
},
"dependencies": {
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"commander": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz",
"integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==",
"dev": true
},
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
"dev": true
}
}
},
"@formatjs/ecma402-abstract": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.2.5.tgz",
"integrity": "sha512-k0fqS3LBNOHueAoMdgig8Ni6TchsH+zbzWBzX2gTFm50X9mxHwnuXdCk0XLlCIbvgVVlzcO254Men/mHAheMbg==",
"requires": {
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-1.3.6.tgz",
"integrity": "sha512-LObg69JtDEZ8+Cqsu10h7AipKrsGpWd5xspIBJjWeQL+U0hTZ/f2PTNf/M5iOH8XRqc8ljCFGkaWn9bZGlmkaw==",
"requires": {
"@formatjs/ecma402-abstract": "^1.2.5",
"@formatjs/intl-displaynames": "^3.3.12",
"@formatjs/intl-listformat": "^4.2.10",
"@formatjs/intl-relativetimeformat": "^7.2.10",
"fast-memoize": "^2.5.2",
"intl-messageformat": "^9.3.11",
"intl-messageformat-parser": "^6.0.10",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl-displaynames": {
"version": "3.3.12",
"resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-3.3.12.tgz",
"integrity": "sha512-otxSrw0Wmv3qbyes/hsI4+tlg6V0dSezhusUJHyegod4dG8U9q0C6gawgDlIWrBANl+VPNvcLooJFPHhG6ni7w==",
"requires": {
"@formatjs/ecma402-abstract": "^1.2.5",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl-listformat": {
"version": "4.2.10",
"resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-4.2.10.tgz",
"integrity": "sha512-Wa9BaZnEg/km45Wj5lbRjFV89YHC/3P2ucsvk9lQklF6Kt7ybfTH6QDwITrlxo2EGvmcKPhxuBNHgrUhlxm9PQ==",
"requires": {
"@formatjs/ecma402-abstract": "^1.2.5",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl-relativetimeformat": {
"version": "7.2.10",
"resolved": "https://registry.npmjs.org/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-7.2.10.tgz",
"integrity": "sha512-3eKfhK0X5O8JkJ9bSgkWCG9fXjFPQCxw18DWqhbZ5thTU2aKejpxBzwFYCo+o5TCIEmtn6G835nBqb2d197Gnw==",
"requires": {
"@formatjs/ecma402-abstract": "^1.2.5",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/ts-transformer": {
"version": "2.11.3",
"resolved": "https://registry.npmjs.org/@formatjs/ts-transformer/-/ts-transformer-2.11.3.tgz",
"integrity": "sha512-nt51rmoeDnORFXGkJGX3tpC1oYY6WDkJTpOCCsYkRxWxmgY1kT5v8wckNB/CvBmz4egFNShr1iRNDa7o+EsKZA==",
"dev": true,
"requires": {
"intl-messageformat-parser": "^6.0.10",
"tslib": "^2.0.1",
"typescript": "^4.0"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
"dev": true
}
}
},
"@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@ -1183,6 +1334,15 @@
"integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==",
"dev": true
},
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/html-minifier-terser": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz",
@ -1230,12 +1390,33 @@
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
"dev": true
},
"@types/json-stable-stringify": {
"version": "1.0.32",
"resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz",
"integrity": "sha512-q9Q6+eUEGwQkv4Sbst3J4PNgDOvpuVuKj79Hl/qnmBMEIPzB5QoFRUtjcgcg2xNUZyYUGXBk5wYIBKHt0A+Mxw==",
"dev": true
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
"@types/lodash": {
"version": "4.14.162",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.162.tgz",
"integrity": "sha512-alvcho1kRUnnD1Gcl4J+hK0eencvzq9rmzvFPRmP5rPHx9VVsJj6bKLTATPVf9ktgv4ujzh7T+XWKp+jhuODig==",
"dev": true
},
"@types/loud-rejection": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/loud-rejection/-/loud-rejection-2.0.0.tgz",
"integrity": "sha512-oTHISsIybJGoh3b3Ay/10csbAd2k0su7G7DGrE1QWciC+IdydPm0WMw1+Gr9YMYjPiJ5poB3g5Ev73IlLoavLw==",
"dev": true,
"requires": {
"loud-rejection": "*"
}
},
"@types/marked": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-1.1.0.tgz",
@ -1263,14 +1444,12 @@
"@types/prop-types": {
"version": "15.7.3",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
"dev": true
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
},
"@types/react": {
"version": "16.9.52",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.52.tgz",
"integrity": "sha512-EHRjmnxiNivwhGdMh9sz1Yw9AUxTSZFxKqdBWAAzyZx3sufWwx6ogqHYh/WB1m/I4ZpjkoZLExF5QTy2ekVi/Q==",
"dev": true,
"requires": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
@ -1861,6 +2040,12 @@
"integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=",
"dev": true
},
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
"dev": true
},
"array-includes": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
@ -1992,6 +2177,12 @@
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true
},
"at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"dev": true
},
"atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
@ -3040,8 +3231,16 @@
"csstype": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz",
"integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==",
"dev": true
"integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag=="
},
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
"integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
"dev": true,
"requires": {
"array-find-index": "^1.0.1"
}
},
"cyclist": {
"version": "1.0.1",
@ -4492,6 +4691,11 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"fast-memoize": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
"integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
},
"fastq": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
@ -4851,6 +5055,18 @@
}
}
},
"fs-extra": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
"integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
"dev": true,
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^1.0.0"
}
},
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@ -5472,6 +5688,39 @@
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
"dev": true
},
"intl-messageformat": {
"version": "9.3.11",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.3.11.tgz",
"integrity": "sha512-eqnfSDa6oI/bBtPgzSAbsjUDUshhdLmMKOQds0xGhpcgp760Gq/Fk+f4HquO7VIGp9wSx7ej65e+NOJQTBe/YQ==",
"requires": {
"fast-memoize": "^2.5.2",
"intl-messageformat-parser": "^6.0.10",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"intl-messageformat-parser": {
"version": "6.0.10",
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.0.10.tgz",
"integrity": "sha512-xURB8PchDsdLEpedzPLzBmGCK996FPBl3yLQIUxcM3EAA3TdhXPArX6GY4LVXQNeq8V4WtwmgxaJOKtdOpA8pg==",
"requires": {
"@formatjs/ecma402-abstract": "^1.2.5",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"ip-regex": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
@ -7179,6 +7428,12 @@
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
"dev": true
},
"json-loader": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
"integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
"dev": true
},
"json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@ -7203,6 +7458,15 @@
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stable-stringify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
"dev": true,
"requires": {
"jsonify": "~0.0.0"
}
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
@ -7224,6 +7488,22 @@
"minimist": "^1.2.5"
}
},
"jsonfile": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^1.0.0"
}
},
"jsonify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
"dev": true
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@ -7373,6 +7653,16 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"loud-rejection": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-2.2.0.tgz",
"integrity": "sha512-S0FayMXku80toa5sZ6Ro4C+s+EtFDCsyJNG/AzFMfX3AxD5Si4dZsgzm/kKnbOxHl5Cv8jBlno8+3XYIh2pNjQ==",
"dev": true,
"requires": {
"currently-unhandled": "^0.4.1",
"signal-exit": "^3.0.2"
}
},
"lower-case": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz",
@ -8775,6 +9065,32 @@
"scheduler": "^0.19.1"
}
},
"react-intl": {
"version": "5.8.6",
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.8.6.tgz",
"integrity": "sha512-+TYAKYAVh1XPhm0ZxZ+LBUIdpjMe3Beit1928jrxaHk6SY0wyf20Qt14/s2sAkM5+FbKy+72pohC+Pqt6Ixvkg==",
"requires": {
"@formatjs/ecma402-abstract": "^1.2.5",
"@formatjs/intl": "^1.3.6",
"@formatjs/intl-displaynames": "^3.3.12",
"@formatjs/intl-listformat": "^4.2.10",
"@formatjs/intl-relativetimeformat": "^7.2.10",
"@types/hoist-non-react-statics": "^3.3.1",
"fast-memoize": "^2.5.2",
"hoist-non-react-statics": "^3.3.2",
"intl-messageformat": "^9.3.11",
"intl-messageformat-parser": "^6.0.10",
"shallow-equal": "^1.2.1",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -9447,6 +9763,11 @@
"kind-of": "^6.0.2"
}
},
"shallow-equal": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@ -10737,6 +11058,12 @@
"imurmurhash": "^0.1.4"
}
},
"universalify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
"dev": true
},
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",

View File

@ -9,12 +9,14 @@
"watchdev": "NODE_ENV=dev webpack --watch --config webpack.dev.js",
"test": "jest",
"check": "eslint --ext .tsx,.ts . --quiet --cache",
"fix": "eslint --ext .tsx,.ts . --quiet --fix --cache"
"fix": "eslint --ext .tsx,.ts . --quiet --fix --cache",
"i18n-extract": "formatjs extract src/**/*.tsx src/**/*.ts --out-file i18n/tmp.json; formatjs compile i18n/tmp.json --out-file i18n/en.json; rm i18n/tmp.json"
},
"dependencies": {
"marked": "^1.1.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-intl": "^5.8.6",
"react-router-dom": "^5.2.0",
"react-simplemde-editor": "^4.1.3"
},
@ -24,6 +26,8 @@
}
},
"devDependencies": {
"@formatjs/cli": "^2.13.2",
"@formatjs/ts-transformer": "^2.11.3",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.0.4",
"@types/jest": "^26.0.14",

View File

@ -1,39 +1,51 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import React, {useState} from 'react'
import {IntlProvider} from 'react-intl'
import {
BrowserRouter as Router,
Switch,
Route,
Link,
} from 'react-router-dom'
import {getCurrentLanguage, getMessages, storeLanguage} from './i18n'
import LoginPage from './pages/loginPage'
import BoardPage from './pages/boardPage'
export default function App(): JSX.Element {
const [language, setLanguage] = useState(getCurrentLanguage())
const setAndStoreLanguage = (lang: string) => {
storeLanguage(lang)
setLanguage(lang)
}
return (
<Router>
<div id='frame'>
<div id='main'>
<Switch>
<Route path='/login'>
<LoginPage/>
</Route>
<Route path='/'>
<BoardPage/>
</Route>
<Route path='/board'>
<BoardPage/>
</Route>
</Switch>
<IntlProvider
locale={language}
messages={getMessages(language)}
>
<Router>
<div id='frame'>
<div id='main'>
<Switch>
<Route path='/login'>
<LoginPage/>
</Route>
<Route path='/'>
<BoardPage setLanguage={setAndStoreLanguage}/>
</Route>
<Route path='/board'>
<BoardPage setLanguage={setAndStoreLanguage}/>
</Route>
</Switch>
</div>
<div id='overlay'/>
<div id='modal'/>
</div>
<div id='overlay'/>
<div id='modal'/>
</div>
</Router>
</Router>
</IntlProvider>
)
}

View File

@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import {FormattedMessage} from 'react-intl'
import {Archiver} from '../archiver'
import {Board, MutableBoard} from '../blocks/board'
@ -15,7 +16,8 @@ type Props = {
showBoard: (id: string) => void
showView: (id: string, boardId?: string) => void
workspaceTree: WorkspaceTree,
boardTree?: BoardTree
boardTree?: BoardTree,
setLanguage: (lang: string) => void,
}
type State = {
@ -77,7 +79,12 @@ class Sidebar extends React.Component<Props, State> {
</div>
{
boards.map((board) => {
const displayTitle = board.title || '(Untitled Board)'
const displayTitle = board.title || (
<FormattedMessage
id='Sidebar.untitled-board'
defaultMessage='(Untitled Board)'
/>
)
const boardViews = views.filter((view) => view.parentId === board.id)
return (
<div key={board.id}>
@ -93,23 +100,30 @@ class Sidebar extends React.Component<Props, State> {
<MenuWrapper>
<div className='octo-button square octo-hover-item'><div className='imageOptions'/></div>
<Menu>
<Menu.Text
id='delete'
name='Delete board'
onClick={async () => {
const nextBoardId = boards.length > 1 ? boards.find((o) => o.id !== board.id).id : undefined
mutator.deleteBlock(
board,
'delete block',
async () => {
nextBoardId && this.props.showBoard(nextBoardId!)
},
async () => {
this.props.showBoard(board.id)
},
)
}}
/>
<FormattedMessage
id='Sidebar.delete-board'
defaultMessage='Delete Board'
>
{(text: string) => (
<Menu.Text
id='delete'
name={text}
onClick={async () => {
const nextBoardId = boards.length > 1 ? boards.find((o) => o.id !== board.id).id : undefined
mutator.deleteBlock(
board,
'delete block',
async () => {
nextBoardId && this.props.showBoard(nextBoardId!)
},
async () => {
this.props.showBoard(board.id)
},
)
}}
/>
)}
</FormattedMessage>
</Menu>
</MenuWrapper>
</div>
@ -124,7 +138,12 @@ class Sidebar extends React.Component<Props, State> {
this.viewClicked(board, view)
}}
>
{view.title || '(Untitled View)'}
{view.title || (
<FormattedMessage
id='Sidebar.untitled-view'
defaultMessage='(Untitled View)'
/>
)}
</div>
</div>)
})}
@ -140,25 +159,73 @@ class Sidebar extends React.Component<Props, State> {
onClick={() => {
this.addBoardClicked()
}}
>+ Add Board</div>
>
<FormattedMessage
id='Sidebar.add-board'
defaultMessage='+ Add Board'
/>
</div>
<div className='octo-spacer'/>
<MenuWrapper>
<div className='octo-button'>Settings</div>
<div className='octo-button'>
<FormattedMessage
id='Sidebar.settings'
defaultMessage='Settings'
/>
</div>
<Menu position='top'>
<Menu.Text
id='import'
name='Import Archive'
onClick={async () => Archiver.importFullArchive(() => {
this.forceUpdate()
})}
/>
<Menu.Text
id='export'
name='Export Archive'
onClick={async () => Archiver.exportFullArchive()}
/>
<FormattedMessage
id='Sidebar.import-archive'
defaultMessage='Import Archive'
>
{(text: string) => (
<Menu.Text
id='import'
name={text}
onClick={async () => Archiver.importFullArchive(() => {
this.forceUpdate()
})}
/>
)}
</FormattedMessage>
<FormattedMessage
id='Sidebar.export-archive'
defaultMessage='Export Archive'
>
{(text: string) => (
<Menu.Text
id='export'
name={text}
onClick={async () => Archiver.exportFullArchive()}
/>
)}
</FormattedMessage>
<FormattedMessage
id='Sidebar.set-english-language'
defaultMessage='Set English Language'
>
{(text: string) => (
<Menu.Text
id='english-lang'
name={text}
onClick={async () => this.props.setLanguage('en')}
/>
)}
</FormattedMessage>
<FormattedMessage
id='Sidebar.set-spanish-language'
defaultMessage='Set Spanish Language'
>
{(text: string) => (
<Menu.Text
id='spanish-lang'
name={text}
onClick={async () => this.props.setLanguage('es')}
/>
)}
</FormattedMessage>
</Menu>
</MenuWrapper>
</div>

View File

@ -17,11 +17,12 @@ type Props = {
showView: (id: string, boardId?: string) => void
showFilter: (el: HTMLElement) => void
setSearchText: (text: string) => void
setLanguage: (lang: string) => void
}
class WorkspaceComponent extends React.Component<Props> {
render() {
const {boardTree, workspaceTree, showBoard, showView} = this.props
const {boardTree, workspaceTree, showBoard, showView, setLanguage} = this.props
Utils.assert(workspaceTree)
const element =
@ -31,6 +32,7 @@ class WorkspaceComponent extends React.Component<Props> {
showView={showView}
workspaceTree={workspaceTree}
boardTree={boardTree}
setLanguage={setLanguage}
/>
{this.mainComponent()}
</div>)

25
webapp/src/i18n.tsx Normal file
View File

@ -0,0 +1,25 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import messages_en from '../i18n/en.json'
import messages_es from '../i18n/es.json'
export function getMessages(lang: string): {[key: string]: string} {
switch (lang) {
case 'es':
return messages_es
}
return messages_en
}
export function getCurrentLanguage(): string {
let lang = localStorage.getItem('language')
if (!lang) {
lang = navigator.language.split(/[-_]/)[0]
}
return lang
}
export function storeLanguage(lang: string): void {
localStorage.setItem('language', lang)
}

View File

@ -14,6 +14,7 @@ import {Utils} from '../utils'
import {MutableWorkspaceTree} from '../viewModel/workspaceTree'
type Props = {
setLanguage: (lang: string) => void
}
type State = {
@ -157,6 +158,7 @@ export default class BoardPage extends React.Component<Props, State> {
setSearchText={(text) => {
this.setSearchText(text)
}}
setLanguage={this.props.setLanguage}
/>
</div>
)

View File

@ -1,5 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
const tsTransformer = require('@formatjs/ts-transformer');
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
@ -18,8 +19,21 @@ function makeCommonConfig() {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
use: {
loader: 'ts-loader',
options: {
getCustomTransformers: {
before: [
tsTransformer.transform({
overrideIdFn: '[sha512:contenthash:base64:6]',
ast: true,
}),
],
},
},
},
exclude: [/node_modules/],
},
{
test: /\.html$/,