@licklist/design 0.44.505 → 0.44.507

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.
Files changed (64) hide show
  1. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.d.ts.map +1 -1
  2. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.js +1 -1
  3. package/dist/events/edit-event-modal/utils/getDefaultProductSet.d.ts.map +1 -1
  4. package/dist/events/edit-event-modal/utils/getDefaultProductSet.js +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/notification/email-template/card/EmailTemplateCard.d.ts +4 -1
  7. package/dist/notification/email-template/card/EmailTemplateCard.d.ts.map +1 -1
  8. package/dist/notification/email-template/card/EmailTemplateCard.js +1 -1
  9. package/dist/notification/email-template/control/EmailTemplateControl.d.ts +3 -0
  10. package/dist/notification/email-template/control/EmailTemplateControl.d.ts.map +1 -1
  11. package/dist/notification/email-template/control/EmailTemplateControl.js +1 -1
  12. package/dist/notification/email-template/form/EmailTemplateForm.d.ts +7 -1
  13. package/dist/notification/email-template/form/EmailTemplateForm.d.ts.map +1 -1
  14. package/dist/notification/email-template/form/EmailTemplateForm.js +1 -1
  15. package/dist/notification/hooks/useTranslatedParameters.d.ts +7 -0
  16. package/dist/notification/hooks/useTranslatedParameters.d.ts.map +1 -0
  17. package/dist/notification/hooks/useTranslatedParameters.js +1 -0
  18. package/dist/notification/sms-template/card/SmsTemplateCard.d.ts +4 -1
  19. package/dist/notification/sms-template/card/SmsTemplateCard.d.ts.map +1 -1
  20. package/dist/notification/sms-template/card/SmsTemplateCard.js +1 -1
  21. package/dist/notification/sms-template/control/SmsTemplateControl.d.ts +6 -1
  22. package/dist/notification/sms-template/control/SmsTemplateControl.d.ts.map +1 -1
  23. package/dist/notification/sms-template/control/SmsTemplateControl.js +1 -1
  24. package/dist/notification/sms-template/form/SmsTemplateForm.d.ts +5 -1
  25. package/dist/notification/sms-template/form/SmsTemplateForm.d.ts.map +1 -1
  26. package/dist/notification/sms-template/form/SmsTemplateForm.js +1 -1
  27. package/dist/product-set/control/ProductSetControl.d.ts +15 -4
  28. package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
  29. package/dist/product-set/control/ProductSetControl.js +1 -1
  30. package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
  31. package/dist/product-set/form/ProductSetForm.js +1 -1
  32. package/dist/product-set/utils/index.d.ts +4 -0
  33. package/dist/product-set/utils/index.d.ts.map +1 -1
  34. package/dist/product-set/utils/index.js +1 -1
  35. package/dist/provider/provider-details-input/ProviderDetailsInput.d.ts.map +1 -1
  36. package/dist/provider/provider-details-input/ProviderDetailsInput.js +1 -1
  37. package/dist/sales/manual-booking/select-menu/SelectMenu.d.ts.map +1 -1
  38. package/dist/styles/snippet-templates/SnippetTemplateCard.scss +16 -0
  39. package/dist/typeahead/Typeahead.d.ts +5 -11
  40. package/dist/typeahead/Typeahead.d.ts.map +1 -1
  41. package/dist/typeahead/Typeahead.js +1 -1
  42. package/package.json +1 -1
  43. package/src/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.tsx +11 -2
  44. package/src/events/edit-event-modal/utils/getDefaultProductSet.ts +5 -4
  45. package/src/notification/email-template/card/EmailTemplateCard.stories.tsx +4 -2
  46. package/src/notification/email-template/card/EmailTemplateCard.tsx +15 -3
  47. package/src/notification/email-template/control/EmailTemplateControl.tsx +90 -6
  48. package/src/notification/email-template/form/EmailTemplateForm.stories.tsx +34 -0
  49. package/src/notification/email-template/form/EmailTemplateForm.tsx +23 -5
  50. package/src/notification/hooks/useTranslatedParameters.ts +27 -0
  51. package/src/notification/sms-template/card/SmsTemplateCard.stories.tsx +3 -1
  52. package/src/notification/sms-template/card/SmsTemplateCard.tsx +13 -3
  53. package/src/notification/sms-template/control/SmsTemplateControl.tsx +40 -2
  54. package/src/notification/sms-template/form/SmsTemplateForm.stories.tsx +28 -0
  55. package/src/notification/sms-template/form/SmsTemplateForm.tsx +6 -1
  56. package/src/product-set/control/ProductSetControl.tsx +38 -33
  57. package/src/product-set/form/ProductSetForm.stories.tsx +41 -2
  58. package/src/product-set/form/ProductSetForm.tsx +11 -0
  59. package/src/product-set/utils/index.ts +28 -0
  60. package/src/provider/provider-details-input/ProviderDetailsInput.tsx +0 -2
  61. package/src/sales/manual-booking/select-menu/SelectMenu.tsx +3 -1
  62. package/src/styles/snippet-templates/SnippetTemplateCard.scss +16 -0
  63. package/src/typeahead/Typeahead.stories.tsx +9 -6
  64. package/src/typeahead/Typeahead.tsx +19 -12
@@ -14,7 +14,9 @@ export const Default: Story<SmsTemplateCardProps> = (args) => (
14
14
 
15
15
  Default.args = {
16
16
  href: "#",
17
- name: "Default Sms Template",
17
+ name: "Default Sms Template with Long name",
18
18
  hasPermission: true,
19
19
  isDefault: true,
20
+ templateType: "confirmation",
21
+ isActive: true,
20
22
  };
@@ -1,16 +1,19 @@
1
1
  import React from "react";
2
2
  import { Link } from "react-router-dom";
3
- import { HasPermissionProp } from "@licklist/plugins/dist/types/permission/Permission";
4
3
  import { useTranslation } from "react-i18next";
5
-
4
+ import { HasPermissionProp } from "@licklist/plugins/dist/types/permission/Permission";
5
+ import { NotificationType } from "@licklist/core/dist/DataMapper/Notification/NotificationTypeDataMapper";
6
6
  import { ConfirmModal, ConfirmModalType } from "../../../modals";
7
7
  import { Icon } from "../../../static";
8
+ import { useTranslatedParameters } from "../../hooks/useTranslatedParameters";
8
9
 
9
10
  export interface SmsTemplateCardProps extends HasPermissionProp {
10
11
  name: string;
11
12
  href: string;
12
13
  onRemove: () => void;
13
14
  isDefault: boolean;
15
+ isActive: boolean;
16
+ type: NotificationType;
14
17
  }
15
18
 
16
19
  export function SmsTemplateCard({
@@ -19,9 +22,13 @@ export function SmsTemplateCard({
19
22
  onRemove,
20
23
  hasPermission = true,
21
24
  isDefault = false,
25
+ isActive = false,
26
+ type,
22
27
  }: SmsTemplateCardProps) {
23
28
  const { t } = useTranslation(["Design"]);
24
29
 
30
+ const texts = useTranslatedParameters({ isActive, isDefault });
31
+
25
32
  return (
26
33
  <div className="snippet-template-card">
27
34
  <div className="snippet-template-card-header">
@@ -50,7 +57,10 @@ export function SmsTemplateCard({
50
57
  )}
51
58
  </div>
52
59
  <div className="mt-2">
53
- {Boolean(isDefault) && <p className="mb-1">{t("Design:default")}</p>}
60
+ {!!texts.length && <p className="mb-1">{texts}</p>}
61
+ <p className="mb-0">
62
+ {t(`Design:type`)}:&nbsp;{t(`Design:${type}`)}
63
+ </p>
54
64
  </div>
55
65
  </div>
56
66
  );
@@ -4,12 +4,18 @@ import { Col, Row, Form } from "react-bootstrap";
4
4
  import { useFormContext } from "react-hook-form";
5
5
  import { useTranslation } from "react-i18next";
6
6
  import HookFormService from "@licklist/plugins/dist/services/Form/HookFormService";
7
-
7
+ import { NotificationType } from "@licklist/core/dist/DataMapper/Notification/NotificationTypeDataMapper";
8
8
  import { SmsTemplateValues } from "../form";
9
9
 
10
10
  const MAX_SMS_LENGTH = 300;
11
11
 
12
- export const SmsTemplateControl = () => {
12
+ type SmsTemplateControlProps = {
13
+ notificationTypes: NotificationType[];
14
+ };
15
+
16
+ export const SmsTemplateControl = ({
17
+ notificationTypes = [],
18
+ }: SmsTemplateControlProps) => {
13
19
  const { t } = useTranslation(["Design"]);
14
20
  const {
15
21
  register,
@@ -20,9 +26,39 @@ export const SmsTemplateControl = () => {
20
26
  } = useFormContext<SmsTemplateValues>();
21
27
 
22
28
  const smsBody = watch("body");
29
+ const id = watch("id");
23
30
 
24
31
  return (
25
32
  <>
33
+ <Row>
34
+ <Form.Group as={Col} controlId="type" xs sm={12} md={8} lg={10} xl={12}>
35
+ <Form.Label>{t("type")}</Form.Label>
36
+
37
+ <Form.Control
38
+ as="select"
39
+ {...register("type", {
40
+ required: t("Validation:fieldRequired", {
41
+ attribute: t("type"),
42
+ }) as string,
43
+ })}
44
+ name="type"
45
+ required
46
+ isInvalid={Boolean(errors.type)}
47
+ placeholder={t("Design:type")}
48
+ disabled={!!id}
49
+ >
50
+ <option value="">{t("Design:choose")}</option>
51
+ {notificationTypes.map((key) => (
52
+ <option key={key} value={key}>
53
+ {t(`Design:${key}`)}
54
+ </option>
55
+ ))}
56
+ </Form.Control>
57
+ <Form.Control.Feedback type="invalid">
58
+ {errors.type?.message}
59
+ </Form.Control.Feedback>
60
+ </Form.Group>
61
+ </Row>
26
62
  <Row>
27
63
  <Form.Group
28
64
  as={Col}
@@ -62,6 +98,8 @@ export const SmsTemplateControl = () => {
62
98
  <Form.Label>{t("Design:smsBody")}</Form.Label>
63
99
  <Form.Control
64
100
  isInvalid={Boolean(errors.body)}
101
+ as="textarea"
102
+ rows={3}
65
103
  {...register("body", {
66
104
  required: true,
67
105
  maxLength: MAX_SMS_LENGTH,
@@ -38,12 +38,26 @@ Default.args = {
38
38
  isDefault: false,
39
39
  body: "Some random sms string",
40
40
  },
41
+ type: "confirmation",
42
+ notificationTypes: [
43
+ "confirmation",
44
+ "paymentLink",
45
+ "afterBooking",
46
+ "preliminaryMail",
47
+ ],
41
48
  };
42
49
 
43
50
  Empty.args = {
44
51
  onSubmit: (data) => console.log(data),
45
52
  isLoading: true,
46
53
  placeholders: [],
54
+ type: "confirmation",
55
+ notificationTypes: [
56
+ "confirmation",
57
+ "paymentLink",
58
+ "afterBooking",
59
+ "preliminaryMail",
60
+ ],
47
61
  };
48
62
 
49
63
  ServerErrors.args = {
@@ -54,4 +68,18 @@ ServerErrors.args = {
54
68
  body: ["Body field is required"],
55
69
  name: ["Name Field is required"],
56
70
  },
71
+ type: "confirmation",
72
+ notificationTypes: [
73
+ "confirmation",
74
+ "paymentLink",
75
+ "afterBooking",
76
+ "preliminaryMail",
77
+ ],
78
+ defaultValues: {
79
+ name: "",
80
+ isActive: false,
81
+ isDefault: false,
82
+ body: "Some random sms string",
83
+ id: 5,
84
+ },
57
85
  };
@@ -8,6 +8,7 @@ import { NotificationPlaceholder } from "@licklist/core/dist/DataMapper/Notifica
8
8
  import { ServerError } from "@licklist/plugins/dist/hooks/Api/useHttpQuery";
9
9
  import FormErrorService from "@licklist/plugins/dist/services/Form/FormErrorService";
10
10
 
11
+ import { NotificationType } from "@licklist/core/dist/DataMapper/Notification/NotificationTypeDataMapper";
11
12
  import { NotificationPlaceholders } from "../../components/NotificationPlaceholders";
12
13
  import { SmsTemplateControl } from "../control/SmsTemplateControl";
13
14
 
@@ -16,6 +17,8 @@ export interface SmsTemplateValues extends FormValues {
16
17
  isActive: boolean;
17
18
  isDefault: boolean;
18
19
  body: string;
20
+ type?: NotificationType;
21
+ id?: number | string;
19
22
  }
20
23
 
21
24
  export interface SmsTemplateProps extends HasPermissionProp {
@@ -24,6 +27,7 @@ export interface SmsTemplateProps extends HasPermissionProp {
24
27
  defaultValues?: SmsTemplateValues;
25
28
  placeholders?: NotificationPlaceholder[];
26
29
  serverErrors?: ServerError;
30
+ notificationTypes?: NotificationType[];
27
31
  }
28
32
 
29
33
  export function SmsTemplateForm({
@@ -32,6 +36,7 @@ export function SmsTemplateForm({
32
36
  hasPermission = true,
33
37
  placeholders = [],
34
38
  serverErrors,
39
+ notificationTypes = [],
35
40
  }: SmsTemplateProps) {
36
41
  const { t } = useTranslation("Design");
37
42
 
@@ -46,7 +51,7 @@ export function SmsTemplateForm({
46
51
  return (
47
52
  <FormProvider {...form}>
48
53
  <Form onSubmit={form.handleSubmit(onSubmit)}>
49
- <SmsTemplateControl />
54
+ <SmsTemplateControl notificationTypes={notificationTypes} />
50
55
  <NotificationPlaceholders placeholders={placeholders} />
51
56
 
52
57
  {hasPermission && (
@@ -27,12 +27,19 @@ import {
27
27
  import TutorialGifCard from "./TutorialGifCard";
28
28
  import { Step } from "../types";
29
29
  import { StepsControl } from "../form/StepsControl";
30
+ import { Typeahead } from "../../typeahead";
30
31
 
31
32
  const OPERATIONAL_COST_TITLES = {
32
33
  [OPERATIONAL_COST_PROVIDER]: "operationalCostProvider",
33
34
  [OPERATIONAL_COST_CUSTOMER]: "operationalCostCustomer",
34
35
  } as const;
35
36
 
37
+ export interface TemplateItem {
38
+ id: string;
39
+ value: EmailTemplate | SmsTemplate;
40
+ label: string;
41
+ }
42
+
36
43
  export interface ProductSetControlValues extends DateAndRecurrenceInputValues {
37
44
  name: string;
38
45
  type: ProductSetType;
@@ -43,8 +50,8 @@ export interface ProductSetControlValues extends DateAndRecurrenceInputValues {
43
50
  productGroups?: SelectItem[];
44
51
  fieldSetId?: number;
45
52
  steps?: Step[];
46
- emailTemplateId?: number;
47
- smsTemplateId?: number;
53
+ emailTemplates?: TemplateItem[];
54
+ smsTemplates?: TemplateItem[];
48
55
  }
49
56
 
50
57
  export interface ProductSetControlShared {
@@ -54,11 +61,17 @@ export interface ProductSetControlShared {
54
61
  smsTemplates?: SmsTemplate[];
55
62
  }
56
63
 
57
- export interface ProductSetControlProps extends ProductSetControlShared {
64
+ export interface ProductSetControlProps {
58
65
  companyName: string;
59
66
  isLoading: boolean;
60
67
  isEventEditProductSet?: boolean;
61
68
  isCreateAction?: boolean;
69
+ emailTemplates?: TemplateItem[];
70
+ smsTemplates?: TemplateItem[];
71
+ fee?: string;
72
+ fieldSets?: FieldSet[];
73
+ showEmailTemplate?: boolean;
74
+ showSmsTemplate?: boolean;
62
75
  }
63
76
 
64
77
  export function ProductSetControl({
@@ -70,6 +83,8 @@ export function ProductSetControl({
70
83
  smsTemplates = [],
71
84
  isEventEditProductSet,
72
85
  isCreateAction,
86
+ showEmailTemplate,
87
+ showSmsTemplate,
73
88
  }: ProductSetControlProps) {
74
89
  const { t } = useTranslation(["Design", "Validation", "Notification"]);
75
90
  const {
@@ -82,8 +97,6 @@ export function ProductSetControl({
82
97
  } = useFormContext<ProductSetControlValues>();
83
98
 
84
99
  const steps = watch("steps");
85
- const smsTemplateId = watch("smsTemplateId");
86
- const emailTemplateId = watch("emailTemplateId");
87
100
 
88
101
  const nameId = useId();
89
102
  const termsAndConditionsId = useId();
@@ -221,20 +234,16 @@ export function ProductSetControl({
221
234
  <Form.Label className="mt-4">
222
235
  {t("Design:emailTemplate")}
223
236
  </Form.Label>
224
- {emailTemplates.length > 0 ? (
225
- <Form.Control {...register("emailTemplateId")} as="select">
226
- <option value="" selected={String(emailTemplateId) === ""}>
227
- {t("Design:choose")}
228
- </option>
229
- {emailTemplates.map((emailTemplate) => (
230
- <option
231
- value={Number(emailTemplate.notification.id)}
232
- key={emailTemplate.id}
233
- >
234
- {emailTemplate.notification.name}
235
- </option>
236
- ))}
237
- </Form.Control>
237
+ {showEmailTemplate ? (
238
+ <Typeahead
239
+ name="emailTemplates"
240
+ options={emailTemplates}
241
+ isMultipleChoise
242
+ placeholder={t("Design:choose")}
243
+ noOptionsMessage={t("Design:noActiveTemplates", {
244
+ notification: t("Design:email"),
245
+ })}
246
+ />
238
247
  ) : (
239
248
  <WarningMessage
240
249
  message={t("Design:noActiveTemplates", {
@@ -248,20 +257,16 @@ export function ProductSetControl({
248
257
  >
249
258
  {t("Design:smsTemplate")}
250
259
  </Form.Label>
251
- {smsTemplates.length > 0 ? (
252
- <Form.Control {...register("smsTemplateId")} as="select">
253
- <option value="" selected={String(smsTemplateId) === ""}>
254
- {t("Design:choose")}
255
- </option>
256
- {smsTemplates.map((smsTemplate) => (
257
- <option
258
- value={Number(smsTemplate.notification.id)}
259
- key={smsTemplate.id}
260
- >
261
- {smsTemplate.notification.name}
262
- </option>
263
- ))}
264
- </Form.Control>
260
+ {showSmsTemplate ? (
261
+ <Typeahead
262
+ name="smsTemplates"
263
+ options={smsTemplates}
264
+ isMultipleChoise
265
+ placeholder={t("Design:choose")}
266
+ noOptionsMessage={t("Design:noActiveTemplates", {
267
+ notification: t("Design:sms"),
268
+ })}
269
+ />
265
270
  ) : (
266
271
  <WarningMessage
267
272
  message={t("Design:noActiveTemplates", {
@@ -3,6 +3,11 @@
3
3
  import React from "react";
4
4
  import { Meta, Story } from "@storybook/react";
5
5
  import { boolean } from "@storybook/addon-knobs";
6
+ import {
7
+ CONFIRMATION_TYPE,
8
+ PAYMENT_LINK_TYPE,
9
+ } from "@licklist/core/dist/DataMapper/Notification/NotificationTypeDataMapper";
10
+
6
11
  import {
7
12
  OPERATIONAL_COST_CUSTOMER,
8
13
  OPERATIONAL_COST_PROVIDER,
@@ -357,12 +362,14 @@ Default.args = {
357
362
  body: "",
358
363
  meta: "",
359
364
  notification: {
360
- isActive: false,
365
+ id: 1,
366
+ isActive: true,
361
367
  isDefault: false,
362
368
  name: "Template name 1",
363
369
  companyId: 1,
364
370
  providerId: 1,
365
371
  fieldSetId: 1,
372
+ type: CONFIRMATION_TYPE,
366
373
  },
367
374
  },
368
375
  {
@@ -371,12 +378,44 @@ Default.args = {
371
378
  body: "",
372
379
  meta: "",
373
380
  notification: {
374
- isActive: false,
381
+ id: 2,
382
+ isActive: true,
383
+ isDefault: false,
384
+ name: "Tempalte name 2",
385
+ companyId: 1,
386
+ providerId: 1,
387
+ fieldSetId: 1,
388
+ type: CONFIRMATION_TYPE,
389
+ },
390
+ },
391
+ ],
392
+ smsTemplates: [
393
+ {
394
+ id: "1",
395
+ body: "",
396
+ notification: {
397
+ id: 3,
398
+ isActive: true,
399
+ isDefault: false,
400
+ name: "Tempalte name 1",
401
+ companyId: 1,
402
+ providerId: 1,
403
+ fieldSetId: 1,
404
+ type: PAYMENT_LINK_TYPE,
405
+ },
406
+ },
407
+ {
408
+ id: "2",
409
+ body: "",
410
+ notification: {
411
+ id: 4,
412
+ isActive: true,
375
413
  isDefault: false,
376
414
  name: "Tempalte name 2",
377
415
  companyId: 1,
378
416
  providerId: 1,
379
417
  fieldSetId: 1,
418
+ type: PAYMENT_LINK_TYPE,
380
419
  },
381
420
  },
382
421
  ],
@@ -20,6 +20,7 @@ import {
20
20
  import { Step } from "../types";
21
21
  import { ProductSetContextProvider, ProductSetLoadingContext } from "./context";
22
22
  import { SelectItem } from "../../types/generic/SelectItem";
23
+ import { getFilteredTemplates } from "../utils";
23
24
 
24
25
  export interface WithIsLoading {
25
26
  isLoading: boolean;
@@ -133,6 +134,16 @@ export function ProductSetForm({
133
134
  <>
134
135
  <ProductSetControl
135
136
  {...shared}
137
+ smsTemplates={getFilteredTemplates(
138
+ shared?.smsTemplates,
139
+ formValues?.smsTemplates
140
+ )}
141
+ emailTemplates={getFilteredTemplates(
142
+ shared?.emailTemplates,
143
+ formValues?.emailTemplates
144
+ )}
145
+ showEmailTemplate={!!shared?.emailTemplates}
146
+ showSmsTemplate={!!shared?.smsTemplates}
136
147
  isLoading={isLoading}
137
148
  isCreateAction={isCreateAction}
138
149
  companyName={companyName}
@@ -1,3 +1,7 @@
1
+ import { EmailTemplate } from "@licklist/core/dist/DataMapper/Notification/EmailTemplateDataMapper";
2
+ import { SmsTemplate } from "@licklist/core/dist/DataMapper/Notification/SmsTemplateDataMapper";
3
+ import { TemplateItem } from "../control/ProductSetControl";
4
+
1
5
  export const moveArrayElements = <T>(
2
6
  array: T[],
3
7
  prevIndex: number,
@@ -14,3 +18,27 @@ export const moveArrayElements = <T>(
14
18
  export const sortArrayByIndex = <T>(array: T[]) => {
15
19
  return array.map((element: T, index) => ({ ...element, sort: index }));
16
20
  };
21
+
22
+ export const getFilteredTemplates = (
23
+ templates?: EmailTemplate[] | SmsTemplate[],
24
+ formTemplates?: TemplateItem[]
25
+ ): TemplateItem[] | undefined => {
26
+ if (!templates) {
27
+ return undefined;
28
+ }
29
+
30
+ return templates
31
+ ?.filter(
32
+ (template) =>
33
+ template.notification.isActive &&
34
+ !formTemplates?.find(
35
+ (formTemplate) =>
36
+ formTemplate.value.notification.type === template.notification.type
37
+ )
38
+ )
39
+ ?.map((template) => ({
40
+ id: template?.id,
41
+ value: template,
42
+ label: template?.notification?.name,
43
+ }));
44
+ };
@@ -34,7 +34,6 @@ export function ProviderDetailsInput({
34
34
  const {
35
35
  register,
36
36
  formState: { errors },
37
- setValue,
38
37
  } = useFormContext<ProviderDetailsInputValues>();
39
38
  const { t } = useTranslation(["App", "Design", "Validation"]);
40
39
 
@@ -149,7 +148,6 @@ export function ProviderDetailsInput({
149
148
  <Typeahead
150
149
  name="company"
151
150
  options={companiesOptions}
152
- setValue={setValue}
153
151
  placeholder={t("App:select")}
154
152
  noOptionsMessage={t("App:noMatchesFound")}
155
153
  />
@@ -39,7 +39,9 @@ export const SelectMenu = ({
39
39
  ) : (
40
40
  <>
41
41
  {!isLoading && (
42
- <Form.Label className="bold-text">{t("Design:productSets")}</Form.Label>
42
+ <Form.Label className="bold-text">
43
+ {t("Design:productSets")}
44
+ </Form.Label>
43
45
  )}
44
46
 
45
47
  <div className="menu-list-manual-booking">
@@ -45,6 +45,22 @@ $snippet-template-card-button-transition: $product-set-card-transition !default;
45
45
  display: flex;
46
46
  justify-content: space-between;
47
47
  align-items: center;
48
+
49
+ a {
50
+ white-space: nowrap;
51
+ display: inline-block;
52
+ text-overflow: ellipsis;
53
+ width: 85%;
54
+ overflow: hidden;
55
+ }
56
+ }
57
+
58
+ .snippet-template-card-subject {
59
+ white-space: nowrap;
60
+ display: inline-block;
61
+ text-overflow: ellipsis;
62
+ width: 100%;
63
+ overflow: hidden;
48
64
  }
49
65
 
50
66
  .snippet-template-card-button {
@@ -1,20 +1,23 @@
1
1
  import React from "react";
2
2
  import { storiesOf } from "@storybook/react";
3
+ import { FormProvider, useForm } from "react-hook-form";
3
4
  import { Typeahead } from "./Typeahead";
4
5
 
5
- storiesOf("Typeahead", module)
6
- .add("Typeahead", () => (
7
- <>
6
+ storiesOf("Typeahead", module).add("Typeahead", () => {
7
+ const form = useForm();
8
+ return (
9
+ <FormProvider {...form}>
8
10
  <Typeahead
9
11
  name="user"
12
+ isMultipleChoise
10
13
  options={[
11
14
  { id: 1, value: "user1", label: "User1" },
12
15
  { id: 2, value: "user2", label: "User2" },
13
16
  { id: 3, value: "user3", label: "User3" },
14
17
  ]}
15
- setValue={() => {}}
16
18
  placeholder="Select"
17
19
  noOptionsMessage="No Options Found"
18
20
  />
19
- </>
20
- ));
21
+ </FormProvider>
22
+ );
23
+ });
@@ -1,47 +1,54 @@
1
1
  import React from "react";
2
2
  import Select from "react-select";
3
- import { useForm, Controller } from "react-hook-form";
3
+ import { Controller, useFormContext } from "react-hook-form";
4
4
 
5
5
  export type TypeaheadOptions = {
6
- id: number;
7
- value: string;
6
+ id: number | string;
7
+ value: any;
8
8
  label: string;
9
9
  };
10
10
 
11
11
  export interface TypeaheadProps {
12
12
  options: TypeaheadOptions[];
13
- setValue: (value: string | any) => void;
14
13
  placeholder: string;
15
14
  isRequired?: boolean;
16
15
  name: string;
16
+ isMultipleChoise?: boolean;
17
17
  noOptionsMessage: string;
18
+ isInvalid?: boolean;
18
19
  }
19
20
 
20
21
  function Typeahead({
21
22
  options,
22
- setValue,
23
23
  placeholder,
24
24
  isRequired = false,
25
+ isMultipleChoise,
25
26
  name = "",
26
27
  noOptionsMessage = "",
27
- }) {
28
- const { control } = useForm({
29
- mode: "onChange",
30
- });
31
- const prefix = "id";
28
+ isInvalid,
29
+ }: TypeaheadProps) {
30
+ const { control } = useFormContext();
31
+
32
+ const getErrorStyle = () => (isInvalid ? { borderColor: "red" } : {});
32
33
 
33
34
  return (
34
35
  <>
35
36
  <Controller
36
- name={`${name}.${prefix as string}` as const}
37
+ name={name}
37
38
  control={control}
38
39
  rules={{ required: isRequired }}
39
40
  render={({ field }) => (
40
41
  <Select
41
42
  placeholder={placeholder}
42
43
  value={field.value}
44
+ isMulti={isMultipleChoise}
45
+ styles={{
46
+ control: (base) => ({
47
+ ...base,
48
+ ...getErrorStyle(),
49
+ }),
50
+ }}
43
51
  onChange={(value) => {
44
- setValue(`${name}.${prefix}`, value.id);
45
52
  field.onChange(value);
46
53
  }}
47
54
  options={options}