matrix-dimension/web/app/admin/terms/new-edit/new-edit.component.ts
2021-11-30 19:29:39 -07:00

232 lines
8.1 KiB
TypeScript

import { Component, OnInit } from "@angular/core";
import { ToasterService } from "angular2-toaster";
import { AdminTermsApiService } from "../../../shared/services/admin/admin-terms-api.service";
import { ActivatedRoute, Router } from "@angular/router";
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import ISO6391 from "iso-639-1";
import { AdminTermsNewEditPublishDialogComponent, } from "./publish/publish.component";
import { TranslateService } from "@ngx-translate/core";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
interface ILanguage {
name: string,
text: string,
langName: string,
url: string,
isExternal: boolean,
externalUrl: string,
}
@Component({
templateUrl: "./new-edit.component.html",
styleUrls: ["./new-edit.component.scss"],
})
export class AdminNewEditTermsComponent implements OnInit {
// TODO: Multiple language support
// TODO: Support external URLs
private shortcode: string;
public Editor = ClassicEditor;
public isLoading = true;
public isUpdating = false;
public takenShortcodes: string[];
public chosenLanguage: string = ISO6391.getAllCodes()[0];
public languages: {
[languageCode: string]: ILanguage;
} = {
"en": {
name: "",
text: "",
langName: "English",
url: "", // TODO: Calculate
isExternal: false,
externalUrl: "",
},
};
public isEditing = false;
public get chosenLanguageCodes(): string[] {
return Object.keys(this.languages);
}
public get availableLanguages(): { name: string, code: string }[] {
return ISO6391.getAllCodes()
.filter(c => !this.chosenLanguageCodes.includes(c))
.map(c => {
return {code: c, name: ISO6391.getName(c)};
});
}
constructor(private adminTerms: AdminTermsApiService,
private toaster: ToasterService,
private router: Router,
private activatedRoute: ActivatedRoute,
private modal: NgbModal,
public translate: TranslateService) {
this.translate = translate;
}
public ngOnInit() {
const params = this.activatedRoute.snapshot.params;
this.shortcode = params.shortcode;
this.isEditing = !!this.shortcode;
if (this.isEditing) {
this.adminTerms.getDraft(this.shortcode).then(policy => {
this.shortcode = policy.shortcode;
this.languages = {};
for (const code in policy.languages) {
const i18nPolicy = policy.languages[code];
this.languages[code] = {
text: i18nPolicy.text,
url: i18nPolicy.url,
name: i18nPolicy.name,
isExternal: false,
langName: ISO6391.getName(code),
externalUrl: "",
};
}
this.isLoading = false;
}).catch(err => {
console.error(err);
this.translate.get('Failed to load policy').subscribe((res: string) => {
this.toaster.pop("error", res);
});
});
} else {
this.adminTerms.getAllPolicies().then(policies => {
this.takenShortcodes = policies.map(p => p.shortcode);
this.isLoading = false;
}).catch(err => {
console.error(err);
this.translate.get('Failed to load policies').subscribe((res: string) => {
this.toaster.pop("error", res);
});
});
}
}
public async publish() {
this.isUpdating = true;
await this.adminTerms.updateDraft(this.shortcode, {
name: this.languages['en'].name,
text: this.languages['en'].text,
url: `${window.location.origin}/widgets/terms/${this.shortcode}/en/draft`,
});
const termsEditRef = this.modal.open(AdminTermsNewEditPublishDialogComponent, {
backdrop: 'static',
size: 'sm',
});
termsEditRef.result.then(async (val) => {
if (!val) return; // closed without publish
try {
// Change the URL of the draft
// TODO: Don't track URLs for drafts
await this.adminTerms.updateDraft(this.shortcode, {
name: this.languages['en'].name,
text: this.languages['en'].text,
url: `${window.location.origin}/widgets/terms/${this.shortcode}/en/${val}`,
});
await this.adminTerms.publishDraft(this.shortcode, val);
this.translate.get('Policy published').subscribe((res: string) => {
this.toaster.pop("success", res);
});
this.router.navigate(["../.."], {relativeTo: this.activatedRoute});
} catch (e) {
console.error(e);
this.translate.get('Error publishing policy').subscribe((res: string) => {
this.toaster.pop("error", res);
});
this.isUpdating = false;
}
});
}
public async create() {
for (const languageCode in this.languages) {
if (this.languages[languageCode].name.trim().length <= 0) {
this.translate.get('Please enter a name for all policies').subscribe((res: string) => {
this.toaster.pop("warning", res);
});
return;
}
if (this.languages[languageCode].text.trim().length <= 0) {
this.translate.get('Please enter text for all policies').subscribe((res: string) => {
this.toaster.pop("warning", res);
});
return;
}
}
this.isUpdating = true;
if (this.isEditing) {
try {
await this.adminTerms.updateDraft(this.shortcode, {
name: this.languages['en'].name,
text: this.languages['en'].text,
url: `${window.location.origin}/widgets/terms/${this.shortcode}/en/draft`,
});
this.translate.get('Draft saved').subscribe((res: string) => {
this.toaster.pop("success", res);
});
this.router.navigate(["../.."], {relativeTo: this.activatedRoute});
} catch (e) {
console.error(e);
this.translate.get('Error saving policy').subscribe((res: string) => {
this.toaster.pop("error", res);
});
this.isUpdating = false;
}
return;
}
const startShortcode = this.languages['en'].name.toLowerCase().replace(/[^a-z0-9]/gi, '_');
let shortcode = startShortcode;
let i = 0;
while (this.takenShortcodes.includes(shortcode)) {
shortcode = `${startShortcode}_${++i}`;
}
try {
await this.adminTerms.createDraft(shortcode, {
name: this.languages['en'].name,
text: this.languages['en'].text,
url: `${window.location.origin}/widgets/terms/${shortcode}/en/draft`,
});
this.translate.get('Draft created').subscribe((res: string) => {
this.toaster.pop("success", res);
});
this.router.navigate([".."], {relativeTo: this.activatedRoute});
} catch (e) {
console.error(e);
this.translate.get('Error creating document').subscribe((res: string) => {
this.toaster.pop("error", res);
});
this.isUpdating = false;
}
}
public addLanguage() {
this.languages[this.chosenLanguage] = {
name: "",
text: "",
url: "", // TODO: Calculate
isExternal: false,
externalUrl: "",
langName: ISO6391.getName(this.chosenLanguage),
};
this.chosenLanguage = this.availableLanguages[0].code;
}
}