Added new function to add cumstom translation strings on Admin panel

This commit is contained in:
Yevhenii Pertiaka 2023-08-17 21:54:14 +09:00
parent 4153fe7d0d
commit b1525d4221
10 changed files with 599 additions and 2 deletions

View file

@ -20,6 +20,10 @@ template(name="settingHeaderBar")
i.fa(class="fa-paperclip")
span {{_ 'attachments'}}
a.setting-header-btn.informations(href="{{pathFor 'translation'}}")
i.fa(class="fa-font")
span {{_ 'translation'}}
a.setting-header-btn.informations(href="{{pathFor 'information'}}")
i.fa(class="fa-info-circle")
span {{_ 'info'}}

View file

@ -0,0 +1,67 @@
.main-body {
overflow: scroll;
}
table {
color: #000;
}
table td,
table th {
border: 1px solid #d2d0d0;
text-align: left;
padding: 8px;
}
table tr:nth-child(even) {
background-color: #ddd;
}
.ext-box {
display: flex;
flex-direction: row;
height: 34px;
}
.ext-box .ext-box-left {
display: flex;
width: 100%;
gap: 10px;
}
.ext-box span {
vertical-align: center;
line-height: 34px;
}
.ext-box input,
.ext-box button {
padding: 0;
}
.ext-box button {
min-width: 90px;
}
.content-wrapper {
margin-top: 10px;
}
.buttonsContainer {
display: flex;
}
.buttonsContainer input {
margin: 0;
}
.buttonsContainer div {
margin: auto;
}
.more-settings-translation {
margin-left: 10px;
}
#cancelBtn {
margin-left: 5% !important;
background: #ffa500;
color: #fff;
}
#deleteAction {
margin-left: 5% !important;
}
p.js-translation-language {
font-weight: bold;
color: #000;
}
p.js-translation-text {
font-weight: bold;
color: #000;
}

View file

@ -0,0 +1,105 @@
template(name="translation")
.setting-content
unless currentUser.isAdmin
| {{_ 'error-notAuthorized'}}
else
.content-title.ext-box
.ext-box-left
if loading.get
+spinner
else if translationSetting.get
span
i.fa.fa-font
unless isMiniScreen
| {{_ 'translation'}}
input#searchTranslationInput(placeholder="{{_ 'search'}}")
button#searchTranslationButton
i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{#unless isMiniScreen}}{{_ 'translation-number'}}{{/unless}} #{translationNumber}
.content-body
.side-menu
ul
li.active
a.js-translation-menu(data-id="translation-setting")
i.fa.fa-font
| {{_ 'translation'}}
.main-body
if loading.get
+spinner
else if translationSetting.get
+translationGeneral
template(name="translationGeneral")
table
tbody
tr
th {{_ 'language'}}
th {{_ 'text'}}
th {{_ 'translation-text'}}
th
+newTranslationRow
each translation in translationList
+translationRow(translationId=translation._id)
template(name="newTranslationRow")
a.new-translation
i.fa.fa-plus-square
| {{_ 'new'}}
template(name="translationRow")
tr
td {{translationData.language}}
td {{translationData.text}}
td {{translationData.translationText}}
td
a.edit-translation
i.fa.fa-edit
| {{_ 'edit'}}
a.more-settings-translation
i.fa.fa-ellipsis-h
template(name="editTranslationPopup")
form
label
| {{_ 'language'}}
input.js-translation-language(type="text" value=translation.language required readonly)
label
| {{_ 'text'}}
input.js-translation-text(type="text" value=translation.text required readonly)
label
| {{_ 'translation-text'}}
input.js-translation-translation-text(type="text" value=translation.translationText)
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="newTranslationPopup")
form
label
| {{_ 'language'}}
input.js-translation-language(type="text" value="en" required)
label
| {{_ 'text'}}
span.error.hide.text-taken
| {{_ 'error-text-taken'}}
input.js-translation-text(type="text" value="" required)
label
| {{_ 'translation-text'}}
input.js-translation-translation-text(type="text" value="")
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="settingsTranslationPopup")
ul.pop-over-list
li
form
label
| {{_ 'delete-translation-confirm-popup'}}
br
label.hide.orgId(type="text" value=org._id)
div.buttonsContainer
input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")

View file

@ -0,0 +1,214 @@
import { ReactiveCache } from '/imports/reactiveCache';
const translationsPerPage = 25;
BlazeComponent.extendComponent({
mixins() {
return [Mixins.InfiniteScrolling];
},
onCreated() {
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
this.translationSetting = new ReactiveVar(true);
this.findTranslationsOptions = new ReactiveVar({});
this.numberTranslations = new ReactiveVar(0);
this.page = new ReactiveVar(1);
this.loadNextPageLocked = false;
this.callFirstWith(null, 'resetNextPeak');
this.autorun(() => {
const limitTranslations = this.page.get() * translationsPerPage;
this.subscribe('translation', this.findTranslationsOptions.get(), 0, () => {
this.loadNextPageLocked = false;
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
this.calculateNextPeak();
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
if (nextPeakBefore === nextPeakAfter) {
this.callFirstWith(null, 'resetNextPeak');
}
});
});
},
events() {
return [
{
'click #searchTranslationButton'() {
this.filterTranslation();
},
'keydown #searchTranslationInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
this.filterTranslation();
}
},
'click #newTranslationButton'() {
Popup.open('newTranslation');
},
'click a.js-translation-menu': this.switchMenu,
},
];
},
filterTranslation() {
const value = $('#searchTranslationInput').first().val();
if (value === '') {
this.findTranslationsOptions.set({});
} else {
const regex = new RegExp(value, 'i');
this.findTranslationsOptions.set({
$or: [
{ language: regex },
{ text: regex },
{ translationText: regex },
],
});
}
},
loadNextPage() {
if (this.loadNextPageLocked === false) {
this.page.set(this.page.get() + 1);
this.loadNextPageLocked = true;
}
},
calculateNextPeak() {
const element = this.find('.main-body');
if (element) {
const altitude = element.scrollHeight;
this.callFirstWith(this, 'setNextPeak', altitude);
}
},
reachNextPeak() {
this.loadNextPage();
},
setError(error) {
this.error.set(error);
},
setLoading(w) {
this.loading.set(w);
},
translationList() {
const translations = ReactiveCache.getTranslations(this.findTranslationsOptions.get(), {
sort: { modifiedAt: 1 },
fields: { _id: true },
});
this.numberTranslations.set(translations.length);
return translations;
},
translationNumber() {
return this.numberTranslations.get();
},
switchMenu(event) {
const target = $(event.target);
if (!target.hasClass('active')) {
$('.side-menu li.active').removeClass('active');
target.parent().addClass('active');
const targetID = target.data('id');
this.translationSetting.set('translation-setting' === targetID);
}
},
}).register('translation');
Template.translationRow.helpers({
translationData() {
return ReactiveCache.getTranslation(this.translationId);
},
});
Template.editTranslationPopup.helpers({
translation() {
return ReactiveCache.getTranslation(this.translationId);
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
Template.newTranslationPopup.onCreated(function () {
this.errorMessage = new ReactiveVar('');
});
Template.newTranslationPopup.helpers({
translation() {
return ReactiveCache.getTranslation(this.translationId);
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
BlazeComponent.extendComponent({
onCreated() {},
translation() {
return ReactiveCache.getTranslation(this.translationId);
},
events() {
return [
{
'click a.edit-translation': Popup.open('editTranslation'),
'click a.more-settings-translation': Popup.open('settingsTranslation'),
},
];
},
}).register('translationRow');
BlazeComponent.extendComponent({
events() {
return [
{
'click a.new-translation': Popup.open('newTranslation'),
},
];
},
}).register('newTranslationRow');
Template.editTranslationPopup.events({
submit(event, templateInstance) {
event.preventDefault();
const translation = ReactiveCache.getTranslation(this.translationId);
const translationText = templateInstance.find('.js-translation-translation-text').value.trim();
Meteor.call(
'setTranslationText',
translation,
translationText
);
Popup.back();
},
});
Template.newTranslationPopup.events({
submit(event, templateInstance) {
event.preventDefault();
const language = templateInstance.find('.js-translation-language').value.trim();
const text = templateInstance.find('.js-translation-text').value.trim();
const translationText = templateInstance.find('.js-translation-translation-text').value.trim();
Meteor.call(
'setCreateTranslation',
language,
text,
translationText,
function(error) {
const textMessageElement = templateInstance.$('.text-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'text-already-taken') {
textMessageElement.show();
}
} else {
textMessageElement.hide();
Popup.back();
}
},
);
Popup.back();
},
});
Template.settingsTranslationPopup.events({
'click #deleteButton'(event) {
event.preventDefault();
Translation.remove(this.translationId);
Popup.back();
}
});