Skip to content
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

Add custom input fields for editing metadata #354

Open
wants to merge 15 commits into
base: feature/metadata-editing/develop
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
}

.choice-group label > span {
font-size: var(--l-paragraph-size);
font-size: var(--s-paragraph-size);
margin-right: 5px;
margin-top: 1px;
padding-left: 24px !important;
Expand Down
3 changes: 1 addition & 2 deletions packages/core/components/ComboBox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ interface Props {
multiSelect?: boolean;
options: IComboBoxOption[];
placeholder: string;
useComboBoxAsMenuWidth?: boolean;
onChange?: (option: IComboBoxOption | undefined, value?: string | undefined) => void;
}

Expand Down Expand Up @@ -67,7 +66,7 @@ export default function BaseComboBox(props: Props) {
comboBoxOptionStyles={{
rootChecked: styles.comboBoxItemChecked,
}}
useComboBoxAsMenuWidth={props?.useComboBoxAsMenuWidth}
useComboBoxAsMenuWidth={true}
aswallace marked this conversation as resolved.
Show resolved Hide resolved
/>
);
}
14 changes: 14 additions & 0 deletions packages/core/components/DurationForm/DurationForm.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.input-wrapper {
display: flex;
}

.input-field {
margin-right: 3px;
max-height: fit-content;
}

.input-field > input {
padding: 6px;
font-size: var(--s-paragraph-size);
max-width: 70px;
}
80 changes: 80 additions & 0 deletions packages/core/components/DurationForm/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import * as React from "react";

import NumberField from "../NumberRangePicker/NumberField";
import annotationFormatterFactory, { AnnotationType } from "../../entity/AnnotationFormatter";

import styles from "./DurationForm.module.css";

interface DurationFormProps {
className?: string;
defaultValue?: number;
onChange: (totalDuration: number) => void;
title?: string;
}

/**
* This component renders a simple form for entering durations
*/
export default function DurationForm(props: DurationFormProps) {
const { onChange } = props;
const [days, setDurationDays] = React.useState<string>("0");
const [hours, setDurationHours] = React.useState<string>("0");
const [minutes, setDurationMinutes] = React.useState<string>("0");
const [seconds, setDurationSeconds] = React.useState<string>("0");
const durationFormatter = annotationFormatterFactory(AnnotationType.DURATION);

React.useEffect(() => {
const durationString = `${Number(days) || 0}D ${Number(hours) || 0}H ${
Number(minutes) || 0
}M ${Number(seconds) || 0}S`;
const totalDurationInMs = Number(durationFormatter.valueOf(durationString));
onChange(totalDurationInMs);
}, [days, hours, minutes, seconds, durationFormatter, onChange]);

return (
<div>
<h3 className={styles.title}>{props?.title}</h3>
<div className={styles.inputWrapper}>
<NumberField
aria-label="Days"
className={styles.inputField}
id="durationDays"
label="Days"
onChange={(event) => setDurationDays(event?.target?.value || "")}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this component could exclusively pass around Number type values (for cases with leading zeroes it would just not yet return a value AKA undefined); NBD to keep this though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree in theory, but running into some implementation bugs

defaultValue={days}
min={0}
/>
<NumberField
aria-label="Hours"
aswallace marked this conversation as resolved.
Show resolved Hide resolved
className={styles.inputField}
id="durationHours"
label="Hrs"
onChange={(event) => setDurationHours(event?.target?.value || "")}
defaultValue={hours}
min={0}
max={23}
/>
<NumberField
aria-label="Minutes"
className={styles.inputField}
id="durationMinutes"
label="Mins"
onChange={(event) => setDurationMinutes(event?.target?.value || "")}
defaultValue={minutes}
min={0}
max={59}
/>
<NumberField
aria-label="Seconds"
className={styles.inputField}
id="durationSeconds"
label="Secs"
onChange={(event) => setDurationSeconds(event?.target?.value || "")}
defaultValue={seconds}
min={0}
max={59}
/>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@

.text-field {
padding-bottom: var(--margin);
max-width: 300px;;
width: 300px;;
aswallace marked this conversation as resolved.
Show resolved Hide resolved
}

.text-field > div > label, .text-field > div > label::after {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import * as React from "react";
import MetadataDetails, { ValueCountItem } from "./MetadataDetails";
import { PrimaryButton, SecondaryButton } from "../Buttons";
import ComboBox from "../ComboBox";
import { AnnotationType } from "../../entity/AnnotationFormatter";

import styles from "./EditMetadata.module.css";

interface ExistingAnnotationProps {
onDismiss: () => void;
annotationValueMap: Map<string, any> | undefined;
annotationOptions: IComboBoxOption[];
annotationOptions: { key: string; text: string; data: string }[];
selectedFileCount: number;
}

Expand All @@ -23,6 +24,7 @@ export default function ExistingAnnotationPathway(props: ExistingAnnotationProps
const [newValues, setNewValues] = React.useState<string>();
const [valueCount, setValueCount] = React.useState<ValueCountItem[]>();
const [selectedAnnotation, setSelectedAnnotation] = React.useState<string | undefined>();
const [annotationType, setAnnotationType] = React.useState<AnnotationType | undefined>();

const onSelectMetadataField = (
option: IComboBoxOption | undefined,
Expand Down Expand Up @@ -61,6 +63,7 @@ export default function ExistingAnnotationPathway(props: ExistingAnnotationProps
];
}
setSelectedAnnotation(selectedFieldName);
setAnnotationType(option?.data);
setValueCount(valueMap);
};

Expand All @@ -74,16 +77,16 @@ export default function ExistingAnnotationPathway(props: ExistingAnnotationProps
<ComboBox
className={styles.comboBox}
label="Select a metadata field"
placeholder="Select a field"
placeholder="Select a field..."
selectedKey={selectedAnnotation}
options={props.annotationOptions}
useComboBoxAsMenuWidth
onChange={onSelectMetadataField}
/>
{!!selectedAnnotation && (
<MetadataDetails
onChange={(value) => setNewValues(value)}
items={valueCount || []}
fieldType={annotationType}
/>
)}
<div className={classNames(styles.footer, styles.footerAlignRight)}>
Expand Down
68 changes: 67 additions & 1 deletion packages/core/components/EditMetadata/MetadataDetails.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@
}

.table-title {
padding-bottom: 5px
padding-bottom: 5px;
}

.values-title {
padding-bottom: 5px;
padding-left: 35px;
}

.stack {
Expand All @@ -62,3 +67,64 @@
.stack-item-right {
width: 275px;
}

.read-only-placeholder {
margin-right: 20px;
font-style: italic;
color: var(--primary-text-color);
}

.input-field input {
background-color: var(--secondary-background-color);
border-radius: var(--small-border-radius);
border: 1px solid var(--border-color);
color: var(--secondary-text-color);
outline: none;
padding: 6px;
font-size: var(--s-paragraph-size);
width: 100%;
min-width: fit-content;
}

.input-field:active > input, .input-field > input:active,
.input-field:focus > input, .input-field > input:focus,
.input-field:focus-within > input, .input-field > input:focus-within {
border: 1px solid var(--aqua);
}

.input-wrapper {
margin-top: 4px;
display: flex;
align-items: center;
}

.date-range-root {
width: 300px;
}

.date-range-text-field div {
background-color: var(--secondary-background-color);
border: none;
border-radius: var(--small-border-radius);
color: var(--primary-text-color);
}

.date-range-text-field div::after {
border: 1px solid var(--aqua)
}

.date-range-text-field > div {
border: 1px solid var(--border-color)
}

.date-range-text-field i {
color: var(--primary-text-color)
}

.no-padding {
padding-bottom: 0;
}

.forward-icon {
padding-right: 20px;
}
Loading
Loading