-
Notifications
You must be signed in to change notification settings - Fork 11
feat: Implement editable field components for scalar value types #335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/node-editing
Are you sure you want to change the base?
Changes from all commits
9dca48d
0195e90
2490cff
149f58a
9279bb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,24 @@ | |
| * limitations under the License. | ||
| */ | ||
|
|
||
| import { useEffect, useRef } from "react"; | ||
| import type { ReactNode } from "react"; | ||
| import type { DetailField } from "@/core/taskDetails"; | ||
| import { Input } from "@/components/ui/input"; | ||
| import { Textarea } from "@/components/ui/textarea"; | ||
| import { Switch } from "@/components/ui/switch"; | ||
| import { | ||
| Combobox, | ||
| ComboboxContent, | ||
| ComboboxItem, | ||
| ComboboxTrigger, | ||
| ComboboxList, | ||
| ComboboxValue, | ||
| } from "@/components/ui/combobox"; | ||
|
|
||
| const ISO_8601_DURATION_REGEX = | ||
| /^P(?=\d|T)(?:\d+Y)?(?:\d+M)?(?:\d+W)?(?:\d+D)?(?:T(?=\d)(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$/; | ||
|
|
||
| export function SectionHeader({ label }: { label: string }) { | ||
| return ( | ||
| <div className="dec-sidebar-section-header"> | ||
|
|
@@ -32,11 +50,88 @@ export function InlineField({ label, value }: { label: string; value: string }) | |
| ); | ||
| } | ||
|
|
||
| export function PropertyField({ label, value }: { label: string; value: string }) { | ||
| function AutoGrowTextarea({ value, disabled }: { value: string; disabled: boolean }) { | ||
| const textareaRef = useRef<HTMLTextAreaElement>(null); | ||
|
|
||
| useEffect(() => { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not fully sure why we need this? This looks like its overriding functionality in the shadcn component? Should just be able to use TextArea component directly? I can see it has the styles for height and size content? |
||
| const textarea = textareaRef.current; | ||
|
|
||
| if (!textarea) { | ||
| return; | ||
| } | ||
|
|
||
| textarea.style.height = "auto"; | ||
| textarea.style.height = `${textarea.scrollHeight}px`; | ||
| }, [value]); | ||
|
|
||
| return <Textarea ref={textareaRef} value={value} disabled={disabled} />; | ||
| } | ||
|
|
||
| export function PropertyField({ | ||
| label, | ||
| field, | ||
| isReadOnly, | ||
| }: { | ||
| label: string; | ||
| field: DetailField; | ||
| isReadOnly: boolean; | ||
| }) { | ||
| let control: ReactNode; | ||
|
|
||
| if (field.kind === "long-string") { | ||
| control = <AutoGrowTextarea value={field.value} disabled={isReadOnly} />; | ||
| } else if (field.kind === "runtime-expression") { | ||
| control = ( | ||
| <div> | ||
| <span className="dec-sidebar-hint-text">Runtime expression</span> | ||
| <Input value={field.value} disabled={isReadOnly} /> | ||
| </div> | ||
| ); | ||
| } else if (field.kind === "duration") { | ||
| control = ( | ||
| <Input | ||
| value={field.value} | ||
| disabled={isReadOnly} | ||
| pattern={ISO_8601_DURATION_REGEX.source} | ||
| title="Enter an ISO 8601 duration, for example PT30S or PT5M" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be in a translation string |
||
| /> | ||
| ); | ||
| } else if (field.kind === "enum") { | ||
|
kumaradityaraj marked this conversation as resolved.
|
||
| control = ( | ||
| <Combobox value={field.value} disabled={isReadOnly}> | ||
|
kumaradityaraj marked this conversation as resolved.
|
||
| <ComboboxTrigger> | ||
| <ComboboxValue placeholder="Select an option" /> | ||
| </ComboboxTrigger> | ||
|
|
||
| <ComboboxContent> | ||
| <ComboboxList> | ||
| {field.options.map((option) => ( | ||
| <ComboboxItem key={option} value={option}> | ||
| {option} | ||
| </ComboboxItem> | ||
| ))} | ||
| </ComboboxList> | ||
| </ComboboxContent> | ||
| </Combobox> | ||
| ); | ||
| } else if (field.kind === "scalar" && typeof field.value === "string") { | ||
| control = <Input value={field.value} disabled={isReadOnly} />; | ||
| } else if (field.kind === "scalar" && typeof field.value === "number") { | ||
| control = <Input type="number" value={field.value} disabled={isReadOnly} />; | ||
| } else if (field.kind === "scalar" && typeof field.value === "boolean") { | ||
| control = <Switch checked={field.value} disabled={isReadOnly} />; | ||
| } else if (field.kind === "scalar") { | ||
| control = String(field.value); | ||
| } else if (field.kind === "array") { | ||
| control = `${field.count} item${field.count === 1 ? "" : "s"}`; | ||
| } else { | ||
| control = "{...}"; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think its cleaner to create a new file FieldControls.tsx that moves this logic. It would export a function that we can call here, something like Above that export function define the fields explicitly then, for example The update the PropertyFunction in this file to call that? |
||
| } | ||
|
|
||
| return ( | ||
| <div className="dec-sidebar-prop"> | ||
| <dt className="dec-sidebar-prop-label">{label}</dt> | ||
| <dd className="dec-sidebar-prop-value">{value}</dd> | ||
| <dd className="dec-sidebar-prop-value">{control}</dd> | ||
| </div> | ||
| ); | ||
|
kumaradityaraj marked this conversation as resolved.
|
||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment to this section that it is temporary until we can dynamically build the form with field types