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;
44 export class AdminSettings extends Component<any, AdminSettingsState> {
45 private siteConfigTextAreaId = `site-config-${randomStr()}`;
46 private isoData = setIsoData(this.context);
47 private subscription: Subscription;
48 private emptyState: AdminSettingsState = {
49 siteRes: this.isoData.site_res,
59 siteConfigLoading: null,
62 constructor(props: any, context: any) {
63 super(props, context);
65 this.state = this.emptyState;
67 this.parseMessage = this.parseMessage.bind(this);
68 this.subscription = wsSubscribe(this.parseMessage);
70 // Only fetch the data if coming from another route
71 if (this.isoData.path == this.context.router.route.match.url) {
72 this.state.siteConfigRes = this.isoData.routeData[0];
73 this.state.siteConfigForm.config_hjson =
74 this.state.siteConfigRes.config_hjson;
75 this.state.banned = this.isoData.routeData[1].banned;
76 this.state.siteConfigLoading = false;
77 this.state.loading = false;
79 this.state.siteConfigForm.auth = authField();
80 WebSocketService.Instance.send(
81 wsClient.getSiteConfig({
85 WebSocketService.Instance.send(
86 wsClient.getBannedPersons({
93 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
94 let promises: Promise<any>[] = [];
96 let siteConfigForm: GetSiteConfig = { auth: req.auth };
97 promises.push(req.client.getSiteConfig(siteConfigForm));
99 let bannedPersonsForm: GetBannedPersons = { auth: req.auth };
100 promises.push(req.client.getBannedPersons(bannedPersonsForm));
105 componentDidMount() {
107 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
112 componentWillUnmount() {
114 this.subscription.unsubscribe();
118 get documentTitle(): string {
119 return `${i18n.t("admin_settings")} - ${
120 this.state.siteRes.site_view.site.name
126 <div class="container">
127 {this.state.loading ? (
133 <div class="col-12 col-md-6">
135 title={this.documentTitle}
136 path={this.context.router.route.match.url}
138 {this.state.siteRes.site_view.site.id && (
139 <SiteForm site={this.state.siteRes.site_view.site} />
144 <div class="col-12 col-md-6">{this.adminSettings()}</div>
154 <h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5>
155 <ul class="list-unstyled">
156 {this.state.siteRes.admins.map(admin => (
157 <li class="list-inline-item">
158 <PersonListing person={admin.person} />
169 <h5>{i18n.t("banned_users")}</h5>
170 <ul class="list-unstyled">
171 {this.state.banned.map(banned => (
172 <li class="list-inline-item">
173 <PersonListing person={banned.person} />
184 <h5>{i18n.t("admin_settings")}</h5>
185 <form onSubmit={linkEvent(this, this.handleSiteConfigSubmit)}>
186 <div class="form-group row">
188 class="col-12 col-form-label"
189 htmlFor={this.siteConfigTextAreaId}
191 {i18n.t("site_config")}
195 id={this.siteConfigTextAreaId}
196 value={this.state.siteConfigForm.config_hjson}
197 onInput={linkEvent(this, this.handleSiteConfigHjsonChange)}
198 class="form-control text-monospace"
203 <div class="form-group row">
205 <button type="submit" class="btn btn-secondary mr-2">
206 {this.state.siteConfigLoading ? (
209 capitalizeFirstLetter(i18n.t("save"))
219 handleSiteConfigSubmit(i: AdminSettings, event: any) {
220 event.preventDefault();
221 i.state.siteConfigLoading = true;
222 WebSocketService.Instance.send(
223 wsClient.saveSiteConfig(i.state.siteConfigForm)
228 handleSiteConfigHjsonChange(i: AdminSettings, event: any) {
229 i.state.siteConfigForm.config_hjson = event.target.value;
233 parseMessage(msg: any) {
234 let op = wsUserOp(msg);
237 toast(i18n.t(msg.error), "danger");
238 this.context.router.history.push("/");
239 this.state.loading = false;
240 this.setState(this.state);
242 } else if (op == UserOperation.EditSite) {
243 let data = wsJsonToRes<SiteResponse>(msg).data;
244 this.state.siteRes.site_view = data.site_view;
245 this.setState(this.state);
246 toast(i18n.t("site_saved"));
247 } else if (op == UserOperation.GetBannedPersons) {
248 let data = wsJsonToRes<BannedPersonsResponse>(msg).data;
249 this.state.banned = data.banned;
250 this.setState(this.state);
251 } else if (op == UserOperation.GetSiteConfig) {
252 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
253 this.state.siteConfigRes = data;
254 this.state.loading = false;
255 this.state.siteConfigForm.config_hjson =
256 this.state.siteConfigRes.config_hjson;
257 this.setState(this.state);
258 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
260 } else if (op == UserOperation.SaveSiteConfig) {
261 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
262 this.state.siteConfigRes = data;
263 this.state.siteConfigForm.config_hjson =
264 this.state.siteConfigRes.config_hjson;
265 this.state.siteConfigLoading = false;
266 toast(i18n.t("site_saved"));
267 this.setState(this.state);