@carlonicora/nextjs-jsonapi 1.115.0 → 1.117.0

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 (78) hide show
  1. package/dist/{AssistantMessageInterface-BuUZFkE5.d.mts → AssistantMessageInterface-Ca0G0vZw.d.mts} +1 -1
  2. package/dist/{AssistantMessageInterface-CQwh5tEb.d.ts → AssistantMessageInterface-DEZ5AnVl.d.ts} +1 -1
  3. package/dist/{BlockNoteEditor-V74ICZY3.js → BlockNoteEditor-6UREFUSJ.js} +19 -19
  4. package/dist/{BlockNoteEditor-V74ICZY3.js.map → BlockNoteEditor-6UREFUSJ.js.map} +1 -1
  5. package/dist/{BlockNoteEditor-Z3EKI3C6.mjs → BlockNoteEditor-UQOOX3UT.mjs} +4 -4
  6. package/dist/{auth.interface-CXBF8Mhi.d.mts → auth.interface-r3XKYOrQ.d.mts} +1 -1
  7. package/dist/{auth.interface-8b601idJ.d.ts → auth.interface-yivTb46w.d.ts} +1 -1
  8. package/dist/billing/index.js +346 -346
  9. package/dist/billing/index.mjs +3 -3
  10. package/dist/{chunk-3MUBMSDD.js → chunk-6KLR3WJQ.js} +7 -7
  11. package/dist/{chunk-3MUBMSDD.js.map → chunk-6KLR3WJQ.js.map} +1 -1
  12. package/dist/{chunk-6LSGIJ5W.js → chunk-HXU2HDRN.js} +1090 -956
  13. package/dist/chunk-HXU2HDRN.js.map +1 -0
  14. package/dist/{chunk-UBBTQUFB.mjs → chunk-M7XAKLSP.mjs} +11 -2
  15. package/dist/{chunk-UBBTQUFB.mjs.map → chunk-M7XAKLSP.mjs.map} +1 -1
  16. package/dist/{chunk-J3DFHESB.js → chunk-S2PTWBN6.js} +27 -18
  17. package/dist/chunk-S2PTWBN6.js.map +1 -0
  18. package/dist/{chunk-BKKVLD42.mjs → chunk-SVEPL5J2.mjs} +514 -380
  19. package/dist/chunk-SVEPL5J2.mjs.map +1 -0
  20. package/dist/{chunk-SJRSR3AF.mjs → chunk-WEPQD5MP.mjs} +2 -2
  21. package/dist/client/index.d.mts +2 -2
  22. package/dist/client/index.d.ts +2 -2
  23. package/dist/client/index.js +4 -4
  24. package/dist/client/index.mjs +3 -3
  25. package/dist/components/index.d.mts +71 -24
  26. package/dist/components/index.d.ts +71 -24
  27. package/dist/components/index.js +6 -4
  28. package/dist/components/index.js.map +1 -1
  29. package/dist/components/index.mjs +5 -3
  30. package/dist/contexts/index.d.mts +3 -3
  31. package/dist/contexts/index.d.ts +3 -3
  32. package/dist/contexts/index.js +4 -4
  33. package/dist/contexts/index.mjs +3 -3
  34. package/dist/core/index.d.mts +10 -8
  35. package/dist/core/index.d.ts +10 -8
  36. package/dist/core/index.js +2 -2
  37. package/dist/core/index.mjs +1 -1
  38. package/dist/features/help/index.js +36 -36
  39. package/dist/features/help/index.mjs +3 -3
  40. package/dist/index.d.mts +5 -5
  41. package/dist/index.d.ts +5 -5
  42. package/dist/index.js +3 -3
  43. package/dist/index.mjs +2 -2
  44. package/dist/{notification.interface-DIxR23eS.d.mts → notification.interface-B3kNUTZs.d.mts} +2 -1
  45. package/dist/{notification.interface-C1T1C2ee.d.ts → notification.interface-LKFmZndR.d.ts} +2 -1
  46. package/dist/{s3.service-CAL5dhGG.d.mts → s3.service-CihgBy97.d.mts} +2 -2
  47. package/dist/{s3.service-COLYvcW2.d.ts → s3.service-Cyvfk3qV.d.ts} +2 -2
  48. package/dist/server/index.d.mts +3 -3
  49. package/dist/server/index.d.ts +3 -3
  50. package/dist/server/index.js +3 -3
  51. package/dist/server/index.mjs +1 -1
  52. package/dist/{useSocket-B1fMIr17.d.mts → useSocket-BSjn1Rlb.d.mts} +1 -1
  53. package/dist/{useSocket-BdJTBXKv.d.ts → useSocket-BsbaGPqE.d.ts} +1 -1
  54. package/package.json +1 -1
  55. package/src/components/forms/CommonDeleter.tsx +49 -18
  56. package/src/components/forms/CommonEditorButtons.tsx +4 -2
  57. package/src/components/forms/CommonEditorHeader.tsx +20 -14
  58. package/src/components/forms/CommonEditorTrigger.tsx +18 -4
  59. package/src/components/forms/DateRangeSelector.tsx +55 -19
  60. package/src/components/forms/EditorSheet.tsx +36 -9
  61. package/src/components/forms/FileUploader.tsx +51 -21
  62. package/src/components/forms/FormDate.tsx +6 -2
  63. package/src/components/forms/FormDateTime.tsx +11 -2
  64. package/src/components/forms/FormFieldWrapper.tsx +3 -1
  65. package/src/components/forms/FormInput.tsx +3 -1
  66. package/src/components/forms/FormPassword.tsx +10 -1
  67. package/src/components/forms/FormPlaceAutocomplete.tsx +8 -3
  68. package/src/components/forms/FormSelect.tsx +3 -0
  69. package/src/components/forms/FormSlider.tsx +3 -1
  70. package/src/components/forms/FormTextarea.tsx +15 -1
  71. package/src/features/notification/data/notification.interface.ts +2 -2
  72. package/src/features/notification/data/notification.ts +21 -5
  73. package/src/shadcnui/ui/badge.tsx +15 -0
  74. package/dist/chunk-6LSGIJ5W.js.map +0 -1
  75. package/dist/chunk-BKKVLD42.mjs.map +0 -1
  76. package/dist/chunk-J3DFHESB.js.map +0 -1
  77. /package/dist/{BlockNoteEditor-Z3EKI3C6.mjs.map → BlockNoteEditor-UQOOX3UT.mjs.map} +0 -0
  78. /package/dist/{chunk-SJRSR3AF.mjs.map → chunk-WEPQD5MP.mjs.map} +0 -0
@@ -26,6 +26,8 @@ export function FormDate({
26
26
  isRequired = false,
27
27
  defaultMonth,
28
28
  allowEmpty,
29
+ description,
30
+ futureYears,
29
31
  }: {
30
32
  form: any;
31
33
  id: string;
@@ -36,6 +38,8 @@ export function FormDate({
36
38
  isRequired?: boolean;
37
39
  defaultMonth?: Date;
38
40
  allowEmpty?: boolean;
41
+ description?: string;
42
+ futureYears?: number;
39
43
  }) {
40
44
  const t = useI18nTranslations();
41
45
  const locale = useI18nLocale();
@@ -117,7 +121,7 @@ export function FormDate({
117
121
 
118
122
  return (
119
123
  <div className="flex w-full flex-col">
120
- <FormFieldWrapper form={form} name={id} label={name} isRequired={isRequired}>
124
+ <FormFieldWrapper form={form} name={id} label={name} isRequired={isRequired} description={description}>
121
125
  {(field) => (
122
126
  <Popover open={open} onOpenChange={setOpen} modal={true}>
123
127
  <InputGroup>
@@ -162,7 +166,7 @@ export function FormDate({
162
166
  month={displayMonth}
163
167
  onMonthChange={setDisplayMonth}
164
168
  startMonth={new Date(1900, 0)}
165
- endMonth={new Date(new Date().getFullYear() + 10, 11)}
169
+ endMonth={new Date(new Date().getFullYear() + (futureYears ?? 10), 11)}
166
170
  />
167
171
  {allowEmpty !== false && (
168
172
  <div className="border-t p-2">
@@ -27,6 +27,9 @@ export function FormDateTime({
27
27
  onChange,
28
28
  allowEmpty,
29
29
  defaultMonth,
30
+ placeholder,
31
+ isRequired,
32
+ description,
30
33
  }: {
31
34
  form: any;
32
35
  id: string;
@@ -36,6 +39,8 @@ export function FormDateTime({
36
39
  onChange?: (date?: Date) => Promise<void>;
37
40
  allowEmpty?: boolean;
38
41
  defaultMonth?: Date;
42
+ isRequired?: boolean;
43
+ description?: string;
39
44
  }) {
40
45
  const [open, setOpen] = useState<boolean>(false);
41
46
  const t = useI18nTranslations();
@@ -100,7 +105,7 @@ export function FormDateTime({
100
105
 
101
106
  return (
102
107
  <div className="flex w-full flex-col">
103
- <FormFieldWrapper form={form} name={id} label={name}>
108
+ <FormFieldWrapper form={form} name={id} label={name} isRequired={isRequired} description={description}>
104
109
  {(field) => (
105
110
  <div className="relative flex flex-row">
106
111
  <Popover open={open} onOpenChange={setOpen} modal={true}>
@@ -113,7 +118,11 @@ export function FormDateTime({
113
118
  />
114
119
  }
115
120
  >
116
- {field.value ? formatDateTime(field.value) : <span>{t(`common.pick_date_time`)}</span>}
121
+ {field.value ? (
122
+ formatDateTime(field.value)
123
+ ) : (
124
+ <span>{placeholder ? placeholder : t(`common.pick_date_time`)}</span>
125
+ )}
117
126
  <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
118
127
  </PopoverTrigger>
119
128
  {field.value && allowEmpty !== false && (
@@ -18,6 +18,7 @@ type FormFieldWrapperProps<T extends FieldValues> = {
18
18
  description?: string;
19
19
  isRequired?: boolean;
20
20
  orientation?: "vertical" | "horizontal" | "responsive";
21
+ className?: string;
21
22
  children: (field: ControllerRenderProps<T, Path<T>>, fieldState: ControllerFieldState) => ReactNode;
22
23
  testId?: string;
23
24
  };
@@ -29,6 +30,7 @@ export function FormFieldWrapper<T extends FieldValues>({
29
30
  description,
30
31
  isRequired,
31
32
  orientation = "vertical",
33
+ className,
32
34
  children,
33
35
  testId,
34
36
  }: FormFieldWrapperProps<T>) {
@@ -37,7 +39,7 @@ export function FormFieldWrapper<T extends FieldValues>({
37
39
  control={form.control}
38
40
  name={name}
39
41
  render={({ field, fieldState }) => (
40
- <Field orientation={orientation} data-invalid={!!fieldState.error} data-testid={testId}>
42
+ <Field orientation={orientation} className={className} data-invalid={!!fieldState.error} data-testid={testId}>
41
43
  {label && (
42
44
  <FieldLabel>
43
45
  {label}
@@ -9,6 +9,7 @@ export function FormInput({
9
9
  form,
10
10
  id,
11
11
  name,
12
+ description,
12
13
  placeholder,
13
14
  type,
14
15
  onBlur,
@@ -22,6 +23,7 @@ export function FormInput({
22
23
  form: any;
23
24
  id: string;
24
25
  name?: string;
26
+ description?: string;
25
27
  placeholder?: string;
26
28
  type?: "text" | "number" | "currency" | "decimal" | "password" | "link";
27
29
  onBlur?: () => Promise<void>;
@@ -36,7 +38,7 @@ export function FormInput({
36
38
 
37
39
  return (
38
40
  <div className="flex w-full flex-col">
39
- <FormFieldWrapper form={form} name={id} label={name} isRequired={isRequired}>
41
+ <FormFieldWrapper form={form} name={id} label={name} description={description} isRequired={isRequired}>
40
42
  {(field) => {
41
43
  const handleBlur = async (e: React.FocusEvent<HTMLInputElement>) => {
42
44
  let value = e.target.value;
@@ -12,6 +12,7 @@ export function FormPassword({
12
12
  disabled,
13
13
  testId,
14
14
  isRequired,
15
+ description,
15
16
  }: {
16
17
  form: any;
17
18
  id: string;
@@ -21,10 +22,18 @@ export function FormPassword({
21
22
  disabled?: boolean;
22
23
  testId?: string;
23
24
  isRequired?: boolean;
25
+ description?: string;
24
26
  }) {
25
27
  return (
26
28
  <div className="flex w-full flex-col">
27
- <FormFieldWrapper form={form} name={id} label={name} isRequired={isRequired} testId={testId}>
29
+ <FormFieldWrapper
30
+ form={form}
31
+ name={id}
32
+ label={name}
33
+ isRequired={isRequired}
34
+ description={description}
35
+ testId={testId}
36
+ >
28
37
  {(field) => (
29
38
  <PasswordInput
30
39
  {...field}
@@ -42,6 +42,7 @@ interface PlaceAutocompleteProps {
42
42
  form: any;
43
43
  id: string;
44
44
  name?: string;
45
+ description?: string;
45
46
  placeholder?: string;
46
47
  disabled?: boolean;
47
48
  testId?: string;
@@ -56,12 +57,15 @@ interface PlaceAutocompleteProps {
56
57
  * For regions, use: ["administrative_area_level_1", "administrative_area_level_2"]
57
58
  */
58
59
  includeTypes?: string[];
60
+ /** Google Places language code for results. Defaults to "en". */
61
+ languageCode?: string;
59
62
  }
60
63
 
61
64
  export function FormPlaceAutocomplete({
62
65
  form,
63
66
  id,
64
67
  name,
68
+ description,
65
69
  placeholder,
66
70
  disabled,
67
71
  testId,
@@ -69,6 +73,7 @@ export function FormPlaceAutocomplete({
69
73
  onPlaceSelect,
70
74
  className,
71
75
  includeTypes,
76
+ languageCode = "en",
72
77
  }: PlaceAutocompleteProps) {
73
78
  const [inputValue, setInputValue] = useState("");
74
79
  const [suggestions, setSuggestions] = useState<PlaceSuggestion[]>([]);
@@ -117,7 +122,7 @@ export function FormPlaceAutocomplete({
117
122
  body: JSON.stringify({
118
123
  input: input,
119
124
  ...(includeTypes ? { includedPrimaryTypes: includeTypes } : {}),
120
- languageCode: "en",
125
+ languageCode: languageCode,
121
126
  }),
122
127
  });
123
128
 
@@ -270,7 +275,7 @@ export function FormPlaceAutocomplete({
270
275
  if (loadError) {
271
276
  return (
272
277
  <div className="flex w-full flex-col">
273
- <FormFieldWrapper form={form} name={id} label={name} isRequired={isRequired}>
278
+ <FormFieldWrapper form={form} name={id} label={name} description={description} isRequired={isRequired}>
274
279
  {(field) => (
275
280
  <Input
276
281
  {...field}
@@ -287,7 +292,7 @@ export function FormPlaceAutocomplete({
287
292
 
288
293
  return (
289
294
  <div className="flex w-full flex-col" ref={containerRef}>
290
- <FormFieldWrapper form={form} name={id} label={name} isRequired={isRequired}>
295
+ <FormFieldWrapper form={form} name={id} label={name} description={description} isRequired={isRequired}>
291
296
  {(field) => (
292
297
  <div className="relative">
293
298
  <Input
@@ -9,6 +9,7 @@ export function FormSelect({
9
9
  form,
10
10
  id,
11
11
  name,
12
+ description,
12
13
  placeholder,
13
14
  disabled,
14
15
  values,
@@ -21,6 +22,7 @@ export function FormSelect({
21
22
  form: any;
22
23
  id: string;
23
24
  name?: string;
25
+ description?: string;
24
26
  placeholder?: string;
25
27
  disabled?: boolean;
26
28
  values: { id: string; text: string }[];
@@ -36,6 +38,7 @@ export function FormSelect({
36
38
  form={form}
37
39
  name={id}
38
40
  label={name}
41
+ description={description}
39
42
  isRequired={isRequired}
40
43
  orientation={useRows ? "horizontal" : "vertical"}
41
44
  testId={testId}
@@ -10,6 +10,7 @@ export function FormSlider({
10
10
  name,
11
11
  disabled,
12
12
  showPercentage,
13
+ description,
13
14
  }: {
14
15
  form: any;
15
16
  id: string;
@@ -17,12 +18,13 @@ export function FormSlider({
17
18
  placeholder?: string;
18
19
  disabled?: boolean;
19
20
  showPercentage?: boolean;
21
+ description?: string;
20
22
  }) {
21
23
  const value = useWatch({ control: form.control, name: id });
22
24
 
23
25
  return (
24
26
  <div className="flex w-full flex-col">
25
- <FormFieldWrapper form={form} name={id} label={name}>
27
+ <FormFieldWrapper form={form} name={id} label={name} description={description}>
26
28
  {() => (
27
29
  <div>
28
30
  {showPercentage && (
@@ -11,6 +11,9 @@ export function FormTextarea({
11
11
  className,
12
12
  placeholder,
13
13
  testId,
14
+ description,
15
+ isRequired,
16
+ textareaRef,
14
17
  }: {
15
18
  form: any;
16
19
  id: string;
@@ -18,13 +21,24 @@ export function FormTextarea({
18
21
  placeholder?: string;
19
22
  className?: string;
20
23
  testId?: string;
24
+ description?: string;
25
+ isRequired?: boolean;
26
+ textareaRef?: React.RefObject<HTMLTextAreaElement>;
21
27
  }) {
22
28
  return (
23
29
  <div className="flex w-full flex-col">
24
- <FormFieldWrapper form={form} name={id} label={name} testId={testId}>
30
+ <FormFieldWrapper
31
+ form={form}
32
+ name={id}
33
+ label={name}
34
+ description={description}
35
+ isRequired={isRequired}
36
+ testId={testId}
37
+ >
25
38
  {(field) => (
26
39
  <Textarea
27
40
  {...field}
41
+ ref={textareaRef}
28
42
  className={cn("min-h-96 w-full", className)}
29
43
  disabled={form.formState.isSubmitting}
30
44
  placeholder={placeholder}
@@ -1,5 +1,4 @@
1
1
  import { ApiDataInterface } from "../../../core";
2
- import { UserInterface } from "../../user";
3
2
 
4
3
  export type NotificationInput = {
5
4
  id: string;
@@ -12,5 +11,6 @@ export interface NotificationInterface extends ApiDataInterface {
12
11
  get message(): string | undefined;
13
12
  get actionUrl(): string | undefined;
14
13
 
15
- get actor(): UserInterface | undefined;
14
+ get actor(): ApiDataInterface | undefined;
15
+ get subject(): ApiDataInterface | undefined;
16
16
  }
@@ -1,5 +1,4 @@
1
- import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from "../../../core";
2
- import { UserInterface } from "../../user";
1
+ import { AbstractApiData, ApiDataInterface, JsonApiHydratedDataInterface, Modules } from "../../../core";
3
2
  import { NotificationInput, NotificationInterface } from "./notification.interface";
4
3
 
5
4
  export class Notification extends AbstractApiData implements NotificationInterface {
@@ -8,7 +7,8 @@ export class Notification extends AbstractApiData implements NotificationInterfa
8
7
  private _message?: string;
9
8
  private _actionUrl?: string;
10
9
 
11
- private _actor?: UserInterface;
10
+ private _actor?: ApiDataInterface;
11
+ private _subject?: ApiDataInterface;
12
12
 
13
13
  get notificationType(): string {
14
14
  if (this._notificationType === undefined) throw new Error("notificationType is not set");
@@ -27,10 +27,14 @@ export class Notification extends AbstractApiData implements NotificationInterfa
27
27
  return this._actionUrl;
28
28
  }
29
29
 
30
- get actor(): UserInterface | undefined {
30
+ get actor(): ApiDataInterface | undefined {
31
31
  return this._actor;
32
32
  }
33
33
 
34
+ get subject(): ApiDataInterface | undefined {
35
+ return this._subject;
36
+ }
37
+
34
38
  rehydrate(data: JsonApiHydratedDataInterface): this {
35
39
  super.rehydrate(data);
36
40
 
@@ -39,7 +43,19 @@ export class Notification extends AbstractApiData implements NotificationInterfa
39
43
  this._message = data.jsonApi.attributes.message;
40
44
  this._actionUrl = data.jsonApi.attributes.actionUrl;
41
45
 
42
- this._actor = this._readIncluded(data, "actor", Modules.User) as UserInterface;
46
+ const rels = (data.jsonApi.relationships ?? {}) as Record<string, { data?: { type: string; id: string } }>;
47
+
48
+ const actorType = rels.actor?.data?.type;
49
+ this._actor = actorType
50
+ ? (this._readIncluded(data, "actor", Modules.findByName(actorType)) as ApiDataInterface)
51
+ : undefined;
52
+
53
+ const subjectName = Object.keys(rels).find((name) => name !== "actor" && rels[name]?.data?.type);
54
+ const subjectType = subjectName ? rels[subjectName]?.data?.type : undefined;
55
+ this._subject =
56
+ subjectName && subjectType
57
+ ? (this._readIncluded(data, subjectName, Modules.findByName(subjectType)) as ApiDataInterface)
58
+ : undefined;
43
59
 
44
60
  return this;
45
61
  }
@@ -17,6 +17,18 @@ const badgeVariants = cva(
17
17
  "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/20 dark:bg-input/30",
18
18
  ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
19
19
  link: "text-primary underline-offset-4 hover:underline",
20
+ warning: "bg-warning text-warning-foreground [a]:hover:bg-warning/80",
21
+ blue: "bg-sky-500 text-primary-foreground [a]:hover:bg-sky-500/80",
22
+ green: "bg-emerald-500 text-primary-foreground [a]:hover:bg-emerald-500/80",
23
+ red: "bg-red-500 text-primary-foreground [a]:hover:bg-red-500/80",
24
+ yellow: "bg-yellow-500 text-primary-foreground [a]:hover:bg-yellow-500/80",
25
+ purple: "bg-purple-500 text-primary-foreground [a]:hover:bg-purple-500/80",
26
+ pink: "bg-pink-500 text-primary-foreground [a]:hover:bg-pink-500/80",
27
+ gray: "bg-gray-500 text-primary-foreground [a]:hover:bg-gray-500/80",
28
+ orange: "bg-orange-500 text-primary-foreground [a]:hover:bg-orange-500/80",
29
+ teal: "bg-teal-500 text-primary-foreground [a]:hover:bg-teal-500/80",
30
+ lime: "bg-lime-500 text-primary-foreground [a]:hover:bg-lime-500/80",
31
+ none: "border-input bg-transparent text-muted-foreground min-w-20 min-h-5",
20
32
  },
21
33
  },
22
34
  defaultVariants: {
@@ -47,4 +59,7 @@ function Badge({
47
59
  });
48
60
  }
49
61
 
62
+ type BadgeProps = useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>;
63
+
50
64
  export { Badge, badgeVariants };
65
+ export type { BadgeProps };