summaryrefslogtreecommitdiff
path: root/web/source/settings/views/moderation/domain-permissions/detail.tsx
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2025-04-04 18:29:22 +0200
committerLibravatar GitHub <noreply@github.com>2025-04-04 18:29:22 +0200
commitb1844323314dd1f0832f1fcdb765a7f67ca01dbc (patch)
treee568a5941a6155e9ca55f3e4194b3256ad2fe352 /web/source/settings/views/moderation/domain-permissions/detail.tsx
parent[chore] bump ncruces/go-sqlite3 to v0.25.0 (#3966) (diff)
downloadgotosocial-b1844323314dd1f0832f1fcdb765a7f67ca01dbc.tar.xz
[feature] Allow editing domain blocks/allows, fix comment import (#3967)
* start implementing editing of existing domain permissions * [feature] Allow editing domain blocks/allows, fix comment import * [bugfix] Use "comment" via /api/v1/instance * fix the stuff
Diffstat (limited to 'web/source/settings/views/moderation/domain-permissions/detail.tsx')
-rw-r--r--web/source/settings/views/moderation/domain-permissions/detail.tsx255
1 files changed, 161 insertions, 94 deletions
diff --git a/web/source/settings/views/moderation/domain-permissions/detail.tsx b/web/source/settings/views/moderation/domain-permissions/detail.tsx
index 0105d9615..e8ef487e3 100644
--- a/web/source/settings/views/moderation/domain-permissions/detail.tsx
+++ b/web/source/settings/views/moderation/domain-permissions/detail.tsx
@@ -32,8 +32,18 @@ import Loading from "../../../components/loading";
import BackButton from "../../../components/back-button";
import MutationButton from "../../../components/form/mutation-button";
-import { useDomainAllowsQuery, useDomainBlocksQuery } from "../../../lib/query/admin/domain-permissions/get";
-import { useAddDomainAllowMutation, useAddDomainBlockMutation, useRemoveDomainAllowMutation, useRemoveDomainBlockMutation } from "../../../lib/query/admin/domain-permissions/update";
+import {
+ useDomainAllowsQuery,
+ useDomainBlocksQuery,
+} from "../../../lib/query/admin/domain-permissions/get";
+import {
+ useAddDomainAllowMutation,
+ useAddDomainBlockMutation,
+ useRemoveDomainAllowMutation,
+ useRemoveDomainBlockMutation,
+ useUpdateDomainAllowMutation,
+ useUpdateDomainBlockMutation,
+} from "../../../lib/query/admin/domain-permissions/update";
import { DomainPerm } from "../../../lib/types/domain-permission";
import { NoArg } from "../../../lib/types/query";
import { Error } from "../../../components/error";
@@ -41,8 +51,10 @@ import { useBaseUrl } from "../../../lib/navigation/util";
import { PermType } from "../../../lib/types/perm";
import { useCapitalize } from "../../../lib/util";
import { formDomainValidator } from "../../../lib/util/formvalidators";
+import UsernameLozenge from "../../../components/username-lozenge";
+import { FormSubmitEvent } from "../../../lib/form/types";
-export default function DomainPermDetail() {
+export default function DomainPermView() {
const baseUrl = useBaseUrl();
const search = useSearch();
@@ -101,33 +113,16 @@ export default function DomainPermDetail() {
? blocks[domain]
: allows[domain];
- // Render different into content depending on
- // if we have a perm already for this domain.
- let infoContent: React.JSX.Element;
- if (existingPerm === undefined) {
- infoContent = (
- <span>
- No stored {permType} yet, you can add one below:
- </span>
- );
- } else {
- infoContent = (
- <div className="info">
- <i className="fa fa-fw fa-exclamation-triangle" aria-hidden="true"></i>
- <b>Editing existing domain {permTypeRaw} isn't implemented yet, <a href="https://github.com/superseriousbusiness/gotosocial/issues/1198" target="_blank" rel="noopener noreferrer">check here for progress</a></b>
- </div>
- );
- }
+ const title = <span>Domain {permType} for {domain}</span>;
return (
- <div>
- <h1 className="text-cutoff">
- <BackButton to={`~${baseUrl}/${permTypeRaw}`} />
- {" "}
- Domain {permType} for {domain}
- </h1>
- {infoContent}
- <DomainPermForm
+ <div className="domain-permission-details">
+ <h1><BackButton to={`~${baseUrl}/${permTypeRaw}`} /> {title}</h1>
+ { existingPerm
+ ? <DomainPermDetails perm={existingPerm} permType={permType} />
+ : <span>No stored {permType} yet, you can add one below:</span>
+ }
+ <CreateOrUpdateDomainPerm
defaultDomain={domain}
perm={existingPerm}
permType={permType}
@@ -136,23 +131,75 @@ export default function DomainPermDetail() {
);
}
-interface DomainPermFormProps {
+interface DomainPermDetailsProps {
+ perm: DomainPerm,
+ permType: PermType,
+}
+
+function DomainPermDetails({
+ perm,
+ permType
+}: DomainPermDetailsProps) {
+ const baseUrl = useBaseUrl();
+ const [ location ] = useLocation();
+
+ const created = useMemo(() => {
+ if (perm.created_at) {
+ return new Date(perm.created_at).toDateString();
+ }
+ return "unknown";
+ }, [perm.created_at]);
+
+ return (
+ <dl className="info-list">
+ <div className="info-list-entry">
+ <dt>Created</dt>
+ <dd><time dateTime={perm.created_at}>{created}</time></dd>
+ </div>
+ <div className="info-list-entry">
+ <dt>Created By</dt>
+ <dd>
+ <UsernameLozenge
+ account={perm.created_by}
+ linkTo={`~/settings/moderation/accounts/${perm.created_by}`}
+ backLocation={`~${baseUrl}${location}`}
+ />
+ </dd>
+ </div>
+ <div className="info-list-entry">
+ <dt>Domain</dt>
+ <dd>{perm.domain}</dd>
+ </div>
+ <div className="info-list-entry">
+ <dt>Permission type</dt>
+ <dd className={`permission-type ${permType}`}>
+ <i
+ aria-hidden={true}
+ className={`fa fa-${permType === "allow" ? "check" : "close"}`}
+ ></i>
+ {permType}
+ </dd>
+ </div>
+ <div className="info-list-entry">
+ <dt>Subscription ID</dt>
+ <dd>{perm.subscription_id ?? "[none]"}</dd>
+ </div>
+ </dl>
+ );
+}
+
+interface CreateOrUpdateDomainPermProps {
defaultDomain: string;
perm?: DomainPerm;
permType: PermType;
}
-function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps) {
+function CreateOrUpdateDomainPerm({
+ defaultDomain,
+ perm,
+ permType
+}: CreateOrUpdateDomainPermProps) {
const isExistingPerm = perm !== undefined;
- const disabledForm = isExistingPerm
- ? {
- disabled: true,
- title: "Domain permissions currently cannot be edited."
- }
- : {
- disabled: false,
- title: "",
- };
const form = {
domain: useTextInput("domain", {
@@ -161,8 +208,8 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps)
validator: formDomainValidator,
}),
obfuscate: useBoolInput("obfuscate", { source: perm }),
- commentPrivate: useTextInput("private_comment", { source: perm }),
- commentPublic: useTextInput("public_comment", { source: perm })
+ privateComment: useTextInput("private_comment", { source: perm }),
+ publicComment: useTextInput("public_comment", { source: perm })
};
// Check which perm type we're meant to be handling
@@ -171,112 +218,132 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps)
// react is like "weh" (mood), but we can decide
// which ones to use conditionally.
const [ addBlock, addBlockResult ] = useAddDomainBlockMutation();
+ const [ updateBlock, updateBlockResult ] = useUpdateDomainBlockMutation({ fixedCacheKey: perm?.id });
const [ removeBlock, removeBlockResult] = useRemoveDomainBlockMutation({ fixedCacheKey: perm?.id });
const [ addAllow, addAllowResult ] = useAddDomainAllowMutation();
+ const [ updateAllow, updateAllowResult ] = useUpdateDomainAllowMutation({ fixedCacheKey: perm?.id });
const [ removeAllow, removeAllowResult ] = useRemoveDomainAllowMutation({ fixedCacheKey: perm?.id });
const [
- addTrigger,
- addResult,
+ createOrUpdateTrigger,
+ createOrUpdateResult,
removeTrigger,
removeResult,
] = useMemo(() => {
- return permType == "block"
- ? [
- addBlock,
- addBlockResult,
- removeBlock,
- removeBlockResult,
- ]
- : [
- addAllow,
- addAllowResult,
- removeAllow,
- removeAllowResult,
- ];
- }, [permType,
- addBlock, addBlockResult, removeBlock, removeBlockResult,
- addAllow, addAllowResult, removeAllow, removeAllowResult,
+ switch (true) {
+ case (permType === "block" && !isExistingPerm):
+ return [ addBlock, addBlockResult, removeBlock, removeBlockResult ];
+ case (permType === "block"):
+ return [ updateBlock, updateBlockResult, removeBlock, removeBlockResult ];
+ case !isExistingPerm:
+ return [ addAllow, addAllowResult, removeAllow, removeAllowResult ];
+ default:
+ return [ updateAllow, updateAllowResult, removeAllow, removeAllowResult ];
+ }
+ }, [permType, isExistingPerm,
+ addBlock, addBlockResult, updateBlock, updateBlockResult, removeBlock, removeBlockResult,
+ addAllow, addAllowResult, updateAllow, updateAllowResult, removeAllow, removeAllowResult,
]);
- // Use appropriate submission params for this permType.
- const [submitForm, submitFormResult] = useFormSubmit(form, [addTrigger, addResult], { changedOnly: false });
+ // Use appropriate submission params for this
+ // permType, and whether we're creating or updating.
+ const [submit, submitResult] = useFormSubmit(
+ form,
+ [ createOrUpdateTrigger, createOrUpdateResult ],
+ {
+ changedOnly: isExistingPerm,
+ // If we're updating an existing perm,
+ // insert the perm ID into the mutation
+ // data before submitting. Otherwise just
+ // return the mutationData unmodified.
+ customizeMutationArgs: (mutationData) => {
+ if (isExistingPerm) {
+ return {
+ id: perm?.id,
+ ...mutationData,
+ };
+ } else {
+ return mutationData;
+ }
+ },
+ },
+ );
// Uppercase first letter of given permType.
const permTypeUpper = useCapitalize(permType);
const [location, setLocation] = useLocation();
-
- function verifyUrlThenSubmit(e) {
+ function onSubmit(e: FormSubmitEvent) {
// Adding a new domain permissions happens on a url like
// "/settings/admin/domain-permissions/:permType/domain.com",
// but if domain input changes, that doesn't match anymore
// and causes issues later on so, before submitting the form,
// silently change url, and THEN submit.
- let correctUrl = `/${permType}s/${form.domain.value}`;
- if (location != correctUrl) {
- setLocation(correctUrl);
+ if (!isExistingPerm) {
+ let correctUrl = `/${permType}s/${form.domain.value}`;
+ if (location != correctUrl) {
+ setLocation(correctUrl);
+ }
}
- return submitForm(e);
+ return submit(e);
}
return (
- <form onSubmit={verifyUrlThenSubmit}>
- <TextInput
- field={form.domain}
- label="Domain"
- placeholder="example.com"
- autoCapitalize="none"
- spellCheck="false"
- {...disabledForm}
- />
+ <form onSubmit={onSubmit}>
+ { !isExistingPerm &&
+ <TextInput
+ field={form.domain}
+ label="Domain"
+ placeholder="example.com"
+ autoCapitalize="none"
+ spellCheck="false"
+ />
+ }
<Checkbox
field={form.obfuscate}
label="Obfuscate domain in public lists"
- {...disabledForm}
/>
<TextArea
- field={form.commentPrivate}
+ field={form.privateComment}
label="Private comment"
autoCapitalize="sentences"
rows={3}
- {...disabledForm}
/>
<TextArea
- field={form.commentPublic}
+ field={form.publicComment}
label="Public comment"
autoCapitalize="sentences"
rows={3}
- {...disabledForm}
/>
<div className="action-buttons row">
<MutationButton
- label={permTypeUpper}
- result={submitFormResult}
- showError={false}
- {...disabledForm}
+ label={isExistingPerm ? "Update " + permType.toString() : permTypeUpper}
+ result={submitResult}
+ disabled={
+ isExistingPerm &&
+ !form.obfuscate.hasChanged() &&
+ !form.privateComment.hasChanged() &&
+ !form.publicComment.hasChanged()
+ }
/>
- {
- isExistingPerm &&
- <MutationButton
+ { isExistingPerm &&
+ <button
type="button"
onClick={() => removeTrigger(perm.id?? "")}
- label="Remove"
- result={removeResult}
className="button danger"
- showError={false}
- disabled={!isExistingPerm}
- />
+ >
+ Remove {permType.toString()}
+ </button>
}
</div>
<>
- {addResult.error && <Error error={addResult.error} />}
+ {createOrUpdateResult.error && <Error error={createOrUpdateResult.error} />}
{removeResult.error && <Error error={removeResult.error} />}
</>