Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@nordcloud/gnui",
"description": "Nordcloud Design System - a collection of reusable React components used in Nordcloud's SaaS products",
"version": "11.5.3",
"version": "11.6.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default {
],
plugins: [
typescript({
include: ["src/**/*.{ts,tsx}"],
useTsconfigDeclarationDir: true,
tsconfigOverride: {
exclude: [
Expand Down
25 changes: 16 additions & 9 deletions src/components/timeRangePicker/TimeRangePicker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import * as TimeRangePickerStories from "./TimeRangePicker.stories";

## TimeRangePicker properties

| properties | required | type | description |
| ------------: | :------: | :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------- |
| initTimeRange | false | Interval | Start date and end date should be within the same day, current date will be used otherwise and by default |
| type | false | <code>Days</code>, <code>Hours</code> | Type of time selected in component |
| weekCounts | false | DailyCount\[] | Item counts in each time range (Type "Hours" only) |
| countsLoading | false | boolean | Loading state of week counts (Type "Hours" only) |
| disabledDays | false | Matcher\[] | Dates not allowed to select |
| onChange | true | <code>(newTimeRange: Interval) => void</code> | Function to handle timeRange change |
| onWeekChange | false | <code>(monday: Date) => void</code> | Function to submit when showing week updates (Type "Hours" only) |
| properties | required | type | description |
| ------------------: | :------: | :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------- |
| initTimeRange | false | Interval | Start date and end date should be within the same day, current date will be used otherwise and by default |
| type | false | <code>Days</code>, <code>Hours</code> | Type of time selected in component |
| weekCounts | false | DailyCount\[] | Item counts in each time range (Type "Hours" only) |
| countsLoading | false | boolean | Loading state of week counts (Type "Hours" only) |
| disabledDays | false | Matcher\[] | Dates not allowed to select |
| keepSelectedWeekday | false | boolean | Whether to preserve week day selection when changing week (Type "Hours" only) |
| onChange | true | <code>(newTimeRange: Interval) => void</code> | Function to handle timeRange change |
| onWeekChange | false | <code>(monday: Date) => void</code> | Function to submit when showing week updates (Type "Hours" only) |

```typescript
import { Interval } from "date-fns";
Expand Down Expand Up @@ -49,6 +50,12 @@ type Matcher = (boolean | (date: Date)) => boolean | Date | Date[] | DateRange |
<Story of={TimeRangePickerStories.TimerangepickerOfHours} />
</Canvas>

## Type "Hours" with preserved day selection

<Canvas>
<Story of={TimeRangePickerStories.TimerangepickerOfHoursWithKeepSelectedWeekday} />
</Canvas>

## Type "Hours" with Histogram

<Canvas>
Expand Down
19 changes: 19 additions & 0 deletions src/components/timeRangePicker/TimeRangePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,28 @@
name: "timerangepicker of hours ",
};

export const TimerangepickerOfHoursWithKeepSelectedWeekday: StoryObj = {
render: () => {
const [value, setValue] = useState<{
start: Date | number;
end: Date | number;
}>();

return (
<>
<TimeRangePicker keepSelectedWeekday onChange={setValue} />
<Spacer height="20rem" />
<div id="result-hours">Current Value:{JSON.stringify(value)}</div>
</>
);
},

name: "timerangepicker of hours with preserved day",
};

export const TimerangepickerOfHoursWithHistogram: StoryObj = {
render: () => {
const [value, setValue] = useState<{

Check warning on line 82 in src/components/timeRangePicker/TimeRangePicker.stories.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

React Hook "useState" is called in function "render" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".

See more on https://sonarcloud.io/project/issues?id=nordcloud_GNUI&issues=AZ5KsNGbEFzP-c7oEzTV&open=AZ5KsNGbEFzP-c7oEzTV&pullRequest=785
start: Date | number;
end: Date | number;
}>();
Expand Down
3 changes: 3 additions & 0 deletions src/components/timeRangePicker/TimeRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DatesPicker, DateHourPicker } from "./components";
type Props = Omit<ComponentProps<typeof DateHourPicker>, "initTimeRange"> & {
initTimeRange?: Interval;
type?: "Days" | "Hours";
keepSelectedWeekday?: boolean;
};

const DEFAULT_TIME_RANGE: Interval = {
Expand All @@ -17,6 +18,7 @@ export function TimeRangePicker({
weekCounts,
countsLoading = false,
disabledDays,
keepSelectedWeekday = false,
onChange,
onWeekChange,
}: Props) {
Expand All @@ -35,6 +37,7 @@ export function TimeRangePicker({
weekCounts={weekCounts}
countsLoading={countsLoading}
disabledDays={disabledDays}
keepSelectedWeekday={keepSelectedWeekday}
onChange={onChange}
onWeekChange={onWeekChange}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import {
getMonday,
getTimeRangeDate,
isSameTimeRange,
getNewSelectedDate,
} from "../utils";
import { DateSelector, HourSelector } from "./components";

type Props = DatesPickerProps & {
weekCounts?: DailyCount[];
countsLoading?: boolean;
keepSelectedWeekday?: boolean;
onWeekChange?: (monday: Date) => void;
};

Expand All @@ -29,11 +31,12 @@ export function DateHourPicker({
weekCounts,
countsLoading = false,
disabledDays,
keepSelectedWeekday = false,
onChange,
onWeekChange,
}: Props) {
const [selectedDate, setSelectedDate] = useState<Date>(
getTimeRangeDate(initTimeRange)
getTimeRangeDate(initTimeRange, "Hours")
);
const [dateOptions, setDateOptions] = useState<DateOption[]>(
getDateOptions(getMonday(initTimeRange.start))
Expand Down Expand Up @@ -93,6 +96,15 @@ export function DateHourPicker({
if (onWeekChange) {
onWeekChange(newMonday);
}
if (keepSelectedWeekday) {
const newSeletedDate = getNewSelectedDate(
selectedDate,
currentMonday,
newMonday
);
setSelectedDate(newSeletedDate);
submitDateHour(newSeletedDate, selectedTimeRange);
}
};

// Function to update time range options
Expand Down
36 changes: 34 additions & 2 deletions src/components/timeRangePicker/components/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import {
addMonths,
addYears,
getHours,
differenceInCalendarDays,
startOfDay,
set,
subMilliseconds,
} from "date-fns";
import { RANGE_TYPE, DateOption, TimeRangeOption } from "../types";
import {
Expand All @@ -23,8 +27,16 @@ export const getMonday = (date: Date | number): Date => {
return isMonday(currentDate) ? currentDate : previousMonday(currentDate);
};

export const getTimeRangeDate = (initRange: Interval): Date => {
return isSameDay(initRange.start, initRange.end)
export const getTimeRangeDate = (
initRange: Interval,
timePickerType?: "Days" | "Hours"
): Date => {
// 18-24 time slot technically ends in different day
const end =
timePickerType === "Hours"
? subMilliseconds(initRange.end, 1)
: initRange.end;
return isSameDay(initRange.start, end)
? new Date(new Date(initRange.start).setSeconds(0, 0))
: new Date();
};
Expand Down Expand Up @@ -139,3 +151,23 @@ export const isSameTimeRange = (
getHours(interval.end) === optionEnd
);
};

export const getNewSelectedDate = (
selectedDate: Date,
currentMonday: Date,
newMonday: Date
) => {
const dayOffset = differenceInCalendarDays(
startOfDay(selectedDate),
startOfDay(currentMonday)
);

const baseDate = addDays(startOfDay(newMonday), dayOffset);

return set(baseDate, {
hours: selectedDate.getHours(),
minutes: selectedDate.getMinutes(),
seconds: selectedDate.getSeconds(),
milliseconds: selectedDate.getMilliseconds(),
});
};
Loading