guestbell-forms 3.0.41 → 3.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/bookingCalendar/BookingCalendar.d.ts +1 -0
- package/build/components/bookingCalendar/BookingCalendar.js +12 -11
- package/build/components/bookingCalendar/BookingCalendar.js.map +1 -1
- package/build/components/bookingCalendar/bookingCalendarGrid/index.d.ts +2 -0
- package/build/components/bookingCalendar/bookingCalendarGrid/index.js +28 -0
- package/build/components/bookingCalendar/bookingCalendarGrid/index.js.map +1 -0
- package/build/components/bookingCalendar/bookingCalendarLane/BookingCalendarLane.js +1 -1
- package/build/components/bookingCalendar/bookingCalendarLane/BookingCalendarLane.js.map +1 -1
- package/build/components/bookingCalendar/bookingCalendarSelection/BookingCalendarSelection.js +6 -5
- package/build/components/bookingCalendar/bookingCalendarSelection/BookingCalendarSelection.js.map +1 -1
- package/build/components/bookingCalendar/bookingCalendarSelection/index.d.ts +2 -0
- package/build/components/bookingCalendar/bookingCalendarSelection/index.js +28 -0
- package/build/components/bookingCalendar/bookingCalendarSelection/index.js.map +1 -0
- package/build/components/bookingCalendar/bookingCalendarTimeAxis/index.d.ts +2 -0
- package/build/components/bookingCalendar/bookingCalendarTimeAxis/index.js +28 -0
- package/build/components/bookingCalendar/bookingCalendarTimeAxis/index.js.map +1 -0
- package/build/components/bookingCalendar/index.d.ts +10 -0
- package/build/components/bookingCalendar/index.js +110 -0
- package/build/components/bookingCalendar/index.js.map +1 -1
- package/build/components/bookingCalendar/utils.d.ts +1 -1
- package/build/components/bookingCalendar/utils.js +10 -6
- package/build/components/bookingCalendar/utils.js.map +1 -1
- package/build/dist/guestbell-forms.css +7 -5
- package/build/dist/guestbell-forms.css.map +1 -1
- package/build/dist/guestbell-forms.min.css +1 -1
- package/build/dist/report.html +2 -2
- package/build/scss/components/bookingCalendar/bookingCalendar.scss +6 -4
- package/package.json +1 -1
- package/src/lib/components/bookingCalendar/BookingCalendar.tsx +43 -49
- package/src/lib/components/bookingCalendar/bookingCalendarGrid/index.ts +2 -0
- package/src/lib/components/bookingCalendar/bookingCalendarLane/BookingCalendarLane.tsx +1 -1
- package/src/lib/components/bookingCalendar/bookingCalendarSelection/BookingCalendarSelection.tsx +10 -4
- package/src/lib/components/bookingCalendar/bookingCalendarSelection/index.ts +2 -0
- package/src/lib/components/bookingCalendar/bookingCalendarTimeAxis/index.ts +2 -0
- package/src/lib/components/bookingCalendar/index.ts +10 -0
- package/src/lib/components/bookingCalendar/utils.ts +9 -6
- package/src/lib/scss/components/bookingCalendar/bookingCalendar.scss +6 -4
- package/src/stories/OverlappingSchedule.stories.ts +16 -0
- package/src/stories/OverlappingSchedule.tsx +174 -0
- package/src/stories/overlappingSchedule.scss +10 -0
@@ -44,6 +44,7 @@ export interface LaneData<T extends BookingCalendarItemT, TLaneData>
|
|
44
44
|
export function splitBookingsToLanes<T extends BookingCalendarItemT, TLaneData>(
|
45
45
|
bookings: T[],
|
46
46
|
from: Moment,
|
47
|
+
till: Moment,
|
47
48
|
minLanesCount: number,
|
48
49
|
lanesSource: LaneSourceData<T, TLaneData>[] = [],
|
49
50
|
unmatchedToFront = true
|
@@ -136,10 +137,12 @@ export function splitBookingsToLanes<T extends BookingCalendarItemT, TLaneData>(
|
|
136
137
|
});*/
|
137
138
|
}
|
138
139
|
for (let index = 0; index < lanes.length; index++) {
|
139
|
-
const
|
140
|
-
|
141
|
-
|
142
|
-
);
|
140
|
+
const laneItems = lanes[index].items;
|
141
|
+
const normal = laneItems.filter((a) => a.till.valueOf() < till.valueOf());
|
142
|
+
normal.sort((a, b) => a.from.valueOf() - b.from.valueOf());
|
143
|
+
const atEnd = laneItems.filter((a) => a.till.valueOf() >= till.valueOf());
|
144
|
+
atEnd.sort((a, b) => a.from.valueOf() - b.from.valueOf());
|
145
|
+
lanes[index].items = [...normal, ...atEnd];
|
143
146
|
}
|
144
147
|
if (lanes.length < minLanesCount) {
|
145
148
|
lanes = lanes.concat(
|
@@ -220,7 +223,7 @@ export function calculateItemsDimensions<T extends BookingCalendarItemT>(
|
|
220
223
|
const end = endIsCut ? (endMs - startMs) / widthMs : realEnd;
|
221
224
|
const realTill = endIsCut ? moment(endMs) : moment(item.till);
|
222
225
|
const marginStart = start - lastEnd;
|
223
|
-
lastEnd = (item.till.valueOf() - startMs) / widthMs;
|
226
|
+
lastEnd = Math.min((item.till.valueOf() - startMs) / widthMs, 1);
|
224
227
|
return {
|
225
228
|
item,
|
226
229
|
start,
|
@@ -268,7 +271,7 @@ export const generateControlItems = (
|
|
268
271
|
.clone()
|
269
272
|
.add(subtract)
|
270
273
|
.add(step.asMilliseconds() * (index + 1)),
|
271
|
-
id: index
|
274
|
+
id: index,
|
272
275
|
}));
|
273
276
|
};
|
274
277
|
|
@@ -63,14 +63,16 @@ $border-color-dark: black;
|
|
63
63
|
}
|
64
64
|
.bookingCalendar__item {
|
65
65
|
position: relative;
|
66
|
-
background-color: rgba($primary-color, 0.9);
|
67
|
-
box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.15),
|
68
|
-
0px 2px 2px 0px rgba(0, 0, 0, 0.12), 0px 3px 1px -2px rgba(0, 0, 0, 0.08);
|
69
|
-
overflow: hidden;
|
70
66
|
}
|
71
67
|
|
72
68
|
.bookingCalendar__renderItem {
|
73
69
|
padding: 0.5rem;
|
70
|
+
background-color: rgba($primary-color, 0.9);
|
71
|
+
box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.15),
|
72
|
+
0px 2px 2px 0px rgba(0, 0, 0, 0.12), 0px 3px 1px -2px rgba(0, 0, 0, 0.08);
|
73
|
+
overflow: hidden;
|
74
|
+
width: 100%;
|
75
|
+
height: 100%;
|
74
76
|
&::before,
|
75
77
|
&::after {
|
76
78
|
content: '';
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
2
|
+
|
3
|
+
import OverlappingSchedule from './OverlappingSchedule';
|
4
|
+
|
5
|
+
const meta = {
|
6
|
+
title: 'Example/OverlappingSchedule',
|
7
|
+
component: OverlappingSchedule,
|
8
|
+
parameters: {
|
9
|
+
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
|
10
|
+
},
|
11
|
+
} satisfies Meta<typeof OverlappingSchedule>;
|
12
|
+
|
13
|
+
export default meta;
|
14
|
+
type Story = StoryObj<typeof meta>;
|
15
|
+
|
16
|
+
export const Default: Story = {};
|
@@ -0,0 +1,174 @@
|
|
1
|
+
import moment, { duration, Moment } from 'moment';
|
2
|
+
import * as React from 'react';
|
3
|
+
import {
|
4
|
+
BookingCalendar,
|
5
|
+
BookingCalendarItemT,
|
6
|
+
BookingCalendarRenderItem,
|
7
|
+
BookingCalendarRenderItemProps,
|
8
|
+
} from '../lib';
|
9
|
+
import classNames from 'classnames';
|
10
|
+
import './overlappingSchedule.scss';
|
11
|
+
|
12
|
+
type TItem = BookingCalendarItemT & { overlapping?: boolean };
|
13
|
+
|
14
|
+
const generateBookingItemsBetweenDates = (
|
15
|
+
from: Moment,
|
16
|
+
till: Moment
|
17
|
+
): TItem[] => {
|
18
|
+
const width = till.valueOf() - from.valueOf();
|
19
|
+
const startMs = from.valueOf();
|
20
|
+
const nonOverlappingCount = 10;
|
21
|
+
const laneCount = 5;
|
22
|
+
let i = 0;
|
23
|
+
return new Array(laneCount)
|
24
|
+
.fill(0)
|
25
|
+
.map((_, laneIndex) => [
|
26
|
+
...new Array(nonOverlappingCount).fill(0).map((_, index) => {
|
27
|
+
const _from = startMs + index * (width / nonOverlappingCount);
|
28
|
+
const _width = width / (nonOverlappingCount + 1);
|
29
|
+
return {
|
30
|
+
id: i++,
|
31
|
+
from: moment(_from),
|
32
|
+
till: moment(_from).add(_width, 'ms'),
|
33
|
+
laneKey: laneIndex,
|
34
|
+
};
|
35
|
+
}),
|
36
|
+
...(laneIndex === 0
|
37
|
+
? [
|
38
|
+
{
|
39
|
+
id: i++,
|
40
|
+
from: moment(from),
|
41
|
+
till: moment(till),
|
42
|
+
laneKey: laneIndex,
|
43
|
+
overlapping: true,
|
44
|
+
},
|
45
|
+
]
|
46
|
+
: laneIndex === 1
|
47
|
+
? [
|
48
|
+
{
|
49
|
+
id: i++,
|
50
|
+
from: moment(from).subtract(width / 2, 'ms'),
|
51
|
+
till: moment(till).add(width / 2, 'ms'),
|
52
|
+
laneKey: laneIndex,
|
53
|
+
overlapping: true,
|
54
|
+
},
|
55
|
+
{
|
56
|
+
id: i++,
|
57
|
+
from: moment(from).subtract(width / 2, 'ms'),
|
58
|
+
till: moment(till).add(width / 2, 'ms'),
|
59
|
+
laneKey: laneIndex,
|
60
|
+
overlapping: true,
|
61
|
+
},
|
62
|
+
]
|
63
|
+
: laneIndex === 2
|
64
|
+
? [
|
65
|
+
{
|
66
|
+
id: i++,
|
67
|
+
from: moment(till).subtract(width / 2, 'ms'),
|
68
|
+
till: moment(till),
|
69
|
+
laneKey: laneIndex,
|
70
|
+
overlapping: true,
|
71
|
+
},
|
72
|
+
]
|
73
|
+
: laneIndex === 3
|
74
|
+
? [
|
75
|
+
{
|
76
|
+
id: i++,
|
77
|
+
from: moment(from).add(width / (nonOverlappingCount * 2), 'ms'),
|
78
|
+
till: moment(till).subtract(
|
79
|
+
width / (nonOverlappingCount * 2),
|
80
|
+
'ms'
|
81
|
+
),
|
82
|
+
laneKey: laneIndex,
|
83
|
+
overlapping: true,
|
84
|
+
},
|
85
|
+
]
|
86
|
+
: laneIndex === 4
|
87
|
+
? [
|
88
|
+
{
|
89
|
+
id: i++,
|
90
|
+
from: moment(from).add(width / (nonOverlappingCount * 2), 'ms'),
|
91
|
+
till: moment(till).subtract(
|
92
|
+
width / (nonOverlappingCount * 2),
|
93
|
+
'ms'
|
94
|
+
),
|
95
|
+
laneKey: laneIndex,
|
96
|
+
overlapping: true,
|
97
|
+
},
|
98
|
+
{
|
99
|
+
id: i++,
|
100
|
+
from: moment(from).add(width / (nonOverlappingCount * 2), 'ms'),
|
101
|
+
till: moment(till).subtract(
|
102
|
+
width / (nonOverlappingCount * 2),
|
103
|
+
'ms'
|
104
|
+
),
|
105
|
+
laneKey: laneIndex,
|
106
|
+
overlapping: true,
|
107
|
+
},
|
108
|
+
]
|
109
|
+
: []),
|
110
|
+
])
|
111
|
+
.reduce((acc, val) => acc.concat(val), [])
|
112
|
+
.filter((a) => a /*&&a?.laneKey === 1*/);
|
113
|
+
};
|
114
|
+
|
115
|
+
export const Schedule = () => {
|
116
|
+
const [{ from, till }, setRange] = React.useState({
|
117
|
+
from: moment().startOf('day').subtract(0, 'day'),
|
118
|
+
till: moment().startOf('day').add(7, 'days'),
|
119
|
+
});
|
120
|
+
|
121
|
+
const bookings = React.useMemo(
|
122
|
+
() =>
|
123
|
+
generateBookingItemsBetweenDates(
|
124
|
+
from.clone().subtract(0, 'day'),
|
125
|
+
till.clone().add(0, 'day')
|
126
|
+
),
|
127
|
+
[]
|
128
|
+
);
|
129
|
+
|
130
|
+
const onSelection = React.useCallback((items: TItem[], _from, _till, e) => {
|
131
|
+
console.log(items);
|
132
|
+
if (e.ctrlKey) {
|
133
|
+
setRange({ from: _from, till: _till });
|
134
|
+
}
|
135
|
+
}, []);
|
136
|
+
const RenderItem: React.FC<BookingCalendarRenderItemProps<TItem>> =
|
137
|
+
React.useCallback((props) => {
|
138
|
+
return (
|
139
|
+
<BookingCalendarRenderItem
|
140
|
+
className={classNames({ overlapping__item: props.item.overlapping })}
|
141
|
+
{...props}
|
142
|
+
alwaysShowContent={true}
|
143
|
+
>
|
144
|
+
<div />
|
145
|
+
</BookingCalendarRenderItem>
|
146
|
+
);
|
147
|
+
}, []);
|
148
|
+
return (
|
149
|
+
<div className="container">
|
150
|
+
<BookingCalendar
|
151
|
+
bookings={bookings}
|
152
|
+
from={from}
|
153
|
+
till={till}
|
154
|
+
step={duration(1, 'day')}
|
155
|
+
onRangeChange={setRange}
|
156
|
+
onSelection={onSelection}
|
157
|
+
selectionContent={'Hold CTRL to zoom'}
|
158
|
+
// lanesCount={3}
|
159
|
+
lanesSource={new Array(5).fill(0).map((_, index) => ({
|
160
|
+
laneKey: index,
|
161
|
+
data: { data: 'test' },
|
162
|
+
rowClassName: 'test',
|
163
|
+
}))}
|
164
|
+
zoomLevels={[
|
165
|
+
{ step: duration(1, 'day'), label: 'Day' },
|
166
|
+
{ step: duration(1, 'week'), label: 'Week' },
|
167
|
+
]}
|
168
|
+
BookingCalendarRenderItem={RenderItem}
|
169
|
+
/>
|
170
|
+
</div>
|
171
|
+
);
|
172
|
+
};
|
173
|
+
|
174
|
+
export default Schedule;
|