Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/components/TimeAgo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ import { timeAgoAbbr } from 'app/util/date'

export const TimeAgo = ({
datetime,
description,
tooltipText,
placement = 'top',
}: {
datetime: Date
description?: string
tooltipText?: string
placement?: Placement
}): JSX.Element => {
const content = (
<div className="flex flex-col">
<span className="text-tertiary">{description}</span>
<span className="text-tertiary">{tooltipText}</span>
<span>{format(datetime, 'MMM d, yyyy p')}</span>
</div>
)
Expand Down
14 changes: 8 additions & 6 deletions app/components/form/fields/FileField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ export function FileField<
id,
name,
label,
description,
tooltipText,
control,
required = false,
accept,
helpText,
description,
}: {
id: string
name: TName
label: string
description?: string
tooltipText?: string
control: Control<TFieldValues>
required?: boolean
accept?: string
helpText?: string
description?: string | React.ReactNode
}) {
return (
<Controller
Expand All @@ -44,12 +44,14 @@ export function FileField<
<FieldLabel
id={`${id}-label`}
htmlFor={id}
tip={description}
tip={tooltipText}
optional={!required}
>
{label}
</FieldLabel>
{helpText && <TextInputHint id={`${id}-help-text`}>{helpText}</TextInputHint>}
{description && (
<TextInputHint id={`${id}-help-text`}>{description}</TextInputHint>
)}
</div>
<FileInput id={id} className="mt-2" accept={accept} {...rest} error={!!error} />
<ErrorMessage error={error} label={label} />
Expand Down
10 changes: 5 additions & 5 deletions app/components/form/fields/ListboxField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export type ListboxFieldProps<
className?: string
label?: string
required?: boolean
helpText?: string
description?: string
description?: string | React.ReactNode | React.ReactNode
tooltipText?: string
control: Control<TFieldValues>
disabled?: boolean
items: ListboxItem[]
Expand All @@ -41,8 +41,8 @@ export function ListboxField<
label = capitalize(name),
disabled,
required,
tooltipText,
description,
helpText,
className,
control,
onChange,
Expand All @@ -59,9 +59,9 @@ export function ListboxField<
render={({ field, fieldState: { error } }) => (
<>
<Listbox
helpText={helpText}
label={label}
description={description}
label={label}
tooltipText={tooltipText}
required={required}
placeholder={placeholder}
selected={field.value || null}
Expand Down
160 changes: 81 additions & 79 deletions app/components/form/fields/NetworkInterfaceField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,88 +43,90 @@ export function NetworkInterfaceField({
return (
<div className="max-w-lg space-y-2">
<FieldLabel id="network-interface-type-label">Network interface</FieldLabel>
<RadioGroup
aria-labelledby="network-interface-type-label"
name="networkInterfaceType"
column
className="pt-1"
defaultChecked={value.type}
onChange={(event) => {
const newType = event.target.value as InstanceNetworkInterfaceAttachment['type']
<div className="space-y-4">
<RadioGroup
aria-labelledby="network-interface-type-label"
name="networkInterfaceType"
column
className="pt-1"
defaultChecked={value.type}
onChange={(event) => {
const newType = event.target.value as InstanceNetworkInterfaceAttachment['type']

if (value.type === 'create') {
setOldParams(value.params)
}
if (value.type === 'create') {
setOldParams(value.params)
}

newType === 'create'
? onChange({ type: newType, params: oldParams })
: onChange({ type: newType })
}}
disabled={disabled}
>
<Radio value="none">None</Radio>
<Radio value="default">Default</Radio>
<Radio value="create">Custom</Radio>
</RadioGroup>
{value.type === 'create' && (
<>
{value.params.length > 0 && (
<MiniTable.Table className="mb-4">
<MiniTable.Header>
<MiniTable.HeadCell>Name</MiniTable.HeadCell>
<MiniTable.HeadCell>VPC</MiniTable.HeadCell>
<MiniTable.HeadCell>Subnet</MiniTable.HeadCell>
{/* For remove button */}
<MiniTable.HeadCell className="w-12" />
</MiniTable.Header>
<MiniTable.Body>
{value.params.map((item, index) => (
<MiniTable.Row
tabIndex={0}
aria-rowindex={index + 1}
aria-label={`Name: ${item.name}, Vpc: ${item.vpcName}, Subnet: ${item.subnetName}`}
key={item.name}
>
<MiniTable.Cell>{item.name}</MiniTable.Cell>
<MiniTable.Cell>{item.vpcName}</MiniTable.Cell>
<MiniTable.Cell>{item.subnetName}</MiniTable.Cell>
<MiniTable.Cell>
<button
onClick={() =>
onChange({
type: 'create',
params: value.params.filter((i) => i.name !== item.name),
})
}
>
<Error16Icon title={`remove ${item.name}`} />
</button>
</MiniTable.Cell>
</MiniTable.Row>
))}
</MiniTable.Body>
</MiniTable.Table>
)}
newType === 'create'
? onChange({ type: newType, params: oldParams })
: onChange({ type: newType })
}}
disabled={disabled}
>
<Radio value="none">None</Radio>
<Radio value="default">Default</Radio>
<Radio value="create">Custom</Radio>
</RadioGroup>
{value.type === 'create' && (
<>
{value.params.length > 0 && (
<MiniTable.Table className="pt-2">
<MiniTable.Header>
<MiniTable.HeadCell>Name</MiniTable.HeadCell>
<MiniTable.HeadCell>VPC</MiniTable.HeadCell>
<MiniTable.HeadCell>Subnet</MiniTable.HeadCell>
{/* For remove button */}
<MiniTable.HeadCell className="w-12" />
</MiniTable.Header>
<MiniTable.Body>
{value.params.map((item, index) => (
<MiniTable.Row
tabIndex={0}
aria-rowindex={index + 1}
aria-label={`Name: ${item.name}, Vpc: ${item.vpcName}, Subnet: ${item.subnetName}`}
key={item.name}
>
<MiniTable.Cell>{item.name}</MiniTable.Cell>
<MiniTable.Cell>{item.vpcName}</MiniTable.Cell>
<MiniTable.Cell>{item.subnetName}</MiniTable.Cell>
<MiniTable.Cell>
<button
onClick={() =>
onChange({
type: 'create',
params: value.params.filter((i) => i.name !== item.name),
})
}
>
<Error16Icon title={`remove ${item.name}`} />
</button>
</MiniTable.Cell>
</MiniTable.Row>
))}
</MiniTable.Body>
</MiniTable.Table>
)}

{showForm && (
<CreateNetworkInterfaceForm
onSubmit={(networkInterface) => {
onChange({
type: 'create',
params: [...value.params, networkInterface],
})
setShowForm(false)
}}
onDismiss={() => setShowForm(false)}
/>
)}
<div className="space-x-3">
<Button size="sm" onClick={() => setShowForm(true)}>
Add network interface
</Button>
</div>
</>
)}
{showForm && (
<CreateNetworkInterfaceForm
onSubmit={(networkInterface) => {
onChange({
type: 'create',
params: [...value.params, networkInterface],
})
setShowForm(false)
}}
onDismiss={() => setShowForm(false)}
/>
)}
<div className="space-x-3">
<Button size="sm" onClick={() => setShowForm(true)}>
Add network interface
</Button>
</div>
</>
)}
</div>
</div>
)
}
14 changes: 7 additions & 7 deletions app/components/form/fields/NumberField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export function NumberField<
name,
label = capitalize(name),
units,
tooltipText,
description,
helpText,
required,
...props
}: Omit<TextFieldProps<TFieldValues, TName>, 'id'>) {
Expand All @@ -33,12 +33,12 @@ export function NumberField<
return (
<div className="max-w-lg">
<div className="mb-2">
<FieldLabel htmlFor={id} id={`${id}-label`} tip={description} optional={!required}>
<FieldLabel htmlFor={id} id={`${id}-label`} tip={tooltipText} optional={!required}>
{label} {units && <span className="ml-1 text-secondary">({units})</span>}
</FieldLabel>
{helpText && (
{description && (
<TextInputHint id={`${id}-help-text`} className="mb-2">
{helpText}
{description}
</TextInputHint>
)}
</div>
Expand All @@ -65,7 +65,7 @@ export const NumberFieldInner = <
label = capitalize(name),
validate,
control,
description,
tooltipText,
required,
id: idProp,
disabled,
Expand All @@ -85,9 +85,9 @@ export const NumberFieldInner = <
id={id}
error={!!error}
aria-labelledby={cn(`${id}-label`, {
[`${id}-help-text`]: !!description,
[`${id}-help-text`]: !!tooltipText,
})}
aria-describedby={description ? `${id}-label-tip` : undefined}
aria-describedby={tooltipText ? `${id}-label-tip` : undefined}
isDisabled={disabled}
{...field}
/>
Expand Down
Loading