Merge branch 'key-autocomplete' into 'main'

(terms)(sources) add autocomplete & convention explanation for the key field

See merge request PronounsPage/PronounsPage!500
This commit is contained in:
Andrea Vos 2024-08-11 12:09:35 +00:00
commit 0d0fda899e
26 changed files with 93 additions and 38 deletions

View File

@ -5,7 +5,7 @@
v-model="filter"
type="text"
class="form-control"
:placeholder="$t('profile.timezone.placeholder')"
v-bind="$attrs"
@focus="show"
@blur="hide"
@keydown="filterKeydown"
@ -26,9 +26,11 @@
<script>
export default {
inheritAttrs: false,
props: {
value: {},
options: { required: true },
freeform: { type: Boolean },
},
data() {
return {
@ -47,6 +49,11 @@ export default {
this.filter = this.options[this.value] || this.value;
this.highlighted = -1;
},
filter() {
if (this.freeform) {
this.$emit('input', this.filter);
}
},
},
methods: {
select(option) {

View File

@ -140,15 +140,16 @@
</div>
<div v-if="$isGranted('sources')" class="form-group">
<label for="key"><T>sources.submit.key</T></label>
<input
<AutocompleteSelect
id="key"
v-model="form.key"
type="text"
class="form-control"
maxlength="255"
>
:options="keys"
freeform
/>
<p class="small text-muted">
<T>sources.submit.keyInfo</T>
<T>sources.submit.keyInfoConvention</T>
</p>
</div>
<div v-if="form.base" class="alert alert-info">
@ -199,6 +200,7 @@ interface Data {
submitting: boolean;
afterSubmit: boolean;
pronounLibrary: PronounLibrary;
keys: Record<string, string>;
}
export default Vue.extend({
@ -226,8 +228,13 @@ export default Vue.extend({
afterSubmit: false,
pronounLibrary,
keys: {},
};
},
async mounted() {
this.keys = await this.$axios.$get('/sources/keys');
},
methods: {
async submit(): Promise<void> {
this.submitting = true;

View File

@ -53,9 +53,10 @@
<div class="row">
<div class="col-12 col-lg-4">
<label for="key"><strong><T>sources.submit.key</T></strong></label>
<input id="key" v-model="form.key" type="text" class="form-control" maxlength="255">
<AutocompleteSelect v-model="form.key" :options="keys" maxlength="255" freeform />
<p class="small text-muted">
<T>sources.submit.keyInfo</T>
<T>sources.submit.keyInfoConvention</T>
</p>
</div>
<div class="col-12 col-lg-4">
@ -122,6 +123,7 @@ interface Data {
};
submitting: boolean;
afterSubmit: boolean;
keys: Record<string, string>,
}
export default Vue.extend({
@ -139,8 +141,12 @@ export default Vue.extend({
},
submitting: false,
afterSubmit: false,
keys: {},
};
},
async mounted() {
this.keys = await this.$axios.$get('/terms/keys');
},
methods: {
async submit(): Promise<void> {
this.submitting = true;

View File

@ -5,7 +5,7 @@
<Icon v="location" />
<T>profile.timezone.detect</T>
</button>
<AutocompleteSelect v-model="timezone" :options="timezones" />
<AutocompleteSelect v-model="timezone" :options="timezones" :placeholder="$t('profile.timezone.placeholder')" />
<button v-if="timezone" class="btn btn-outline-danger" type="button" @click="timezone = null">
<Icon v="times" />
</button>

View File

@ -139,7 +139,8 @@ sources:
another: 'Submit another one'
moderation: 'Submissions will have to get approved before getting published.'
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.'
keyInfoConvention: 'Ideally: the simplest form of the term, in English, in lower-case.'
images: 'Images'
spoiler: 'Spoiler'
otherVersions: 'In other languages'

View File

@ -151,7 +151,7 @@ sources:
another: 'Ein weiteres Beispiel einreichen'
moderation: 'Einreichungen müssen erst genehmigt werden, bevor sie veröffentlicht werden.'
key: 'Schlüssel'
keyInfo: 'Kennzeichen, um Quellen zwischen Sprachversionen und dem Wörterbuch zu verbinden'
keyInfo: 'Kennzeichen, um Quellen zwischen Sprachversionen und dem Wörterbuch zu verbinden.'
images: 'Bilder'
spoiler: 'Spoiler'
otherVersions: 'In anderen Sprachen'

View File

@ -137,7 +137,8 @@ sources:
another: 'Submit another one'
moderation: 'Submissions will have to get approved before getting published.'
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.'
keyInfoConvention: 'Ideally: the simplest form of the term, in English, in lower-case.'
images: 'Images'
spoiler: 'Spoiler'
otherVersions: 'In other languages'

View File

@ -101,7 +101,7 @@ sources:
another: 'Alsendi pluan'
moderation: 'Alsendaĵoj estas aprobendaj antaŭ ol publikigo.'
key: 'Ŝlosilo'
keyInfo: 'Identigilo por ligi fontojn inter lingvoversiojn kaj ligado al la vortaro'
keyInfo: 'Identigilo por ligi fontojn inter lingvoversiojn kaj ligado al la vortaro.'
images: 'Bildoj'
otherVersions: 'En aliaj lingvoj'
referenced: 'Ekzemploj de uzo'

View File

@ -128,7 +128,7 @@ sources:
another: 'Enviar otro'
moderation: 'Los envíos deben ser aprobados antes de ser publicados.'
key: 'Clave'
keyInfo: 'Identificador para vincular fuentes entre versiones en varios idiomas y vincularlas con el diccionario'
keyInfo: 'Identificador para vincular fuentes entre versiones en varios idiomas y vincularlas con el diccionario.'
images: 'Imágenes'
spoiler: 'Spoiler'
fragmentsInfo: >

View File

@ -100,7 +100,7 @@ sources:
another: 'Esita veel üks'
moderation: 'Esitatud viited kinnitatakse enne avaldamist moderaatori poolt.'
key: 'Võti'
keyInfo: 'Identifikaator allikate sidumiseks keeleversioonide vahel ning sõnastikuga'
keyInfo: 'Identifikaator allikate sidumiseks keeleversioonide vahel ning sõnastikuga.'
images: 'Pildid'
spoiler: 'Spoiler'
otherVersions: 'Teistes keeltes'

View File

@ -118,7 +118,7 @@ sources:
thanks: 'Merci de votre contribution !'
another: 'Soumettre un autre exemple'
moderation: 'Les soumissions devront être approuvées avant dêtre publiées.'
keyInfo: 'Identifiant pour relier les sources entre les versions linguistiques et établir des liens avec le dictionnaire'
keyInfo: 'Identifiant pour relier les sources entre les versions linguistiques et établir des liens avec le dictionnaire.'
images: 'Images'
spoiler: 'Spoiler'
otherVersions: 'Dans dautres langues'

View File

@ -115,7 +115,7 @@ sources:
another: 'Enviar outro'
moderation: 'Os envios devem ser aprovados antes de serem publicados.'
key: 'Chave'
keyInfo: 'Identificador para conectar fontes entre versões e conectar com dicionário'
keyInfo: 'Identificador para conectar fontes entre versões e conectar com dicionário.'
images: 'Imagens'
spoiler: 'Spoiler' # TODO
otherVersions: 'Em outros idiomas'

View File

@ -128,7 +128,7 @@ sources:
another: 'Inviane un altro'
moderation: 'Il materiale deve essere approvato prima della sua pubblicazione.'
key: 'Chiave'
keyInfo: 'Identificativo per collegare fonti tra lingue diverse e collegarle con il dizionario'
keyInfo: 'Identificativo per collegare fonti tra lingue diverse e collegarle con il dizionario.'
images: 'Immagini'
otherVersions: 'In altre lingue'
referenced: 'Esempi di utilizzo'

View File

@ -101,7 +101,7 @@ sources:
another: 'もう一つ送信'
moderation: '承認されるまで投稿は公開されません。'
key: 'キー'
keyInfo: '言語間、及び辞書とリンクするのための識別子'
keyInfo: '言語間、及び辞書とリンクするのための識別子'
images: '画像'
spoiler: 'ネタバレ'
otherVersions: '他の言語で'

View File

@ -118,7 +118,7 @@ sources:
another: '제출 더하기'
moderation: '제출물은 먼저 승인받아야합니다.'
key: '키'
keyInfo: '언어 버전 간 소스 연결 및 사전 연결 식별자'
keyInfo: '언어 버전 간 소스 연결 및 사전 연결 식별자.'
images: '이미지'
spoiler: '스포주의'
otherVersions: '다른 언어'

View File

@ -117,7 +117,7 @@ sources:
another: 'Embiar otruno'
moderation: 'Los embios deven ser aseptados antes de ser publikados.'
key: 'Yave'
keyInfo: 'Identifiador para atar manaderos entre versiones en varias linguas i atarlas kon el diksionaryo'
keyInfo: 'Identifiador para atar manaderos entre versiones en varias linguas i atarlas kon el diksionaryo.'
images: 'Imajes'
spoiler: 'Spoiler'
otherVersions: 'En otras linguas'

View File

@ -116,7 +116,7 @@ sources:
another: 'Dien nog een voorbeeld in'
moderation: 'Inzendingen zullen moeten worden goedgekeurd alvorens te worden gepubliceerd.'
key: 'Sleutel'
keyInfo: 'Identifier om bronnen te linken tussen verschillende vertalingen van de website en om met het woordenboek te linken'
keyInfo: 'Identifier om bronnen te linken tussen verschillende vertalingen van de website en om met het woordenboek te linken.'
images: 'Afbeeldingen'
spoiler: 'Spoiler'
otherVersions: 'In andere talen'

View File

@ -110,7 +110,7 @@ sources:
another: 'Legg til en til'
moderation: 'Bidrag må bli vurdert og godtatt før de blir lagt ut.'
key: 'Nøkkel'
keyInfo: 'identifiserer for å linke kilder mellom språkversjoner og linker med ordboken'
keyInfo: 'identifiserer for å linke kilder mellom språkversjoner og linker med ordboken.'
images: 'Bilder'
spoiler: 'Sladd'
otherVersions: 'På andre språk'

View File

@ -141,7 +141,8 @@ sources:
another: 'Zgłoś kolejne źródło'
moderation: 'Propozycje będą musiały zostać zatwierdzone przed opublikowaniem.'
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.'
keyInfoConvention: 'Najlepiej: najprostsza forma wpisu, po angielsku, małymi literami.'
images: 'Obrazki'
spoiler: 'Spoiler'
otherVersions: 'W innych językach'

View File

@ -126,7 +126,7 @@ sources:
another: 'Enviar outro'
moderation: 'Os envios devem ser aprovados antes de serem publicados.'
key: 'Chave'
keyInfo: 'Identificador para conectar fontes entre versões e conectar com dicionário'
keyInfo: 'Identificador para conectar fontes entre versões e conectar com dicionário.'
images: 'Imagens'
spoiler: 'Spoiler'
fragmentsInfo: >

View File

@ -122,7 +122,7 @@ sources:
another: 'Добавить ещё'
moderation: 'Предложения должны быть одобрены перед публикацией.'
key: 'Ключ'
keyInfo: 'Идентификатор, используемый для связки источников из разных языковых версий и связки со словарём'
keyInfo: 'Идентификатор, используемый для связки источников из разных языковых версий и связки со словарём.'
images: 'Изображения'
spoiler: 'Спойлер'
otherVersions: 'На других языках'

View File

@ -122,7 +122,7 @@ sources:
another: 'Skicka in en till'
moderation: 'Bidragen måste godkännas innan de publiceras.'
key: 'Nyckel'
keyInfo: 'Identifierare för att länka källor mellan språkversioner och länka till ordbok'
keyInfo: 'Identifierare för att länka källor mellan språkversioner och länka till ordbok.'
images: 'Bilder'
spoiler: 'Spoiler' # Swedish just takes the word spoiler directly
otherVersions: 'På andra språk'

View File

@ -128,7 +128,7 @@ sources:
another: 'Gửi thêm'
moderation: 'Các ví dụ sẽ phải được phê duyệt trước khi được thêm vào.'
key: 'Mã định danh'
keyInfo: 'Mã định danh để liên kết các nguồn ở các phiên bản ngôn ngữ khác và liên kết với từ điển'
keyInfo: 'Mã định danh để liên kết các nguồn ở các phiên bản ngôn ngữ khác và liên kết với từ điển.'
images: 'Ảnh'
spoiler: 'Spoiler'
otherVersions: 'Trong các ngôn ngữ khác'

View File

@ -119,7 +119,7 @@ sources:
another: '提交另一個'
moderation: '提交的內容必須先獲得批准才能發布。'
key: '鍵' # TODO
keyInfo: '用於在語言版本之間連接源並與字典連接的標誌符'
keyInfo: '用於在語言版本之間連接源並與字典連接的標誌符'
images: '意象'
spoiler: '劇透內容'
otherVersions: '在其他語言'

View File

@ -95,17 +95,6 @@ router.get('/sources', handleErrorAsync(async (req, res) => {
return res.json(await linkOtherVersions(req, await req.db.all(sql)));
}));
router.get('/sources/:id', handleErrorAsync(async (req, res) => {
return res.json(await linkOtherVersions(req, 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 = ${global.config.locale}
AND s.deleted = 0
AND s.approved >= ${req.isGranted('sources') ? 0 : 1}
AND s.id = ${req.params.id}
`)));
}));
router.post('/sources/submit', handleErrorAsync(async (req, res) => {
if (!req.user || !await req.isUserAllowedToPost()) {
return res.status(401).json({ error: 'Unauthorised' });
@ -176,4 +165,31 @@ router.post('/sources/remove/:id', handleErrorAsync(async (req, res) => {
return res.json('ok');
}));
router.get('/sources/keys', handleErrorAsync(async (req, res) => {
const keys = await req.db.all<{ key: string }>(SQL`
SELECT trim(key) AS key
FROM sources
WHERE key IS NOT NULL
AND deleted = 0
AND approved = 1
GROUP BY key
ORDER BY key
`);
return res.json(
Object.fromEntries(keys.map((k) => [k.key, k.key])),
);
}));
router.get('/sources/:id', handleErrorAsync(async (req, res) => {
return res.json(await linkOtherVersions(req, 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 = ${global.config.locale}
AND s.deleted = 0
AND s.approved >= ${req.isGranted('sources') ? 0 : 1}
AND s.id = ${req.params.id}
`)));
}));
export default router;

View File

@ -174,4 +174,20 @@ router.post('/terms/remove/:id', handleErrorAsync(async (req, res) => {
return res.json('ok');
}));
router.get('/terms/keys', handleErrorAsync(async (req, res) => {
const keys = await req.db.all<{ key: string }>(SQL`
SELECT trim(key) AS key
FROM terms
WHERE key IS NOT NULL
AND deleted = 0
AND approved = 1
GROUP BY key
ORDER BY key
`);
return res.json(
Object.fromEntries(keys.map((k) => [k.key, k.key])),
);
}));
export default router;