+import {
+ fetchThemeList,
+ myAuthRequired,
+ setIsoData,
+ showLocal,
+} from "@utils/app";
+import { capitalizeFirstLetter } from "@utils/helpers";
+import { RouteDataResponse } from "@utils/types";
+import classNames from "classnames";
import { Component, linkEvent } from "inferno";
import {
BannedPersonsResponse,
GetSiteResponse,
PersonView,
} from "lemmy-js-client";
-import { i18n } from "../../i18next";
import { InitialFetchRequest } from "../../interfaces";
-import { FirstLoadService } from "../../services/FirstLoadService";
+import { removeFromEmojiDataModel, updateEmojiDataModel } from "../../markdown";
+import { FirstLoadService, I18NextService } from "../../services";
import { HttpService, RequestState } from "../../services/HttpService";
-import {
- capitalizeFirstLetter,
- fetchThemeList,
- myAuthRequired,
- removeFromEmojiDataModel,
- setIsoData,
- showLocal,
- toast,
- updateEmojiDataModel,
-} from "../../utils";
+import { toast } from "../../toast";
import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon";
import Tabs from "../common/tabs";
import { SiteForm } from "./site-form";
import { TaglineForm } from "./tagline-form";
+type AdminSettingsData = RouteDataResponse<{
+ bannedRes: BannedPersonsResponse;
+ instancesRes: GetFederatedInstancesResponse;
+}>;
+
interface AdminSettingsState {
siteRes: GetSiteResponse;
banned: PersonView[];
instancesRes: RequestState<GetFederatedInstancesResponse>;
bannedRes: RequestState<BannedPersonsResponse>;
leaveAdminTeamRes: RequestState<GetSiteResponse>;
+ loading: boolean;
themeList: string[];
isIsomorphic: boolean;
}
export class AdminSettings extends Component<any, AdminSettingsState> {
- private isoData = setIsoData(this.context);
+ private isoData = setIsoData<AdminSettingsData>(this.context);
state: AdminSettingsState = {
siteRes: this.isoData.site_res,
banned: [],
bannedRes: { state: "empty" },
instancesRes: { state: "empty" },
leaveAdminTeamRes: { state: "empty" },
+ loading: false,
themeList: [],
isIsomorphic: false,
};
// Only fetch the data if coming from another route
if (FirstLoadService.isFirstLoad) {
- const [bannedRes, instancesRes] = this.isoData.routeData;
+ const { bannedRes, instancesRes } = this.isoData.routeData;
+
this.state = {
...this.state,
bannedRes,
}
}
- async fetchData() {
- this.setState({
- bannedRes: { state: "loading" },
- instancesRes: { state: "loading" },
- themeList: [],
- });
-
- const auth = myAuthRequired();
-
- const [bannedRes, instancesRes, themeList] = await Promise.all([
- HttpService.client.getBannedPersons({ auth }),
- HttpService.client.getFederatedInstances({ auth }),
- fetchThemeList(),
- ]);
-
- this.setState({
- bannedRes,
- instancesRes,
- themeList,
- });
- }
-
- static fetchInitialData({
+ static async fetchInitialData({
auth,
client,
- }: InitialFetchRequest): Promise<any>[] {
- const promises: Promise<RequestState<any>>[] = [];
-
- if (auth) {
- promises.push(client.getBannedPersons({ auth }));
- promises.push(client.getFederatedInstances({ auth }));
- } else {
- promises.push(
- Promise.resolve({ state: "empty" }),
- Promise.resolve({ state: "empty" })
- );
- }
-
- return promises;
+ }: InitialFetchRequest): Promise<AdminSettingsData> {
+ return {
+ bannedRes: await client.getBannedPersons({
+ auth: auth as string,
+ }),
+ instancesRes: await client.getFederatedInstances({
+ auth: auth as string,
+ }),
+ };
}
async componentDidMount() {
}
get documentTitle(): string {
- return `${i18n.t("admin_settings")} - ${
+ return `${I18NextService.i18n.t("admin_settings")} - ${
this.state.siteRes.site_view.site.name
}`;
}
: undefined;
return (
- <div className="container-lg">
+ <div className="admin-settings container-lg">
<HtmlTags
title={this.documentTitle}
path={this.context.router.route.match.url}
tabs={[
{
key: "site",
- label: i18n.t("site"),
- getNode: () => (
- <div className="row">
- <div className="col-12 col-md-6">
- <SiteForm
- showLocal={showLocal(this.isoData)}
- allowedInstances={federationData?.allowed}
- blockedInstances={federationData?.blocked}
- onSaveSite={this.handleEditSite}
- siteRes={this.state.siteRes}
- themeList={this.state.themeList}
- />
- </div>
- <div className="col-12 col-md-6">
- {this.admins()}
- {this.bannedUsers()}
+ label: I18NextService.i18n.t("site"),
+ getNode: isSelected => (
+ <div
+ className={classNames("tab-pane show", {
+ active: isSelected,
+ })}
+ role="tabpanel"
+ id="site-tab-pane"
+ >
+ <h1 className="h4 mb-4">
+ {I18NextService.i18n.t("site_config")}
+ </h1>
+ <div className="row">
+ <div className="col-12 col-md-6">
+ <SiteForm
+ showLocal={showLocal(this.isoData)}
+ allowedInstances={federationData?.allowed}
+ blockedInstances={federationData?.blocked}
+ onSaveSite={this.handleEditSite}
+ siteRes={this.state.siteRes}
+ themeList={this.state.themeList}
+ loading={this.state.loading}
+ />
+ </div>
+ <div className="col-12 col-md-6">
+ {this.admins()}
+ <hr />
+ {this.bannedUsers()}
+ </div>
</div>
</div>
),
{
key: "rate_limiting",
label: "Rate Limiting",
- getNode: () => (
- <RateLimitForm
- rateLimits={
- this.state.siteRes.site_view.local_site_rate_limit
- }
- onSaveSite={this.handleEditSite}
- />
+ getNode: isSelected => (
+ <div
+ className={classNames("tab-pane", {
+ active: isSelected,
+ })}
+ role="tabpanel"
+ id="rate_limiting-tab-pane"
+ >
+ <RateLimitForm
+ rateLimits={
+ this.state.siteRes.site_view.local_site_rate_limit
+ }
+ onSaveSite={this.handleEditSite}
+ loading={this.state.loading}
+ />
+ </div>
),
},
{
key: "taglines",
- label: i18n.t("taglines"),
- getNode: () => (
- <div className="row">
- <TaglineForm
- taglines={this.state.siteRes.taglines}
- onSaveSite={this.handleEditSite}
- />
+ label: I18NextService.i18n.t("taglines"),
+ getNode: isSelected => (
+ <div
+ className={classNames("tab-pane", {
+ active: isSelected,
+ })}
+ role="tabpanel"
+ id="taglines-tab-pane"
+ >
+ <div className="row">
+ <TaglineForm
+ taglines={this.state.siteRes.taglines}
+ onSaveSite={this.handleEditSite}
+ loading={this.state.loading}
+ />
+ </div>
</div>
),
},
{
key: "emojis",
- label: i18n.t("emojis"),
- getNode: () => (
- <div className="row">
- <EmojiForm
- onCreate={this.handleCreateEmoji}
- onDelete={this.handleDeleteEmoji}
- onEdit={this.handleEditEmoji}
- />
+ label: I18NextService.i18n.t("emojis"),
+ getNode: isSelected => (
+ <div
+ className={classNames("tab-pane", {
+ active: isSelected,
+ })}
+ role="tabpanel"
+ id="emojis-tab-pane"
+ >
+ <div className="row">
+ <EmojiForm
+ onCreate={this.handleCreateEmoji}
+ onDelete={this.handleDeleteEmoji}
+ onEdit={this.handleEditEmoji}
+ />
+ </div>
</div>
),
},
);
}
+ async fetchData() {
+ this.setState({
+ bannedRes: { state: "loading" },
+ instancesRes: { state: "loading" },
+ themeList: [],
+ });
+
+ const auth = myAuthRequired();
+
+ const [bannedRes, instancesRes, themeList] = await Promise.all([
+ HttpService.client.getBannedPersons({ auth }),
+ HttpService.client.getFederatedInstances({ auth }),
+ fetchThemeList(),
+ ]);
+
+ this.setState({
+ bannedRes,
+ instancesRes,
+ themeList,
+ });
+ }
+
admins() {
return (
<>
- <h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5>
+ <h2 className="h5">
+ {capitalizeFirstLetter(I18NextService.i18n.t("admins"))}
+ </h2>
<ul className="list-unstyled">
{this.state.siteRes.admins.map(admin => (
<li key={admin.person.id} className="list-inline-item">
{this.state.leaveAdminTeamRes.state == "loading" ? (
<Spinner />
) : (
- i18n.t("leave_admin_team")
+ I18NextService.i18n.t("leave_admin_team")
)}
</button>
);
const bans = this.state.bannedRes.data.banned;
return (
<>
- <h5>{i18n.t("banned_users")}</h5>
+ <h2 className="h5">{I18NextService.i18n.t("banned_users")}</h2>
<ul className="list-unstyled">
{bans.map(banned => (
<li key={banned.person.id} className="list-inline-item">
}
async handleEditSite(form: EditSite) {
+ this.setState({ loading: true });
+
const editRes = await HttpService.client.editSite(form);
if (editRes.state === "success") {
s.siteRes.taglines = editRes.data.taglines;
return s;
});
- toast(i18n.t("site_saved"));
+ toast(I18NextService.i18n.t("site_saved"));
}
+ this.setState({ loading: false });
+
return editRes;
}
});
if (this.state.leaveAdminTeamRes.state === "success") {
- toast(i18n.t("left_admin_team"));
+ toast(I18NextService.i18n.t("left_admin_team"));
this.context.router.history.replace("/");
}
}