#123 [sources] sources: linking different language versions

This commit is contained in:
Avris 2021-01-05 00:07:10 +01:00
parent 3b1b8f82d7
commit b272557ef9
7 changed files with 61 additions and 8 deletions

View File

@ -1,7 +1,9 @@
<template> <template>
<div class="my-2" v-if="!deleted"> <div class="my-2" v-if="!deleted">
<h3 class="h6">
<Icon :v="source.icon()"/> <Icon :v="source.icon()"/>
<strong><template v-if="source.author">{{source.author.replace('^', '')}}</template><span v-if="source.author"> </span><em><a v-if="source.link" :href="source.link" target="_blank" rel="noopener">{{source.title}}</a><span v-else>{{source.title}}</span></em></strong><template v-if="source.extra"> ({{source.extra}})</template>, {{source.year}}<template v-if="source.comment">; {{source.comment}}</template> <strong><template v-if="source.author">{{source.author.replace('^', '')}}</template><span v-if="source.author"> </span><em><a v-if="source.link" :href="source.link" target="_blank" rel="noopener">{{source.title}}</a><span v-else>{{source.title}}</span></em></strong><template v-if="source.extra"> ({{source.extra}})</template>, {{source.year}}<template v-if="source.comment">; {{source.comment}}</template>
</h3>
<ul class="list-inline" v-if="manage && $isGranted('sources')"> <ul class="list-inline" v-if="manage && $isGranted('sources')">
<li v-if="!source.approved" class="list-inline-item"> <li v-if="!source.approved" class="list-inline-item">
<span class="badge badge-danger"> <span class="badge badge-danger">
@ -62,6 +64,19 @@
<T>quotation.start</T><span v-html="fragment.replace(/\n/g, '<br/>')"></span><T>quotation.end</T> <T>quotation.start</T><span v-html="fragment.replace(/\n/g, '<br/>')"></span><T>quotation.end</T>
</li> </li>
</ul> </ul>
<div v-if="source.versions.length" class="my-3">
<h4 class="h6"><T>sources.otherVersions</T>:</h4>
<ul>
<li v-for="version in source.versions">
<h4 class="h6">
<strong>
<a :href="`${locales[version.locale].url}/${version.pronouns[0]}`" target="_blank" rel="noopener">{{locales[version.locale].name}}</a>:
</strong>
</h4>
<Source :source="version"/>
</li>
</ul>
</div>
</div> </div>
</template> </template>
@ -69,6 +84,7 @@
import {pronounLibrary} from "../src/data"; import {pronounLibrary} from "../src/data";
export default { export default {
name: 'Source',
props: { props: {
source: { required: true }, source: { required: true },
manage: { type: Boolean }, manage: { type: Boolean },

View File

@ -96,6 +96,7 @@ sources:
moderation: 'Submissions will have to get approved before getting published.' moderation: 'Submissions will have to get approved before getting published.'
key: 'Key' key: 'Key'
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary'
otherVersions: 'In other languages'
nouns: nouns:

View File

@ -96,6 +96,7 @@ sources:
moderation: 'Los envíos deben ser aprobados antes de ser publicados.' moderation: 'Los envíos deben ser aprobados antes de ser publicados.'
key: 'Key' # TODO key: 'Key' # TODO
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO
otherVersions: 'In other languages' # TODO
nouns: nouns:
header: 'Diccionario' header: 'Diccionario'

View File

@ -195,6 +195,7 @@ sources:
moderation: 'Propozycje będą musiały zostać zatwierdzone przed opublikowaniem.' moderation: 'Propozycje będą musiały zostać zatwierdzone przed opublikowaniem.'
key: 'Klucz' key: 'Klucz'
keyInfo: 'Identyfikator do łączenia tekstów między wersjami językowymi i łączenia ze słownikiem' keyInfo: 'Identyfikator do łączenia tekstów między wersjami językowymi i łączenia ze słownikiem'
otherVersions: 'W innych językach'
nouns: nouns:
header: 'Słowniki' header: 'Słowniki'

View File

@ -94,6 +94,7 @@ sources:
moderation: '提交的內容必須先獲得批准才能發布。' moderation: '提交的內容必須先獲得批准才能發布。'
key: 'Key' # TODO key: 'Key' # TODO
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO
otherVersions: 'In other languages' # TODO
nouns: nouns:
header: '字典' header: '字典'

View File

@ -18,27 +18,53 @@ const approve = async (db, id) => {
`); `);
} }
const linkOtherVersions = async (req, sources) => {
const keys = new Set(sources.filter(s => !!s && s.key).map(s => `'` + s.key + `'`));
const otherVersions = await req.db.all(SQL`
SELECT s.*, u.username AS submitter FROM sources s
LEFT JOIN users u ON s.submitter_id = u.id
WHERE s.locale != ${req.config.locale}
AND s.deleted = 0
AND s.approved >= ${req.isGranted('sources') ? 0 : 1}
AND s.key IN (`.append([...keys].join(',')).append(SQL`)
`));
const otherVersionsMap = {};
otherVersions.forEach(version => {
if (otherVersionsMap[version.key] === undefined) {
otherVersionsMap[version.key] = [];
}
otherVersionsMap[version.key].push(version);
});
return sources.map(s => {
s.versions = s.key ? otherVersionsMap[s.key] || [] : [];
return s;
});
};
const router = Router(); const router = Router();
router.get('/sources', async (req, res) => { router.get('/sources', async (req, res) => {
return res.json(await req.db.all(SQL` return res.json(await linkOtherVersions(req, await req.db.all(SQL`
SELECT s.*, u.username AS submitter FROM sources s SELECT s.*, u.username AS submitter FROM sources s
LEFT JOIN users u ON s.submitter_id = u.id LEFT JOIN users u ON s.submitter_id = u.id
WHERE s.locale = ${req.config.locale} WHERE s.locale = ${req.config.locale}
AND s.deleted = 0 AND s.deleted = 0
AND s.approved >= ${req.isGranted('sources') ? 0 : 1} AND s.approved >= ${req.isGranted('sources') ? 0 : 1}
`)); `)));
}); });
router.get('/sources/:id', async (req, res) => { router.get('/sources/:id', async (req, res) => {
return res.json(await req.db.all(SQL` return res.json(await linkOtherVersions(req, await req.db.all(SQL`
SELECT s.*, u.username AS submitter FROM sources s SELECT s.*, u.username AS submitter FROM sources s
LEFT JOIN users u ON s.submitter_id = u.id LEFT JOIN users u ON s.submitter_id = u.id
WHERE s.locale = ${req.config.locale} WHERE s.locale = ${req.config.locale}
AND s.deleted = 0 AND s.deleted = 0
AND s.approved >= ${req.isGranted('sources') ? 0 : 1} AND s.approved >= ${req.isGranted('sources') ? 0 : 1}
AND s.id = ${req.params.id} AND s.id = ${req.params.id}
`)); `)));
}); });
router.post('/sources/submit', async (req, res) => { router.post('/sources/submit', async (req, res) => {

View File

@ -99,7 +99,12 @@ function clone(mainObject) {
} }
export class Source { export class Source {
constructor ({id, pronouns, type, author, title, extra, year, fragments = '', comment = null, link = null, key = null, submitter = null, approved, base_id = null,}) { constructor ({
id, pronouns, type, author, title, extra, year, fragments = '',
comment = null, link = null,
submitter = null, approved, base_id = null,
key = null, versions = [], locale = config.locale,
}) {
this.id = id; this.id = id;
this.pronouns = pronouns ? pronouns.split(';') : []; this.pronouns = pronouns ? pronouns.split(';') : [];
this.type = type; this.type = type;
@ -110,10 +115,12 @@ export class Source {
this.fragments = fragments ? fragments.replace(/\|/g, '\n').split('@') : []; this.fragments = fragments ? fragments.replace(/\|/g, '\n').split('@') : [];
this.comment = comment; this.comment = comment;
this.link = link; this.link = link;
this.key = key;
this.submitter = submitter; this.submitter = submitter;
this.approved = approved; this.approved = approved;
this.base_id = base_id; this.base_id = base_id;
this.key = key;
this.versions = versions.map(v => new Source(v));
this.locale = locale;
} }
static get TYPES() { static get TYPES() {