1 import { Component, linkEvent } from 'inferno';
2 import { Subscription } from 'rxjs';
10 } from 'lemmy-js-client';
11 import { UserService, WebSocketService } from '../services';
14 capitalizeFirstLetter,
22 import autosize from 'autosize';
23 import { SiteForm } from './site-form';
24 import { UserListing } from './user-listing';
25 import { HtmlTags } from './html-tags';
26 import { i18n } from '../i18next';
27 import { InitialFetchRequest } from 'shared/interfaces';
29 interface AdminSettingsState {
30 siteRes: GetSiteResponse;
31 siteConfigRes: GetSiteConfigResponse;
32 siteConfigForm: SaveSiteConfig;
34 siteConfigLoading: boolean;
37 export class AdminSettings extends Component<any, AdminSettingsState> {
38 private siteConfigTextAreaId = `site-config-${randomStr()}`;
39 private isoData = setIsoData(this.context);
40 private subscription: Subscription;
41 private emptyState: AdminSettingsState = {
42 siteRes: this.isoData.site_res,
45 auth: UserService.Instance.authField(),
51 siteConfigLoading: null,
54 constructor(props: any, context: any) {
55 super(props, context);
57 this.state = this.emptyState;
59 this.parseMessage = this.parseMessage.bind(this);
60 this.subscription = wsSubscribe(this.parseMessage);
62 // Only fetch the data if coming from another route
63 if (this.isoData.path == this.context.router.route.match.url) {
64 this.state.siteConfigRes = this.isoData.routeData[0];
65 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
66 this.state.siteConfigLoading = false;
67 this.state.loading = false;
69 WebSocketService.Instance.client.getSiteConfig({
70 auth: UserService.Instance.authField(),
75 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
76 let form: GetSiteConfig = { auth: 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')} - ${
95 this.state.siteRes.site_view.site.name
101 <div class="container">
103 title={this.documentTitle}
104 path={this.context.router.route.match.url}
106 {this.state.loading ? (
108 <svg class="icon icon-spinner spin">
109 <use xlinkHref="#icon-spinner"></use>
114 <div class="col-12 col-md-6">
115 {this.state.siteRes.site_view.site.id && (
116 <SiteForm site={this.state.siteRes.site_view.site} />
121 <div class="col-12 col-md-6">{this.adminSettings()}</div>
131 <h5>{capitalizeFirstLetter(i18n.t('admins'))}</h5>
132 <ul class="list-unstyled">
133 {this.state.siteRes.admins.map(admin => (
134 <li class="list-inline-item">
135 <UserListing user={admin.user} />
146 <h5>{i18n.t('banned_users')}</h5>
147 <ul class="list-unstyled">
148 {this.state.siteRes.banned.map(banned => (
149 <li class="list-inline-item">
150 <UserListing user={banned.user} />
161 <h5>{i18n.t('admin_settings')}</h5>
162 <form onSubmit={linkEvent(this, this.handleSiteConfigSubmit)}>
163 <div class="form-group row">
165 class="col-12 col-form-label"
166 htmlFor={this.siteConfigTextAreaId}
168 {i18n.t('site_config')}
172 id={this.siteConfigTextAreaId}
173 value={this.state.siteConfigForm.config_hjson}
174 onInput={linkEvent(this, this.handleSiteConfigHjsonChange)}
175 class="form-control text-monospace"
180 <div class="form-group row">
182 <button type="submit" class="btn btn-secondary mr-2">
183 {this.state.siteConfigLoading ? (
184 <svg class="icon icon-spinner spin">
185 <use xlinkHref="#icon-spinner"></use>
188 capitalizeFirstLetter(i18n.t('save'))
198 handleSiteConfigSubmit(i: AdminSettings, event: any) {
199 event.preventDefault();
200 i.state.siteConfigLoading = true;
201 WebSocketService.Instance.client.saveSiteConfig(i.state.siteConfigForm);
205 handleSiteConfigHjsonChange(i: AdminSettings, event: any) {
206 i.state.siteConfigForm.config_hjson = event.target.value;
210 parseMessage(msg: any) {
211 let op = wsUserOp(msg);
213 toast(i18n.t(msg.error), 'danger');
214 this.context.router.history.push('/');
215 this.state.loading = false;
216 this.setState(this.state);
218 } else if (msg.reconnect) {
219 } else if (op == UserOperation.EditSite) {
220 let data = wsJsonToRes<SiteResponse>(msg).data;
221 this.state.siteRes.site_view = data.site_view;
222 this.setState(this.state);
223 toast(i18n.t('site_saved'));
224 } else if (op == UserOperation.GetSiteConfig) {
225 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
226 this.state.siteConfigRes = data;
227 this.state.loading = false;
228 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
229 this.setState(this.state);
230 var textarea: any = document.getElementById(this.siteConfigTextAreaId);
232 } else if (op == UserOperation.SaveSiteConfig) {
233 let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
234 this.state.siteConfigRes = data;
235 this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
236 this.state.siteConfigLoading = false;
237 toast(i18n.t('site_saved'));
238 this.setState(this.state);