@licklist/design 0.63.3-dev.3 → 0.63.3
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/bitbucket-pipelines.yml +8 -0
- package/dist/date-time-button/DateTimeButton.js +1 -1
- package/dist/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.d.ts.map +1 -1
- package/dist/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.js +1 -1
- package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.d.ts.map +1 -1
- package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.js +1 -1
- package/dist/iframe/payment/order-items-table/utils/paymentSummary.d.ts.map +1 -1
- package/dist/iframe/ryft/RyftPaymentForm.d.ts +1 -4
- package/dist/iframe/ryft/RyftPaymentForm.d.ts.map +1 -1
- package/dist/iframe/ryft/RyftPaymentForm.js +1 -1
- package/dist/iframe/ryft/utils/ryft-form.d.ts +2 -5
- package/dist/iframe/ryft/utils/ryft-form.d.ts.map +1 -1
- package/dist/iframe/ryft/utils/ryft-form.js +1 -1
- package/dist/product-set/control/DateAndRecurrenceInput.d.ts +1 -1
- package/dist/product-set/control/DateAndRecurrenceInput.d.ts.map +1 -1
- package/dist/product-set/control/DateAndRecurrenceInput.js +1 -1
- package/dist/product-set/control/DateInput.js +1 -1
- package/dist/product-set/control/ProductSetControl.d.ts +2 -3
- package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
- package/dist/product-set/control/ProductSetControl.js +1 -1
- package/dist/product-set/form/ProductCategoriesControl.d.ts +1 -3
- package/dist/product-set/form/ProductCategoriesControl.d.ts.map +1 -1
- package/dist/product-set/form/ProductCategoriesControl.js +1 -1
- package/dist/product-set/form/ProductSetForm.d.ts +2 -6
- package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
- package/dist/product-set/form/ProductSetForm.js +1 -1
- package/dist/product-set/form/ProductsControl.d.ts +1 -3
- package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
- package/dist/product-set/form/ProductsControl.js +1 -1
- package/dist/product-set/form/StepsControl.d.ts +1 -3
- package/dist/product-set/form/StepsControl.d.ts.map +1 -1
- package/dist/product-set/form/StepsControl.js +1 -1
- package/dist/product-set/product/ProductControl.d.ts +0 -1
- package/dist/product-set/product/ProductControl.d.ts.map +1 -1
- package/dist/product-set/product/ProductControl.js +1 -1
- package/dist/product-set/step/StepControl.d.ts +1 -2
- package/dist/product-set/step/StepControl.d.ts.map +1 -1
- package/dist/product-set/step/StepControl.js +1 -1
- package/dist/provider/working-hours-input/WorkingHoursInputDescription.d.ts.map +1 -1
- package/dist/provider/working-hours-input/WorkingHoursInputDescription.js +1 -1
- package/dist/recurring-date-picker-input/RecurrenceIntervalAndFrequencyInput.d.ts.map +1 -1
- package/dist/recurring-date-picker-input/RecurrenceIntervalAndFrequencyInput.js +1 -1
- package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts +1 -3
- package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts.map +1 -1
- package/dist/recurring-date-picker-input/RecurringDatePickerInput.js +1 -1
- package/dist/recurring-date-picker-input/utils.d.ts +0 -5
- package/dist/recurring-date-picker-input/utils.d.ts.map +1 -1
- package/dist/recurring-date-picker-input/utils.js +1 -1
- package/dist/sales/booking/results/components/ResultCard.d.ts.map +1 -1
- package/dist/setting/admin/AdminSettingForm.d.ts +2 -2
- package/dist/setting/admin/AdminSettingForm.d.ts.map +1 -1
- package/dist/sortable-tree/SortableTreeItem.d.ts +2 -1
- package/dist/sortable-tree/SortableTreeItem.d.ts.map +1 -1
- package/dist/sortable-tree/SortableTreeItem.js +1 -1
- package/dist/styles/date-time-button/DateTimeButton.scss +0 -1
- package/dist/styles/iframe-page/PageBody.scss +1 -0
- package/dist/styles/ryft-payment-form/RyftPaymentForm.scss +0 -8
- package/dist/styles/sales/BookingResults.scss +1 -1
- package/dist/styles/zones/ZoneForm.scss +1 -2
- package/dist/zone/form/ZoneForm.d.ts +2 -2
- package/dist/zone/form/ZoneForm.d.ts.map +1 -1
- package/dist/zone/form/ZoneForm.js +1 -1
- package/dist/zone/form/components/ZoneControl.d.ts +2 -2
- package/dist/zone/form/components/ZoneControl.d.ts.map +1 -1
- package/dist/zone/form/components/ZoneControl.js +1 -1
- package/dist/zone/form/components/ZoneRecurrencesControl.d.ts +4 -4
- package/dist/zone/form/components/ZoneRecurrencesControl.d.ts.map +1 -1
- package/dist/zone/form/components/ZoneRecurrencesControl.js +1 -1
- package/dist/zone/form/utils/dates.d.ts.map +1 -1
- package/jest.config.js +29 -0
- package/package.json +39 -14
- package/src/date-time-button/DateTimeButton.stories.tsx +1 -2
- package/src/date-time-button/DateTimeButton.tsx +5 -7
- package/src/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.tsx +9 -14
- package/src/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.tsx +0 -2
- package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +0 -1
- package/src/iframe/ryft/RyftPaymentForm.tsx +2 -11
- package/src/iframe/ryft/utils/ryft-form.ts +4 -23
- package/src/product-set/control/DateAndRecurrenceInput.tsx +4 -3
- package/src/product-set/control/DateInput.tsx +2 -2
- package/src/product-set/control/ProductSetControl.tsx +4 -11
- package/src/product-set/form/ProductCategoriesControl.tsx +4 -15
- package/src/product-set/form/ProductSetForm.tsx +2 -13
- package/src/product-set/form/ProductsControl.tsx +77 -93
- package/src/product-set/form/StepsControl.tsx +7 -15
- package/src/product-set/product/ProductControl.tsx +5 -8
- package/src/product-set/step/StepControl.tsx +3 -4
- package/src/provider/working-hours-input/WorkingHoursInputDescription.tsx +18 -4
- package/src/recurring-date-picker-input/RecurrenceIntervalAndFrequencyInput.tsx +21 -40
- package/src/recurring-date-picker-input/RecurringDatePickerInput.stories.tsx +7 -13
- package/src/recurring-date-picker-input/RecurringDatePickerInput.tsx +1 -12
- package/src/recurring-date-picker-input/utils.ts +1 -90
- package/src/sales/booking/results/components/ResultCard.tsx +3 -0
- package/src/setting/admin/AdminSettingForm.tsx +2 -2
- package/src/sortable-tree/SortableTreeItem.tsx +3 -0
- package/src/static/switch/BooleanSwitch.tsx +1 -1
- package/src/styles/date-time-button/DateTimeButton.scss +0 -1
- package/src/styles/iframe-page/PageBody.scss +1 -0
- package/src/styles/ryft-payment-form/RyftPaymentForm.scss +0 -8
- package/src/styles/sales/BookingResults.scss +1 -1
- package/src/styles/zones/ZoneForm.scss +1 -2
- package/src/zone/form/ZoneForm.tsx +2 -3
- package/src/zone/form/components/ZoneControl.tsx +3 -3
- package/src/zone/form/components/ZoneRecurrencesControl.tsx +5 -7
- package/src/zone/form/utils/dates.ts +10 -9
- package/tests/Auth/Authorizer.test.tsx +194 -0
- package/tests/Auth/Layout/UserNavDropDown.test.tsx +43 -0
- package/tests/Auth/Layout/UserNavDropDownToggle.test.tsx +33 -0
- package/tests/Auth/Login/LoginComponent.test.tsx +246 -0
- package/tests/Auth/Login/LoginFormComponent.test.tsx +182 -0
- package/tests/Auth/Register/RegisterComponent.test.tsx +285 -0
- package/tests/Auth/Register/RegisterFormComponent.test.tsx +170 -0
- package/tests/Auth/Settings/Dashboard/IpInput.test.tsx +130 -0
- package/tests/Auth/Social/SocialCallbackComponent.test.tsx +133 -0
- package/tests/Auth/Social/SocialFormComponent.test.tsx +118 -0
- package/tests/FileUpload/FileUpload.test.tsx +42 -0
- package/tests/Notification/EmailTemplate.test.tsx +82 -0
- package/tests/ProductSet/ProductSetPopover.test.tsx +40 -0
- package/tests/Report/Report.test.tsx +48 -0
- package/tests/Sales/Coupon.test.tsx +51 -0
- package/tests/Sales/SalesAndVIews.test.tsx +63 -0
- package/tests/SnippetTemplates/SnippetTemplates.test.tsx +56 -0
- package/tests/Table/FilterHelperComponent.test.tsx +88 -0
- package/tests/Table/PaginationHelperComponent.test.tsx +109 -0
- package/tests/Table/PerPageHelperComponent.test.tsx +34 -0
- package/tests/Table/TableHelperComponent.test.tsx +295 -0
- package/tests/TipTapEditor/TipTapEditor.test.tsx +28 -0
- package/tests/__mock__/hooks/useAuthApi.ts +13 -0
- package/tests/__mock__/hooks/useAuthMock.ts +13 -0
- package/tests/__mock__/hooks/useFormMock.ts +27 -0
- package/tests/__mock__/hooks/useNotificationMock.ts +13 -0
- package/tests/__mock__/hooks/useQueryMock.ts +16 -0
- package/tests/__mock__/hooks/useSocialApiMock.ts +20 -0
- package/tests/__mock__/hooks/useTranslationMock.ts +17 -0
- package/tests/__mock__/hooks/useUserApiMock.ts +18 -0
- package/tests/__mock__/hooks/useUserMock.ts +13 -0
- package/tests/__mock__/styleMock.js +1 -0
- package/tests/__mock__/windowMock.ts +5 -0
- package/tests/packages/react-query.tsx +28 -0
- package/tests/setupTests.ts +10 -0
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { WorkHour } from "@licklist/core/dist/DataMapper/Provider/WorkHourDataMapper";
|
|
3
|
-
import { fromFormat } from "@licklist/plugins/dist/utils/dateTime";
|
|
4
|
-
import { DateTime, Interval } from "luxon";
|
|
5
|
-
import { Validate } from "react-hook-form";
|
|
6
|
-
import { useTranslation } from "react-i18next";
|
|
1
|
+
import { DateTime } from "luxon";
|
|
7
2
|
import RRule, { Frequency, Weekday } from "rrule";
|
|
8
3
|
|
|
9
4
|
export const getWeekdayForFrequency = ({
|
|
@@ -16,7 +11,6 @@ export const getWeekdayForFrequency = ({
|
|
|
16
11
|
const parsedDate = DateTime.fromISO(date);
|
|
17
12
|
return new Weekday(
|
|
18
13
|
parsedDate.weekday - 1,
|
|
19
|
-
// eslint-disable-next-line no-nested-ternary
|
|
20
14
|
frequency !== Frequency.MONTHLY
|
|
21
15
|
? undefined
|
|
22
16
|
: parsedDate.day + 7 > parsedDate.daysInMonth
|
|
@@ -115,86 +109,3 @@ export const parseAndValidateRRule = ({
|
|
|
115
109
|
until: options.until,
|
|
116
110
|
} as ParsedRRuleOptions;
|
|
117
111
|
};
|
|
118
|
-
|
|
119
|
-
export const useWorkHoursValidation = (
|
|
120
|
-
byWeekDay: Weekday[] = [],
|
|
121
|
-
workHours: WorkHour[] | undefined
|
|
122
|
-
): {
|
|
123
|
-
validate?: Validate<string>;
|
|
124
|
-
} => {
|
|
125
|
-
const { t } = useTranslation("Validation");
|
|
126
|
-
if (!workHours) return {};
|
|
127
|
-
|
|
128
|
-
const fromTimeFormat = fromFormat(TIME_FORMAT);
|
|
129
|
-
const fromTimeFullFormat = fromFormat(TIME_FULL_FORMAT);
|
|
130
|
-
|
|
131
|
-
// map every day to array of intervals describing workhours for that day
|
|
132
|
-
let intervalsByDay = workHours.map((workhour, index, self) => {
|
|
133
|
-
const res: Interval[] = [];
|
|
134
|
-
|
|
135
|
-
const startTime = fromTimeFormat(workhour.start);
|
|
136
|
-
const endTime = fromTimeFormat(workhour.end);
|
|
137
|
-
|
|
138
|
-
if (endTime > startTime) {
|
|
139
|
-
res.push(Interval.fromDateTimes(startTime, endTime));
|
|
140
|
-
} else {
|
|
141
|
-
// if end is before start, then it means that end is on the next day
|
|
142
|
-
// so count only to the end of current day
|
|
143
|
-
res.push(Interval.fromDateTimes(startTime, startTime.endOf("day")));
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const prevIndex = index === 0 ? self.length - 1 : index - 1;
|
|
147
|
-
|
|
148
|
-
const prevStartTime = fromTimeFormat(self[prevIndex].start);
|
|
149
|
-
const prevEndTime = fromTimeFormat(self[prevIndex].end);
|
|
150
|
-
|
|
151
|
-
// if prevStartTime > prevEndTime then it means that prevEndTime is on the current day
|
|
152
|
-
// so we need to add interval from start of current day to prevEndTime
|
|
153
|
-
if (prevStartTime > prevEndTime) {
|
|
154
|
-
res.push(Interval.fromDateTimes(prevEndTime.startOf("day"), prevEndTime));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return res;
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// if length === 0 or length === 7 then all workhours are selected, no need to filter
|
|
161
|
-
if (![0, 7].includes(byWeekDay.length)) {
|
|
162
|
-
intervalsByDay = intervalsByDay.filter((_, index) =>
|
|
163
|
-
byWeekDay.find(({ weekday }) => weekday === index)
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
validate: (_time: string) => {
|
|
169
|
-
// workaround for issue with form values
|
|
170
|
-
// default values and entered values have different formats
|
|
171
|
-
const time = fromTimeFormat(_time).isValid
|
|
172
|
-
? fromTimeFormat(_time)
|
|
173
|
-
: fromTimeFullFormat(_time);
|
|
174
|
-
|
|
175
|
-
const notFittingIntervalsByDay = intervalsByDay.reduce<Interval[][]>(
|
|
176
|
-
(acc, intervalsByDay) => {
|
|
177
|
-
if (!intervalsByDay.some((interval) => interval.contains(time))) {
|
|
178
|
-
acc.push(intervalsByDay);
|
|
179
|
-
}
|
|
180
|
-
return acc;
|
|
181
|
-
},
|
|
182
|
-
[]
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
const notFittingIntervals = notFittingIntervalsByDay
|
|
186
|
-
.flat()
|
|
187
|
-
.filter((interval) => !interval.contains(time));
|
|
188
|
-
|
|
189
|
-
const attribute = notFittingIntervals
|
|
190
|
-
.map((interval) => interval.toFormat("HH:mm"))
|
|
191
|
-
.join(", ");
|
|
192
|
-
|
|
193
|
-
if (notFittingIntervalsByDay.length !== 0) {
|
|
194
|
-
return t("outsideWorkingHours", { attribute }) as string;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return true;
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
};
|
|
@@ -12,6 +12,7 @@ import { TIME_FORMAT } from "@licklist/core/dist/Config";
|
|
|
12
12
|
import * as Config from "@licklist/core/dist/Config";
|
|
13
13
|
import { formatDateStringForEvent } from "@licklist/plugins/dist/utils/formatDate";
|
|
14
14
|
import { getOrderSourceTitle } from "@licklist/plugins/dist/utils/sourceTitle";
|
|
15
|
+
|
|
15
16
|
import Icon from "../../../../static/Icon";
|
|
16
17
|
|
|
17
18
|
export type ResultCardProps = {
|
|
@@ -21,6 +22,8 @@ export type ResultCardProps = {
|
|
|
21
22
|
onCardClick?: (id: number) => void;
|
|
22
23
|
};
|
|
23
24
|
|
|
25
|
+
// @TODO integrate when API will be available
|
|
26
|
+
// activity and staff keys
|
|
24
27
|
export const ResultCard = ({
|
|
25
28
|
order,
|
|
26
29
|
className,
|
|
@@ -11,7 +11,7 @@ import Row from "react-bootstrap/Row";
|
|
|
11
11
|
import Col from "react-bootstrap/Col";
|
|
12
12
|
import { Link } from "react-router-dom";
|
|
13
13
|
import HookFormService from "@licklist/plugins/dist/services/Form/HookFormService";
|
|
14
|
-
import {
|
|
14
|
+
import { ProviderType } from "@licklist/core/dist/DataMapper/Provider/ProvidableDataMapper";
|
|
15
15
|
import Icon from "../../static/Icon";
|
|
16
16
|
import { PaymentFeeForm, PaymentFeeFormFieldValues } from "./PaymentFeeForm";
|
|
17
17
|
import { Currency } from "../../types/currency";
|
|
@@ -33,7 +33,7 @@ export interface AdminSettingFormProps extends HasPermissionProp {
|
|
|
33
33
|
providerMetadata: {
|
|
34
34
|
country?: string;
|
|
35
35
|
providableId?: number;
|
|
36
|
-
providerType?:
|
|
36
|
+
providerType?: ProviderType;
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -53,6 +53,7 @@ export interface SortableTreeItemProps {
|
|
|
53
53
|
};
|
|
54
54
|
setIsExpanded?: () => void;
|
|
55
55
|
isOverride?: boolean;
|
|
56
|
+
isProduct?: boolean;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
export function SortableTreeItem({
|
|
@@ -80,6 +81,7 @@ export function SortableTreeItem({
|
|
|
80
81
|
secondaryBadge,
|
|
81
82
|
setIsExpanded,
|
|
82
83
|
isOverride,
|
|
84
|
+
isProduct = false,
|
|
83
85
|
}: SortableTreeItemProps) {
|
|
84
86
|
const [expanded, setExpanded] = useState(isExpanded);
|
|
85
87
|
const [isModalVisible, setIsModalVisible] = useState(isNewAdded);
|
|
@@ -150,6 +152,7 @@ export function SortableTreeItem({
|
|
|
150
152
|
};
|
|
151
153
|
|
|
152
154
|
const onEdit = (e) => {
|
|
155
|
+
if (isOverride && !isProduct) return;
|
|
153
156
|
e.stopPropagation();
|
|
154
157
|
if (edit && !isModalVisible) edit();
|
|
155
158
|
setIsModalVisible(true);
|
|
@@ -23,7 +23,7 @@ export function BooleanSwitch({
|
|
|
23
23
|
const { t } = useTranslation("Design");
|
|
24
24
|
|
|
25
25
|
const options: SelectItem[] = [
|
|
26
|
-
{ id: 1, value: firstValueTitle ??
|
|
26
|
+
{ id: 1, value: firstValueTitle ?? t("yes") },
|
|
27
27
|
{ id: 0, value: secondValueTitle ?? t("no") },
|
|
28
28
|
];
|
|
29
29
|
|
|
@@ -135,14 +135,6 @@
|
|
|
135
135
|
margin-bottom: 0.5rem;
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
.ryft-pay-grid {
|
|
139
|
-
display: flex;
|
|
140
|
-
flex-direction: column;
|
|
141
|
-
.apple-pay-button {
|
|
142
|
-
height: 2.5rem;
|
|
143
|
-
margin-top: 1rem;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
138
|
.mobile-pay-title {
|
|
147
139
|
display: block;
|
|
148
140
|
font-weight: 600;
|
|
@@ -13,7 +13,7 @@ export type ZoneFormProps = {
|
|
|
13
13
|
onSubmit: (values: Partial<Zone>) => void;
|
|
14
14
|
serverErrors?: ServerError;
|
|
15
15
|
isLoading?: boolean;
|
|
16
|
-
workHours
|
|
16
|
+
workHours?: WorkHour[];
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export type ZoneFormValues = Partial<Zone> & {
|
|
@@ -25,7 +25,6 @@ export const ZoneForm = ({
|
|
|
25
25
|
onSubmit,
|
|
26
26
|
serverErrors,
|
|
27
27
|
isLoading = false,
|
|
28
|
-
workHours,
|
|
29
28
|
}: ZoneFormProps) => {
|
|
30
29
|
const { t } = useTranslation("Design");
|
|
31
30
|
const form = useForm<ZoneFormValues>({
|
|
@@ -55,7 +54,7 @@ export const ZoneForm = ({
|
|
|
55
54
|
return (
|
|
56
55
|
<FormProvider {...form}>
|
|
57
56
|
<Form onSubmit={handleSubmit(onFormSubmit)}>
|
|
58
|
-
<ZoneControl isLoading={isLoading}
|
|
57
|
+
<ZoneControl isLoading={isLoading} />
|
|
59
58
|
<Row>
|
|
60
59
|
<Col md={6} sm={12} />
|
|
61
60
|
<Col
|
|
@@ -11,15 +11,15 @@ import { GameDurationControl } from "./GameDurationControl";
|
|
|
11
11
|
|
|
12
12
|
export type ZoneControlProps = {
|
|
13
13
|
isLoading: boolean;
|
|
14
|
-
workHours
|
|
14
|
+
workHours?: WorkHour[];
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export const ZoneControl = ({ isLoading
|
|
17
|
+
export const ZoneControl = ({ isLoading }: ZoneControlProps) => {
|
|
18
18
|
return (
|
|
19
19
|
<Row>
|
|
20
20
|
<Col md={6} sm={12} className="pr-5">
|
|
21
21
|
<NameControl isLoading={isLoading} />
|
|
22
|
-
<ZoneRecurrencesControl
|
|
22
|
+
<ZoneRecurrencesControl />
|
|
23
23
|
<hr />
|
|
24
24
|
<Row>
|
|
25
25
|
<Col md={6} sm={6}>
|
|
@@ -25,13 +25,12 @@ export interface DateAndRecurrenceInputValues {
|
|
|
25
25
|
zoneRecurrences?: Partial<ZoneRecurrence>[];
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
type ZoneRecurrenceControlProps = {
|
|
29
|
-
workHours
|
|
28
|
+
export type ZoneRecurrenceControlProps = {
|
|
29
|
+
workHours?: WorkHour[];
|
|
30
|
+
isLoading?: boolean;
|
|
30
31
|
};
|
|
31
32
|
|
|
32
|
-
export const ZoneRecurrencesControl = ({
|
|
33
|
-
workHours,
|
|
34
|
-
}: ZoneRecurrenceControlProps) => {
|
|
33
|
+
export const ZoneRecurrencesControl = () => {
|
|
35
34
|
const {
|
|
36
35
|
control,
|
|
37
36
|
register,
|
|
@@ -70,7 +69,7 @@ export const ZoneRecurrencesControl = ({
|
|
|
70
69
|
clearEditState();
|
|
71
70
|
});
|
|
72
71
|
|
|
73
|
-
const popoverId = useId()
|
|
72
|
+
const popoverId = useId()!;
|
|
74
73
|
|
|
75
74
|
const { t } = useTranslation(["Design", "Validation"]);
|
|
76
75
|
|
|
@@ -167,7 +166,6 @@ export const ZoneRecurrencesControl = ({
|
|
|
167
166
|
onChange={handleRecurringDateChange}
|
|
168
167
|
onDelete={handleDelete}
|
|
169
168
|
setInitialStartDateAfterSelect
|
|
170
|
-
workHours={workHours}
|
|
171
169
|
/>
|
|
172
170
|
</Popover.Content>
|
|
173
171
|
</Popover>
|
|
@@ -53,17 +53,18 @@ export const getCheckboxesByWorkHours = (workHours?: WorkHour[]) => {
|
|
|
53
53
|
if (!workHours || !workHours.length)
|
|
54
54
|
return getTimeCheckboxRanges(DEFAULT_START_DAY_TIME, DEFAULT_END_DAY_TIME);
|
|
55
55
|
|
|
56
|
-
const providerWorkHoursByWeek = workHours.reduce
|
|
57
|
-
{ start: string; end: string }[]
|
|
58
|
-
|
|
59
|
-
const { start, end } = currentWorkHour;
|
|
56
|
+
const providerWorkHoursByWeek = workHours.reduce(
|
|
57
|
+
(workHoursNextArray: { start: string; end: string }[], currentWorkHour) => {
|
|
58
|
+
const { start, end } = currentWorkHour;
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
if (start && end) {
|
|
61
|
+
return [...workHoursNextArray, { start, end }];
|
|
62
|
+
}
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
return workHoursNextArray;
|
|
65
|
+
},
|
|
66
|
+
[]
|
|
67
|
+
);
|
|
67
68
|
|
|
68
69
|
// If venue has filled only 1 work day from wee
|
|
69
70
|
// For another days we use default 00:00 and 23:59
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import RouteService from "@licklist/plugins/dist/services/Route/RouteService";
|
|
2
|
+
import { mount, shallow } from "enzyme";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { act } from "react-dom/test-utils";
|
|
5
|
+
import { QueryClientProvider } from "react-query";
|
|
6
|
+
import { Authorizer } from "../../src/auth/Authorizer";
|
|
7
|
+
import useAuthMock from "../__mock__/hooks/useAuthMock";
|
|
8
|
+
import useUserMock from "../__mock__/hooks/useUserMock";
|
|
9
|
+
import useAuthApi from "../__mock__/hooks/useAuthApi";
|
|
10
|
+
import { queryClient } from "../packages/react-query";
|
|
11
|
+
|
|
12
|
+
jest.mock("react-i18next", () => ({
|
|
13
|
+
Trans: jest.fn().mockReturnValue("test"),
|
|
14
|
+
useTranslation: () => ({
|
|
15
|
+
t: jest.fn((arg) => arg),
|
|
16
|
+
}),
|
|
17
|
+
}));
|
|
18
|
+
jest.mock("@licklist/plugins/dist/context/user/hooks/useAuth");
|
|
19
|
+
jest.mock("@licklist/plugins/dist/context/user/hooks/useUser");
|
|
20
|
+
jest.mock("@licklist/plugins/dist/hooks/Api/useAuthApi");
|
|
21
|
+
|
|
22
|
+
const DEFAULT_PROFILE_RESPONSE = {
|
|
23
|
+
useProfile: () => ({
|
|
24
|
+
isLoading: false,
|
|
25
|
+
isFetching: false,
|
|
26
|
+
isError: false,
|
|
27
|
+
data: { access_token: "test" },
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const DEFAULT_PROFILE_LOADING_RESPONSE = {
|
|
32
|
+
useProfile: () => ({
|
|
33
|
+
isLoading: true,
|
|
34
|
+
isFetching: false,
|
|
35
|
+
isError: false,
|
|
36
|
+
data: { access_token: "test" },
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
describe("Authorizer", () => {
|
|
41
|
+
it("should be rendered without issues", () => {
|
|
42
|
+
useAuthMock({
|
|
43
|
+
secrets: null,
|
|
44
|
+
});
|
|
45
|
+
useUserMock({
|
|
46
|
+
profile: null,
|
|
47
|
+
});
|
|
48
|
+
useAuthApi(DEFAULT_PROFILE_LOADING_RESPONSE);
|
|
49
|
+
|
|
50
|
+
const component = shallow(
|
|
51
|
+
<QueryClientProvider client={queryClient}>
|
|
52
|
+
<Authorizer />
|
|
53
|
+
</QueryClientProvider>
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
expect(component.exists()).toBeTruthy();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("should render children if authorized", () => {
|
|
60
|
+
let component: any;
|
|
61
|
+
|
|
62
|
+
useAuthMock({
|
|
63
|
+
secrets: "not-null",
|
|
64
|
+
});
|
|
65
|
+
useUserMock({
|
|
66
|
+
profile: "not-null",
|
|
67
|
+
});
|
|
68
|
+
useAuthApi(DEFAULT_PROFILE_LOADING_RESPONSE);
|
|
69
|
+
|
|
70
|
+
RouteService.getCurrentPage = jest.fn();
|
|
71
|
+
RouteService.getCurrentRoute = jest.fn();
|
|
72
|
+
RouteService.cleanRedirect = jest.fn();
|
|
73
|
+
|
|
74
|
+
act(() => {
|
|
75
|
+
component = mount(
|
|
76
|
+
<QueryClientProvider client={queryClient}>
|
|
77
|
+
<Authorizer>
|
|
78
|
+
<p>test</p>
|
|
79
|
+
</Authorizer>
|
|
80
|
+
</QueryClientProvider>
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
component.update();
|
|
85
|
+
|
|
86
|
+
expect(RouteService.getCurrentPage).toHaveBeenCalledTimes(0);
|
|
87
|
+
expect(RouteService.getCurrentRoute).toHaveBeenCalledTimes(0);
|
|
88
|
+
expect(RouteService.cleanRedirect).toHaveBeenCalledTimes(0);
|
|
89
|
+
expect(component.exists()).toBeTruthy();
|
|
90
|
+
expect(component.find("BlockLoader").exists()).toBeTruthy();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("should render children if current page is login", () => {
|
|
94
|
+
let component: any;
|
|
95
|
+
|
|
96
|
+
useAuthMock({
|
|
97
|
+
secrets: null,
|
|
98
|
+
});
|
|
99
|
+
useUserMock({
|
|
100
|
+
profile: null,
|
|
101
|
+
});
|
|
102
|
+
useAuthApi(DEFAULT_PROFILE_LOADING_RESPONSE);
|
|
103
|
+
|
|
104
|
+
RouteService.getCurrentPage = jest.fn().mockReturnValue("/login");
|
|
105
|
+
RouteService.getCurrentRoute = jest.fn();
|
|
106
|
+
RouteService.cleanRedirect = jest.fn();
|
|
107
|
+
|
|
108
|
+
act(() => {
|
|
109
|
+
component = mount(
|
|
110
|
+
<QueryClientProvider client={queryClient}>
|
|
111
|
+
<Authorizer>
|
|
112
|
+
<p>test</p>
|
|
113
|
+
</Authorizer>
|
|
114
|
+
</QueryClientProvider>
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
component.update();
|
|
119
|
+
|
|
120
|
+
expect(RouteService.getCurrentPage).toHaveBeenCalledTimes(0);
|
|
121
|
+
expect(RouteService.getCurrentRoute).toHaveBeenCalledTimes(0);
|
|
122
|
+
expect(RouteService.cleanRedirect).toHaveBeenCalledTimes(0);
|
|
123
|
+
expect(component.exists()).toBeTruthy();
|
|
124
|
+
expect(component.find("BlockLoader").exists()).toBeTruthy();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("should NOT render children if profile is loading or fetching", () => {
|
|
128
|
+
let component: any;
|
|
129
|
+
|
|
130
|
+
useAuthMock({
|
|
131
|
+
secrets: null,
|
|
132
|
+
});
|
|
133
|
+
useUserMock({
|
|
134
|
+
profile: null,
|
|
135
|
+
});
|
|
136
|
+
useAuthApi(DEFAULT_PROFILE_LOADING_RESPONSE);
|
|
137
|
+
|
|
138
|
+
RouteService.getCurrentPage = jest.fn();
|
|
139
|
+
RouteService.getCurrentRoute = jest.fn();
|
|
140
|
+
RouteService.cleanRedirect = jest.fn();
|
|
141
|
+
|
|
142
|
+
act(() => {
|
|
143
|
+
component = mount(
|
|
144
|
+
<QueryClientProvider client={queryClient}>
|
|
145
|
+
<Authorizer>
|
|
146
|
+
<p>test</p>
|
|
147
|
+
</Authorizer>
|
|
148
|
+
</QueryClientProvider>
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
component.update();
|
|
153
|
+
|
|
154
|
+
expect(RouteService.getCurrentPage).toHaveBeenCalledTimes(0);
|
|
155
|
+
expect(RouteService.getCurrentRoute).toHaveBeenCalledTimes(0);
|
|
156
|
+
expect(RouteService.cleanRedirect).toHaveBeenCalledTimes(0);
|
|
157
|
+
expect(component.exists()).toBeTruthy();
|
|
158
|
+
expect(component.find("BlockLoader").exists()).toBeTruthy();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("should NOT render children if unauthorized and current page is not login", () => {
|
|
162
|
+
let component: any;
|
|
163
|
+
|
|
164
|
+
useAuthMock({
|
|
165
|
+
secrets: null,
|
|
166
|
+
});
|
|
167
|
+
useUserMock({
|
|
168
|
+
profile: null,
|
|
169
|
+
});
|
|
170
|
+
useAuthApi(DEFAULT_PROFILE_RESPONSE);
|
|
171
|
+
|
|
172
|
+
RouteService.getCurrentPage = jest.fn();
|
|
173
|
+
RouteService.getCurrentRoute = jest.fn();
|
|
174
|
+
RouteService.cleanRedirect = jest.fn();
|
|
175
|
+
|
|
176
|
+
act(() => {
|
|
177
|
+
component = mount(
|
|
178
|
+
<QueryClientProvider client={queryClient}>
|
|
179
|
+
<Authorizer>
|
|
180
|
+
<p>test</p>
|
|
181
|
+
</Authorizer>
|
|
182
|
+
</QueryClientProvider>
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
component.update();
|
|
187
|
+
|
|
188
|
+
expect(RouteService.getCurrentPage).toHaveBeenCalledTimes(3);
|
|
189
|
+
expect(RouteService.getCurrentRoute).toHaveBeenCalledTimes(1);
|
|
190
|
+
expect(RouteService.cleanRedirect).toHaveBeenCalledTimes(1);
|
|
191
|
+
expect(component.exists()).toBeTruthy();
|
|
192
|
+
expect(component.find("BlockLoader").exists()).toBeTruthy();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import RouteService from "@licklist/plugins/dist/services/Route/RouteService";
|
|
2
|
+
import { mount, shallow } from "enzyme";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import useTranslationMock from "../../__mock__/hooks/useTranslationMock";
|
|
5
|
+
import useUserMock from "../../__mock__/hooks/useUserMock";
|
|
6
|
+
import { UserNavDropDown } from "../../../src/auth/Layout/UserNavDropDown";
|
|
7
|
+
|
|
8
|
+
jest.mock("react-i18next");
|
|
9
|
+
jest.mock("@licklist/plugins/dist/context/user/hooks/useUser");
|
|
10
|
+
|
|
11
|
+
describe("UserNavDropDown", () => {
|
|
12
|
+
it("should be rendered without issues", () => {
|
|
13
|
+
useTranslationMock({
|
|
14
|
+
t: jest.fn(),
|
|
15
|
+
});
|
|
16
|
+
useUserMock({
|
|
17
|
+
profile: null,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const component = shallow(<UserNavDropDown />);
|
|
21
|
+
|
|
22
|
+
expect(component.exists()).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("should logout on click", () => {
|
|
26
|
+
useTranslationMock({
|
|
27
|
+
t: jest.fn(),
|
|
28
|
+
});
|
|
29
|
+
useUserMock({
|
|
30
|
+
logout: jest.fn(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
RouteService.redirectTo = jest.fn();
|
|
34
|
+
|
|
35
|
+
const component = mount(<UserNavDropDown />);
|
|
36
|
+
|
|
37
|
+
expect(component.exists()).toBeTruthy();
|
|
38
|
+
|
|
39
|
+
component.children().prop("onClick")();
|
|
40
|
+
|
|
41
|
+
expect(RouteService.redirectTo).toHaveBeenCalledTimes(1);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { IUser } from "@licklist/plugins/dist/types/context/user/IUser";
|
|
2
|
+
import { shallow } from "enzyme";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { UserNavDropDownToggle } from "../../../src/auth/Layout/UserNavDropDownToggle";
|
|
5
|
+
import useTranslationMock from "../../__mock__/hooks/useTranslationMock";
|
|
6
|
+
|
|
7
|
+
jest.mock("react-i18next");
|
|
8
|
+
jest.mock("@licklist/plugins/dist/context/user/hooks/useUser");
|
|
9
|
+
|
|
10
|
+
const user: IUser = {
|
|
11
|
+
id: 1,
|
|
12
|
+
first_name: "first_name",
|
|
13
|
+
last_name: "last_name",
|
|
14
|
+
email: "email",
|
|
15
|
+
user_roles: [],
|
|
16
|
+
user_detail: {
|
|
17
|
+
postcode: "",
|
|
18
|
+
birthday: "",
|
|
19
|
+
phone: "",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
describe("UserNavDropDownToggle", () => {
|
|
24
|
+
it("should be rendered without issues", () => {
|
|
25
|
+
useTranslationMock({
|
|
26
|
+
t: jest.fn(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const component = shallow(<UserNavDropDownToggle user={user} />);
|
|
30
|
+
|
|
31
|
+
expect(component.exists()).toBeTruthy();
|
|
32
|
+
});
|
|
33
|
+
});
|