]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/home/rate-limit-form.tsx
component classes v2
[lemmy-ui.git] / src / shared / components / home / rate-limit-form.tsx
index 95f7fee9a68c9f85660506c96e6df3e7929d319e..1b2e281b243402bd7802269e7c07a22a379493ce 100644 (file)
@@ -1,6 +1,8 @@
 import { Component, FormEventHandler, linkEvent } from "inferno";
-import { LocalSiteRateLimit } from "lemmy-js-client";
+import { EditSite, LocalSiteRateLimit } from "lemmy-js-client";
 import { i18n } from "../../i18next";
+import { capitalizeFirstLetter, myAuthRequired } from "../../utils";
+import { Spinner } from "../common/icon";
 import Tabs from "../common/tabs";
 
 const rateLimitTypes = [
@@ -15,61 +17,63 @@ const rateLimitTypes = [
 interface RateLimitsProps {
   handleRateLimit: FormEventHandler<HTMLInputElement>;
   handleRateLimitPerSecond: FormEventHandler<HTMLInputElement>;
-  rateLimitLabel: string;
   rateLimitValue?: number;
   rateLimitPerSecondValue?: number;
 }
 
 interface RateLimitFormProps {
-  localSiteRateLimit: LocalSiteRateLimit;
+  rateLimits: LocalSiteRateLimit;
+  onSaveSite(form: EditSite): void;
+  loading: boolean;
 }
 
 interface RateLimitFormState {
-  message?: number;
-  message_per_second?: number;
-  post?: number;
-  post_per_second?: number;
-  comment?: number;
-  comment_per_second?: number;
-  image?: number;
-  image_per_second?: number;
-  search?: number;
-  search_per_second?: number;
-  register?: number;
-  register_per_second?: number;
+  form: {
+    message?: number;
+    message_per_second?: number;
+    post?: number;
+    post_per_second?: number;
+    comment?: number;
+    comment_per_second?: number;
+    image?: number;
+    image_per_second?: number;
+    search?: number;
+    search_per_second?: number;
+    register?: number;
+    register_per_second?: number;
+  };
 }
 
 function RateLimits({
   handleRateLimit,
   handleRateLimitPerSecond,
-  rateLimitLabel,
   rateLimitPerSecondValue,
   rateLimitValue,
 }: RateLimitsProps) {
   return (
-    <div className="form-group row">
-      <label className="col-12 col-form-label" htmlFor="rate-limit">
-        {rateLimitLabel}
-      </label>
-      <input
-        type="number"
-        id="rate-limit"
-        className="form-control col-12"
-        min={0}
-        value={rateLimitValue}
-        onInput={handleRateLimit}
-      />
-      <label className="col-12 col-form-label" htmlFor="rate-limit-per-second">
-        {i18n.t("per_second")}
-      </label>
-      <input
-        type="number"
-        id="rate-limit-per-second"
-        className="form-control col-12"
-        min={0}
-        value={rateLimitPerSecondValue}
-        onInput={handleRateLimitPerSecond}
-      />
+    <div className="mb-3 row">
+      <div className="col-md-6">
+        <label htmlFor="rate-limit">{i18n.t("rate_limit")}</label>
+        <input
+          type="number"
+          id="rate-limit"
+          className="form-control"
+          min={0}
+          value={rateLimitValue}
+          onInput={handleRateLimit}
+        />
+      </div>
+      <div className="col-md-6">
+        <label htmlFor="rate-limit-per-second">{i18n.t("per_second")}</label>
+        <input
+          type="number"
+          id="rate-limit-per-second"
+          className="form-control"
+          min={0}
+          value={rateLimitPerSecondValue}
+          onInput={handleRateLimitPerSecond}
+        />
+      </div>
     </div>
   );
 }
@@ -78,84 +82,98 @@ function handleRateLimitChange(
   { rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm },
   event: any
 ) {
-  ctx.setState({
-    [rateLimitType]: Number(event.target.value),
-  });
+  ctx.setState(prev => ({
+    ...prev,
+    form: {
+      ...prev.form,
+      [rateLimitType]: Number(event.target.value),
+    },
+  }));
 }
 
 function handlePerSecondChange(
   { rateLimitType, ctx }: { rateLimitType: string; ctx: RateLimitsForm },
   event: any
 ) {
-  ctx.setState({
-    [`${rateLimitType}_per_second`]: Number(event.target.value),
-  });
+  ctx.setState(prev => ({
+    ...prev,
+    form: {
+      ...prev.form,
+      [`${rateLimitType}_per_second`]: Number(event.target.value),
+    },
+  }));
+}
+
+function submitRateLimitForm(i: RateLimitsForm, event: any) {
+  event.preventDefault();
+  const auth = myAuthRequired();
+  const form: EditSite = Object.entries(i.state.form).reduce(
+    (acc, [key, val]) => {
+      acc[`rate_limit_${key}`] = val;
+      return acc;
+    },
+    {
+      auth,
+    }
+  );
+
+  i.props.onSaveSite(form);
 }
 
 export default class RateLimitsForm extends Component<
   RateLimitFormProps,
   RateLimitFormState
 > {
-  state: RateLimitFormState = {};
-  constructor(props: RateLimitFormProps, context) {
+  state: RateLimitFormState = {
+    form: this.props.rateLimits,
+  };
+  constructor(props: RateLimitFormProps, context: any) {
     super(props, context);
-
-    const {
-      comment,
-      comment_per_second,
-      image,
-      image_per_second,
-      message,
-      message_per_second,
-      post,
-      post_per_second,
-      register,
-      register_per_second,
-      search,
-      search_per_second,
-    } = props.localSiteRateLimit;
-
-    this.state = {
-      comment,
-      comment_per_second,
-      image,
-      image_per_second,
-      message,
-      message_per_second,
-      post,
-      post_per_second,
-      register,
-      register_per_second,
-      search,
-      search_per_second,
-    };
   }
 
   render() {
     return (
-      <Tabs
-        tabs={rateLimitTypes.map(rateLimitType => ({
-          key: rateLimitType,
-          label: rateLimitType,
-          getNode: () => (
-            <RateLimits
-              handleRateLimit={linkEvent(
-                { rateLimitType, ctx: this },
-                handleRateLimitChange
-              )}
-              handleRateLimitPerSecond={linkEvent(
-                { rateLimitType, ctx: this },
-                handlePerSecondChange
-              )}
-              rateLimitLabel={i18n.t(`rate_limit_${rateLimitType}`)}
-              rateLimitValue={this.state[rateLimitType]}
-              rateLimitPerSecondValue={
-                this.state[`${rateLimitType}_per_second`]
-              }
-            />
-          ),
-        }))}
-      />
+      <form
+        className="rate-limit-form"
+        onSubmit={linkEvent(this, submitRateLimitForm)}
+      >
+        <h5>{i18n.t("rate_limit_header")}</h5>
+        <Tabs
+          tabs={rateLimitTypes.map(rateLimitType => ({
+            key: rateLimitType,
+            label: i18n.t(`rate_limit_${rateLimitType}`),
+            getNode: () => (
+              <RateLimits
+                handleRateLimit={linkEvent(
+                  { rateLimitType, ctx: this },
+                  handleRateLimitChange
+                )}
+                handleRateLimitPerSecond={linkEvent(
+                  { rateLimitType, ctx: this },
+                  handlePerSecondChange
+                )}
+                rateLimitValue={this.state.form[rateLimitType]}
+                rateLimitPerSecondValue={
+                  this.state.form[`${rateLimitType}_per_second`]
+                }
+              />
+            ),
+          }))}
+        />
+        <div className="col-12 mb-3">
+          <button
+            type="submit"
+            className="btn btn-secondary me-2"
+            disabled={this.props.loading}
+          >
+            {this.props.loading ? (
+              <Spinner />
+            ) : (
+              capitalizeFirstLetter(i18n.t("save"))
+            )}
+          </button>
+        </div>
+      </form>
     );
   }
 }