@headless-adminapp/fluent 0.0.17-alpha.64 → 0.0.17-alpha.65
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/PageCalendar/CalendarSection.d.ts +20 -0
- package/PageCalendar/CalendarSection.js +108 -0
- package/PageCalendar/EventDialog/AttributeController.d.ts +10 -0
- package/PageCalendar/EventDialog/AttributeController.js +17 -0
- package/PageCalendar/EventDialog/EventDialog.d.ts +25 -0
- package/PageCalendar/EventDialog/EventDialog.js +21 -0
- package/PageCalendar/EventDialog/EventFormBody.d.ts +18 -0
- package/PageCalendar/EventDialog/EventFormBody.js +69 -0
- package/PageCalendar/EventDialog/EventFormContent.d.ts +10 -0
- package/PageCalendar/EventDialog/EventFormContent.js +27 -0
- package/PageCalendar/EventDialog/types.d.ts +3 -0
- package/PageCalendar/EventDialog/types.js +2 -0
- package/PageCalendar/EventDialog/utils.d.ts +23 -0
- package/PageCalendar/EventDialog/utils.js +57 -0
- package/PageCalendar/Header.d.ts +8 -0
- package/PageCalendar/Header.js +35 -0
- package/PageCalendar/PageCalendar.d.ts +7 -0
- package/PageCalendar/PageCalendar.js +231 -0
- package/PageCalendar/TitleSelector.d.ts +10 -0
- package/PageCalendar/TitleSelector.js +73 -0
- package/PageCalendar/ViewSelector.d.ts +8 -0
- package/PageCalendar/ViewSelector.js +52 -0
- package/PageCalendar/baseEventAttributes.d.ts +35 -0
- package/PageCalendar/baseEventAttributes.js +38 -0
- package/PageCalendar/context.d.ts +20 -0
- package/PageCalendar/context.js +5 -0
- package/PageCalendar/hooks/index.d.ts +1 -0
- package/PageCalendar/hooks/index.js +17 -0
- package/PageCalendar/hooks/useConfig.d.ts +3 -0
- package/PageCalendar/hooks/useConfig.js +8 -0
- package/PageCalendar/index.d.ts +1 -0
- package/PageCalendar/index.js +5 -0
- package/PageCalendar/renderEventContent.d.ts +2 -0
- package/PageCalendar/renderEventContent.js +22 -0
- package/PageCalendar/types.d.ts +5 -0
- package/PageCalendar/types.js +9 -0
- package/PageCalendar/utils.d.ts +3 -0
- package/PageCalendar/utils.js +17 -0
- package/components/BodyLoading.d.ts +1 -1
- package/components/BodyLoading.js +1 -0
- package/form/controls/DateControl.d.ts +1 -1
- package/form/controls/DateTimeControl.js +11 -3
- package/package.json +8 -2
- package/styles.css +49 -0
- package/types/index.d.ts +2 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DateSelectArg, EventClickArg, EventInput } from '@fullcalendar/core';
|
|
2
|
+
import { ViewType } from './types';
|
|
3
|
+
interface CalendarSectionProps {
|
|
4
|
+
startDate: Date | null;
|
|
5
|
+
endDate: Date | null;
|
|
6
|
+
viewType: ViewType;
|
|
7
|
+
onRangeChange?: (props: {
|
|
8
|
+
currentStart: Date;
|
|
9
|
+
currentEnd: Date;
|
|
10
|
+
activeStart: Date;
|
|
11
|
+
activeEnd: Date;
|
|
12
|
+
viewType: ViewType;
|
|
13
|
+
}) => void;
|
|
14
|
+
events: EventInput[];
|
|
15
|
+
onEventClick?: (event: EventClickArg) => void;
|
|
16
|
+
onDateSelect?: (event: DateSelectArg) => void;
|
|
17
|
+
loading?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const CalendarSection: ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, onEventClick, loading, }: Readonly<CalendarSectionProps>) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CalendarSection = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_components_1 = require("@fluentui/react-components");
|
|
9
|
+
const daygrid_1 = __importDefault(require("@fullcalendar/daygrid"));
|
|
10
|
+
const interaction_1 = __importDefault(require("@fullcalendar/interaction"));
|
|
11
|
+
const react_1 = __importDefault(require("@fullcalendar/react"));
|
|
12
|
+
const timegrid_1 = __importDefault(require("@fullcalendar/timegrid"));
|
|
13
|
+
const locale_1 = require("@headless-adminapp/app/locale");
|
|
14
|
+
const icons_1 = require("@headless-adminapp/icons");
|
|
15
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
16
|
+
const isoWeek_1 = __importDefault(require("dayjs/plugin/isoWeek"));
|
|
17
|
+
const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
|
|
18
|
+
const utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
19
|
+
const react_2 = require("react");
|
|
20
|
+
const BodyLoading_1 = require("../components/BodyLoading");
|
|
21
|
+
const renderEventContent_1 = require("./renderEventContent");
|
|
22
|
+
const TitleSelector_1 = require("./TitleSelector");
|
|
23
|
+
const types_1 = require("./types");
|
|
24
|
+
const ViewSelector_1 = require("./ViewSelector");
|
|
25
|
+
dayjs_1.default.extend(utc_1.default);
|
|
26
|
+
dayjs_1.default.extend(timezone_1.default);
|
|
27
|
+
dayjs_1.default.extend(isoWeek_1.default);
|
|
28
|
+
const CalendarSection = ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, onEventClick, loading, }) => {
|
|
29
|
+
const calendarRef = (0, react_2.useRef)(null);
|
|
30
|
+
const { timezone } = (0, locale_1.useLocale)();
|
|
31
|
+
const isToday = (0, react_2.useMemo)(() => {
|
|
32
|
+
if (!startDate || !endDate) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
let today = (0, dayjs_1.default)().tz(timezone);
|
|
36
|
+
if (viewType === types_1.ViewType.Month) {
|
|
37
|
+
today = today.startOf('month');
|
|
38
|
+
}
|
|
39
|
+
else if (viewType === types_1.ViewType.Week) {
|
|
40
|
+
today = today.startOf('isoWeek');
|
|
41
|
+
}
|
|
42
|
+
return (today.format('YYYY-MM-DD') ===
|
|
43
|
+
(0, dayjs_1.default)(startDate).tz(timezone).format('YYYY-MM-DD'));
|
|
44
|
+
}, [startDate, endDate, timezone, viewType]);
|
|
45
|
+
function handleDateRangeChange(props) {
|
|
46
|
+
const currentStart = props.view.currentStart;
|
|
47
|
+
const currentEnd = props.view.currentEnd;
|
|
48
|
+
const activeStart = props.view.activeStart;
|
|
49
|
+
const activeEnd = props.view.activeEnd;
|
|
50
|
+
switch (props.view.type) {
|
|
51
|
+
case types_1.ViewType.Month:
|
|
52
|
+
onRangeChange?.({
|
|
53
|
+
currentStart: currentStart, //dayjs(currentStart).tz(timezone).startOf('month').toDate(),
|
|
54
|
+
currentEnd: currentEnd, // dayjs(currentEnd).tz(timezone).endOf('month').toDate(),
|
|
55
|
+
activeStart: activeStart, // dayjs(activeStart).tz(timezone).startOf('day').toDate(),
|
|
56
|
+
activeEnd: activeEnd, // dayjs(activeEnd).tz(timezone).endOf('day').toDate(),
|
|
57
|
+
viewType: types_1.ViewType.Month,
|
|
58
|
+
});
|
|
59
|
+
break;
|
|
60
|
+
case types_1.ViewType.Week:
|
|
61
|
+
onRangeChange?.({
|
|
62
|
+
currentStart: (0, dayjs_1.default)(currentStart)
|
|
63
|
+
.tz(timezone)
|
|
64
|
+
.startOf('isoWeek')
|
|
65
|
+
.toDate(),
|
|
66
|
+
currentEnd: (0, dayjs_1.default)(currentEnd).tz(timezone).endOf('isoWeek').toDate(),
|
|
67
|
+
activeStart: (0, dayjs_1.default)(activeStart).tz(timezone).startOf('day').toDate(),
|
|
68
|
+
activeEnd: (0, dayjs_1.default)(activeEnd).tz(timezone).endOf('day').toDate(),
|
|
69
|
+
viewType: types_1.ViewType.Week,
|
|
70
|
+
});
|
|
71
|
+
break;
|
|
72
|
+
case types_1.ViewType.Day:
|
|
73
|
+
onRangeChange?.({
|
|
74
|
+
currentStart: (0, dayjs_1.default)(currentStart)
|
|
75
|
+
.tz(timezone)
|
|
76
|
+
.startOf('day')
|
|
77
|
+
.toDate(),
|
|
78
|
+
currentEnd: (0, dayjs_1.default)(currentEnd).tz(timezone).endOf('day').toDate(),
|
|
79
|
+
activeStart: (0, dayjs_1.default)(activeStart).tz(timezone).startOf('day').toDate(),
|
|
80
|
+
activeEnd: (0, dayjs_1.default)(activeEnd).tz(timezone).endOf('day').toDate(),
|
|
81
|
+
viewType: types_1.ViewType.Day,
|
|
82
|
+
});
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
87
|
+
display: 'flex',
|
|
88
|
+
flexDirection: 'column',
|
|
89
|
+
flex: 1,
|
|
90
|
+
position: 'relative',
|
|
91
|
+
background: react_components_1.tokens.colorNeutralBackground1,
|
|
92
|
+
padding: react_components_1.tokens.spacingHorizontalL,
|
|
93
|
+
borderRadius: react_components_1.tokens.borderRadiusMedium,
|
|
94
|
+
boxShadow: react_components_1.tokens.shadow2,
|
|
95
|
+
gap: react_components_1.tokens.spacingVerticalM,
|
|
96
|
+
}, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: react_components_1.tokens.spacingHorizontalS }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { flex: 1, display: 'flex', gap: react_components_1.tokens.spacingHorizontalS }, children: [(0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "outline", style: { fontWeight: react_components_1.tokens.fontWeightMedium }, icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Calendar, {}), onClick: () => calendarRef.current?.getApi().today(), disabled: isToday, children: "Today" }), (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.ChevronLeft, {}), onClick: () => calendarRef.current?.getApi().prev() }), (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.ChevronRight, {}), onClick: () => calendarRef.current?.getApi().next() })] }), (0, jsx_runtime_1.jsx)(TitleSelector_1.TitleSelector, { start: startDate, end: endDate, onChange: (start) => {
|
|
97
|
+
const api = calendarRef.current?.getApi();
|
|
98
|
+
if (!api) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
api.gotoDate(start);
|
|
102
|
+
}, viewType: viewType }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flex: 1, justifyContent: 'flex-end' }, children: (0, jsx_runtime_1.jsx)(ViewSelector_1.ViewSelector, { viewType: viewType, onChange: (viewType) => {
|
|
103
|
+
calendarRef.current?.getApi().changeView(viewType);
|
|
104
|
+
} }) })] }), (0, jsx_runtime_1.jsxs)("div", { style: { flex: 1, position: 'relative' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', inset: 0 }, children: (0, jsx_runtime_1.jsx)(react_1.default, { ref: calendarRef, plugins: [daygrid_1.default, timegrid_1.default, interaction_1.default], initialView: types_1.ViewType.Month, weekends: true, firstDay: 1, events: events, datesSet: handleDateRangeChange, select: onDateSelect, eventClick: onEventClick, eventContent: renderEventContent_1.renderEventContent, timeZone: timezone, height: "100%", editable: false, selectable: true, selectMirror: true, dayMaxEvents: true, eventMinHeight: 24, eventTimeFormat: (props) => {
|
|
105
|
+
return (0, dayjs_1.default)(props.start.marker).tz(timezone).format('hh:mm A');
|
|
106
|
+
}, headerToolbar: false }) }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: loading })] })] }));
|
|
107
|
+
};
|
|
108
|
+
exports.CalendarSection = CalendarSection;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Attribute } from '@headless-adminapp/core';
|
|
2
|
+
import { Path, UseFormReturn } from 'react-hook-form';
|
|
3
|
+
import { BaseFieldValues } from './types';
|
|
4
|
+
interface AttributeControllerProps {
|
|
5
|
+
attribute: Attribute;
|
|
6
|
+
attributeName: Path<BaseFieldValues>;
|
|
7
|
+
form: UseFormReturn<BaseFieldValues>;
|
|
8
|
+
}
|
|
9
|
+
export declare function AttributeController({ attribute, attributeName, form, }: Readonly<AttributeControllerProps>): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AttributeController = AttributeController;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_hook_form_1 = require("react-hook-form");
|
|
6
|
+
const SectionControl_1 = require("../../DataForm/SectionControl");
|
|
7
|
+
const StandardControl_1 = require("../../PageEntityForm/StandardControl");
|
|
8
|
+
function AttributeController({ attribute, attributeName, form, }) {
|
|
9
|
+
return ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: form.control, name: attributeName, render: ({ field, fieldState, formState }) => {
|
|
10
|
+
const isError = (fieldState.isTouched || formState.isSubmitted) &&
|
|
11
|
+
!!fieldState.error?.message;
|
|
12
|
+
const errorMessage = fieldState.isTouched || formState.isSubmitted
|
|
13
|
+
? fieldState.error?.message
|
|
14
|
+
: '';
|
|
15
|
+
return ((0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelPosition: "left", required: attribute.required, isError: isError, errorMessage: errorMessage, children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur, errorMessage: errorMessage, isError: isError, readOnly: attribute.readonly }) }));
|
|
16
|
+
} }));
|
|
17
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseEventAttributes } from '@headless-adminapp/app/calendar/baseEventAttributes';
|
|
2
|
+
import { CalendarConfig, CalendarEventResolverFn } from '@headless-adminapp/app/calendar/types';
|
|
3
|
+
import { InferredSchemaType, SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
4
|
+
import { Nullable } from '@headless-adminapp/core/types';
|
|
5
|
+
export declare function defineEventAttributes<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes>(beforeDescriptionAttributes?: SA1, afterDescriptionAttributes?: SA2): BaseEventAttributes & SA1 & SA2;
|
|
6
|
+
interface EventDialogProps<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes> {
|
|
7
|
+
isOpen: boolean;
|
|
8
|
+
title?: string;
|
|
9
|
+
beforeDescriptionAttributes?: SA1;
|
|
10
|
+
afterDescriptionAttributes?: SA2;
|
|
11
|
+
values: Partial<Nullable<InferredSchemaType<BaseEventAttributes>>>;
|
|
12
|
+
onSubmit?: (data: {
|
|
13
|
+
modifiedValues: Partial<Nullable<InferredSchemaType<BaseEventAttributes>>>;
|
|
14
|
+
values: Nullable<InferredSchemaType<BaseEventAttributes>>;
|
|
15
|
+
}) => Promise<void>;
|
|
16
|
+
onCancel?: () => void;
|
|
17
|
+
onDismiss?: () => void;
|
|
18
|
+
allowOpenRecord?: boolean;
|
|
19
|
+
onOpenRecord?: (id: string) => void;
|
|
20
|
+
onDelete?: (id: string) => void;
|
|
21
|
+
eventResolver?: CalendarEventResolverFn;
|
|
22
|
+
config: CalendarConfig;
|
|
23
|
+
}
|
|
24
|
+
export declare function EventDialog<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes>(props: Readonly<EventDialogProps<SA1, SA2>>): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineEventAttributes = defineEventAttributes;
|
|
4
|
+
exports.EventDialog = EventDialog;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_components_1 = require("@fluentui/react-components");
|
|
7
|
+
const baseEventAttributes_1 = require("@headless-adminapp/app/calendar/baseEventAttributes");
|
|
8
|
+
const utils_1 = require("@headless-adminapp/core/schema/utils");
|
|
9
|
+
const EventFormBody_1 = require("./EventFormBody");
|
|
10
|
+
function defineEventAttributes(beforeDescriptionAttributes, afterDescriptionAttributes) {
|
|
11
|
+
return (0, utils_1.defineSchemaAttributes)({
|
|
12
|
+
...baseEventAttributes_1.baseEventAttributes,
|
|
13
|
+
...beforeDescriptionAttributes,
|
|
14
|
+
...afterDescriptionAttributes,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function EventDialog(props) {
|
|
18
|
+
return ((0, jsx_runtime_1.jsx)(react_components_1.Dialog, { open: props.isOpen, onOpenChange: () => {
|
|
19
|
+
props.onDismiss?.();
|
|
20
|
+
}, children: (0, jsx_runtime_1.jsx)(react_components_1.DialogSurface, { style: { maxWidth: 480 }, children: (0, jsx_runtime_1.jsx)(EventFormBody_1.EventFormBody, { values: props.values, config: props.config, onCancel: props.onCancel, onSubmit: props.onSubmit, allowOpenRecord: props.allowOpenRecord, onOpenRecord: props.onOpenRecord, onDelete: props.onDelete }) }) }));
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseEventAttributes } from '@headless-adminapp/app/calendar/baseEventAttributes';
|
|
2
|
+
import { CalendarConfig } from '@headless-adminapp/app/calendar/types';
|
|
3
|
+
import { InferredSchemaType, SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
4
|
+
import { Nullable } from '@headless-adminapp/core/types';
|
|
5
|
+
interface EventFormBodyProps<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes> {
|
|
6
|
+
values: Partial<Nullable<InferredSchemaType<BaseEventAttributes> & InferredSchemaType<SA1> & InferredSchemaType<SA2>>>;
|
|
7
|
+
onSubmit?: (data: {
|
|
8
|
+
modifiedValues: Partial<Nullable<InferredSchemaType<BaseEventAttributes>>>;
|
|
9
|
+
values: Nullable<InferredSchemaType<BaseEventAttributes>>;
|
|
10
|
+
}) => Promise<void>;
|
|
11
|
+
onCancel?: () => void;
|
|
12
|
+
allowOpenRecord?: boolean;
|
|
13
|
+
onOpenRecord?: (id: string) => void;
|
|
14
|
+
onDelete?: (id: string) => void;
|
|
15
|
+
config: CalendarConfig;
|
|
16
|
+
}
|
|
17
|
+
export declare function EventFormBody(props: Readonly<EventFormBodyProps>): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventFormBody = EventFormBody;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_components_1 = require("@fluentui/react-components");
|
|
6
|
+
const baseEventAttributes_1 = require("@headless-adminapp/app/calendar/baseEventAttributes");
|
|
7
|
+
const saveRecord_1 = require("@headless-adminapp/app/dataform/utils/saveRecord");
|
|
8
|
+
const form_1 = require("@headless-adminapp/app/form");
|
|
9
|
+
const locale_1 = require("@headless-adminapp/app/locale");
|
|
10
|
+
const icons_fluent_1 = require("@headless-adminapp/icons-fluent");
|
|
11
|
+
const react_query_1 = require("@tanstack/react-query");
|
|
12
|
+
const react_1 = require("react");
|
|
13
|
+
const react_hook_form_1 = require("react-hook-form");
|
|
14
|
+
const BodyLoading_1 = require("../../components/BodyLoading");
|
|
15
|
+
const EventFormContent_1 = require("./EventFormContent");
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
function EventFormBody(props) {
|
|
18
|
+
const { language, region } = (0, locale_1.useLocale)();
|
|
19
|
+
const formValidationStrings = (0, form_1.useFormValidationStrings)();
|
|
20
|
+
const { data: record, isPending } = (0, react_query_1.useQuery)({
|
|
21
|
+
queryKey: ['calendar-events', 'event', props.values.id],
|
|
22
|
+
queryFn: async () => {
|
|
23
|
+
if (props.values.id && props.config.eventResolver) {
|
|
24
|
+
return props.config.eventResolver(props.values.id);
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
const form = (0, react_hook_form_1.useForm)({
|
|
30
|
+
mode: 'all',
|
|
31
|
+
defaultValues: props.values,
|
|
32
|
+
shouldUnregister: false,
|
|
33
|
+
resolver: (0, utils_1.formValidator)({
|
|
34
|
+
attributes: baseEventAttributes_1.baseEventAttributes,
|
|
35
|
+
language,
|
|
36
|
+
strings: formValidationStrings,
|
|
37
|
+
region,
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
const formRef = (0, react_1.useRef)(form);
|
|
41
|
+
formRef.current = form;
|
|
42
|
+
const defaultValues = (0, react_1.useMemo)(() => {
|
|
43
|
+
return {
|
|
44
|
+
...props.values,
|
|
45
|
+
...record,
|
|
46
|
+
id: props.values.id,
|
|
47
|
+
title: props.values.title,
|
|
48
|
+
description: props.values.description,
|
|
49
|
+
start: props.values.start,
|
|
50
|
+
end: props.values.end,
|
|
51
|
+
allDay: props.values.allDay,
|
|
52
|
+
};
|
|
53
|
+
}, [record, props.values]);
|
|
54
|
+
(0, react_1.useEffect)(() => {
|
|
55
|
+
formRef.current.reset(defaultValues);
|
|
56
|
+
}, [defaultValues]);
|
|
57
|
+
return ((0, jsx_runtime_1.jsxs)(react_components_1.DialogBody, { children: [(0, jsx_runtime_1.jsxs)(react_components_1.DialogTitle, { action: props.values.id ? ((0, jsx_runtime_1.jsxs)(react_components_1.Menu, { positioning: "below-end", children: [(0, jsx_runtime_1.jsx)(react_components_1.MenuTrigger, { children: (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", "aria-label": "close", icon: (0, jsx_runtime_1.jsx)(icons_fluent_1.iconSet.MoreVertical, {}) }) }), (0, jsx_runtime_1.jsx)(react_components_1.MenuPopover, { children: (0, jsx_runtime_1.jsxs)(react_components_1.MenuList, { children: [props.allowOpenRecord && ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: (0, jsx_runtime_1.jsx)(icons_fluent_1.iconSet.OpenInNew, { size: 20 }), onClick: () => props.onOpenRecord?.(props.values.id), children: "Open" })), (0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: (0, jsx_runtime_1.jsx)(icons_fluent_1.iconSet.Delete, { size: 20 }), onClick: () => props.onDelete?.(props.values.id), children: "Delete" })] }) })] })) : null, children: [props.values.id ? 'Edit' : 'New', ' ', props.config.eventLabel.toLowerCase()] }), (0, jsx_runtime_1.jsx)(EventFormContent_1.EventFormContent, { form: form, afterDescriptionAttributes: props.config.afterDescriptionAttributes, beforeDescriptionAttributes: props.config.beforeDescriptionAttributes }), (0, jsx_runtime_1.jsxs)(react_components_1.DialogActions, { children: [(0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "primary", disabled: form.formState.submitCount > 0 && !form.formState.isValid, onClick: async () => {
|
|
58
|
+
await form.handleSubmit(async (values) => {
|
|
59
|
+
await props.onSubmit?.({
|
|
60
|
+
modifiedValues: values.id
|
|
61
|
+
? (0, saveRecord_1.getModifiedValues)(defaultValues, values)
|
|
62
|
+
: values,
|
|
63
|
+
values,
|
|
64
|
+
});
|
|
65
|
+
})();
|
|
66
|
+
}, children: props.values.id ? 'Save' : 'Create' }), (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "secondary", type: "button", onClick: () => {
|
|
67
|
+
props.onCancel?.();
|
|
68
|
+
}, children: props.values.id ? 'Close' : 'Cancel' })] }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: isPending })] }));
|
|
69
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
2
|
+
import { UseFormReturn } from 'react-hook-form';
|
|
3
|
+
import { BaseFieldValues } from './types';
|
|
4
|
+
interface EventFormContentProps<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes> {
|
|
5
|
+
form: UseFormReturn<BaseFieldValues>;
|
|
6
|
+
beforeDescriptionAttributes?: SA1;
|
|
7
|
+
afterDescriptionAttributes?: SA2;
|
|
8
|
+
}
|
|
9
|
+
export declare function EventFormContent<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes>({ form, afterDescriptionAttributes, beforeDescriptionAttributes, }: Readonly<EventFormContentProps<SA1, SA2>>): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventFormContent = EventFormContent;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_components_1 = require("@fluentui/react-components");
|
|
6
|
+
const baseEventAttributes_1 = require("@headless-adminapp/app/calendar/baseEventAttributes");
|
|
7
|
+
const AttributeController_1 = require("./AttributeController");
|
|
8
|
+
function EventFormContent({ form, afterDescriptionAttributes, beforeDescriptionAttributes, }) {
|
|
9
|
+
const allDay = form.watch('allDay');
|
|
10
|
+
return ((0, jsx_runtime_1.jsx)(react_components_1.DialogContent, { children: (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
11
|
+
display: 'flex',
|
|
12
|
+
flexDirection: 'column',
|
|
13
|
+
gap: react_components_1.tokens.spacingVerticalM,
|
|
14
|
+
marginTop: react_components_1.tokens.spacingVerticalL,
|
|
15
|
+
marginBottom: react_components_1.tokens.spacingVerticalL,
|
|
16
|
+
}, children: [(0, jsx_runtime_1.jsx)(AttributeController_1.AttributeController, { form: form, attributeName: "title", attribute: baseEventAttributes_1.baseEventAttributes.title }), (0, jsx_runtime_1.jsx)(AttributeController_1.AttributeController, { form: form, attributeName: "start", attribute: {
|
|
17
|
+
...baseEventAttributes_1.baseEventAttributes.start,
|
|
18
|
+
...(allDay ? { format: 'date' } : { format: 'datetime' }),
|
|
19
|
+
} }), (0, jsx_runtime_1.jsx)(AttributeController_1.AttributeController, { form: form, attributeName: "end", attribute: {
|
|
20
|
+
...baseEventAttributes_1.baseEventAttributes.end,
|
|
21
|
+
...(allDay ? { format: 'date' } : { format: 'datetime' }),
|
|
22
|
+
} }), (0, jsx_runtime_1.jsx)(AttributeController_1.AttributeController, { form: form, attributeName: "allDay", attribute: baseEventAttributes_1.baseEventAttributes.allDay }), Object.entries(beforeDescriptionAttributes ?? {}).map(([attributeName, attribute]) => {
|
|
23
|
+
return ((0, jsx_runtime_1.jsx)(AttributeController_1.AttributeController, { form: form, attributeName: attributeName, attribute: attribute }, attributeName));
|
|
24
|
+
}), (0, jsx_runtime_1.jsx)(AttributeController_1.AttributeController, { form: form, attributeName: "description", attribute: baseEventAttributes_1.baseEventAttributes.description }), Object.entries(afterDescriptionAttributes ?? {}).map(([attributeName, attribute]) => {
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)(AttributeController_1.AttributeController, { form: form, attributeName: attributeName, attribute: attribute }, attributeName));
|
|
26
|
+
})] }) }));
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FormValidationStringSet } from '@headless-adminapp/app/form';
|
|
2
|
+
import { SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
3
|
+
import * as yup from 'yup';
|
|
4
|
+
export declare const formValidator: (<A extends SchemaAttributes = SchemaAttributes>({ attributes, language, strings, region, }: {
|
|
5
|
+
attributes: A;
|
|
6
|
+
language: string;
|
|
7
|
+
strings: FormValidationStringSet;
|
|
8
|
+
region: string;
|
|
9
|
+
}) => (values: Record<string, any>, context: any, options: any) => Promise<import("react-hook-form").ResolverResult<{
|
|
10
|
+
[x: string]: any;
|
|
11
|
+
[x: number]: any;
|
|
12
|
+
[x: symbol]: any;
|
|
13
|
+
}>>) & import("lodash").MemoizedFunction;
|
|
14
|
+
export declare const generateValidationSchema: (<A extends SchemaAttributes = SchemaAttributes>({ attributes, language, strings, region, }: {
|
|
15
|
+
attributes: A;
|
|
16
|
+
language: string;
|
|
17
|
+
strings: FormValidationStringSet;
|
|
18
|
+
region: string;
|
|
19
|
+
}) => yup.ObjectSchema<{
|
|
20
|
+
[x: string]: any;
|
|
21
|
+
}, yup.AnyObject, {
|
|
22
|
+
[x: string]: any;
|
|
23
|
+
}, "">) & import("lodash").MemoizedFunction;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.generateValidationSchema = exports.formValidator = void 0;
|
|
27
|
+
const utils_1 = require("@headless-adminapp/app/dataform/utils");
|
|
28
|
+
const yup_1 = require("@hookform/resolvers/yup");
|
|
29
|
+
const lodash_1 = require("lodash");
|
|
30
|
+
const yup = __importStar(require("yup"));
|
|
31
|
+
// TODO: refactor duplicate code
|
|
32
|
+
exports.formValidator = (0, lodash_1.memoize)(function formValidator({ attributes, language, strings, region, }) {
|
|
33
|
+
return async (values, context, options) => {
|
|
34
|
+
const validator = (0, exports.generateValidationSchema)({
|
|
35
|
+
attributes,
|
|
36
|
+
language,
|
|
37
|
+
strings,
|
|
38
|
+
region,
|
|
39
|
+
});
|
|
40
|
+
const resolver = (0, yup_1.yupResolver)(validator);
|
|
41
|
+
const result = await resolver(values, context, options);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
}, (options) => JSON.stringify(options));
|
|
45
|
+
exports.generateValidationSchema = (0, lodash_1.memoize)(function generateValidationSchema({ attributes, language, strings, region, }) {
|
|
46
|
+
const columns = Object.keys(attributes);
|
|
47
|
+
return yup.object().shape({
|
|
48
|
+
...columns.reduce((acc, column) => {
|
|
49
|
+
const attribute = attributes[column];
|
|
50
|
+
const validationSchema = (0, utils_1.generateAttributeValidationSchema)(attribute, language, strings, region);
|
|
51
|
+
return {
|
|
52
|
+
...acc,
|
|
53
|
+
[column]: validationSchema,
|
|
54
|
+
};
|
|
55
|
+
}, {}),
|
|
56
|
+
});
|
|
57
|
+
}, (options) => JSON.stringify(options));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { InferredSchemaType, SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
2
|
+
import { UseFormReturn } from 'react-hook-form';
|
|
3
|
+
interface HeaderProps<SA extends SchemaAttributes = SchemaAttributes> {
|
|
4
|
+
filterForm: UseFormReturn<InferredSchemaType<SA>, unknown, undefined>;
|
|
5
|
+
onCreateButtonClick: () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function Header<SA extends SchemaAttributes = SchemaAttributes>({ filterForm, onCreateButtonClick, }: Readonly<HeaderProps<SA>>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Header = Header;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_components_1 = require("@fluentui/react-components");
|
|
6
|
+
const useConfig_1 = require("@headless-adminapp/app/calendar/hooks/useConfig");
|
|
7
|
+
const icons_fluent_1 = require("@headless-adminapp/icons-fluent");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const react_hook_form_1 = require("react-hook-form");
|
|
10
|
+
const StandardControl_1 = require("../PageEntityForm/StandardControl");
|
|
11
|
+
function Header({ filterForm, onCreateButtonClick, }) {
|
|
12
|
+
const config = (0, useConfig_1.useConfig)();
|
|
13
|
+
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
14
|
+
display: 'flex',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
background: react_components_1.tokens.colorNeutralBackground1,
|
|
17
|
+
borderRadius: react_components_1.tokens.borderRadiusLarge,
|
|
18
|
+
paddingBlock: react_components_1.tokens.spacingVerticalS,
|
|
19
|
+
paddingInline: react_components_1.tokens.spacingHorizontalM,
|
|
20
|
+
gap: react_components_1.tokens.spacingVerticalS,
|
|
21
|
+
boxShadow: react_components_1.tokens.shadow2,
|
|
22
|
+
}, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
|
|
23
|
+
display: 'flex',
|
|
24
|
+
alignItems: 'center',
|
|
25
|
+
gap: react_components_1.tokens.spacingHorizontalM,
|
|
26
|
+
}, children: [(0, jsx_runtime_1.jsx)("div", { style: { flex: 1 }, children: (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsx)(react_components_1.Subtitle2, { style: { color: react_components_1.tokens.colorNeutralForeground1 }, children: config.title }), (0, jsx_runtime_1.jsx)(react_components_1.Caption1, { style: { color: react_components_1.tokens.colorNeutralForeground2 }, children: config.description })] }) }) }), (0, jsx_runtime_1.jsx)("div", { style: {
|
|
27
|
+
display: 'flex',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
gap: react_components_1.tokens.spacingHorizontalS,
|
|
30
|
+
}, children: (0, jsx_runtime_1.jsx)(react_components_1.Button, { style: { fontWeight: react_components_1.tokens.fontWeightMedium }, icon: (0, jsx_runtime_1.jsx)(icons_fluent_1.iconSet.Add, {}), appearance: "primary", onClick: onCreateButtonClick, children: "Create" }) })] }), !!config.filterAttributes && ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: react_components_1.tokens.spacingHorizontalS }, children: Object.entries(config.filterAttributes).map(([attributeName, attribute]) => {
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: filterForm.control, name: attributeName, render: ({ field }) => {
|
|
32
|
+
return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: attributeName, value: field.value, onChange: field.onChange, onBlur: field.onBlur }) }));
|
|
33
|
+
} }, attributeName));
|
|
34
|
+
}) })] }))] }));
|
|
35
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CalendarConfig } from '@headless-adminapp/app/calendar/types';
|
|
2
|
+
import { SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
3
|
+
interface PageCalendarProps<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes, SA3 extends SchemaAttributes = SchemaAttributes> {
|
|
4
|
+
config: CalendarConfig<SA1, SA2, SA3>;
|
|
5
|
+
}
|
|
6
|
+
export declare function PageCalendar<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes, SA3 extends SchemaAttributes = SchemaAttributes>(props: Readonly<PageCalendarProps<SA1, SA2, SA3>>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|