1 import autosize from "autosize";
2 import { Component, linkEvent } from "inferno";
13 } from "lemmy-js-client";
14 import { Subscription } from "rxjs";
15 import { i18n } from "../../i18next";
16 import { InitialFetchRequest } from "../../interfaces";
17 import { WebSocketService } from "../../services";
20 capitalizeFirstLetter,
30 import { HtmlTags } from "../common/html-tags";
31 import { Spinner } from "../common/icon";
32 import { PersonListing } from "../person/person-listing";
33 import { SiteForm } from "./site-form";
35 interface AdminSettingsState {
36 siteRes: GetSiteResponse;
37 siteConfigRes: GetSiteConfigResponse;
38 siteConfigForm: SaveSiteConfig;
40 banned: PersonViewSafe[];
41 siteConfigLoading: boolean;
42 leaveAdminTeamLoading: boolean;
45 export class AdminSettings extends Component<any, AdminSettingsState> {
46 private siteConfigTextAreaId = `site-config-${randomStr()}`;
47 private isoData = setIsoData(this.context);
48 private subscription: Subscription;
49 private emptyState: AdminSettingsState = {
50 siteRes: this.isoData.site_res,
60 siteConfigLoading: null,
61 leaveAdminTeamLoading: null,
64 constructor(props: any, context: any) {
65 super(props, context);
67 this.state = this.emptyState;
69 this.parseMessage = this.parseMessage.bind(this);
70 this.subscription = wsSubscribe(this.parseMessage);
72 // Only fetch the data if coming from another route
73 if (this.isoData.path == this.context.router.route.match.url) {
74 this.state.siteConfigRes = this.isoData.routeData[0];
75 this.state.siteConfigForm.config_hjson =
76 this.state.siteConfigRes.config_hjson;
77 this.state.banned = this.isoData.routeData[1].banned;
78 this.state.siteConfigLoading = false;
79 this.state.loading = false;
81 this.state.siteConfigForm.auth = authField();
82 WebSocketService.Instance.send(
83 wsClient.getSiteConfig({
87 WebSocketService.Instance.send(
88 wsClient.getBannedPersons({
95 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
96 let promises: Promise<any>[] = [];
98 let siteConfigForm: GetSiteConfig = { auth: req.auth };
99 promises.push(req.client.getSiteConfig(siteConfigForm));
101 let bannedPersonsForm: GetBannedPersons = { auth: req.auth };
102 promises.push(req.client.getBannedPersons(bannedPersonsForm));
107 componentDidMount() {
109 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
114 componentWillUnmount() {
116 this.subscription.unsubscribe();
120 get documentTitle(): string {
121 return `${i18n.t("admin_settings")} - ${
122 this.state.siteRes.site_view.site.name
128 <div class="container">
129 {this.state.loading ? (
135 <div class="col-12 col-md-6">
137 title={this.documentTitle}
138 path={this.context.router.route.match.url}
140 {this.state.siteRes.site_view.site.id && (
141 <SiteForm site={this.state.siteRes.site_view.site} />
146 <div class="col-12 col-md-6">{this.adminSettings()}</div>
156 <h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5>
157 <ul class="list-unstyled">
158 {this.state.siteRes.admins.map(admin => (
159 <li class="list-inline-item">
160 <PersonListing person={admin.person} />
172 onClick={linkEvent(this, this.handleLeaveAdminTeam)}
173 class="btn btn-danger mb-2"
175 {this.state.leaveAdminTeamLoading ? (
178 i18n.t("leave_admin_team")
187 <h5>{i18n.t("banned_users")}</h5>
188 <ul class="list-unstyled">
189 {this.state.banned.map(banned => (
190 <li class="list-inline-item">
191 <PersonListing person={banned.person} />
202 <h5>{i18n.t("admin_settings")}</h5>
203 <form onSubmit={linkEvent(this, this.handleSiteConfigSubmit)}>
204 <div class="form-group row">
206 class="col-12 col-form-label"
207 htmlFor={this.siteConfigTextAreaId}
209 {i18n.t("site_config")}
213 id={this.siteConfigTextAreaId}
214 value={this.state.siteConfigForm.config_hjson}
215 onInput={linkEvent(this, this.handleSiteConfigHjsonChange)}
216 class="form-control text-monospace"
221 <div class="form-group row">
223 <button type="submit" class="btn btn-secondary mr-2">
224 {this.state.siteConfigLoading ? (
227 capitalizeFirstLetter(i18n.t("save"))
237 handleSiteConfigSubmit(i: AdminSettings, event: any) {
238 event.preventDefault();
239 i.state.siteConfigLoading = true;
240 WebSocketService.Instance.send(
241 wsClient.saveSiteConfig(i.state.siteConfigForm)
246 handleSiteConfigHjsonChange(i: AdminSettings, event: any) {
247 i.state.siteConfigForm.config_hjson = event.target.value;
251 handleLeaveAdminTeam(i: AdminSettings) {
252 i.state.leaveAdminTeamLoading = true;
253 WebSocketService.Instance.send(wsClient.leaveAdmin({ auth: authField() }));
257 parseMessage(msg: any) {
258 let op = wsUserOp(msg);
261 toast(i18n.t(msg.error), "danger");
262 this.context.router.history.push("/");
263 this.state.loading = false;
264 this.setState(this.state);
266 } else if (op == UserOperation.EditSite) {
267 let data = wsJsonToRes<SiteResponse>(msg).data;
268 this.state.siteRes.site_view = data.site_view;
269 this.setState(this.state);
270 toast(i18n.t("site_saved"));
271 } else if (op == UserOperation.GetBannedPersons) {
272 let data = wsJsonToRes<BannedPersonsResponse>(msg).data;
273 this.state.banned = data.banned;
274 this.setState(this.state);
275 } else if (op == UserOperation.GetSiteConfig) {
276 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
277 this.state.siteConfigRes = data;
278 this.state.loading = false;
279 this.state.siteConfigForm.config_hjson =
280 this.state.siteConfigRes.config_hjson;
281 this.setState(this.state);
282 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
284 } else if (op == UserOperation.LeaveAdmin) {
285 let data = wsJsonToRes<GetSiteResponse>(msg).data;
286 this.state.siteRes.site_view = data.site_view;
287 this.setState(this.state);
288 this.state.leaveAdminTeamLoading = false;
289 toast(i18n.t("left_admin_team"));
290 this.setState(this.state);
291 this.context.router.history.push("/");
292 } else if (op == UserOperation.SaveSiteConfig) {
293 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
294 this.state.siteConfigRes = data;
295 this.state.siteConfigForm.config_hjson =
296 this.state.siteConfigRes.config_hjson;
297 this.state.siteConfigLoading = false;
298 toast(i18n.t("site_saved"));
299 this.setState(this.state);