1 import { Component, linkEvent } from 'inferno';
2 import { Subscription } from 'rxjs';
10 } from 'lemmy-js-client';
11 import { WebSocketService } from '../services';
14 capitalizeFirstLetter,
24 import autosize from 'autosize';
25 import { SiteForm } from './site-form';
26 import { UserListing } from './user-listing';
27 import { HtmlTags } from './html-tags';
28 import { i18n } from '../i18next';
29 import { InitialFetchRequest } from 'shared/interfaces';
31 interface AdminSettingsState {
32 siteRes: GetSiteResponse;
33 siteConfigRes: GetSiteConfigResponse;
34 siteConfigForm: SaveSiteConfig;
36 siteConfigLoading: boolean;
39 export class AdminSettings extends Component<any, AdminSettingsState> {
40 private siteConfigTextAreaId = `site-config-${randomStr()}`;
41 private isoData = setIsoData(this.context);
42 private subscription: Subscription;
43 private emptyState: AdminSettingsState = {
44 siteRes: this.isoData.site_res,
53 siteConfigLoading: null,
56 constructor(props: any, context: any) {
57 super(props, context);
59 this.state = this.emptyState;
61 this.parseMessage = this.parseMessage.bind(this);
62 this.subscription = wsSubscribe(this.parseMessage);
64 // Only fetch the data if coming from another route
65 if (this.isoData.path == this.context.router.route.match.url) {
66 this.state.siteConfigRes = this.isoData.routeData[0];
67 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
68 this.state.siteConfigLoading = false;
69 this.state.loading = false;
71 WebSocketService.Instance.send(
72 wsClient.getSiteConfig({
79 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
80 let form: GetSiteConfig = { auth: req.auth };
81 return [req.client.getSiteConfig(form)];
86 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
91 componentWillUnmount() {
93 this.subscription.unsubscribe();
97 get documentTitle(): string {
98 return `${i18n.t('admin_settings')} - ${
99 this.state.siteRes.site_view.site.name
105 <div class="container">
107 title={this.documentTitle}
108 path={this.context.router.route.match.url}
110 {this.state.loading ? (
112 <svg class="icon icon-spinner spin">
113 <use xlinkHref="#icon-spinner"></use>
118 <div class="col-12 col-md-6">
119 {this.state.siteRes.site_view.site.id && (
120 <SiteForm site={this.state.siteRes.site_view.site} />
125 <div class="col-12 col-md-6">{this.adminSettings()}</div>
135 <h5>{capitalizeFirstLetter(i18n.t('admins'))}</h5>
136 <ul class="list-unstyled">
137 {this.state.siteRes.admins.map(admin => (
138 <li class="list-inline-item">
139 <UserListing user={admin.user} />
150 <h5>{i18n.t('banned_users')}</h5>
151 <ul class="list-unstyled">
152 {this.state.siteRes.banned.map(banned => (
153 <li class="list-inline-item">
154 <UserListing user={banned.user} />
165 <h5>{i18n.t('admin_settings')}</h5>
166 <form onSubmit={linkEvent(this, this.handleSiteConfigSubmit)}>
167 <div class="form-group row">
169 class="col-12 col-form-label"
170 htmlFor={this.siteConfigTextAreaId}
172 {i18n.t('site_config')}
176 id={this.siteConfigTextAreaId}
177 value={this.state.siteConfigForm.config_hjson}
178 onInput={linkEvent(this, this.handleSiteConfigHjsonChange)}
179 class="form-control text-monospace"
184 <div class="form-group row">
186 <button type="submit" class="btn btn-secondary mr-2">
187 {this.state.siteConfigLoading ? (
188 <svg class="icon icon-spinner spin">
189 <use xlinkHref="#icon-spinner"></use>
192 capitalizeFirstLetter(i18n.t('save'))
202 handleSiteConfigSubmit(i: AdminSettings, event: any) {
203 event.preventDefault();
204 i.state.siteConfigLoading = true;
205 WebSocketService.Instance.send(
206 wsClient.saveSiteConfig(i.state.siteConfigForm)
211 handleSiteConfigHjsonChange(i: AdminSettings, event: any) {
212 i.state.siteConfigForm.config_hjson = event.target.value;
216 parseMessage(msg: any) {
217 let op = wsUserOp(msg);
219 toast(i18n.t(msg.error), 'danger');
220 this.context.router.history.push('/');
221 this.state.loading = false;
222 this.setState(this.state);
224 } else if (msg.reconnect) {
225 } else if (op == UserOperation.EditSite) {
226 let data = wsJsonToRes<SiteResponse>(msg).data;
227 this.state.siteRes.site_view = data.site_view;
228 this.setState(this.state);
229 toast(i18n.t('site_saved'));
230 } else if (op == UserOperation.GetSiteConfig) {
231 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
232 this.state.siteConfigRes = data;
233 this.state.loading = false;
234 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
235 this.setState(this.state);
236 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
238 } else if (op == UserOperation.SaveSiteConfig) {
239 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
240 this.state.siteConfigRes = data;
241 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
242 this.state.siteConfigLoading = false;
243 toast(i18n.t('site_saved'));
244 this.setState(this.state);