@licklist/design 0.62.1 → 0.62.3-dev.1
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 +0 -8
- package/dist/date-time-button/DateTimeButton.js +1 -1
- package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.d.ts +3 -1
- package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.d.ts.map +1 -1
- package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.js +1 -1
- package/dist/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.d.ts +3 -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 +3 -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.js +1 -1
- 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.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.d.ts.map +1 -1
- package/dist/product-set/control/DateInput.js +1 -1
- package/dist/product-set/control/ProductSetControl.d.ts +1 -1
- package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
- package/dist/product-set/form/ProductSetForm.d.ts +4 -1
- package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
- package/dist/product-set/hooks/useSortableTreeFunctions.d.ts.map +1 -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/product/fixed-duration-fields/FixedDurationOptions.d.ts.map +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/RecurrenceAndFrequencyInput.d.ts.map +1 -1
- package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts +3 -1
- 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 +12 -0
- 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/sales/booking/results/components/ResultCard.js +1 -1
- package/dist/sales/coupon/control/CouponFormControl.d.ts +2 -1
- package/dist/sales/coupon/control/CouponFormControl.d.ts.map +1 -1
- package/dist/sales/coupon/control/CouponFormControl.js +1 -1
- package/dist/sales/coupon/form/CouponFrom.d.ts +2 -2
- package/dist/sales/coupon/form/CouponFrom.d.ts.map +1 -1
- package/dist/sales/coupon/utils/index.d.ts +7 -0
- package/dist/sales/coupon/utils/index.d.ts.map +1 -0
- package/dist/sales/coupon/utils/index.js +1 -0
- package/dist/setting/admin/AdminSettingForm.d.ts +2 -2
- package/dist/setting/admin/AdminSettingForm.d.ts.map +1 -1
- package/dist/setting/dashboard/DashboardSettingForm.d.ts +1 -0
- package/dist/setting/dashboard/DashboardSettingForm.d.ts.map +1 -1
- package/dist/setting/dashboard/DashboardSettingForm.js +1 -1
- package/dist/styles/iframe-external-modal/IframeExternalModal.scss +5 -2
- package/dist/styles/ryft-payment-form/RyftPaymentForm.scss +99 -113
- package/dist/styles/sales/BookingResults.scss +1 -1
- package/dist/typeahead/Typeahead.d.ts +2 -1
- package/dist/typeahead/Typeahead.d.ts.map +1 -1
- package/dist/typeahead/Typeahead.js +1 -1
- 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/package.json +10 -35
- package/src/date-time-button/DateTimeButton.stories.tsx +2 -1
- package/src/date-time-button/DateTimeButton.tsx +7 -5
- package/src/events/edit-event-modal/component/EditEventForm/EditEventForm.tsx +4 -0
- package/src/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.tsx +10 -8
- package/src/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.tsx +4 -0
- package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +6 -6
- package/src/iframe/ryft/RyftPaymentForm.tsx +12 -4
- package/src/iframe/ryft/utils/ryft-form.ts +8 -4
- package/src/product-set/control/DateAndRecurrenceInput.tsx +3 -2
- package/src/product-set/control/DateInput.tsx +2 -4
- package/src/product-set/control/ProductSetControl.tsx +1 -1
- package/src/product-set/form/ProductCategoriesControl.tsx +1 -1
- package/src/product-set/form/ProductSetForm.tsx +5 -1
- package/src/product-set/hooks/useSortableTreeFunctions.ts +2 -0
- package/src/product-set/product/ProductControl.tsx +38 -38
- package/src/product-set/product/fixed-duration-fields/FixedDurationOptions.tsx +0 -2
- package/src/provider/working-hours-input/WorkingHoursInputDescription.tsx +4 -18
- package/src/recurring-date-picker-input/RecurrenceAndFrequencyInput.tsx +0 -1
- package/src/recurring-date-picker-input/RecurringDatePickerInput.tsx +11 -1
- package/src/recurring-date-picker-input/utils.ts +77 -0
- package/src/sales/booking/results/BookingResults.stories.tsx +3 -2
- package/src/sales/booking/results/components/ResultCard.tsx +2 -5
- package/src/sales/coupon/control/CouponFormControl.tsx +29 -50
- package/src/sales/coupon/form/CouponFrom.tsx +5 -15
- package/src/sales/coupon/utils/index.ts +13 -0
- package/src/setting/admin/AdminSettingForm.tsx +2 -2
- package/src/setting/dashboard/DashboardSettingForm.tsx +13 -0
- package/src/sortable-tree/SortableTreeItem.tsx +1 -1
- package/src/static/switch/BooleanSwitch.tsx +1 -1
- package/src/styles/iframe-external-modal/IframeExternalModal.scss +5 -2
- package/src/styles/ryft-payment-form/RyftPaymentForm.scss +99 -113
- package/src/styles/sales/BookingResults.scss +1 -1
- package/src/typeahead/Typeahead.tsx +16 -3
- package/src/zone/form/ZoneForm.tsx +3 -2
- package/src/zone/form/components/ZoneControl.tsx +3 -3
- package/src/zone/form/components/ZoneRecurrencesControl.tsx +7 -5
- package/src/zone/form/utils/dates.ts +9 -10
- package/jest.config.js +0 -29
- package/tests/Auth/Authorizer.test.tsx +0 -194
- package/tests/Auth/Layout/UserNavDropDown.test.tsx +0 -43
- package/tests/Auth/Layout/UserNavDropDownToggle.test.tsx +0 -33
- package/tests/Auth/Login/LoginComponent.test.tsx +0 -246
- package/tests/Auth/Login/LoginFormComponent.test.tsx +0 -182
- package/tests/Auth/Register/RegisterComponent.test.tsx +0 -285
- package/tests/Auth/Register/RegisterFormComponent.test.tsx +0 -170
- package/tests/Auth/Settings/Dashboard/IpInput.test.tsx +0 -130
- package/tests/Auth/Social/SocialCallbackComponent.test.tsx +0 -133
- package/tests/Auth/Social/SocialFormComponent.test.tsx +0 -118
- package/tests/FileUpload/FileUpload.test.tsx +0 -42
- package/tests/Notification/EmailTemplate.test.tsx +0 -82
- package/tests/ProductSet/ProductSetPopover.test.tsx +0 -40
- package/tests/Report/Report.test.tsx +0 -48
- package/tests/Sales/Coupon.test.tsx +0 -51
- package/tests/Sales/SalesAndVIews.test.tsx +0 -63
- package/tests/SnippetTemplates/SnippetTemplates.test.tsx +0 -56
- package/tests/Table/FilterHelperComponent.test.tsx +0 -88
- package/tests/Table/PaginationHelperComponent.test.tsx +0 -109
- package/tests/Table/PerPageHelperComponent.test.tsx +0 -34
- package/tests/Table/TableHelperComponent.test.tsx +0 -295
- package/tests/TipTapEditor/TipTapEditor.test.tsx +0 -28
- package/tests/__mock__/hooks/useAuthApi.ts +0 -13
- package/tests/__mock__/hooks/useAuthMock.ts +0 -13
- package/tests/__mock__/hooks/useFormMock.ts +0 -27
- package/tests/__mock__/hooks/useNotificationMock.ts +0 -13
- package/tests/__mock__/hooks/useQueryMock.ts +0 -16
- package/tests/__mock__/hooks/useSocialApiMock.ts +0 -20
- package/tests/__mock__/hooks/useTranslationMock.ts +0 -17
- package/tests/__mock__/hooks/useUserApiMock.ts +0 -18
- package/tests/__mock__/hooks/useUserMock.ts +0 -13
- package/tests/__mock__/styleMock.js +0 -1
- package/tests/__mock__/windowMock.ts +0 -5
- package/tests/packages/react-query.tsx +0 -28
- package/tests/setupTests.ts +0 -10
|
@@ -24,8 +24,10 @@ export const useSortableTreeFunctions = ({
|
|
|
24
24
|
const cancelChanges = (index: number) => {
|
|
25
25
|
if (isOverrides) return;
|
|
26
26
|
if (!previousValue) {
|
|
27
|
+
// eslint-disable-next-line consistent-return
|
|
27
28
|
return remove(index);
|
|
28
29
|
}
|
|
30
|
+
// eslint-disable-next-line consistent-return
|
|
29
31
|
return setValue(`${fieldName}.${index}` as const, previousValue);
|
|
30
32
|
};
|
|
31
33
|
|
|
@@ -7,14 +7,17 @@ import {
|
|
|
7
7
|
QUANTITY_TYPE_LIST_DTO,
|
|
8
8
|
QUANTITY_TYPE_RECHARGING,
|
|
9
9
|
} from "@licklist/core/dist/DataMapper/Product/ProductCategoryDataMapper";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
ProductType,
|
|
12
|
+
PRODUCT_DEfAULT_COLORS,
|
|
13
|
+
} from "@licklist/core/dist/DataMapper/Product/ProductDataMapper";
|
|
11
14
|
import HookFormService from "@licklist/plugins/dist/services/Form/HookFormService";
|
|
15
|
+
import clsx from "clsx";
|
|
12
16
|
import {
|
|
13
17
|
FieldNamePrefixPath,
|
|
14
18
|
FormValues,
|
|
15
19
|
} from "@licklist/plugins/dist/types/services/Form/hook-form-service";
|
|
16
20
|
import { useId } from "@react-aria/utils";
|
|
17
|
-
import clsx from "clsx";
|
|
18
21
|
import React, {
|
|
19
22
|
ChangeEvent,
|
|
20
23
|
useCallback,
|
|
@@ -36,7 +39,7 @@ import {
|
|
|
36
39
|
} from "react-hook-form";
|
|
37
40
|
import { useTranslation } from "react-i18next";
|
|
38
41
|
import { useImages } from "@licklist/plugins/dist/hooks/Media/useImages";
|
|
39
|
-
|
|
42
|
+
|
|
40
43
|
import {
|
|
41
44
|
Image,
|
|
42
45
|
IMAGE_TYPE_IMAGE,
|
|
@@ -146,7 +149,7 @@ export function ProductControl<T extends FormValues>({
|
|
|
146
149
|
clearErrors,
|
|
147
150
|
} = useFormContext<T>();
|
|
148
151
|
|
|
149
|
-
const { setLoading } = useContext(ProductSetLoadingContext);
|
|
152
|
+
const { setLoading, productGroupList } = useContext(ProductSetLoadingContext);
|
|
150
153
|
const { t } = useTranslation(["Design", "Validation", "ProductSet"]);
|
|
151
154
|
const [expanded, setExpanded] = useState(false);
|
|
152
155
|
const [initialImages, setInitialImages] = useState<Image[] | null>(null);
|
|
@@ -159,8 +162,8 @@ export function ProductControl<T extends FormValues>({
|
|
|
159
162
|
|
|
160
163
|
const advancedId = useId();
|
|
161
164
|
const nameId = useId();
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
|
|
166
|
+
const productGroupId = useId();
|
|
164
167
|
const descriptionId = useId();
|
|
165
168
|
const termsAndConditionsId = useId();
|
|
166
169
|
const isAvailableId = useId();
|
|
@@ -400,6 +403,35 @@ export function ProductControl<T extends FormValues>({
|
|
|
400
403
|
isRequired={false}
|
|
401
404
|
defaultColors={PRODUCT_DEfAULT_COLORS}
|
|
402
405
|
/>
|
|
406
|
+
|
|
407
|
+
<Form.Group controlId={productGroupId}>
|
|
408
|
+
<Form.Label>{t("productGroup")}</Form.Label>
|
|
409
|
+
<Form.Control
|
|
410
|
+
as="select"
|
|
411
|
+
{...register(`${fieldNamePrefix}.productGroupId` as Path<T>)}
|
|
412
|
+
isInvalid={HookFormService.isInvalid<T>(
|
|
413
|
+
`${fieldNamePrefix}.productGroupId` as Path<T>,
|
|
414
|
+
errors
|
|
415
|
+
)}
|
|
416
|
+
disabled={isLoading}
|
|
417
|
+
defaultValue=""
|
|
418
|
+
>
|
|
419
|
+
<option value="">{t("Design:selectProductGroup")}</option>
|
|
420
|
+
{productGroupList.map((productGroup) => {
|
|
421
|
+
return (
|
|
422
|
+
<option value={productGroup.id} key={productGroup.id}>
|
|
423
|
+
{productGroup.value}
|
|
424
|
+
</option>
|
|
425
|
+
);
|
|
426
|
+
})}
|
|
427
|
+
</Form.Control>
|
|
428
|
+
<Form.Control.Feedback type="invalid">
|
|
429
|
+
{HookFormService.getErrors<T>(
|
|
430
|
+
`${fieldNamePrefix}.productGroupId` as Path<T>,
|
|
431
|
+
errors
|
|
432
|
+
)}
|
|
433
|
+
</Form.Control.Feedback>
|
|
434
|
+
</Form.Group>
|
|
403
435
|
</Col>
|
|
404
436
|
</Row>
|
|
405
437
|
|
|
@@ -672,38 +704,6 @@ export function ProductControl<T extends FormValues>({
|
|
|
672
704
|
</Collapse>
|
|
673
705
|
|
|
674
706
|
<Row>
|
|
675
|
-
{/* @TODO: no need for v1 release
|
|
676
|
-
<Col xs={12} sm={6}>
|
|
677
|
-
<Form.Group controlId={productGroupId}>
|
|
678
|
-
<Form.Label>{t("productGroup")}</Form.Label>
|
|
679
|
-
<Form.Control
|
|
680
|
-
as="select"
|
|
681
|
-
{...register(`${fieldNamePrefix}.productGroupId` as Path<T>)}
|
|
682
|
-
isInvalid={HookFormService.isInvalid<T>(
|
|
683
|
-
`${fieldNamePrefix}.productGroupId` as Path<T>,
|
|
684
|
-
errors
|
|
685
|
-
)}
|
|
686
|
-
disabled={isLoading}
|
|
687
|
-
defaultValue=""
|
|
688
|
-
>
|
|
689
|
-
<option value="">{t("Design:selectProductGroup")}</option>
|
|
690
|
-
{productGroupList.map((productGroup) => {
|
|
691
|
-
return (
|
|
692
|
-
<option value={productGroup.id} key={productGroup.id}>
|
|
693
|
-
{productGroup.value}
|
|
694
|
-
</option>
|
|
695
|
-
);
|
|
696
|
-
})}
|
|
697
|
-
</Form.Control>
|
|
698
|
-
<Form.Control.Feedback type="invalid">
|
|
699
|
-
{HookFormService.getErrors<T>(
|
|
700
|
-
`${fieldNamePrefix}.productGroupId` as Path<T>,
|
|
701
|
-
errors
|
|
702
|
-
)}
|
|
703
|
-
</Form.Control.Feedback>
|
|
704
|
-
</Form.Group>
|
|
705
|
-
</Col> */}
|
|
706
|
-
|
|
707
707
|
<Col xs={12}>
|
|
708
708
|
{hasBookingManagement && (
|
|
709
709
|
<ProductBookingManagementControl<T>
|
|
@@ -5,8 +5,6 @@ import { FieldNamePrefixPath } from "@licklist/plugins/dist/types/services/Form/
|
|
|
5
5
|
import { useWatch } from "react-hook-form";
|
|
6
6
|
import { FormNumberInput } from "../../../static";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
8
|
interface FixedDurationOptionsProps<T> extends FieldNamePrefixPath<T> {
|
|
11
9
|
isOverrides?: boolean;
|
|
12
10
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { DateTime } from "luxon";
|
|
2
1
|
import React from "react";
|
|
3
2
|
import { Col, Row } from "react-bootstrap";
|
|
4
3
|
import { useFormContext } from "react-hook-form";
|
|
5
4
|
import { useTranslation } from "react-i18next";
|
|
6
|
-
import { TIME_FORMAT } from "@licklist/core/dist/Config";
|
|
7
5
|
import { WorkingHoursInputValues } from ".";
|
|
8
6
|
import { useWeekdays } from "./utils";
|
|
9
7
|
|
|
@@ -25,22 +23,10 @@ export function WorkingHoursInputDescription() {
|
|
|
25
23
|
<Row key={i}>
|
|
26
24
|
<Col xs="auto">{weekdays[i]}:</Col>
|
|
27
25
|
<Col>
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
TIME_FORMAT
|
|
33
|
-
),
|
|
34
|
-
end: DateTime.fromISO(weekday.start).toFormat(
|
|
35
|
-
TIME_FORMAT
|
|
36
|
-
),
|
|
37
|
-
})
|
|
38
|
-
: t("timeFrom", {
|
|
39
|
-
start: DateTime.fromISO(weekday.start).toFormat(
|
|
40
|
-
TIME_FORMAT
|
|
41
|
-
),
|
|
42
|
-
})
|
|
43
|
-
: null}
|
|
26
|
+
{t("timeInterval", {
|
|
27
|
+
start: weekday.start,
|
|
28
|
+
end: weekday.end,
|
|
29
|
+
})}
|
|
44
30
|
</Col>
|
|
45
31
|
</Row>
|
|
46
32
|
);
|
|
@@ -12,9 +12,14 @@ import {
|
|
|
12
12
|
import { usePreviousValue } from "@licklist/plugins/dist/hooks/Value/usePreviousValue";
|
|
13
13
|
import { FormProvider, useForm } from "react-hook-form";
|
|
14
14
|
import { Form } from "react-bootstrap";
|
|
15
|
+
import { WorkHour } from "@licklist/core/dist/DataMapper/Provider/WorkHourDataMapper";
|
|
15
16
|
import RecurrenceIntervalAndFrequencyInput from "./RecurrenceIntervalAndFrequencyInput";
|
|
16
17
|
import RecurrenceWeekdaysInput from "./RecurrenceWeekdaysInput";
|
|
17
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
parseAndValidateRRule,
|
|
20
|
+
SupportedFrequency,
|
|
21
|
+
useWorkHoursValidationRules,
|
|
22
|
+
} from "./utils";
|
|
18
23
|
import { ConfirmModal } from "../modals";
|
|
19
24
|
import { DeleteFieldButton } from "../product-set/elements";
|
|
20
25
|
|
|
@@ -26,6 +31,7 @@ export interface RecurringDatePickerInputProps {
|
|
|
26
31
|
initialFrequency?: Frequency;
|
|
27
32
|
setInitialStartDateAfterSelect?: boolean;
|
|
28
33
|
minDate?: string;
|
|
34
|
+
workHours: WorkHour[] | undefined;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
export interface RecurringDatePickerInputValues {
|
|
@@ -51,6 +57,7 @@ export function RecurringDatePickerInput({
|
|
|
51
57
|
setInitialStartDateAfterSelect = false,
|
|
52
58
|
children,
|
|
53
59
|
minDate,
|
|
60
|
+
workHours,
|
|
54
61
|
}: PropsWithChildren<RecurringDatePickerInputProps>) {
|
|
55
62
|
const { t } = useTranslation(["Design"]);
|
|
56
63
|
|
|
@@ -84,6 +91,8 @@ export function RecurringDatePickerInput({
|
|
|
84
91
|
byWeekDay,
|
|
85
92
|
});
|
|
86
93
|
|
|
94
|
+
const validationRules = useWorkHoursValidationRules(byWeekDay, workHours);
|
|
95
|
+
|
|
87
96
|
const onSubmit = (nextState: RecurringDatePickerInputValues) => {
|
|
88
97
|
const end = getDateTimeObject(endDate, endTime || "23:59:59");
|
|
89
98
|
|
|
@@ -188,6 +197,7 @@ export function RecurringDatePickerInput({
|
|
|
188
197
|
<RecurrenceIntervalAndFrequencyInput
|
|
189
198
|
disabled={disabled}
|
|
190
199
|
minDate={minDate}
|
|
200
|
+
{...validationRules}
|
|
191
201
|
/>
|
|
192
202
|
|
|
193
203
|
{children}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { TIME_FORMAT } from "@licklist/core/dist/Config";
|
|
2
|
+
import { WorkHour } from "@licklist/core/dist/DataMapper/Provider/WorkHourDataMapper";
|
|
3
|
+
import { dateTimesSortFn } from "@licklist/plugins/dist/utils/dateTime";
|
|
1
4
|
import { DateTime } from "luxon";
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
2
6
|
import RRule, { Frequency, Weekday } from "rrule";
|
|
3
7
|
|
|
4
8
|
export const getWeekdayForFrequency = ({
|
|
@@ -11,6 +15,7 @@ export const getWeekdayForFrequency = ({
|
|
|
11
15
|
const parsedDate = DateTime.fromISO(date);
|
|
12
16
|
return new Weekday(
|
|
13
17
|
parsedDate.weekday - 1,
|
|
18
|
+
// eslint-disable-next-line no-nested-ternary
|
|
14
19
|
frequency !== Frequency.MONTHLY
|
|
15
20
|
? undefined
|
|
16
21
|
: parsedDate.day + 7 > parsedDate.daysInMonth
|
|
@@ -109,3 +114,75 @@ export const parseAndValidateRRule = ({
|
|
|
109
114
|
until: options.until,
|
|
110
115
|
} as ParsedRRuleOptions;
|
|
111
116
|
};
|
|
117
|
+
|
|
118
|
+
export const useWorkHoursValidationRules = (
|
|
119
|
+
byWeekDay: Weekday[] = [],
|
|
120
|
+
workHours: WorkHour[] | undefined
|
|
121
|
+
) => {
|
|
122
|
+
const { t } = useTranslation("Validation");
|
|
123
|
+
if (!workHours) return {};
|
|
124
|
+
|
|
125
|
+
// workhours of selected days, all if no days selected
|
|
126
|
+
const selectedWorkHours = byWeekDay.length
|
|
127
|
+
? byWeekDay.map(({ weekday }) =>
|
|
128
|
+
workHours.find(({ day }) => day === weekday)
|
|
129
|
+
)
|
|
130
|
+
: workHours;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* start time
|
|
134
|
+
*/
|
|
135
|
+
const startTimes = selectedWorkHours
|
|
136
|
+
.map((workhour) => DateTime.fromFormat(workhour.start, TIME_FORMAT))
|
|
137
|
+
.sort(dateTimesSortFn("desc"));
|
|
138
|
+
|
|
139
|
+
const latestStartTime = startTimes[0];
|
|
140
|
+
|
|
141
|
+
const startTimeRules = {
|
|
142
|
+
validate: (date: string) => {
|
|
143
|
+
const selectedDate = DateTime.fromFormat(date, TIME_FORMAT);
|
|
144
|
+
if (selectedDate >= latestStartTime) return true;
|
|
145
|
+
|
|
146
|
+
return t("fieldTimeAfter", {
|
|
147
|
+
attribute: t("Design:startTimeSmall"),
|
|
148
|
+
time: latestStartTime.toFormat(TIME_FORMAT),
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* end time
|
|
155
|
+
*/
|
|
156
|
+
const endTimes = selectedWorkHours
|
|
157
|
+
.map<string>(({ start, end }) => {
|
|
158
|
+
const startDateTime = DateTime.fromFormat(start, TIME_FORMAT);
|
|
159
|
+
const endDateTime = DateTime.fromFormat(end, TIME_FORMAT);
|
|
160
|
+
|
|
161
|
+
if (startDateTime <= endDateTime) return end;
|
|
162
|
+
|
|
163
|
+
// if end is before start, then it means that end is on the next day
|
|
164
|
+
// so count only to the end of current day
|
|
165
|
+
return "23:59";
|
|
166
|
+
})
|
|
167
|
+
.map((workhour) => DateTime.fromFormat(workhour, TIME_FORMAT))
|
|
168
|
+
.sort(dateTimesSortFn("asc"));
|
|
169
|
+
|
|
170
|
+
const earliestEndTime = endTimes[0];
|
|
171
|
+
|
|
172
|
+
const endTimeRules = {
|
|
173
|
+
validate: (date: string) => {
|
|
174
|
+
const selectedDate = DateTime.fromFormat(date, TIME_FORMAT);
|
|
175
|
+
if (selectedDate <= earliestEndTime) return true;
|
|
176
|
+
|
|
177
|
+
return t("fieldTimeBefore", {
|
|
178
|
+
attribute: t("Design:endTimeSmall"),
|
|
179
|
+
time: earliestEndTime.toFormat(TIME_FORMAT),
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
startTimeRules,
|
|
186
|
+
endTimeRules,
|
|
187
|
+
};
|
|
188
|
+
};
|
|
@@ -3,11 +3,12 @@ import { Meta } from "@storybook/react";
|
|
|
3
3
|
import { Event } from "@licklist/core/dist/DataMapper/Provider/EventDataMapper";
|
|
4
4
|
import { User } from "@licklist/core/dist/DataMapper/User/UserDataMapper";
|
|
5
5
|
import { Product } from "@licklist/core/dist/DataMapper/Product/ProductDataMapper";
|
|
6
|
-
import { Order } from "@licklist/core/dist/DataMapper/Order/OrderDataMapper";
|
|
7
6
|
import {
|
|
7
|
+
Order,
|
|
8
8
|
ORDER_SOURCE_IFRAME,
|
|
9
9
|
ORDER_SOURCE_MANUAL,
|
|
10
|
-
} from "@licklist/core/
|
|
10
|
+
} from "@licklist/core/dist/DataMapper/Order/OrderDataMapper";
|
|
11
|
+
|
|
11
12
|
import { BookingResults } from "./BookingResults";
|
|
12
13
|
|
|
13
14
|
export default {
|
|
@@ -12,7 +12,6 @@ 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
|
-
|
|
16
15
|
import Icon from "../../../../static/Icon";
|
|
17
16
|
|
|
18
17
|
export type ResultCardProps = {
|
|
@@ -22,8 +21,6 @@ export type ResultCardProps = {
|
|
|
22
21
|
onCardClick?: (id: number) => void;
|
|
23
22
|
};
|
|
24
23
|
|
|
25
|
-
// @TODO integrate when API will be available
|
|
26
|
-
// activity and staff keys
|
|
27
24
|
export const ResultCard = ({
|
|
28
25
|
order,
|
|
29
26
|
className,
|
|
@@ -41,10 +38,10 @@ export const ResultCard = ({
|
|
|
41
38
|
startDate,
|
|
42
39
|
products,
|
|
43
40
|
source,
|
|
44
|
-
totalAmount,
|
|
45
41
|
event,
|
|
46
42
|
menu,
|
|
47
43
|
remainingToPay,
|
|
44
|
+
paidAmount,
|
|
48
45
|
} = order;
|
|
49
46
|
|
|
50
47
|
const productList = products.map((product) => product.name)?.join(", ") || "";
|
|
@@ -108,7 +105,7 @@ export const ResultCard = ({
|
|
|
108
105
|
)}
|
|
109
106
|
<p>
|
|
110
107
|
{t("paidAmount")}:{" "}
|
|
111
|
-
{formatNumber(
|
|
108
|
+
{formatNumber(paidAmount, {
|
|
112
109
|
style: "currency",
|
|
113
110
|
currency: Config.Currency.GBP,
|
|
114
111
|
})}
|
|
@@ -21,12 +21,14 @@ import couponCodeRules from "@licklist/plugins/dist/validation/Rules/couponCodeR
|
|
|
21
21
|
// import { useId } from "@react-aria/utils";
|
|
22
22
|
|
|
23
23
|
import HTMLInputDateElement from "../../../types/static/HTMLInputDateElement";
|
|
24
|
+
import { Typeahead, TypeaheadOptions } from "../../../typeahead";
|
|
25
|
+
import { convertToTypeaheadOptions } from "../utils";
|
|
24
26
|
|
|
25
27
|
export interface CouponFormValues {
|
|
26
28
|
name?: string;
|
|
27
29
|
code: string;
|
|
28
30
|
discountType: CouponType;
|
|
29
|
-
productGroupIds:
|
|
31
|
+
productGroupIds: Array<TypeaheadOptions | ProductGroup>;
|
|
30
32
|
discount: number;
|
|
31
33
|
totalType: CouponTotalType;
|
|
32
34
|
startFrom: string;
|
|
@@ -58,9 +60,9 @@ export const CouponFormControl = ({
|
|
|
58
60
|
watch,
|
|
59
61
|
} = useFormContext<CouponFormValues>();
|
|
60
62
|
const { t } = useTranslation(["Design", "Notification", "App"]);
|
|
61
|
-
const [selectedProductGroups, setSelectedProductGroups] = useState<
|
|
62
|
-
[]
|
|
63
|
-
);
|
|
63
|
+
const [selectedProductGroups, setSelectedProductGroups] = useState<
|
|
64
|
+
TypeaheadOptions[]
|
|
65
|
+
>([]);
|
|
64
66
|
/* TODO: Show Recurrent date, when reccurent date bugs are fixed */
|
|
65
67
|
// const rrule = watch("rrule");
|
|
66
68
|
// const [recurrent, setRecurrent] = useState(Boolean(rrule));
|
|
@@ -85,15 +87,20 @@ export const CouponFormControl = ({
|
|
|
85
87
|
[COUPON_TOTAL_TYPE_TOTAL]: t("Design:depositTotal"),
|
|
86
88
|
};
|
|
87
89
|
|
|
88
|
-
// Set pre-selected Product Groups
|
|
89
90
|
useEffect(() => {
|
|
90
|
-
|
|
91
|
+
const defaultProductGroup = getValues("productGroupIds");
|
|
92
|
+
|
|
93
|
+
setSelectedProductGroups(
|
|
94
|
+
convertToTypeaheadOptions(defaultProductGroup as ProductGroup[])
|
|
95
|
+
);
|
|
91
96
|
}, [getValues]);
|
|
92
97
|
|
|
93
98
|
useEffect(() => {
|
|
94
99
|
setValue("productGroupIds", selectedProductGroups);
|
|
95
100
|
}, [getValues, setValue, selectedProductGroups]);
|
|
96
101
|
|
|
102
|
+
const productGroupList = convertToTypeaheadOptions(productGroups);
|
|
103
|
+
|
|
97
104
|
/* TODO: Show Recurrent date, when reccurent date bugs are fixed */
|
|
98
105
|
// useEffect(() => {
|
|
99
106
|
// if (!recurrent && rrule) {
|
|
@@ -251,51 +258,23 @@ export const CouponFormControl = ({
|
|
|
251
258
|
</Form.Group>
|
|
252
259
|
</Col>
|
|
253
260
|
</Row>
|
|
254
|
-
|
|
255
|
-
<
|
|
256
|
-
<
|
|
257
|
-
<
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
<Form.Check
|
|
267
|
-
key={productGroup.id}
|
|
268
|
-
label={productGroup.name}
|
|
269
|
-
defaultChecked={isGroupSelected}
|
|
270
|
-
disabled={isLoading}
|
|
271
|
-
onChange={(e) => {
|
|
272
|
-
if (e.target.checked) {
|
|
273
|
-
setSelectedProductGroups((prevGroups) =>
|
|
274
|
-
Array.from(
|
|
275
|
-
new Set([...prevGroups, String(productGroup.id)])
|
|
276
|
-
)
|
|
277
|
-
);
|
|
278
|
-
} else {
|
|
279
|
-
setSelectedProductGroups((prevGroups) => {
|
|
280
|
-
return prevGroups.filter(
|
|
281
|
-
(id) => String(productGroup.id) !== id
|
|
282
|
-
);
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}}
|
|
286
|
-
/>
|
|
287
|
-
);
|
|
261
|
+
<Row>
|
|
262
|
+
<Col>
|
|
263
|
+
<Form.Group className="mb-3">
|
|
264
|
+
<Form.Label>{t("Design:productGroups")}</Form.Label>
|
|
265
|
+
<Typeahead
|
|
266
|
+
name="productGroupIds"
|
|
267
|
+
options={productGroupList}
|
|
268
|
+
isMultipleChoise
|
|
269
|
+
isCouponForm
|
|
270
|
+
placeholder={t("Design:choose")}
|
|
271
|
+
noOptionsMessage={t("Design:noActiveTemplates", {
|
|
272
|
+
notification: t("Design:email"),
|
|
288
273
|
})}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
disabled={isLoading}
|
|
294
|
-
/>
|
|
295
|
-
</Form.Group>
|
|
296
|
-
</Col>
|
|
297
|
-
</Row>
|
|
298
|
-
)}
|
|
274
|
+
/>
|
|
275
|
+
</Form.Group>
|
|
276
|
+
</Col>
|
|
277
|
+
</Row>
|
|
299
278
|
|
|
300
279
|
{/* TODO: Show Recurrent date, when reccurent date bugs are fixed */}
|
|
301
280
|
{/* {startFromValue && (
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ProductGroup,
|
|
4
|
+
ProductGroupDTO,
|
|
5
|
+
} from "@licklist/core/dist/DataMapper/Product/ProductGroupDataMapper";
|
|
3
6
|
import {
|
|
4
7
|
CouponTotalType,
|
|
5
8
|
CouponType,
|
|
@@ -16,7 +19,7 @@ export interface CouponFormValues {
|
|
|
16
19
|
name?: string;
|
|
17
20
|
code: string;
|
|
18
21
|
discountType: CouponType;
|
|
19
|
-
productGroupIds:
|
|
22
|
+
productGroupIds: ProductGroupDTO[];
|
|
20
23
|
discount: number;
|
|
21
24
|
totalType: CouponTotalType;
|
|
22
25
|
startFrom: string;
|
|
@@ -54,19 +57,6 @@ export const CouponForm = ({
|
|
|
54
57
|
const { setError } = form;
|
|
55
58
|
const { t } = useTranslation(["Design", "Notification", "App"]);
|
|
56
59
|
|
|
57
|
-
// @TODO: dont need for v1 release
|
|
58
|
-
// const [selectedProductGroups, setSelectedProductGroups] = useState<string[]>(
|
|
59
|
-
// []
|
|
60
|
-
// );
|
|
61
|
-
// Set pre-selected Product Groups
|
|
62
|
-
// useEffect(() => {
|
|
63
|
-
// setSelectedProductGroups(getValues("productGroupIds"));
|
|
64
|
-
// }, [getValues]);
|
|
65
|
-
|
|
66
|
-
// useEffect(() => {
|
|
67
|
-
// setValue("productGroupIds", selectedProductGroups);
|
|
68
|
-
// }, [getValues, setValue, selectedProductGroups]);
|
|
69
|
-
|
|
70
60
|
useEffect(() => {
|
|
71
61
|
FormErrorService.handleServerErrors(serverErrors, setError);
|
|
72
62
|
}, [serverErrors, setError]);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProductGroup } from "@licklist/core/dist/DataMapper/Product/ProductGroupDataMapper";
|
|
2
|
+
|
|
3
|
+
export const convertToTypeaheadOptions = (productGroups?: ProductGroup[]) => {
|
|
4
|
+
if (!productGroups || !productGroups.length) {
|
|
5
|
+
return [];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return productGroups.map(({ id, name }: ProductGroup) => ({
|
|
9
|
+
id: Number(id),
|
|
10
|
+
value: name,
|
|
11
|
+
label: name,
|
|
12
|
+
}));
|
|
13
|
+
};
|
|
@@ -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 { ProvidableType } 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?: ProvidableType;
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -31,6 +31,7 @@ export type DashboardSettingFormFieldValues = {
|
|
|
31
31
|
isEnquiryOnly: boolean;
|
|
32
32
|
hasUserVerification: boolean;
|
|
33
33
|
metaPixelId?: number;
|
|
34
|
+
eventDeadlineErrorMessage?: string;
|
|
34
35
|
} & EventSettingFormFieldValues &
|
|
35
36
|
ProviderSettingFormFieldValues;
|
|
36
37
|
|
|
@@ -81,6 +82,7 @@ export const DashboardSettingForm = ({
|
|
|
81
82
|
const orderReportFormatId = useId();
|
|
82
83
|
const userVerificationId = useId();
|
|
83
84
|
const metaPixelId = useId();
|
|
85
|
+
const eventDeadlineErrorMessageId = useId();
|
|
84
86
|
|
|
85
87
|
const orderReportFormatList: SelectItem[] = [
|
|
86
88
|
{ id: 1, value: t("groupItemsByOrder") },
|
|
@@ -234,6 +236,17 @@ export const DashboardSettingForm = ({
|
|
|
234
236
|
<EventSettingForm isLoading={isLoading} />
|
|
235
237
|
|
|
236
238
|
<ProviderSettingForm isLoading={isLoading} />
|
|
239
|
+
<Form.Group controlId={eventDeadlineErrorMessageId}>
|
|
240
|
+
<Form.Label>{t("eventDeadlineErrorMessage")}</Form.Label>
|
|
241
|
+
<Form.Control
|
|
242
|
+
{...register("eventDeadlineErrorMessage")}
|
|
243
|
+
isInvalid={Boolean(errors.eventDeadlineErrorMessage)}
|
|
244
|
+
disabled={isLoading}
|
|
245
|
+
/>
|
|
246
|
+
<Form.Control.Feedback type="invalid">
|
|
247
|
+
{errors.eventDeadlineErrorMessage?.message}
|
|
248
|
+
</Form.Control.Feedback>
|
|
249
|
+
</Form.Group>
|
|
237
250
|
</FormProvider>
|
|
238
251
|
{hasPermission && (
|
|
239
252
|
<Button
|
|
@@ -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
|
|
|
@@ -4,7 +4,8 @@ html[bkdt-scrollable="false"] {
|
|
|
4
4
|
overflow: hidden !important;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
body[bkdt-scrollable="false"] .bkdt-modal,
|
|
7
|
+
body[bkdt-scrollable="false"] .bkdt-modal,
|
|
8
|
+
body[bkdt-scrollable="false"] .bkdt-mask {
|
|
8
9
|
display: block;
|
|
9
10
|
}
|
|
10
11
|
|
|
@@ -15,7 +16,7 @@ body[bkdt-scrollable="false"] .bkdt-modal, body[bkdt-scrollable="false"] .bkdt-m
|
|
|
15
16
|
width: 100%;
|
|
16
17
|
height: 100%;
|
|
17
18
|
z-index: 1000000;
|
|
18
|
-
background-color: rgba(0,0,0,0.5);
|
|
19
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
19
20
|
display: none;
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -82,6 +83,7 @@ body[bkdt-scrollable="false"] .bkdt-modal, body[bkdt-scrollable="false"] .bkdt-m
|
|
|
82
83
|
width: 100%;
|
|
83
84
|
height: 100%;
|
|
84
85
|
max-width: 800px;
|
|
86
|
+
min-height: unset;
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
}
|
|
@@ -98,6 +100,7 @@ body[bkdt-scrollable="false"] .bkdt-modal, body[bkdt-scrollable="false"] .bkdt-m
|
|
|
98
100
|
.bkdt-modal-content {
|
|
99
101
|
.bkdt-modal-body {
|
|
100
102
|
height: 35rem;
|
|
103
|
+
max-height: 85vh;
|
|
101
104
|
}
|
|
102
105
|
}
|
|
103
106
|
}
|