atmosphere explorer pds.ls
tool typescript atproto

cleanup create record confirm submit

handle.invalid 7f0903b2 d45eeb56

verified
+63 -78
+63 -78
src/components/create/confirm-submit.tsx
··· 1 - import { createSignal, Show } from "solid-js"; 1 + import { createSignal, For, Show } from "solid-js"; 2 2 import { hasUserScope } from "../../auth/scope-utils"; 3 3 import { Button } from "../button.jsx"; 4 4 5 + const VALIDATE_OPTIONS: { label: string; value: boolean | undefined }[] = [ 6 + { label: "Unset", value: undefined }, 7 + { label: "True", value: true }, 8 + { label: "False", value: false }, 9 + ]; 10 + 11 + const activeClass = "bg-neutral-200 font-medium dark:bg-neutral-600"; 12 + const inactiveClass = "hover:bg-neutral-100 dark:hover:bg-neutral-700"; 13 + 5 14 export const ConfirmSubmit = (props: { 6 15 isCreate: boolean; 7 16 onConfirm: (validate: boolean | undefined, recreate: boolean) => void; ··· 10 19 const [validate, setValidate] = createSignal<boolean | undefined>(undefined); 11 20 const [recreate, setRecreate] = createSignal(false); 12 21 13 - const getValidateLabel = () => { 14 - return ( 15 - validate() === true ? "True" 16 - : validate() === false ? "False" 17 - : "Unset" 18 - ); 19 - }; 22 + return ( 23 + <div class="flex flex-col gap-3 text-sm"> 24 + <h2 class="font-semibold">{props.isCreate ? "Create" : "Edit"} record</h2> 20 25 21 - const cycleValidate = () => { 22 - setValidate( 23 - validate() === undefined ? true 24 - : validate() === true ? false 25 - : undefined, 26 - ); 27 - }; 26 + <div class="flex flex-col gap-1.5"> 27 + <div class="flex items-center justify-between gap-2"> 28 + <span>Validate</span> 29 + <div class="flex overflow-hidden rounded-md border border-neutral-200 text-xs dark:border-neutral-600"> 30 + <For each={VALIDATE_OPTIONS}> 31 + {(opt) => ( 32 + <button 33 + type="button" 34 + onClick={() => setValidate(opt.value)} 35 + class={`border-r border-neutral-200 px-2.5 py-1.5 transition-colors last:border-r-0 dark:border-neutral-600 ${validate() === opt.value ? activeClass : inactiveClass}`} 36 + > 37 + {opt.label} 38 + </button> 39 + )} 40 + </For> 41 + </div> 42 + </div> 43 + <p class="text-xs text-neutral-500 dark:text-neutral-400"> 44 + Set to 'false' to skip lexicon schema validation by the PDS, 'true' to require it, or 45 + leave unset to validate only for known lexicons. 46 + </p> 47 + </div> 28 48 29 - return ( 30 - <> 31 - <div class="flex flex-col gap-3 text-sm"> 32 - <h2 class="font-semibold">{props.isCreate ? "Create" : "Edit"} record</h2> 49 + <Show when={!props.isCreate}> 33 50 <div class="flex flex-col gap-1.5"> 34 - <div class="flex items-center gap-2"> 35 - <button 36 - type="button" 37 - class="-ml-2 flex min-w-30 items-center gap-1.5 rounded-lg px-2 py-1 text-xs hover:bg-neutral-200/50 dark:hover:bg-neutral-700" 38 - onClick={cycleValidate} 39 - > 40 - <span 41 - classList={{ 42 - iconify: true, 43 - "lucide--square-check text-green-500 dark:text-green-400": validate() === true, 44 - "lucide--square-x text-red-500 dark:text-red-400": validate() === false, 45 - "lucide--square text-neutral-500 dark:text-neutral-400": validate() === undefined, 46 - }} 47 - ></span> 48 - <span>Validate: {getValidateLabel()}</span> 49 - </button> 50 - </div> 51 - <p class="text-xs text-neutral-600 dark:text-neutral-400"> 52 - Set to 'false' to skip lexicon schema validation by the PDS, 'true' to require it, or 53 - leave unset to validate only for known lexicons. 51 + <label 52 + class={`flex items-center gap-2 text-sm ${!hasUserScope("create") ? "opacity-40" : ""}`} 53 + > 54 + <input 55 + type="checkbox" 56 + checked={recreate()} 57 + disabled={!hasUserScope("create")} 58 + onChange={(e) => setRecreate(e.currentTarget.checked)} 59 + class="h-3.5 w-3.5 accent-blue-500" 60 + /> 61 + Recreate{!hasUserScope("create") ? " (create permission needed)" : ""} 62 + </label> 63 + <p class="text-xs text-neutral-500 dark:text-neutral-400"> 64 + Delete the existing record and create a new one with the same record key. 54 65 </p> 55 66 </div> 56 - <Show when={!props.isCreate}> 57 - <div class="flex flex-col gap-1.5"> 58 - <div class="flex items-center gap-2"> 59 - <button 60 - type="button" 61 - class={ 62 - hasUserScope("create") ? 63 - "-ml-2 flex items-center gap-1.5 rounded-lg px-2 py-1 text-xs hover:bg-neutral-200/50 dark:hover:bg-neutral-700" 64 - : "-ml-2 flex items-center gap-1.5 rounded-lg px-2 py-1 text-xs opacity-40" 65 - } 66 - onClick={() => hasUserScope("create") && setRecreate(!recreate())} 67 - > 68 - <span 69 - classList={{ 70 - iconify: true, 71 - "lucide--square-check text-green-500 dark:text-green-400": recreate(), 72 - "lucide--square text-neutral-500 dark:text-neutral-400": !recreate(), 73 - }} 74 - ></span> 75 - <span>Recreate{hasUserScope("create") ? "" : " (create permission needed)"}</span> 76 - </button> 77 - </div> 78 - <p class="text-xs text-neutral-600 dark:text-neutral-400"> 79 - Delete the existing record and create a new one with the same record key. 80 - </p> 81 - </div> 82 - </Show> 83 - <div class="flex justify-between gap-2"> 84 - <Button onClick={props.onClose}>Cancel</Button> 85 - <Button 86 - onClick={() => props.onConfirm(validate(), recreate())} 87 - classList={{ 88 - "bg-blue-500! text-white! border-none! hover:bg-blue-600! active:bg-blue-700! dark:bg-blue-600! dark:hover:bg-blue-500! dark:active:bg-blue-400!": true, 89 - }} 90 - > 91 - {props.isCreate ? "Create" : "Edit"} 92 - </Button> 93 - </div> 67 + </Show> 68 + 69 + <div class="flex justify-between gap-2"> 70 + <Button onClick={props.onClose}>Cancel</Button> 71 + <Button 72 + onClick={() => props.onConfirm(validate(), recreate())} 73 + classList={{ 74 + "bg-blue-500! text-white! border-none! hover:bg-blue-600! active:bg-blue-700! dark:bg-blue-600! dark:hover:bg-blue-500! dark:active:bg-blue-400!": true, 75 + }} 76 + > 77 + {props.isCreate ? "Create" : "Edit"} 78 + </Button> 94 79 </div> 95 - </> 80 + </div> 96 81 ); 97 82 };