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,
31 import { HtmlTags } from "../common/html-tags";
32 import { Spinner } from "../common/icon";
33 import { PersonListing } from "../person/person-listing";
34 import { SiteForm } from "./site-form";
36 interface AdminSettingsState {
37 siteRes: GetSiteResponse;
38 siteConfigRes: GetSiteConfigResponse;
39 siteConfigHjson: string;
41 banned: PersonViewSafe[];
42 siteConfigLoading: boolean;
43 leaveAdminTeamLoading: boolean;
46 export class AdminSettings extends Component<any, AdminSettingsState> {
47 private siteConfigTextAreaId = `site-config-${randomStr()}`;
48 private isoData = setIsoData(this.context);
49 private subscription: Subscription;
50 private emptyState: AdminSettingsState = {
51 siteRes: this.isoData.site_res,
52 siteConfigHjson: null,
58 siteConfigLoading: null,
59 leaveAdminTeamLoading: 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.siteConfigHjson = this.state.siteConfigRes.config_hjson;
74 this.state.banned = this.isoData.routeData[1].banned;
75 this.state.siteConfigLoading = false;
76 this.state.loading = false;
78 WebSocketService.Instance.send(
79 wsClient.getSiteConfig({
83 WebSocketService.Instance.send(
84 wsClient.getBannedPersons({
91 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
92 let promises: Promise<any>[] = [];
94 let siteConfigForm: GetSiteConfig = { auth: req.auth };
95 promises.push(req.client.getSiteConfig(siteConfigForm));
97 let bannedPersonsForm: GetBannedPersons = { auth: req.auth };
98 promises.push(req.client.getBannedPersons(bannedPersonsForm));
103 componentDidMount() {
105 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
110 componentWillUnmount() {
112 this.subscription.unsubscribe();
116 get documentTitle(): string {
117 return `${i18n.t("admin_settings")} - ${
118 this.state.siteRes.site_view.site.name
124 <div class="container">
125 {this.state.loading ? (
131 <div class="col-12 col-md-6">
133 title={this.documentTitle}
134 path={this.context.router.route.match.url}
136 {this.state.siteRes.site_view.site.id && (
138 site={this.state.siteRes.site_view.site}
139 showLocal={showLocal(this.isoData)}
145 <div class="col-12 col-md-6">{this.adminSettings()}</div>
155 <h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5>
156 <ul class="list-unstyled">
157 {this.state.siteRes.admins.map(admin => (
158 <li class="list-inline-item">
159 <PersonListing person={admin.person} />
171 onClick={linkEvent(this, this.handleLeaveAdminTeam)}
172 class="btn btn-danger mb-2"
174 {this.state.leaveAdminTeamLoading ? (
177 i18n.t("leave_admin_team")
186 <h5>{i18n.t("banned_users")}</h5>
187 <ul class="list-unstyled">
188 {this.state.banned.map(banned => (
189 <li class="list-inline-item">
190 <PersonListing person={banned.person} />
201 <h5>{i18n.t("admin_settings")}</h5>
202 <form onSubmit={linkEvent(this, this.handleSiteConfigSubmit)}>
203 <div class="form-group row">
205 class="col-12 col-form-label"
206 htmlFor={this.siteConfigTextAreaId}
208 {i18n.t("site_config")}
212 id={this.siteConfigTextAreaId}
213 value={this.state.siteConfigHjson}
214 onInput={linkEvent(this, this.handleSiteConfigHjsonChange)}
215 class="form-control text-monospace"
220 <div class="form-group row">
222 <button type="submit" class="btn btn-secondary mr-2">
223 {this.state.siteConfigLoading ? (
226 capitalizeFirstLetter(i18n.t("save"))
236 handleSiteConfigSubmit(i: AdminSettings, event: any) {
237 event.preventDefault();
238 i.state.siteConfigLoading = true;
239 let form: SaveSiteConfig = {
240 config_hjson: i.state.siteConfigHjson,
243 WebSocketService.Instance.send(wsClient.saveSiteConfig(form));
247 handleSiteConfigHjsonChange(i: AdminSettings, event: any) {
248 i.state.siteConfigHjson = event.target.value;
252 handleLeaveAdminTeam(i: AdminSettings) {
253 i.state.leaveAdminTeamLoading = true;
254 WebSocketService.Instance.send(wsClient.leaveAdmin({ auth: authField() }));
258 parseMessage(msg: any) {
259 let op = wsUserOp(msg);
262 toast(i18n.t(msg.error), "danger");
263 this.context.router.history.push("/");
264 this.state.loading = false;
265 this.setState(this.state);
267 } else if (op == UserOperation.EditSite) {
268 let data = wsJsonToRes<SiteResponse>(msg).data;
269 this.state.siteRes.site_view = data.site_view;
270 this.setState(this.state);
271 toast(i18n.t("site_saved"));
272 } else if (op == UserOperation.GetBannedPersons) {
273 let data = wsJsonToRes<BannedPersonsResponse>(msg).data;
274 this.state.banned = data.banned;
275 this.setState(this.state);
276 } else if (op == UserOperation.GetSiteConfig) {
277 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
278 this.state.siteConfigRes = data;
279 this.state.loading = false;
280 this.state.siteConfigHjson = 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.siteConfigHjson = this.state.siteConfigRes.config_hjson;
296 this.state.siteConfigLoading = false;
297 toast(i18n.t("site_saved"));
298 this.setState(this.state);