diff --git a/apps/web-mzima-client/src/app/core/enums/icons.ts b/apps/web-mzima-client/src/app/core/enums/icons.ts index 28bc3415fe..4c59be5e77 100644 --- a/apps/web-mzima-client/src/app/core/enums/icons.ts +++ b/apps/web-mzima-client/src/app/core/enums/icons.ts @@ -75,4 +75,5 @@ export enum Icons { thumbUp = 'thumb-up', ellipses = 'ellipses', lock = 'lock', + translate = 'translate', } diff --git a/apps/web-mzima-client/src/app/core/services/event-bus.service.ts b/apps/web-mzima-client/src/app/core/services/event-bus.service.ts index bd908a6542..0e2dc5e557 100644 --- a/apps/web-mzima-client/src/app/core/services/event-bus.service.ts +++ b/apps/web-mzima-client/src/app/core/services/event-bus.service.ts @@ -22,6 +22,7 @@ export const enum EventType { RefreshSurveysCounters = 'REFRESH_SURVEYS_COUNTERS', StopExportPolling = 'STOP_EXPORT_POLLING', ExportDone = 'EXPORT_DONE', + DisplayTranslatedPost = 'DISPLAY_TRANSLATED_POST', StatusChange = 'STATUS_CHANGE', } diff --git a/apps/web-mzima-client/src/app/core/services/language.service.ts b/apps/web-mzima-client/src/app/core/services/language.service.ts index cbd54c874b..6ab674cfc5 100644 --- a/apps/web-mzima-client/src/app/core/services/language.service.ts +++ b/apps/web-mzima-client/src/app/core/services/language.service.ts @@ -4,6 +4,7 @@ import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject } from 'rxjs'; import { LanguageInterface } from '@mzima-client/sdk'; import LangJSON from '../../../assets/locales/languages.json'; +import entityLanguages from '../../../assets/locales/entity-languages.json'; import { SessionService } from './session.service'; @Injectable({ @@ -41,6 +42,9 @@ export class LanguageService { private set initialLanguage(value: string) { localStorage.setItem(this.languageKey, value); } + getEntityLanguages() { + return entityLanguages; + } getLanguages(): LanguageInterface[] { if (LangJSON.languages && LangJSON.languages.length > 0) { diff --git a/apps/web-mzima-client/src/app/post/post-details/post-details.component.html b/apps/web-mzima-client/src/app/post/post-details/post-details.component.html index 67bfece381..0c1aae326f 100644 --- a/apps/web-mzima-client/src/app/post/post-details/post-details.component.html +++ b/apps/web-mzima-client/src/app/post/post-details/post-details.component.html @@ -17,28 +17,43 @@ [deleteable]="post.allowed_privileges.includes('delete')" (statusChanged)="statusChangedHandle()" (deleted)="deletedHandle()" + (openTranslationModal)="openTranslatePost()" > - +
-

{{ post.form.name }}

-

{{ post.form.description }}

+

{{ post.form.translations[displayLanguage]?.name || post.form.name }}

+

{{ post.form.translations[displayLanguage]?.description || post.form.description }}

- {{ post.title || post.content }} + {{ + post.translations[displayLanguage]?.title || + post.title || + post.translations[displayLanguage]?.description || + post.content + }}

-

+

@@ -60,7 +75,7 @@

*ngIf="field.input !== 'tags' ? field.value : field.value?.length" class="post__group" > -

{{ field.label }}

+

{{ field.translations[displayLanguage]?.label || field.label }}

@@ -121,12 +136,21 @@

{{ field.label }}

-

-

{{ field.value.value || '-' }}

+

+ {{ + field.value.translations[displayLanguage]?.value || field.value.value || '-' + }} +

-

+

@@ -228,7 +252,9 @@

{{ field.label }}

- {{ field.value.value || '-' }} + {{ + field.value.translations[displayLanguage]?.value || field.value.value || '-' + }} diff --git a/apps/web-mzima-client/src/app/post/post-details/post-details.component.ts b/apps/web-mzima-client/src/app/post/post-details/post-details.component.ts index 0593bc20c6..a0710a29bf 100644 --- a/apps/web-mzima-client/src/app/post/post-details/post-details.component.ts +++ b/apps/web-mzima-client/src/app/post/post-details/post-details.component.ts @@ -25,11 +25,14 @@ import { SurveysService, } from '@mzima-client/sdk'; import { TranslateService } from '@ngx-translate/core'; +import { untilDestroyed } from '@ngneat/until-destroy'; import { lastValueFrom, Subscription } from 'rxjs'; import { BaseComponent } from '../../base.component'; import { preparingVideoUrl } from '../../core/helpers/validators'; import { dateHelper } from '@helpers'; import { BreakpointService, EventBusService, EventType, SessionService } from '@services'; +import { LanguageService } from '../../core/services/language.service'; +import { PostTranslateComponent } from '../post-translate/post-translate.component'; @Component({ selector: 'app-post-details', @@ -51,6 +54,8 @@ export class PostDetailsComponent extends BaseComponent implements OnChanges, On public isPostLoading: boolean = true; public isManagePosts: boolean = false; public postChanged: boolean; + public displayLanguage: string; + public post: PostResult; private dataSubscription: Subscription; constructor( @@ -66,6 +71,7 @@ export class PostDetailsComponent extends BaseComponent implements OnChanges, On private surveyService: SurveysService, protected sanitizer: DomSanitizer, private eventBusService: EventBusService, + private languageService: LanguageService, ) { super(sessionService, breakpointService); this.getUserData(); @@ -86,6 +92,7 @@ export class PostDetailsComponent extends BaseComponent implements OnChanges, On //---------------------- this.allowed_privileges = localStorage.getItem('USH_allowed_privileges') ?? ''; this.postId = Number(params['id']); + this.translatePost(); } }); if (this.postFromModal) { @@ -98,6 +105,16 @@ export class PostDetailsComponent extends BaseComponent implements OnChanges, On }); } } + translatePost() { + this.eventBusService + .on(EventType.DisplayTranslatedPost) + .pipe(untilDestroyed(this)) + .subscribe({ + next: (language) => { + this.displayLanguage = language.code; + }, + }); + } loadData(): void {} @@ -314,4 +331,27 @@ export class PostDetailsComponent extends BaseComponent implements OnChanges, On public getDate(value: any, format: string): string { return dateHelper.getDateWithTz(value, format); } + + public openTranslatePost() { + const dialogRef = this.dialog.open(PostTranslateComponent, { + width: '100%', + maxWidth: '768px', + panelClass: ['modal', 'select-languages-modal'], + data: { + post: this.post, + languages: this.languageService.getEntityLanguages(), + }, + }); + + dialogRef.afterClosed().subscribe((response) => { + if (response) { + this.post = response.post; + this.displayLanguage = response.displayLanguage.code; + } + }); + } + + public displayOriginalPost() { + this.displayLanguage = ''; + } } diff --git a/apps/web-mzima-client/src/app/post/post-edit/post-edit.component.ts b/apps/web-mzima-client/src/app/post/post-edit/post-edit.component.ts index 0270bc42b1..ee5643dc06 100644 --- a/apps/web-mzima-client/src/app/post/post-edit/post-edit.component.ts +++ b/apps/web-mzima-client/src/app/post/post-edit/post-edit.component.ts @@ -565,11 +565,12 @@ export class PostEditComponent extends BaseComponent implements OnInit, OnChange } async preparationData(): Promise { - for (const task of this.tasks) { + for (const [index, task] of this.tasks.entries()) { task.fields = await Promise.all( task.fields.map( async (field: { key: string | number; input: string; type: string; options: any }) => { let value: any = { + translations: [], value: this.form.value[field.key], }; @@ -705,8 +706,13 @@ export class PostEditComponent extends BaseComponent implements OnInit, OnChange this.form.value[field.key]?.map((fieldValue: any) => fieldValue.value) || []; break; default: + const postField = this.post.post_content[index].fields.find( + (f: any) => f.key === field.key, + ); value.value = this.form.value[field.key] || null; + value.translations = postField?.value?.translations || []; } + return { ...field, value, @@ -731,18 +737,19 @@ export class PostEditComponent extends BaseComponent implements OnInit, OnChange return; } + const postLanguage = this.selectedLanguage?.code || this.languageService.initialLanguage; const postData = { - base_language: 'en', + base_language: postLanguage, completed_stages: this.completeStages, content: this.description, description: '', - enabled_languages: {}, form_id: this.formId, locale: 'en_US', post_content: this.tasks, published_to: [], title: this.title, type: 'report', + translations: this.post?.translations || [], }; if (!this.form.valid) this.form.markAllAsTouched(); diff --git a/apps/web-mzima-client/src/app/post/post-head/post-head.component.html b/apps/web-mzima-client/src/app/post/post-head/post-head.component.html index e93e68cc3d..7c23c586f1 100644 --- a/apps/web-mzima-client/src/app/post/post-head/post-head.component.html +++ b/apps/web-mzima-client/src/app/post/post-head/post-head.component.html @@ -33,6 +33,22 @@ > + 0; + return !this.hideTranslationsIcon && (languagesAvailabe || this.editable); + } } diff --git a/apps/web-mzima-client/src/app/post/post-preview/post-preview.component.html b/apps/web-mzima-client/src/app/post/post-preview/post-preview.component.html index 772da88e31..05fb48f59d 100644 --- a/apps/web-mzima-client/src/app/post/post-preview/post-preview.component.html +++ b/apps/web-mzima-client/src/app/post/post-preview/post-preview.component.html @@ -21,6 +21,7 @@ [deleteable]="post.allowed_privileges.includes('delete')" (deleted)="deletedHandle()" (statusChanged)="statusChangedHandle()" + [hideTranslationsIcon]="true" > diff --git a/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.html b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.html new file mode 100644 index 0000000000..329c7fbd5e --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.html @@ -0,0 +1,168 @@ + + + + +{{ 'translations.translate_post' | translate }} + + +{{ 'translations.translate_post_to' | translate : { language: activeLanguage.name } }} + + +
+ +
+

{{ 'translations.available_languages' | translate }}

+ + + + {{ language.name }} + + + +
+
+

{{ 'translations.select_translate_edit' | translate }}

+
    +
  • + + {{ defaultLanguage.name }} ({{ 'translations.default_language' | translate }}) + +
  • +
  • + + {{ language.name }} + +
  • +
+
+
+ + +
+
+
+ +
+ {{ field?.translations[activeLanguage.code]?.label || field?.label }} + +
+
+ {{ 'translations.text_in_original' | translate }} +
+
+

{{ getOriginalValue(field) }}

+
+
+ {{ 'translations.add_translation' | translate }} + + * + + + + + + * + + + + + + + + + + + + + + + + + + + +

+ {{ 'post.modify.errors.required' | translate : { label: field.label } }} +

+
+
+
+
+
+
+ +
+ + {{ 'app.cancel' | translate }} + + + {{ 'app.save' | translate }} + +
+
+
diff --git a/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.scss b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.scss new file mode 100644 index 0000000000..315b343d62 --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.scss @@ -0,0 +1,62 @@ +@import 'helpers'; +.select-language { + margin-bottom: 26px; +} +.list-label { + margin: 4px 0 8px 0; + font-size: 14px; + font-weight: 700; +} + +.types-list { + display: flex; + margin: 0 -8px; + flex-wrap: wrap; +} + +.type-item { + display: flex; + padding: 8px 12px; + margin: 0 4px 8px; + border-radius: 4px; + width: calc(50% - 8px); + transition: color 0.35s ease; + background: var(--color-neutral-10); + + @include breakpoint-max($tablet) { + border-inline-start-width: 4px; + box-shadow: inset 0 0 0 1px var(--color-neutral-20); + } + + @include breakpoint-max($mobile) { + width: calc(100% - 8px); + } +} + +.translate-post { + &__fields { + display: flex; + flex-direction: column; + width: 100%; + padding: 24px 16px; + border-radius: 4px; + gap: 24px; + background: var(--Neutral-Neutral-10, #f5f5f5); + } + + .field-label { + font-weight: 500; + line-height: 160%; /* 22.4px */ + letter-spacing: -0.07px; + } + + &__original { + padding: 24px; + border: 1px solid var(--Neutral-Neutral-30, #e2e2e3); + background-color: white; + } + + .mat-form-field { + background: white; + } +} diff --git a/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.spec.ts b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.spec.ts new file mode 100644 index 0000000000..9a1a44daaf --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { PostTranslateComponent } from './post-translate.component'; + +describe('PostTranslateComponent', () => { + let component: PostTranslateComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [PostTranslateComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(PostTranslateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.ts b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.ts new file mode 100644 index 0000000000..9870dfbdda --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translate/post-translate.component.ts @@ -0,0 +1,162 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { FormGroup, FormControl, Validators } from '@angular/forms'; +import { LanguageInterface, PostResult, PostsService } from '@mzima-client/sdk'; +import { EventBusService, EventType } from '@services'; +import { UntilDestroy } from '@ngneat/until-destroy'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { MatSelectChange } from '@angular/material/select'; +import { MatSnackBar } from '@angular/material/snack-bar'; + +export interface PostTranslateComponentData { + post: PostResult; + languages: LanguageInterface[]; +} + +@UntilDestroy() +@Component({ + selector: 'app-post-translate', + templateUrl: './post-translate.component.html', + styleUrls: ['./post-translate.component.scss'], +}) +export class PostTranslateComponent implements OnInit { + public languages: LanguageInterface[]; + public enabledLanguages: any; + public isTranslateMode: boolean; + public activeLanguage: LanguageInterface; + public defaultLanguage: LanguageInterface | undefined; + public post: any; + public translateForm: FormGroup; + public displayPostLanguage: LanguageInterface; + constructor( + @Inject(MAT_DIALOG_DATA) + public data: PostTranslateComponentData, + private postsService: PostsService, + private eventBusService: EventBusService, + private snackBar: MatSnackBar, + private matDialogRef: MatDialogRef, + ) {} + + ngOnInit(): void { + this.languages = this.data.languages; + this.isTranslateMode = false; + this.post = structuredClone(this.data.post); + this.enabledLanguages = this.languages.filter((lang) => + this.post.enabled_languages?.available?.includes(lang.code), + ); + this.defaultLanguage = this.languages.find((lang) => lang.code === this.post.base_language); + } + public closeModal(ref?: any): void { + this.matDialogRef.close(ref); + } + public displayTranslatedPost(event: MatSelectChange) { + this.eventBusService.next({ + type: EventType.DisplayTranslatedPost, + payload: event.value, + }); + this.closeModal({ displayLanguage: event.value, post: this.post }); + } + saveTranslation() { + this.translateForm.disable(); + this.post.post_content.forEach((task: any) => { + task.fields + .filter((field: any) => field.key in this.translateForm.controls) + .forEach((field: any) => { + const translatedValue = this.translateForm.controls[field.key].value; + field.value = field.value || {}; + field.value.translations = field.value.translations || {}; + + if (Array.isArray(field.value.translations) && field.value.translations.length === 0) { + field.value.translations = {}; + } + + field.value.translations[this.activeLanguage.code] = { value: translatedValue }; + + if (field.type === 'title' || field.type === 'description') { + this.post.translations = this.post.translations || {}; + if (Array.isArray(this.post.translations) && this.post.translations.length === 0) { + this.post.translations = {}; + } + this.post.translations[this.activeLanguage.code] = + this.post.translations[this.activeLanguage.code] || {}; + this.post.translations[this.activeLanguage.code][field.type] = translatedValue; + } + }); + }); + this.post.enabled_languages = { default: 'en', available: this.enabledLanguages }; + delete this.post.completed_stages; + + this.postsService.updateTranslations(this.post.id, this.post).subscribe({ + next: ({ result }) => { + this.postsService.unlockPost(this.post.id).subscribe(); + this.showMessage('Translation saved successfully', 'success'); + this.postsService.unlockPost(this.post.id).subscribe(); + this.closeModal({ displayLanguage: this.activeLanguage, post: result }); + }, + error: ({ error }) => { + this.translateForm.enable(); + this.postsService.unlockPost(this.post.id).subscribe(); + this.showMessage(`Failed to save translation. ${error.errors.message}`, 'error'); + }, + }); + } + + private showMessage(message: string, type: string) { + this.snackBar.open(message, 'Close', { + panelClass: [type], + duration: 3000, + }); + } + selectLanguage(event: Event, lang: LanguageInterface) { + this.postsService.lockPost(this.post.id).subscribe(); + this.activeLanguage = lang; + this.translateForm = this.createForm(); + this.enabledLanguages.push(lang.code); + this.isTranslateMode = true; + } + + createForm() { + const newForm = new FormGroup({}); + this.post.post_content + .flatMap((task: any) => task.fields) + .filter((field: any) => this.isTranslateableContent(field)) + .forEach((field: any) => { + if (field.type === 'title' || field.type === 'description') { + newForm.addControl(field.key, new FormControl('', Validators.required)); + } else { + newForm.addControl(field.key, new FormControl('')); + } + const translation = this.getTranslationValue(field); + if (translation) { + newForm.get(field.key)?.setValue(translation); + } + }); + return newForm; + } + + getOriginalValue(field: any) { + if (field.type === 'title') { + return this.post.title; + } + if (field.type === 'description') { + return this.post.content; + } + return field.value.value; + } + + getTranslationValue(field: any) { + if (field.type === 'title') { + return this.post.translations?.[this.activeLanguage.code]?.title || ''; + } + if (field.type === 'description') { + return this.post.translations?.[this.activeLanguage.code]?.description || ''; + } + return field.value?.translations?.[this.activeLanguage.code]?.value || ''; + } + + isTranslateableContent(field: any) { + if (field.type === 'title' || field.type === 'description') return true; + if (field.value && field.value.value) + return field.input === 'text' || field.input === 'textarea' || field.input === 'markdown'; + return false; + } +} diff --git a/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.html b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.html new file mode 100644 index 0000000000..303d1ae40f --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.html @@ -0,0 +1,32 @@ + +
+
+ +
+
+

+ {{ + 'translations.translated_to' | translate : { language: getLanguageName(displayLanguage) } + }} +

+

+ {{ 'translations.viewing_translated' | translate }} +

+ + + {{ 'translations.view_original' | translate }} + + {{ + 'translations.change_lang' | translate + }} +
+
+
diff --git a/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.scss b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.scss new file mode 100644 index 0000000000..a890fefeae --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.scss @@ -0,0 +1,21 @@ +.alert { + display: flex; + .icon { + width: 1em; + height: 1em; + font-size: 32px; + margin-inline-end: 18px; + margin-top: -2px; + } + .link-blue { + color: #006acd; + } + ::ng-deep { + .original-post { + button { + width: unset; + padding: 4px; + } + } + } +} diff --git a/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.spec.ts b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.spec.ts new file mode 100644 index 0000000000..e4e98315d6 --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { PostTranslatedComponent } from './post-translated.component'; + +describe('PostTranslatedComponent', () => { + let component: PostTranslatedComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [PostTranslatedComponent], + imports: [IonicModule.forRoot()], + }).compileComponents(); + + fixture = TestBed.createComponent(PostTranslatedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.ts b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.ts new file mode 100644 index 0000000000..37818ed46f --- /dev/null +++ b/apps/web-mzima-client/src/app/post/post-translated/post-translated.component.ts @@ -0,0 +1,29 @@ +import { Component, EventEmitter, Output, Input } from '@angular/core'; +import { LanguageService } from '../../core/services/language.service'; + +@Component({ + selector: 'app-post-translated', + templateUrl: './post-translated.component.html', + styleUrls: ['./post-translated.component.scss'], +}) +export class PostTranslatedComponent { + @Output() public displayOriginalPost = new EventEmitter(); + @Output() public openTranslationModal = new EventEmitter(); + @Input() public baseLanguage: string; + @Input() public displayLanguage: string; + constructor(private languageService: LanguageService) {} + + public getLanguageName(code: string) { + return ( + this.languageService.getEntityLanguages().find((lang) => lang.code === code)?.name || code + ); + } + + originalPost() { + this.displayOriginalPost.emit(); + } + + openTranslations() { + this.openTranslationModal.emit(); + } +} diff --git a/apps/web-mzima-client/src/app/post/post.module.ts b/apps/web-mzima-client/src/app/post/post.module.ts index 48b253fc49..1611210f53 100644 --- a/apps/web-mzima-client/src/app/post/post.module.ts +++ b/apps/web-mzima-client/src/app/post/post.module.ts @@ -39,6 +39,8 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { PostNotFoundComponent } from './post-not-found/post-not-found.component'; import { PostNotAllowedComponent } from './post-not-allowed/post-not-allowed.component'; import { PostConversationComponent } from './post-conversation/post-conversation.component'; +import { PostTranslateComponent } from './post-translate/post-translate.component'; +import { PostTranslatedComponent } from './post-translated/post-translated.component'; @NgModule({ declarations: [ @@ -54,6 +56,8 @@ import { PostConversationComponent } from './post-conversation/post-conversation PostNotFoundComponent, PostNotAllowedComponent, PostConversationComponent, + PostTranslateComponent, + PostTranslatedComponent, ], imports: [ CommonModule, @@ -96,6 +100,7 @@ import { PostConversationComponent } from './post-conversation/post-conversation PostNotFoundComponent, PostNotAllowedComponent, PostConversationComponent, + PostTranslatedComponent, ], }) export class PostModule {} diff --git a/apps/web-mzima-client/src/assets/icons/translate.svg b/apps/web-mzima-client/src/assets/icons/translate.svg new file mode 100644 index 0000000000..f087508b88 --- /dev/null +++ b/apps/web-mzima-client/src/assets/icons/translate.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web-mzima-client/src/assets/locales/en.json b/apps/web-mzima-client/src/assets/locales/en.json index 78873aa0b4..071cc81787 100644 --- a/apps/web-mzima-client/src/assets/locales/en.json +++ b/apps/web-mzima-client/src/assets/locales/en.json @@ -2162,15 +2162,19 @@ "i_agree": "I agree to Ushahidi's Privacy Policy and\nTerms and Conditions." }, "translations": { + "available_languages": "Available translations (select to see post):", + "translate_post": "Translate post", + "translate_post_to": "Translate post to {{language}}", "languages": "Languages", "language": "Language", "default": "default", + "default_language": "Default language", + "text_in_original": "Text in original language:", "translation_default": "(default)", "translate_field": "Translate field", "survey_select_default": "Select default language for this survey", "category_select_default": "Select default language for this category", "error_translation_exists": "You cannot select this language since there is already a translation for it.", - "edit_default_text": "Text in default language", "edit_placeholder": "Write your translation here", "add_translation": "Add your translation below:", "survey_name_required": "Translation for survey-name is required", @@ -2184,7 +2188,12 @@ "add_a_language": "Add a language", "error_no_default": "You need to specify a default language before adding a new translation.", "select_language": "Select a language to add translation for", - "default_lang_info": "This is the language that will be used if no translations are available for the language the user has set for the deployment." + "select_translate_edit": "Select a language to translate to, or edit:", + "default_lang_info": "This is the language that will be used if no translations are available for the language the user has set for the deployment.", + "translated_to": "Translated to {{language}}", + "viewing_translated":"You are viewing a translated version of this post.", + "view_original":"View original post", + "change_lang": "Change language" }, "languages": { "ach": "Acoli", diff --git a/apps/web-mzima-client/src/assets/locales/entity-languages.json b/apps/web-mzima-client/src/assets/locales/entity-languages.json new file mode 100644 index 0000000000..bb0044cb69 --- /dev/null +++ b/apps/web-mzima-client/src/assets/locales/entity-languages.json @@ -0,0 +1,390 @@ +[{ "code": "ach", "name": "Acoli" }, + { "code": "ady", "name": "Adyghe" }, + { "code": "af", "name": "Afrikaans" }, + { "code": "af-ZA", "name": "Afrikaans (South Africa)" }, + { "code": "ak", "name": "Akan" }, + { "code": "sq", "name": "Albanian" }, + { "code": "sq-AL", "name": "Albanian (Albania)" }, + { "code": "aln", "name": "Albanian Gheg" }, + { "code": "am", "name": "Amharic" }, + { "code": "am-ET", "name": "Amharic (Ethiopia)" }, + { "code": "ar", "name": "Arabic" }, + { "code": "ar-EG", "name": "Arabic (Egypt)" }, + { "code": "ar-SA", "name": "Arabic (Saudi Arabia)" }, + { "code": "ar-SD", "name": "Arabic (Sudan)" }, + { "code": "ar-SY", "name": "Arabic (Syria)" }, + { "code": "ar-AA", "name": "Arabic (Unitag)" }, + { "code": "an", "name": "Aragonese" }, + { "code": "hy", "name": "Armenian" }, + { "code": "hy-AM", "name": "Armenian (Armenia)" }, + { "code": "as", "name": "Assamese" }, + { "code": "as-IN", "name": "Assamese (India)" }, + { "code": "ast", "name": "Asturian" }, + { "code": "ast-ES", "name": "Asturian (Spain)" }, + { "code": "az", "name": "Azerbaijani" }, + { "code": "az@Arab", "name": "Azerbaijani (Arabic)" }, + { "code": "az-AZ", "name": "Azerbaijani (Azerbaijan)" }, + { "code": "az-IR", "name": "Azerbaijani (Iran)" }, + { "code": "az@latin", "name": "Azerbaijani (Latin)" }, + { "code": "bal", "name": "Balochi" }, + { "code": "ba", "name": "Bashkir" }, + { "code": "eu", "name": "Basque" }, + { "code": "eu-ES", "name": "Basque (Spain)" }, + { "code": "bar", "name": "Bavarian" }, + { "code": "be", "name": "Belarusian" }, + { "code": "be-BY", "name": "Belarusian (Belarus)" }, + { "code": "be@tarask", "name": "Belarusian (Tarask)" }, + { "code": "bn", "name": "Bengali" }, + { "code": "bn-BD", "name": "Bengali (Bangladesh)" }, + { "code": "bn-IN", "name": "Bengali (India)" }, + { "code": "brx", "name": "Bodo" }, + { "code": "bs", "name": "Bosnian" }, + { "code": "bs-BA", "name": "Bosnian (Bosnia and Herzegovina)" }, + { "code": "br", "name": "Breton" }, + { "code": "bg", "name": "Bulgarian" }, + { "code": "bg-BG", "name": "Bulgarian (Bulgaria)" }, + { "code": "my", "name": "Burmese" }, + { "code": "my-MM", "name": "Burmese (Myanmar)" }, + { "code": "ca", "name": "Catalan" }, + { "code": "ca-ES", "name": "Catalan (Spain)" }, + { "code": "ca@valencia", "name": "Catalan (Valencian)" }, + { "code": "ceb", "name": "Cebuano" }, + { "code": "tzm", "name": "Central Atlas Tamazight" }, + { "code": "hne", "name": "Chhattisgarhi" }, + { "code": "cgg", "name": "Chiga" }, + { "code": "zh", "name": "Chinese" }, + { "code": "zh-CN", "name": "Chinese (China)" }, + { "code": "zh-CN.GB2312", "name": "Chinese (China) (GB2312)" }, + { "code": "gan", "name": "Chinese (Gan)" }, + { "code": "hak", "name": "Chinese (Hakka)" }, + { "code": "zh-HK", "name": "Chinese (Hong Kong)" }, + { "code": "czh", "name": "Chinese (Huizhou)" }, + { "code": "cjy", "name": "Chinese (Jinyu)" }, + { "code": "lzh", "name": "Chinese (Literary)" }, + { "code": "cmn", "name": "Chinese (Mandarin)" }, + { "code": "mnp", "name": "Chinese (Min Bei)" }, + { "code": "cdo", "name": "Chinese (Min Dong)" }, + { "code": "nan", "name": "Chinese (Min Nan)" }, + { "code": "czo", "name": "Chinese (Min Zhong)" }, + { "code": "cpx", "name": "Chinese (Pu-Xian)" }, + { "code": "zh-Hans", "name": "Chinese Simplified" }, + { "code": "zh-TW", "name": "Chinese (Taiwan)" }, + { "code": "zh-TW.Big5", "name": "Chinese (Taiwan) (Big5) " }, + { "code": "zh-Hant", "name": "Chinese Traditional" }, + { "code": "wuu", "name": "Chinese (Wu)" }, + { "code": "hsn", "name": "Chinese (Xiang)" }, + { "code": "yue", "name": "Chinese (Yue)" }, + { "code": "cv", "name": "Chuvash" }, + { "code": "ksh", "name": "Colognian" }, + { "code": "kw", "name": "Cornish" }, + { "code": "co", "name": "Corsican" }, + { "code": "crh", "name": "Crimean Turkish" }, + { "code": "hr", "name": "Croatian" }, + { "code": "hr-HR", "name": "Croatian (Croatia)" }, + { "code": "cs", "name": "Czech" }, + { "code": "cs-CZ", "name": "Czech (Czech Republic)" }, + { "code": "da", "name": "Danish" }, + { "code": "da-DK", "name": "Danish (Denmark)" }, + { "code": "dv", "name": "Divehi" }, + { "code": "doi", "name": "Dogri" }, + { "code": "nl", "name": "Dutch" }, + { "code": "nl-BE", "name": "Dutch (Belgium)" }, + { "code": "nl-NL", "name": "Dutch (Netherlands)" }, + { "code": "dz", "name": "Dzongkha" }, + { "code": "dz-BT", "name": "Dzongkha (Bhutan)" }, + { "code": "en", "name": "English" }, + { "code": "en-BD", "name": "English (Bangladesh)" }, + { "code": "en-CA", "name": "English (Canada)" }, + { "code": "en-GH", "name": "English (Ghana)" }, + { "code": "en-HK", "name": "English (Hong Kong)" }, + { "code": "en-HU", "name": "English (Hungary)" }, + { "code": "en-IN", "name": "English (India)" }, + { "code": "en-IE", "name": "English (Ireland)" }, + { "code": "en-NL", "name": "English (Netherlands)" }, + { "code": "en-NZ", "name": "English (New Zealand)" }, + { "code": "en-NG", "name": "English (Nigeria)" }, + { "code": "en-PK", "name": "English (Pakistan)" }, + { "code": "en-ZA", "name": "English (South Africa)" }, + { "code": "en-LK", "name": "English (Sri Lanka)" }, + { "code": "en-GB", "name": "English (United Kingdom)" }, + { "code": "en-US", "name": "English (United States)" }, + { "code": "en-EN", "name": "English" }, + { "code": "myv", "name": "Erzya" }, + { "code": "eo", "name": "Esperanto" }, + { "code": "et", "name": "Estonian" }, + { "code": "et-EE", "name": "Estonian (Estonia)" }, + { "code": "fo", "name": "Faroese" }, + { "code": "fo-FO", "name": "Faroese (Faroe Islands)" }, + { "code": "fil", "name": "Filipino" }, + { "code": "fi", "name": "Finnish" }, + { "code": "fi-FI", "name": "Finnish (Finland)" }, + { "code": "frp", "name": "Franco-Provençal (Arpitan)" }, + { "code": "fr", "name": "French" }, + { "code": "fr-BE", "name": "French (Belgium)" }, + { "code": "fr-CA", "name": "French (Canada)" }, + { "code": "fr-FR", "name": "French (France)" }, + { "code": "fr-CH", "name": "French (Switzerland)" }, + { "code": "fur", "name": "Friulian" }, + { "code": "ff", "name": "Fulah" }, + { "code": "ff-SN", "name": "Fulah (Senegal)" }, + { "code": "gd", "name": "Gaelic, Scottish" }, + { "code": "gl", "name": "Galician" }, + { "code": "gl-ES", "name": "Galician (Spain)" }, + { "code": "lg", "name": "Ganda" }, + { "code": "ka", "name": "Georgian" }, + { "code": "ka-GE", "name": "Georgian (Georgia)" }, + { "code": "de", "name": "German" }, + { "code": "de-AT", "name": "German (Austria)" }, + { "code": "de-DE", "name": "German (Germany)" }, + { "code": "de-CH", "name": "German (Switzerland)" }, + { "code": "el", "name": "Greek" }, + { "code": "el-GR", "name": "Greek (Greece)" }, + { "code": "kl", "name": "Greenlandic" }, + { "code": "gu", "name": "Gujarati" }, + { "code": "gu-IN", "name": "Gujarati (India)" }, + { "code": "gun", "name": "Gun" }, + { "code": "ht", "name": "Haitian (Haitian Creole)" }, + { "code": "ht-HT", "name": "Haitian (Haitian Creole) (Haiti)" }, + { "code": "ha", "name": "Hausa" }, + { "code": "haw", "name": "Hawaiian" }, + { "code": "he", "name": "Hebrew" }, + { "code": "he-IL", "name": "Hebrew (Israel)" }, + { "code": "hi", "name": "Hindi" }, + { "code": "hi-IN", "name": "Hindi (India)" }, + { "code": "hu", "name": "Hungarian" }, + { "code": "hu-HU", "name": "Hungarian (Hungary)" }, + { "code": "is", "name": "Icelandic" }, + { "code": "is-IS", "name": "Icelandic (Iceland)" }, + { "code": "io", "name": "Ido" }, + { "code": "ig", "name": "Igbo" }, + { "code": "ilo", "name": "Iloko" }, + { "code": "id", "name": "Indonesian" }, + { "code": "id-ID", "name": "Indonesian (Indonesia)" }, + { "code": "ia", "name": "Interlingua" }, + { "code": "iu", "name": "Inuktitut" }, + { "code": "ga", "name": "Irish" }, + { "code": "ga-IE", "name": "Irish (Ireland)" }, + { "code": "it", "name": "Italian" }, + { "code": "it-IT", "name": "Italian (Italy)" }, + { "code": "it-CH", "name": "Italian (Switzerland)" }, + { "code": "ja", "name": "Japanese" }, + { "code": "ja-JP", "name": "Japanese (Japan)" }, + { "code": "jv", "name": "Javanese" }, + { "code": "kab", "name": "Kabyle" }, + { "code": "kn", "name": "Kannada" }, + { "code": "kn-IN", "name": "Kannada (India)" }, + { "code": "pam", "name": "Kapampangan" }, + { "code": "ks", "name": "Kashmiri" }, + { "code": "ks-IN", "name": "Kashmiri (India)" }, + { "code": "csb", "name": "Kashubian" }, + { "code": "kk", "name": "Kazakh" }, + { "code": "kk@Arab", "name": "Kazakh (Arabic)" }, + { "code": "kk@Cyrl", "name": "Kazakh (Cyrillic)" }, + { "code": "kk-KZ", "name": "Kazakh (Kazakhstan)" }, + { "code": "kk@latin", "name": "Kazakh (Latin)" }, + { "code": "km", "name": "Khmer" }, + { "code": "km-KH", "name": "Khmer (Cambodia)" }, + { "code": "rw", "name": "Kinyarwanda" }, + { "code": "ky", "name": "Kirgyz" }, + { "code": "tlh", "name": "Klingon" }, + { "code": "kok", "name": "Konkani" }, + { "code": "ko", "name": "Korean" }, + { "code": "ko-KR", "name": "Korean (Korea)" }, + { "code": "ku", "name": "Kurdish" }, + { "code": "ku-IQ", "name": "Kurdish (Iraq)" }, + { "code": "lad", "name": "Ladino" }, + { "code": "lo", "name": "Lao" }, + { "code": "lo-LA", "name": "Lao (Laos)" }, + { "code": "ltg", "name": "Latgalian" }, + { "code": "la", "name": "Latin" }, + { "code": "lv", "name": "Latvian" }, + { "code": "lv-LV", "name": "Latvian (Latvia)" }, + { "code": "lez", "name": "Lezghian" }, + { "code": "lij", "name": "Ligurian" }, + { "code": "li", "name": "Limburgian" }, + { "code": "ln", "name": "Lingala" }, + { "code": "lt", "name": "Lithuanian" }, + { "code": "lt-LT", "name": "Lithuanian (Lithuania)" }, + { "code": "jbo", "name": "Lojban" }, + { "code": "lmo", "name": "Lombard" }, + { "code": "dsb", "name": "Lower Sorbian" }, + { "code": "nds", "name": "Low German" }, + { "code": "lb", "name": "Luxembourgish" }, + { "code": "mk", "name": "Macedonian" }, + { "code": "mk-MK", "name": "Macedonian (Macedonia)" }, + { "code": "mai", "name": "Maithili" }, + { "code": "mg", "name": "Malagasy" }, + { "code": "ms", "name": "Malay" }, + { "code": "ml", "name": "Malayalam" }, + { "code": "ml-IN", "name": "Malayalam (India)" }, + { "code": "ms-MY", "name": "Malay (Malaysia)" }, + { "code": "mt", "name": "Maltese" }, + { "code": "mt-MT", "name": "Maltese (Malta)" }, + { "code": "mni", "name": "Manipuri" }, + { "code": "mi", "name": "Maori" }, + { "code": "arn", "name": "Mapudungun" }, + { "code": "mr", "name": "Marathi" }, + { "code": "mr-IN", "name": "Marathi (India)" }, + { "code": "mh", "name": "Marshallese" }, + { "code": "mw1", "name": "Mirandese" }, + { "code": "mn", "name": "Mongolian" }, + { "code": "mn-MN", "name": "Mongolian (Mongolia)" }, + { "code": "nah", "name": "Nahuatl" }, + { "code": "nv", "name": "Navajo" }, + { "code": "nr", "name": "Ndebele, South" }, + { "code": "nap", "name": "Neapolitan" }, + { "code": "ne", "name": "Nepali" }, + { "code": "ne-NP", "name": "Nepali (Nepal)" }, + { "code": "nia", "name": "Nias" }, + { "code": "nqo", "name": "N'ko" }, + { "code": "se", "name": "Northern Sami" }, + { "code": "nso", "name": "Northern Sotho" }, + { "code": "no", "name": "Norwegian" }, + { "code": "nb", "name": "Norwegian Bokmål" }, + { "code": "nb-NO", "name": "Norwegian Bokmål (Norway)" }, + { "code": "no-NO", "name": "Norwegian (Norway)" }, + { "code": "nn", "name": "Norwegian Nynorsk" }, + { "code": "nn-NO", "name": "Norwegian Nynorsk (Norway)" }, + { "code": "ny", "name": "Nyanja" }, + { "code": "oc", "name": "Occitan (post 1500)" }, + { "code": "or", "name": "Oriya" }, + { "code": "or-IN", "name": "Oriya (India)" }, + { "code": "om", "name": "Oromo" }, + { "code": "os", "name": "Ossetic" }, + { "code": "pfl", "name": "Palatinate German" }, + { "code": "pa", "name": "Panjabi (Punjabi)" }, + { "code": "pa-IN", "name": "Panjabi (Punjabi) (India)" }, + { "code": "pap", "name": "Papiamento" }, + { "code": "fa", "name": "Persian" }, + { "code": "fa-AF", "name": "Persian (Afghanistan)" }, + { "code": "fa-IR", "name": "Persian (Iran)" }, + { "code": "pms", "name": "Piemontese" }, + { "code": "pl", "name": "Polish" }, + { "code": "pl-PL", "name": "Polish (Poland)" }, + { "code": "pt", "name": "Portuguese" }, + { "code": "pt-BR", "name": "Portuguese (Brazil)" }, + { "code": "pt-PT", "name": "Portuguese (Portugal)" }, + { "code": "ps", "name": "Pushto" }, + { "code": "ro", "name": "Romanian" }, + { "code": "ro-RO", "name": "Romanian (Romania)" }, + { "code": "rm", "name": "Romansh" }, + { "code": "ru", "name": "Russian" }, + { "code": "ru-ee", "name": "Russian (Estonia)" }, + { "code": "ru-lv", "name": "Russian (Latvia)" }, + { "code": "ru-lt", "name": "Russian (Lithuania)" }, + { "code": "ru@petr1708", "name": "Russian Petrine orthography" }, + { "code": "ru-RU", "name": "Russian (Russia)" }, + { "code": "sah", "name": "Sakha (Yakut)" }, + { "code": "sm", "name": "Samoan" }, + { "code": "sa", "name": "Sanskrit" }, + { "code": "sat", "name": "Santali" }, + { "code": "sc", "name": "Sardinian" }, + { "code": "sco", "name": "Scots" }, + { "code": "sr", "name": "Serbian" }, + { "code": "sr@Ijekavian", "name": "Serbian (Ijekavian)" }, + { "code": "sr@ijekavianlatin", "name": "Serbian (Ijekavian Latin)" }, + { "code": "sr@latin", "name": "Serbian (Latin)" }, + { "code": "sr-RS@latin", "name": "Serbian (Latin) (Serbia)" }, + { "code": "sr-RS", "name": "Serbian (Serbia)" }, + { "code": "sn", "name": "Shona" }, + { "code": "scn", "name": "Sicilian" }, + { "code": "szl", "name": "Silesian" }, + { "code": "sd", "name": "Sindhi" }, + { "code": "si", "name": "Sinhala" }, + { "code": "si-LK", "name": "Sinhala (Sri Lanka)" }, + { "code": "sk", "name": "Slovak" }, + { "code": "sk-SK", "name": "Slovak (Slovakia)" }, + { "code": "sl", "name": "Slovenian" }, + { "code": "sl-SI", "name": "Slovenian (Slovenia)" }, + { "code": "so", "name": "Somali" }, + { "code": "son", "name": "Songhay" }, + { "code": "st", "name": "Sotho, Southern" }, + { "code": "st-ZA", "name": "Sotho, Southern (South Africa)" }, + { "code": "sma", "name": "Southern Sami" }, + { "code": "es", "name": "Spanish" }, + { "code": "es-AR", "name": "Spanish (Argentina)" }, + { "code": "es-BO", "name": "Spanish (Bolivia)" }, + { "code": "es-CL", "name": "Spanish (Chile)" }, + { "code": "es-CO", "name": "Spanish (Colombia)" }, + { "code": "es-CR", "name": "Spanish (Costa Rica)" }, + { "code": "es-DO", "name": "Spanish (Dominican Republic)" }, + { "code": "es-EC", "name": "Spanish (Ecuador)" }, + { "code": "es-SV", "name": "Spanish (El Salvador)" }, + { "code": "es-GT", "name": "Spanish (Guatemala)" }, + { "code": "es-419", "name": "Spanish (Latin America)" }, + { "code": "es-MX", "name": "Spanish (Mexico)" }, + { "code": "es-NI", "name": "Spanish (Nicaragua)" }, + { "code": "es-PA", "name": "Spanish (Panama)" }, + { "code": "es-PY", "name": "Spanish (Paraguay)" }, + { "code": "es-PE", "name": "Spanish (Peru)" }, + { "code": "es-PR", "name": "Spanish (Puerto Rico)" }, + { "code": "es-ES", "name": "Spanish (Spain)" }, + { "code": "es-US", "name": "Spanish (United States)" }, + { "code": "es-UY", "name": "Spanish (Uruguay)" }, + { "code": "es-VE", "name": "Spanish (Venezuela)" }, + { "code": "su", "name": "Sundanese" }, + { "code": "sw", "name": "Swahili" }, + { "code": "sw-KE", "name": "Swahili (Kenya)" }, + { "code": "ss", "name": "Swati" }, + { "code": "sv", "name": "Swedish" }, + { "code": "sv-FI", "name": "Swedish (Finland)" }, + { "code": "sv-SE", "name": "Swedish (Sweden)" }, + { "code": "tl", "name": "Tagalog" }, + { "code": "tl-PH", "name": "Tagalog (Philippines)" }, + { "code": "tg", "name": "Tajik" }, + { "code": "tg-TJ", "name": "Tajik (Tajikistan)" }, + { "code": "tzl", "name": "Talossan" }, + { "code": "ta", "name": "Tamil" }, + { "code": "ta-IN", "name": "Tamil (India)" }, + { "code": "ta-LK", "name": "Tamil (Sri-Lanka)" }, + { "code": "tt", "name": "Tatar" }, + { "code": "te", "name": "Telugu" }, + { "code": "te-IN", "name": "Telugu (India)" }, + { "code": "tet", "name": "Tetum (Tetun)" }, + { "code": "th", "name": "Thai" }, + { "code": "th-TH", "name": "Thai (Thailand)" }, + { "code": "bo", "name": "Tibetan" }, + { "code": "bo-CN", "name": "Tibetan (China)" }, + { "code": "ti", "name": "Tigrinya" }, + { "code": "to", "name": "Tongan" }, + { "code": "ts", "name": "Tsonga" }, + { "code": "tn", "name": "Tswana" }, + { "code": "tr", "name": "Turkish" }, + { "code": "tr-TR", "name": "Turkish (Turkey)" }, + { "code": "tk", "name": "Turkmen" }, + { "code": "tk-TM", "name": "Turkmen (Turkmenistan)" }, + { "code": "udm", "name": "Udmurt" }, + { "code": "ug", "name": "Uighur" }, + { "code": "ug@Arab", "name": "Uighur (Arabic)" }, + { "code": "ug@Cyrl", "name": "Uighur (Cyrillic)" }, + { "code": "ug@Latin", "name": "Uighur (Latin)" }, + { "code": "uk", "name": "Ukrainian" }, + { "code": "uk-UA", "name": "Ukrainian (Ukraine)" }, + { "code": "vmf", "name": "Upper Franconian" }, + { "code": "hsb", "name": "Upper Sorbian" }, + { "code": "ur", "name": "Urdu" }, + { "code": "ur-PK", "name": "Urdu (Pakistan)" }, + { "code": "uz", "name": "Uzbek" }, + { "code": "uz@Arab", "name": "Uzbek (Arabic)" }, + { "code": "uz@Cyrl", "name": "Uzbek (Cyrillic)" }, + { "code": "uz@Latn", "name": "Uzbek (Latin)" }, + { "code": "uz-UZ", "name": "Uzbek (Uzbekistan)" }, + { "code": "ve", "name": "Venda" }, + { "code": "vec", "name": "Venetian" }, + { "code": "vi", "name": "Vietnamese" }, + { "code": "vi-VN", "name": "Vietnamese (Viet Nam)" }, + { "code": "vls", "name": "Vlaams" }, + { "code": "wa", "name": "Walloon" }, + { "code": "war", "name": "Wáray-Wáray" }, + { "code": "cy", "name": "Welsh" }, + { "code": "cy-GB", "name": "Welsh (United Kingdom)" }, + { "code": "fy", "name": "Western Frisian" }, + { "code": "fy-NL", "name": "Western Frisian (Netherlands)" }, + { "code": "wo", "name": "Wolof" }, + { "code": "wo-SN", "name": "Wolof (Senegal)" }, + { "code": "xh", "name": "Xhosa" }, + { "code": "yi", "name": "Yiddish" }, + { "code": "yo", "name": "Yoruba" }, + { "code": "zu", "name": "Zulu" }, + { "code": "zu-ZA", "name": "Zulu (South Africa)" }] + \ No newline at end of file diff --git a/apps/web-mzima-client/src/styles.scss b/apps/web-mzima-client/src/styles.scss index c7238e2ec8..c6a2c49f0c 100644 --- a/apps/web-mzima-client/src/styles.scss +++ b/apps/web-mzima-client/src/styles.scss @@ -133,6 +133,14 @@ a { .notice { margin: 0; } + + &.success-info { + background-color: #e4f9ed; + border: none; + border-radius: 4px; + padding: 16px; + font-style: normal; + } } .mat-drawer-container { diff --git a/libs/sdk/src/lib/helpers/api.ts b/libs/sdk/src/lib/helpers/api.ts index 9e0c90187b..8647d79600 100644 --- a/libs/sdk/src/lib/helpers/api.ts +++ b/libs/sdk/src/lib/helpers/api.ts @@ -14,7 +14,8 @@ export const ONLY = { NAME_ID_COLOR: 'name,id,color', NAME_COLOR_PERMISSIONS: 'name,color,everyone_can_create,can_create', NAME_ID_DESCRIPTION: 'name,id,description', - NEEDED_POSTS_LIST_PROPERTIES: 'id,title,content,status,color,contact,locks,post_media,data_source_message_id,post_date', + NEEDED_POSTS_LIST_PROPERTIES: + 'id,title,content,status,color,contact,locks,post_media,data_source_message_id,post_date', TAG_ID_PARENTID_PARENT_SLUG: 'tag,id,parent_id,parent,slug', TAG_ID_PARENTID_PARENT_SLUG_CHILDREN: 'tag,id,parent_id,parent,slug,children', TAG_ID_PARENTID_CHILDREN: 'tag,id,parent_id,children', diff --git a/libs/sdk/src/lib/models/posts.interface.ts b/libs/sdk/src/lib/models/posts.interface.ts index 4cd047cb1b..e685830012 100644 --- a/libs/sdk/src/lib/models/posts.interface.ts +++ b/libs/sdk/src/lib/models/posts.interface.ts @@ -61,6 +61,7 @@ export interface PostPropertiesInterface { locks?: any[]; data_source_message_id?: string; allowed_privileges: string[]; + enabled_languages: PostEnabledLanguages; } export interface PostPropertiesUser { @@ -80,6 +81,8 @@ export enum PostStatus { } export interface PostResult { + translations: any; + base_language: string; allowed_privileges: string[]; author_email?: string; author_realname?: string; @@ -112,6 +115,7 @@ export interface PostResult { form_id?: number; user?: PostPropertiesUser; post_content?: PostContent[]; + enabled_languages: PostEnabledLanguages; post_media?: any; } @@ -125,6 +129,7 @@ interface PostForm { url: string; description?: string; name?: string; + translations: any; } export interface PostContent { @@ -178,3 +183,8 @@ export interface PostContentField { type: string; value?: any; } + +export interface PostEnabledLanguages { + default: string; + available: string[]; +} diff --git a/libs/sdk/src/lib/services/posts.service.ts b/libs/sdk/src/lib/services/posts.service.ts index e3b8542949..e323495000 100644 --- a/libs/sdk/src/lib/services/posts.service.ts +++ b/libs/sdk/src/lib/services/posts.service.ts @@ -50,7 +50,6 @@ export class PostsService extends ResourceService { private responseObject: any; private awaitedResponse = new Subject(); public awaitedResponse$ = this.awaitedResponse.asObservable(); - constructor( protected override httpClient: HttpClient, protected override currentLoader: EnvLoader, @@ -70,6 +69,9 @@ export class PostsService extends ResourceService { updateStatus(id: string | number, status: string) { return super.patch(id, { status }); } + updateTranslations(id: string, post: any) { + return super.update(id, post); + } override post(params: any): Observable { return super.post(params);