Skip to content

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

Merged

Conversation

phantrung18072001
Copy link
Contributor

@phantrung18072001 phantrung18072001 commented Aug 23, 2024

PR fulfills these requirements

  • Commit message(s) and PR title follows the format [fix|feat|ci|chore|doc]: TICKET-ID: Short description of change made ex. fix: DEV-XXXX: Removed inconsistent code usage causing intermittent errors
  • Docs have been added/updated (for bug fixes/features)
  • Best efforts were made to ensure docs/code are concise and coherent (checked for spelling/grammatical errors, commented out code, debug logs etc.)
  • Self-reviewed and ran all changes on a local instance (for bug fixes/features)

Change has impacts in these area(s)

(check all that apply)

  • Product design
  • Backend (Database)
  • Backend (API)
  • Frontend

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.
image

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)

  • Yes, and covered entirely by feature flag(s)
  • Yes, and covered partially by feature flag(s)
  • No
  • Not sure (briefly explain the situation below)

Copy link

netlify bot commented Aug 23, 2024

👷 Deploy request for label-studio-docs-new-theme pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 42fc949

Copy link

netlify bot commented Aug 23, 2024

👷 Deploy request for heartex-docs pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 42fc949

@makseq makseq changed the title Add duration time in info tab feat; Add duration time in info tab Aug 23, 2024
@makseq makseq changed the title feat; Add duration time in info tab feat: Add duration time in info tab Aug 23, 2024
@phantrung18072001 phantrung18072001 force-pushed the feature/add-duration-time branch from 11149e0 to c0a2352 Compare August 26, 2024 03:59
@phantrung18072001
Copy link
Contributor Author

I don't know how to add title (Start Time, End Time, Duration) to make it clearly for user. Please help me.

@bmartel
Copy link
Contributor

bmartel commented Aug 26, 2024

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.

@bmartel
Copy link
Contributor

bmartel commented Aug 26, 2024

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 label prop in the in the Timebox component:

      <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
      />

@phantrung18072001
Copy link
Contributor Author

phantrung18072001 commented Aug 28, 2024

Thanks @bmartel, I have a typescript error when importing Label into TimeBox. Is this acceptable ? And it doesn't work as I expeted.
image

@bmartel
Copy link
Contributor

bmartel commented Aug 28, 2024

Thanks @bmartel, I have a typescript error when importing Label into TimeBox. Is this acceptable ? And it doesn't work as I expeted. image

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.

@bmartel
Copy link
Contributor

bmartel commented Aug 28, 2024

I fixed the styles for these components so it should now look fairly good 👍.

Screenshot 2024-08-28 at 9 16 33 AM

@phantrung18072001
Copy link
Contributor Author

phantrung18072001 commented Aug 29, 2024

Thank you, it's perfect for me. Please merge the PR and go live as soon as possible.

@bmartel
Copy link
Contributor

bmartel commented Sep 9, 2024

/jira create

Workflow run
Jira issue TRIAG-836 is created

@bmartel bmartel merged commit 36dd393 into HumanSignal:develop Sep 10, 2024
59 of 60 checks passed
@binhnq94
Copy link

binhnq94 commented Oct 1, 2024

@bmartel Can you tell me how to config for showing the duration?
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants