-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat: Add duration time in info tab #6244
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
feat: Add duration time in info tab #6244
Conversation
👷 Deploy request for label-studio-docs-new-theme pending review.Visit the deploys page to approve it
|
👷 Deploy request for heartex-docs pending review.Visit the deploys page to approve it
|
11149e0
to
c0a2352
Compare
I don't know how to add title (Start Time, End Time, Duration) to make it clearly for user. Please help me. |
Thanks for this contribution @phantrung18072001, this makes good sense to add. With regards to differentiating the Start Time, End Time and Duration, that would require a label for each which the TimeBox component currently does not offer directly as a prop which would have to be added as an optional prop and styled in a way that is unobtrusive to the layout of the component. |
As an initial start, you could try updating the code for the Timebox component to reflect the following: import React, { type FC, useCallback, useEffect, useState } from "react";
import { Block, Elem } from "../../utils/bem";
import { MaskUtil } from "../../utils/InputMask";
import { Label } from "../Label/Label";
import "./TimeBox.styl";
export interface TimerProps {
sidepanel: boolean;
value: number;
readonly?: boolean;
inverted?: boolean;
onChange: (value: number) => void;
label?: string;
}
export const TimeBox: FC<TimerProps> = ({
sidepanel = false,
value,
inverted = false,
readonly = false,
onChange,
label,
...props
}) => {
const inputRef = React.createRef<HTMLInputElement>();
const [currentInputTime, setCurrentInputTime] = useState<string | number | undefined>(value);
useEffect(() => {
if (inputRef.current)
new MaskUtil(inputRef.current, "11:11:11:111", (data: string) => {
setCurrentInputTime(data);
});
}, []);
useEffect(() => {
setCurrentInputTime(formatTime(value || 0, true));
}, [value]);
const formatTime = useCallback((time: number, input = false): any => {
const timeDate = new Date(time * 1000).toISOString();
let formatted = time > 3600 ? timeDate.substr(11, 8) : `00:${timeDate.substr(14, 5)}`;
if (input) {
const isHour = timeDate.substr(11, 2) !== "00";
formatted = timeDate.substr(isHour ? 11 : 14, isHour ? 12 : 9).replace(".", ":");
formatted = !isHour ? `00:${formatted}` : formatted;
}
return formatted;
}, []);
const convertTextToTime = (value: string) => {
const splittedValue = value.split(":").reverse();
let totalTime = 0;
if (value.indexOf("_") >= 0) return;
const calcs = [(x: number) => x / 1000, (x: number) => x, (x: number) => x * 60, (x: number) => x * 60 * 60];
splittedValue.forEach((value, index) => {
totalTime += calcs[index](Number.parseFloat(value));
});
onChange(totalTime);
};
const handleBlurInput = (e: React.FormEvent<HTMLInputElement>) => {
const splittedValue = e.currentTarget.value.split(":");
splittedValue[0] =
splittedValue[0].toString().length === 1 ? `0${splittedValue[0].toString()}` : `${splittedValue[0]}`;
convertTextToTime(splittedValue.join(":"));
setCurrentInputTime(formatTime(value || 0, true));
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
e.currentTarget?.blur?.();
}
};
const renderInputTime = () => {
return (
<Elem
name={"input-time"}
maxLength={12}
tag={"input"}
ref={inputRef}
type="text"
readOnly={readonly}
value={currentInputTime}
onKeyDown={handleKeyDown}
onChange={() => {}}
onBlur={handleBlurInput}
/>
);
};
const timeBoxContent = (
<Block name="time-box" mod={{ inverted, sidepanel }} {...props}>
{renderInputTime()}
</Block>
);
return label ? (
<Label text={label}>
{timeBoxContent}
</Label>
) : (
timeBoxContent
);
}; Which should provide an optional label. The label might be too large but that can be fixed if needed through a simple style change. Then you can use the <TimeBox
sidepanel={isSidepanel}
readonly={startTimeReadonly}
value={_currentTime}
label="Start"
onChange={handleChangeCurrentTime}
data-testid="timebox-current-time"
/>
<TimeBox
sidepanel={isSidepanel}
readonly={endTimeReadonly}
value={endTime}
label="End"
onChange={handleChangeEndTime}
data-testid="timebox-end-time"
inverted
/>
<TimeBox
sidepanel={isSidepanel}
readonly={true}
value={endTime - startTime}
label="Duration"
onChange={()=> {}}
data-testid="timebox-duration-time"
inverted
/> |
Thanks @bmartel, I have a typescript error when importing Label into TimeBox. Is this acceptable ? And it doesn't work as I expeted. |
The error is due to the Label component being written only in Javascript, so that error can be ignored. The one thing I just pushed up an amendment to is the Label only takes children as props for assigning text values. Try it out now, I'm certain styling will have to be updated but maybe it gets close. |
Thank you, it's perfect for me. Please merge the PR and go live as soon as possible. |
/jira create
|
@bmartel Can you tell me how to config for showing the duration? |
PR fulfills these requirements
[fix|feat|ci|chore|doc]: TICKET-ID: Short description of change made
ex.fix: DEV-XXXX: Removed inconsistent code usage causing intermittent errors
Change has impacts in these area(s)
(check all that apply)
Describe the reason for change
The reason for this change is to add a new TimeBox component to display the duration time between startTime and endTime in the TimeDurationControl component. This update enhances the UI by showing the total duration in a read-only format.

What is the current behavior?
Currently, the duration between startTime and endTime is not displayed in the TimeDurationControl component.
Does this PR introduce a breaking change?
(check only one)