Allow user to submit rate limit changes

This commit is contained in:
abias 2023-05-21 12:40:22 -04:00
parent 2e3c1a6cfa
commit cf58a0c451
3 changed files with 124 additions and 54 deletions

View file

@ -35,6 +35,7 @@ export default class Tabs extends Component<TabsProps, TabsState> {
{this.props.tabs.map(({ key, label }) => ( {this.props.tabs.map(({ key, label }) => (
<li key={key} className="nav-item"> <li key={key} className="nav-item">
<button <button
type="button"
className={`nav-link btn${ className={`nav-link btn${
this.state?.currentTab === key ? " active" : "" this.state?.currentTab === key ? " active" : ""
}`} }`}

View file

@ -157,6 +157,10 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
localSiteRateLimit={ localSiteRateLimit={
this.state.siteRes.site_view.local_site_rate_limit this.state.siteRes.site_view.local_site_rate_limit
} }
applicationQuestion={
this.state.siteRes.site_view.local_site
.application_question
}
/> />
), ),
}, },

View file

@ -1,6 +1,9 @@
import { Component, FormEventHandler, linkEvent } from "inferno"; import { Component, FormEventHandler, linkEvent } from "inferno";
import { LocalSiteRateLimit } from "lemmy-js-client"; import { EditSite, LocalSiteRateLimit } from "lemmy-js-client";
import { i18n } from "../../i18next"; import { i18n } from "../../i18next";
import { WebSocketService } from "../../services";
import { capitalizeFirstLetter, myAuth, wsClient } from "../../utils";
import { Spinner } from "../common/icon";
import Tabs from "../common/tabs"; import Tabs from "../common/tabs";
const rateLimitTypes = [ const rateLimitTypes = [
@ -22,21 +25,25 @@ interface RateLimitsProps {
interface RateLimitFormProps { interface RateLimitFormProps {
localSiteRateLimit: LocalSiteRateLimit; localSiteRateLimit: LocalSiteRateLimit;
applicationQuestion?: string;
} }
interface RateLimitFormState { interface RateLimitFormState {
message?: number; form: {
message_per_second?: number; message?: number;
post?: number; message_per_second?: number;
post_per_second?: number; post?: number;
comment?: number; post_per_second?: number;
comment_per_second?: number; comment?: number;
image?: number; comment_per_second?: number;
image_per_second?: number; image?: number;
search?: number; image_per_second?: number;
search_per_second?: number; search?: number;
register?: number; search_per_second?: number;
register_per_second?: number; register?: number;
register_per_second?: number;
};
loading: boolean;
} }
function RateLimits({ function RateLimits({
@ -78,25 +85,52 @@ function handleRateLimitChange(
{ rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm }, { rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm },
event: any event: any
) { ) {
ctx.setState({ ctx.setState(prev => ({
[rateLimitType]: Number(event.target.value), ...prev,
}); form: {
...prev.form,
[rateLimitType]: Number(event.target.value),
},
}));
} }
function handlePerSecondChange( function handlePerSecondChange(
{ rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm }, { rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm },
event: any event: any
) { ) {
ctx.setState({ ctx.setState(prev => ({
[`${rateLimitType}_per_second`]: Number(event.target.value), ...prev,
}); form: {
...prev.form,
[`${rateLimitType}_per_second`]: Number(event.target.value),
},
}));
}
function submitRateLimitForm(i: RateLimitsForm, event: any) {
event.preventDefault();
const auth = myAuth() ?? "TODO";
const form: EditSite = Object.entries(i.state.form).reduce(
(acc, [key, val]) => {
acc[`rate_limit_${key}`] = val;
return acc;
},
{ auth, application_question: i.props.applicationQuestion }
);
i.setState({ loading: true });
WebSocketService.Instance.send(wsClient.editSite(form));
} }
export default class RateLimitsForm extends Component< export default class RateLimitsForm extends Component<
RateLimitFormProps, RateLimitFormProps,
RateLimitFormState RateLimitFormState
> { > {
state: RateLimitFormState = {}; state: RateLimitFormState = {
loading: false,
form: {},
};
constructor(props: RateLimitFormProps, context) { constructor(props: RateLimitFormProps, context) {
super(props, context); super(props, context);
@ -116,46 +150,77 @@ export default class RateLimitsForm extends Component<
} = props.localSiteRateLimit; } = props.localSiteRateLimit;
this.state = { this.state = {
comment, ...this.state,
comment_per_second, form: {
image, comment,
image_per_second, comment_per_second,
message, image,
message_per_second, image_per_second,
post, message,
post_per_second, message_per_second,
register, post,
register_per_second, post_per_second,
search, register,
search_per_second, register_per_second,
search,
search_per_second,
},
}; };
} }
render() { render() {
return ( return (
<Tabs <form onSubmit={linkEvent(this, submitRateLimitForm)}>
tabs={rateLimitTypes.map(rateLimitType => ({ <Tabs
key: rateLimitType, tabs={rateLimitTypes.map(rateLimitType => ({
label: rateLimitType, key: rateLimitType,
getNode: () => ( label: rateLimitType,
<RateLimits getNode: () => (
handleRateLimit={linkEvent( <RateLimits
{ rateLimitType, ctx: this }, handleRateLimit={linkEvent(
handleRateLimitChange { rateLimitType, ctx: this },
handleRateLimitChange
)}
handleRateLimitPerSecond={linkEvent(
{ rateLimitType, ctx: this },
handlePerSecondChange
)}
rateLimitLabel={i18n.t(`rate_limit_${rateLimitType}`)}
rateLimitValue={this.state.form[rateLimitType]}
rateLimitPerSecondValue={
this.state.form[`${rateLimitType}_per_second`]
}
/>
),
}))}
/>
<div className="form-group row">
<div className="col-12">
<button
type="submit"
className="btn btn-secondary mr-2"
disabled={this.state.loading}
>
{this.state.loading ? (
<Spinner />
) : (
capitalizeFirstLetter(i18n.t("save"))
)} )}
handleRateLimitPerSecond={linkEvent( </button>
{ rateLimitType, ctx: this }, </div>
handlePerSecondChange </div>
)} </form>
rateLimitLabel={i18n.t(`rate_limit_${rateLimitType}`)}
rateLimitValue={this.state[rateLimitType]}
rateLimitPerSecondValue={
this.state[`${rateLimitType}_per_second`]
}
/>
),
}))}
/>
); );
} }
componentDidUpdate({ localSiteRateLimit }: RateLimitFormProps) {
if (
this.state.loading &&
Object.entries(localSiteRateLimit).some(
([key, val]) => this.state.form[key] !== val
)
) {
this.setState({ loading: false });
}
}
} }