| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | /* | 
					
						
							|  |  |  | 	GoToSocial | 
					
						
							|  |  |  | 	Copyright (C) GoToSocial Authors admin@gotosocial.org | 
					
						
							|  |  |  | 	SPDX-License-Identifier: AGPL-3.0-or-later | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | 	it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  | 	the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | 	(at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | 	but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | 	GNU Affero General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  | 	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import React from "react"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { useMemo } from "react"; | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | import { useLocation, useParams, useSearch } from "wouter"; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | import { useTextInput, useBoolInput } from "../../../lib/form"; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | import useFormSubmit from "../../../lib/form/submit"; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | import { TextInput, Checkbox, TextArea } from "../../../components/form/inputs"; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | import Loading from "../../../components/loading"; | 
					
						
							|  |  |  | import BackButton from "../../../components/back-button"; | 
					
						
							|  |  |  | import MutationButton from "../../../components/form/mutation-button"; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | import {  | 
					
						
							|  |  |  | 	useDomainAllowsQuery, | 
					
						
							|  |  |  | 	useDomainBlocksQuery, | 
					
						
							|  |  |  | } from "../../../lib/query/admin/domain-permissions/get"; | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  | 	useAddDomainAllowMutation, | 
					
						
							|  |  |  | 	useAddDomainBlockMutation, | 
					
						
							|  |  |  | 	useRemoveDomainAllowMutation, | 
					
						
							|  |  |  | 	useRemoveDomainBlockMutation, | 
					
						
							|  |  |  | 	useUpdateDomainAllowMutation, | 
					
						
							|  |  |  | 	useUpdateDomainBlockMutation, | 
					
						
							|  |  |  | } from "../../../lib/query/admin/domain-permissions/update"; | 
					
						
							| 
									
										
										
										
											2024-05-05 13:47:22 +02:00
										 |  |  | import { DomainPerm } from "../../../lib/types/domain-permission"; | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | import { NoArg } from "../../../lib/types/query"; | 
					
						
							|  |  |  | import { Error } from "../../../components/error"; | 
					
						
							|  |  |  | import { useBaseUrl } from "../../../lib/navigation/util"; | 
					
						
							| 
									
										
										
										
											2024-05-05 13:47:22 +02:00
										 |  |  | import { PermType } from "../../../lib/types/perm"; | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | import { useCapitalize } from "../../../lib/util"; | 
					
						
							|  |  |  | import { formDomainValidator } from "../../../lib/util/formvalidators"; | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | import UsernameLozenge from "../../../components/username-lozenge"; | 
					
						
							|  |  |  | import { FormSubmitEvent } from "../../../lib/form/types"; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | export default function DomainPermView() { | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | 	const baseUrl = useBaseUrl(); | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | 	const search = useSearch(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Parse perm type from routing params, converting
 | 
					
						
							|  |  |  | 	// "blocks" => "block" and "allows" => "allow".
 | 
					
						
							|  |  |  | 	const params = useParams(); | 
					
						
							|  |  |  | 	const permTypeRaw = params.permType; | 
					
						
							|  |  |  | 	if (permTypeRaw !== "blocks" && permTypeRaw !== "allows") { | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | 		throw "unrecognized perm type " + params.permType; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | 	const permType = useMemo(() => { | 
					
						
							|  |  |  | 		return permTypeRaw.slice(0, -1) as PermType; | 
					
						
							|  |  |  | 	}, [permTypeRaw]); | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | 	// Conditionally fetch either domain blocks or domain
 | 
					
						
							|  |  |  | 	// allows depending on which perm type we're looking at.
 | 
					
						
							|  |  |  | 	const { | 
					
						
							|  |  |  | 		data: blocks = {}, | 
					
						
							|  |  |  | 		isLoading: loadingBlocks, | 
					
						
							|  |  |  | 		isFetching: fetchingBlocks, | 
					
						
							|  |  |  | 	} = useDomainBlocksQuery(NoArg, { skip: permType !== "block" }); | 
					
						
							|  |  |  | 	const { | 
					
						
							|  |  |  | 		data: allows = {}, | 
					
						
							|  |  |  | 		isLoading: loadingAllows, | 
					
						
							|  |  |  | 		isFetching: fetchingAllows, | 
					
						
							|  |  |  | 	} = useDomainAllowsQuery(NoArg, { skip: permType !== "allow" }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Wait until we're done loading.
 | 
					
						
							|  |  |  | 	const loading = permType === "block" | 
					
						
							|  |  |  | 		? loadingBlocks || fetchingBlocks | 
					
						
							|  |  |  | 		: loadingAllows || fetchingAllows; | 
					
						
							|  |  |  | 	if (loading) { | 
					
						
							|  |  |  | 		return <Loading />; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 12:12:47 +02:00
										 |  |  | 	// Parse domain from routing params.
 | 
					
						
							|  |  |  | 	let domain = params.domain ?? "unknown"; | 
					
						
							|  |  |  | 	if (domain === "view") { | 
					
						
							|  |  |  | 		// Retrieve domain from form field submission.
 | 
					
						
							|  |  |  | 		const searchParams = new URLSearchParams(search); | 
					
						
							|  |  |  | 		const searchDomain = searchParams.get("domain"); | 
					
						
							|  |  |  | 		if (!searchDomain) { | 
					
						
							|  |  |  | 			throw "empty view domain"; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		domain = searchDomain; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | 	// Normalize / decode domain
 | 
					
						
							|  |  |  | 	// (it may be URL-encoded).
 | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	domain = decodeURIComponent(domain); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | 	// Check if we already have a perm
 | 
					
						
							|  |  |  | 	// of the desired type for this domain.
 | 
					
						
							|  |  |  | 	const existingPerm = permType === "block" | 
					
						
							|  |  |  | 		? blocks[domain] | 
					
						
							|  |  |  | 		: allows[domain]; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 	const title = <span>Domain {permType} for {domain}</span>; | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ( | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 		<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 | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				defaultDomain={domain} | 
					
						
							|  |  |  | 				perm={existingPerm} | 
					
						
							|  |  |  | 				permType={permType} | 
					
						
							|  |  |  | 			/> | 
					
						
							|  |  |  | 		</div> | 
					
						
							|  |  |  | 	); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 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 { | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	defaultDomain: string; | 
					
						
							|  |  |  | 	perm?: DomainPerm; | 
					
						
							|  |  |  | 	permType: PermType; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | function CreateOrUpdateDomainPerm({ | 
					
						
							|  |  |  | 	defaultDomain, | 
					
						
							|  |  |  | 	perm, | 
					
						
							|  |  |  | 	permType | 
					
						
							|  |  |  | }: CreateOrUpdateDomainPermProps) { | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	const isExistingPerm = perm !== undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const form = { | 
					
						
							| 
									
										
										
										
											2024-07-08 09:38:27 +02:00
										 |  |  | 		domain: useTextInput("domain", { | 
					
						
							|  |  |  | 			source: perm, | 
					
						
							|  |  |  | 			defaultValue: defaultDomain, | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | 			validator: formDomainValidator, | 
					
						
							| 
									
										
										
										
											2024-07-08 09:38:27 +02:00
										 |  |  | 		}), | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 		obfuscate: useBoolInput("obfuscate", { source: perm }), | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 		privateComment: useTextInput("private_comment", { source: perm }), | 
					
						
							|  |  |  | 		publicComment: useTextInput("public_comment", { source: perm }) | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check which perm type we're meant to be handling
 | 
					
						
							|  |  |  | 	// here, and use appropriate mutations and results.
 | 
					
						
							|  |  |  | 	// We can't call these hooks conditionally because
 | 
					
						
							|  |  |  | 	// react is like "weh" (mood), but we can decide
 | 
					
						
							|  |  |  | 	// which ones to use conditionally.
 | 
					
						
							|  |  |  | 	const [ addBlock, addBlockResult ] = useAddDomainBlockMutation(); | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 	const [ updateBlock, updateBlockResult ] = useUpdateDomainBlockMutation({ fixedCacheKey: perm?.id }); | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	const [ removeBlock, removeBlockResult] = useRemoveDomainBlockMutation({ fixedCacheKey: perm?.id }); | 
					
						
							|  |  |  | 	const [ addAllow, addAllowResult ] = useAddDomainAllowMutation(); | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 	const [ updateAllow, updateAllowResult ] = useUpdateDomainAllowMutation({ fixedCacheKey: perm?.id }); | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	const [ removeAllow, removeAllowResult ] = useRemoveDomainAllowMutation({ fixedCacheKey: perm?.id }); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	const [ | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 		createOrUpdateTrigger, | 
					
						
							|  |  |  | 		createOrUpdateResult, | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 		removeTrigger, | 
					
						
							|  |  |  | 		removeResult, | 
					
						
							|  |  |  | 	] = useMemo(() => { | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 		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, | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 	// 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; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Uppercase first letter of given permType.
 | 
					
						
							| 
									
										
										
										
											2024-11-21 14:09:58 +01:00
										 |  |  | 	const permTypeUpper = useCapitalize(permType); | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	const [location, setLocation] = useLocation(); | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 	function onSubmit(e: FormSubmitEvent) { | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 		// 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.
 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 		if (!isExistingPerm) { | 
					
						
							|  |  |  | 			let correctUrl = `/${permType}s/${form.domain.value}`; | 
					
						
							|  |  |  | 			if (location != correctUrl) { | 
					
						
							|  |  |  | 				setLocation(correctUrl); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 		return submit(e); | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ( | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 		<form onSubmit={onSubmit}> | 
					
						
							|  |  |  | 			{ !isExistingPerm &&  | 
					
						
							|  |  |  | 				<TextInput | 
					
						
							|  |  |  | 					field={form.domain} | 
					
						
							|  |  |  | 					label="Domain" | 
					
						
							|  |  |  | 					placeholder="example.com" | 
					
						
							|  |  |  | 					autoCapitalize="none" | 
					
						
							|  |  |  | 					spellCheck="false" | 
					
						
							|  |  |  | 				/> | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			<Checkbox | 
					
						
							|  |  |  | 				field={form.obfuscate} | 
					
						
							|  |  |  | 				label="Obfuscate domain in public lists" | 
					
						
							|  |  |  | 			/> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			<TextArea | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 				field={form.privateComment} | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				label="Private comment" | 
					
						
							| 
									
										
										
										
											2024-07-08 09:38:27 +02:00
										 |  |  | 				autoCapitalize="sentences" | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				rows={3} | 
					
						
							|  |  |  | 			/> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			<TextArea | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 				field={form.publicComment} | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				label="Public comment" | 
					
						
							| 
									
										
										
										
											2024-07-08 09:38:27 +02:00
										 |  |  | 				autoCapitalize="sentences" | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				rows={3} | 
					
						
							|  |  |  | 			/> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			<div className="action-buttons row"> | 
					
						
							|  |  |  | 				<MutationButton | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 					label={isExistingPerm ? "Update " + permType.toString() : permTypeUpper} | 
					
						
							|  |  |  | 					result={submitResult} | 
					
						
							|  |  |  | 					disabled={ | 
					
						
							|  |  |  | 						isExistingPerm && | 
					
						
							|  |  |  | 						!form.obfuscate.hasChanged() && | 
					
						
							|  |  |  | 						!form.privateComment.hasChanged() && | 
					
						
							|  |  |  | 						!form.publicComment.hasChanged() | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				/> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 				{ isExistingPerm && | 
					
						
							|  |  |  | 					<button | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 						type="button" | 
					
						
							|  |  |  | 						onClick={() => removeTrigger(perm.id?? "")} | 
					
						
							|  |  |  | 						className="button danger" | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 					> | 
					
						
							|  |  |  | 						Remove {permType.toString()} | 
					
						
							|  |  |  | 					</button> | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			</div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			<> | 
					
						
							| 
									
										
										
										
											2025-04-04 18:29:22 +02:00
										 |  |  | 				{createOrUpdateResult.error && <Error error={createOrUpdateResult.error} />} | 
					
						
							| 
									
										
										
										
											2023-10-17 12:46:06 +02:00
										 |  |  | 				{removeResult.error && <Error error={removeResult.error} />} | 
					
						
							|  |  |  | 			</> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		</form> | 
					
						
							|  |  |  | 	); | 
					
						
							|  |  |  | } |