1 import { Component, linkEvent } from 'inferno';
2 import { Subscription } from 'rxjs';
11 } from 'lemmy-js-client';
12 import { WebSocketService } from '../services';
15 capitalizeFirstLetter,
23 import autosize from 'autosize';
24 import { SiteForm } from './site-form';
25 import { UserListing } from './user-listing';
26 import { HtmlTags } from './html-tags';
27 import { i18n } from '../i18next';
28 import { InitialFetchRequest } from 'shared/interfaces';
30 interface AdminSettingsState {
31 siteRes: GetSiteResponse;
32 siteConfigRes: GetSiteConfigResponse;
33 siteConfigForm: SiteConfigForm;
35 siteConfigLoading: boolean;
38 export class AdminSettings extends Component<any, AdminSettingsState> {
39 private siteConfigTextAreaId = `site-config-${randomStr()}`;
40 private isoData = setIsoData(this.context);
41 private subscription: Subscription;
42 private emptyState: AdminSettingsState = {
43 siteRes: this.isoData.site,
52 siteConfigLoading: null,
55 constructor(props: any, context: any) {
56 super(props, context);
58 this.state = this.emptyState;
60 this.parseMessage = this.parseMessage.bind(this);
61 this.subscription = wsSubscribe(this.parseMessage);
63 // Only fetch the data if coming from another route
64 if (this.isoData.path == this.context.router.route.match.url) {
65 this.state.siteConfigRes = this.isoData.routeData[0];
66 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
67 this.state.siteConfigLoading = false;
68 this.state.loading = false;
70 WebSocketService.Instance.getSiteConfig();
74 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
75 let form: GetSiteConfig = {};
76 setAuth(form, req.auth);
77 return [req.client.getSiteConfig(form)];
82 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
87 componentWillUnmount() {
89 this.subscription.unsubscribe();
93 get documentTitle(): string {
94 return `${i18n.t('admin_settings')} - ${this.state.siteRes.site.name}`;
99 <div class="container">
101 title={this.documentTitle}
102 path={this.context.router.route.match.url}
104 {this.state.loading ? (
106 <svg class="icon icon-spinner spin">
107 <use xlinkHref="#icon-spinner"></use>
112 <div class="col-12 col-md-6">
113 {this.state.siteRes.site.id && (
114 <SiteForm site={this.state.siteRes.site} />
119 <div class="col-12 col-md-6">{this.adminSettings()}</div>
129 <h5>{capitalizeFirstLetter(i18n.t('admins'))}</h5>
130 <ul class="list-unstyled">
131 {this.state.siteRes.admins.map(admin => (
132 <li class="list-inline-item">
136 preferred_username: admin.preferred_username,
137 avatar: admin.avatar,
140 actor_id: admin.actor_id,
153 <h5>{i18n.t('banned_users')}</h5>
154 <ul class="list-unstyled">
155 {this.state.siteRes.banned.map(banned => (
156 <li class="list-inline-item">
160 preferred_username: banned.preferred_username,
161 avatar: banned.avatar,
164 actor_id: banned.actor_id,
177 <h5>{i18n.t('admin_settings')}</h5>
178 <form onSubmit={linkEvent(this, this.handleSiteConfigSubmit)}>
179 <div class="form-group row">
181 class="col-12 col-form-label"
182 htmlFor={this.siteConfigTextAreaId}
184 {i18n.t('site_config')}
188 id={this.siteConfigTextAreaId}
189 value={this.state.siteConfigForm.config_hjson}
190 onInput={linkEvent(this, this.handleSiteConfigHjsonChange)}
191 class="form-control text-monospace"
196 <div class="form-group row">
198 <button type="submit" class="btn btn-secondary mr-2">
199 {this.state.siteConfigLoading ? (
200 <svg class="icon icon-spinner spin">
201 <use xlinkHref="#icon-spinner"></use>
204 capitalizeFirstLetter(i18n.t('save'))
214 handleSiteConfigSubmit(i: AdminSettings, event: any) {
215 event.preventDefault();
216 i.state.siteConfigLoading = true;
217 WebSocketService.Instance.saveSiteConfig(i.state.siteConfigForm);
221 handleSiteConfigHjsonChange(i: AdminSettings, event: any) {
222 i.state.siteConfigForm.config_hjson = event.target.value;
226 parseMessage(msg: WebSocketJsonResponse) {
228 let res = wsJsonToRes(msg);
230 toast(i18n.t(msg.error), 'danger');
231 this.context.router.history.push('/');
232 this.state.loading = false;
233 this.setState(this.state);
235 } else if (msg.reconnect) {
236 } else if (res.op == UserOperation.EditSite) {
237 let data = res.data as SiteResponse;
238 this.state.siteRes.site = data.site;
239 this.setState(this.state);
240 toast(i18n.t('site_saved'));
241 } else if (res.op == UserOperation.GetSiteConfig) {
242 let data = res.data as GetSiteConfigResponse;
243 this.state.siteConfigRes = data;
244 this.state.loading = false;
245 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
246 this.setState(this.state);
247 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
249 } else if (res.op == UserOperation.SaveSiteConfig) {
250 let data = res.data as GetSiteConfigResponse;
251 this.state.siteConfigRes = data;
252 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
253 this.state.siteConfigLoading = false;
254 toast(i18n.t('site_saved'));
255 this.setState(this.state);