@headless-adminapp/fluent 1.2.1 → 1.2.2
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 +3 -1
- package/PageCalendar/CalendarSection.js +10 -4
- package/PageCalendar/PageCalendar.d.ts +3 -0
- package/PageCalendar/PageCalendar.js +1 -1
- package/PageCalendar/PageCalendarUI.d.ts +7 -1
- package/PageCalendar/PageCalendarUI.js +58 -3
- package/PageCalendar/renderEventContent.js +26 -19
- package/package.json +3 -2
|
@@ -14,6 +14,8 @@ interface CalendarSectionProps {
|
|
|
14
14
|
events: EventInput[];
|
|
15
15
|
onDateSelect?: (event: DateSelectArg) => void;
|
|
16
16
|
loading?: boolean;
|
|
17
|
+
selectable?: boolean;
|
|
18
|
+
initialDate?: Date;
|
|
17
19
|
}
|
|
18
|
-
export declare const CalendarSection: ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, loading, }: Readonly<CalendarSectionProps>) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export declare const CalendarSection: ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, loading, selectable, initialDate, }: Readonly<CalendarSectionProps>) => import("react/jsx-runtime").JSX.Element;
|
|
19
21
|
export {};
|
|
@@ -8,6 +8,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
8
8
|
const react_components_1 = require("@fluentui/react-components");
|
|
9
9
|
const daygrid_1 = __importDefault(require("@fullcalendar/daygrid"));
|
|
10
10
|
const interaction_1 = __importDefault(require("@fullcalendar/interaction"));
|
|
11
|
+
const moment_timezone_1 = __importDefault(require("@fullcalendar/moment-timezone"));
|
|
11
12
|
const react_1 = __importDefault(require("@fullcalendar/react"));
|
|
12
13
|
const timegrid_1 = __importDefault(require("@fullcalendar/timegrid"));
|
|
13
14
|
const hooks_1 = require("@headless-adminapp/app/hooks");
|
|
@@ -26,9 +27,9 @@ const ViewSelector_1 = require("./ViewSelector");
|
|
|
26
27
|
dayjs_1.default.extend(utc_1.default);
|
|
27
28
|
dayjs_1.default.extend(timezone_1.default);
|
|
28
29
|
dayjs_1.default.extend(isoWeek_1.default);
|
|
29
|
-
const CalendarSection = ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, loading, }) => {
|
|
30
|
+
const CalendarSection = ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, loading, selectable, initialDate, }) => {
|
|
30
31
|
const calendarRef = (0, react_2.useRef)(null);
|
|
31
|
-
const { timezone } = (0, locale_1.useLocale)();
|
|
32
|
+
const { timezone, timeFormats } = (0, locale_1.useLocale)();
|
|
32
33
|
const isMobile = (0, hooks_1.useIsMobile)();
|
|
33
34
|
const isToday = (0, react_2.useMemo)(() => {
|
|
34
35
|
if (!startDate || !endDate) {
|
|
@@ -130,8 +131,13 @@ const CalendarSection = ({ startDate, endDate, viewType, onRangeChange, events,
|
|
|
130
131
|
}, children: (0, jsx_runtime_1.jsx)(ViewSelector_1.ViewSelector, { viewType: viewType, onChange: (viewType) => {
|
|
131
132
|
calendarRef.current?.getApi().changeView(viewType);
|
|
132
133
|
calendarRef.current?.getApi().scrollToTime(initialScrollTime);
|
|
133
|
-
} }) })] }), (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: [
|
|
134
|
-
|
|
134
|
+
} }) })] }), (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: [
|
|
135
|
+
daygrid_1.default,
|
|
136
|
+
timegrid_1.default,
|
|
137
|
+
interaction_1.default,
|
|
138
|
+
moment_timezone_1.default,
|
|
139
|
+
], initialView: viewType, initialDate: initialDate, weekends: true, firstDay: 1, events: events, datesSet: handleDateRangeChange, select: onDateSelect, eventContent: renderEventContent_1.renderEventContent, timeZone: timezone, height: "100%", nowIndicator: true, scrollTime: initialScrollTime, scrollTimeReset: false, editable: false, selectable: selectable, selectMirror: true, dayMaxEvents: true, eventMinHeight: 24, eventTimeFormat: (props) => {
|
|
140
|
+
return (0, dayjs_1.default)(new Date(props.start.year, props.start.month, props.start.day, props.start.hour, props.start.minute)).format(timeFormats.short);
|
|
135
141
|
}, headerToolbar: false }) }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: loading })] })] }));
|
|
136
142
|
};
|
|
137
143
|
exports.CalendarSection = CalendarSection;
|
|
@@ -2,6 +2,9 @@ import { CalendarConfig } from '@headless-adminapp/app/calendar/types';
|
|
|
2
2
|
import { SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
3
3
|
interface PageCalendarProps<SA1 extends SchemaAttributes = SchemaAttributes, SA2 extends SchemaAttributes = SchemaAttributes, SA3 extends SchemaAttributes = SchemaAttributes> {
|
|
4
4
|
config: CalendarConfig<SA1, SA2, SA3>;
|
|
5
|
+
initialView?: string;
|
|
6
|
+
initialDate?: string;
|
|
7
|
+
onChange?: (view: string, date: string) => void;
|
|
5
8
|
}
|
|
6
9
|
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
10
|
export {};
|
|
@@ -16,5 +16,5 @@ function PageCalendar(props) {
|
|
|
16
16
|
});
|
|
17
17
|
}, [contextValue, props.config]);
|
|
18
18
|
const config = props.config;
|
|
19
|
-
return ((0, jsx_runtime_1.jsx)(CalendarProvider_1.CalendarProvider, { config: config, children: (0, jsx_runtime_1.jsx)(PageCalendarUI_1.PageCalendarUI, {}) }));
|
|
19
|
+
return ((0, jsx_runtime_1.jsx)(CalendarProvider_1.CalendarProvider, { config: config, children: (0, jsx_runtime_1.jsx)(PageCalendarUI_1.PageCalendarUI, { initialView: props.initialView, initialDate: props.initialDate, onChange: props.onChange }) }));
|
|
20
20
|
}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import { SchemaAttributes } from '@headless-adminapp/core/schema';
|
|
2
|
-
|
|
2
|
+
interface PageCalendarUIProps {
|
|
3
|
+
initialView?: string;
|
|
4
|
+
initialDate?: string;
|
|
5
|
+
onChange?: (view: string, date: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function PageCalendarUI<SA3 extends SchemaAttributes = SchemaAttributes>(props: Readonly<PageCalendarUIProps>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -33,6 +33,7 @@ const auth_1 = require("@headless-adminapp/app/auth");
|
|
|
33
33
|
const hooks_1 = require("@headless-adminapp/app/calendar/hooks");
|
|
34
34
|
const useOpenDetailDialog_1 = require("@headless-adminapp/app/calendar/hooks/useOpenDetailDialog");
|
|
35
35
|
const hooks_2 = require("@headless-adminapp/app/hooks");
|
|
36
|
+
const locale_1 = require("@headless-adminapp/app/locale");
|
|
36
37
|
const navigation_1 = require("@headless-adminapp/app/navigation");
|
|
37
38
|
const route_1 = require("@headless-adminapp/app/route");
|
|
38
39
|
const toast_notification_1 = require("@headless-adminapp/app/toast-notification");
|
|
@@ -51,15 +52,50 @@ const CalendarSection = (0, react_1.lazy)(() => Promise.resolve().then(() => __i
|
|
|
51
52
|
dayjs_1.default.extend(utc_1.default);
|
|
52
53
|
dayjs_1.default.extend(timezone_1.default);
|
|
53
54
|
dayjs_1.default.extend(isoWeek_1.default);
|
|
54
|
-
function
|
|
55
|
+
function strToViewType(view) {
|
|
56
|
+
switch (view) {
|
|
57
|
+
case 'month':
|
|
58
|
+
case types_1.ViewType.Month:
|
|
59
|
+
return types_1.ViewType.Month;
|
|
60
|
+
case 'week':
|
|
61
|
+
case types_1.ViewType.Week:
|
|
62
|
+
return types_1.ViewType.Week;
|
|
63
|
+
case 'day':
|
|
64
|
+
case types_1.ViewType.Day:
|
|
65
|
+
return types_1.ViewType.Day;
|
|
66
|
+
default:
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function viewTypeToStr(view) {
|
|
71
|
+
switch (view) {
|
|
72
|
+
case types_1.ViewType.Month:
|
|
73
|
+
return 'month';
|
|
74
|
+
case types_1.ViewType.Week:
|
|
75
|
+
return 'week';
|
|
76
|
+
case types_1.ViewType.Day:
|
|
77
|
+
return 'day';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function getInitialView(isMobile, initialView) {
|
|
81
|
+
if (initialView) {
|
|
82
|
+
const _view = strToViewType(initialView);
|
|
83
|
+
if (_view) {
|
|
84
|
+
return _view;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return isMobile ? types_1.ViewType.Day : types_1.ViewType.Month;
|
|
88
|
+
}
|
|
89
|
+
function PageCalendarUI(props) {
|
|
55
90
|
const config = (0, hooks_1.useConfig)();
|
|
56
91
|
const openToastNotification = (0, toast_notification_1.useOpenToastNotification)();
|
|
57
92
|
const isMobile = (0, hooks_2.useIsMobile)();
|
|
93
|
+
const { timezone } = (0, locale_1.useLocale)();
|
|
58
94
|
const [activeStartDate, setActiveStartDate] = (0, react_1.useState)(null);
|
|
59
95
|
const [activeEndDate, setActiveEndDate] = (0, react_1.useState)(null);
|
|
60
96
|
const [currentStartDate, setCurrentStartDate] = (0, react_1.useState)(null);
|
|
61
97
|
const [currentEndDate, setCurrentEndDate] = (0, react_1.useState)(null);
|
|
62
|
-
const [viewType, setViewType] = (0, react_1.useState)(isMobile
|
|
98
|
+
const [viewType, setViewType] = (0, react_1.useState)(getInitialView(isMobile, props.initialView));
|
|
63
99
|
const filterForm = (0, react_hook_form_1.useForm)({
|
|
64
100
|
mode: 'all',
|
|
65
101
|
defaultValues: config.defaultFilter,
|
|
@@ -100,10 +136,28 @@ function PageCalendarUI() {
|
|
|
100
136
|
},
|
|
101
137
|
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
102
138
|
});
|
|
139
|
+
const initialDate = (0, react_1.useMemo)(() => {
|
|
140
|
+
if (!props.initialDate) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
return (0, dayjs_1.default)(props.initialDate).tz(timezone, true).toDate();
|
|
144
|
+
}, [props.initialDate, timezone]);
|
|
103
145
|
const openEventDetailModel = (0, useOpenDetailDialog_1.useOpenDetailDialog)(EventDialog_1.EventDialog);
|
|
104
146
|
const router = (0, route_1.useRouter)();
|
|
105
147
|
const routeResolver = (0, route_1.useRouteResolver)();
|
|
106
148
|
const openForm = (0, navigation_1.useOpenForm)();
|
|
149
|
+
const selectable = (0, react_1.useMemo)(() => {
|
|
150
|
+
if (!config.createOptions) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (config.createOptions.mode === 'dialog') {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
if (config.createOptions.mode === 'custom') {
|
|
157
|
+
return config.createOptions.allowQuickCreate ?? false;
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
}, [config.createOptions]);
|
|
107
161
|
const handleNewRecord = (values) => {
|
|
108
162
|
if (!config.createOptions) {
|
|
109
163
|
return;
|
|
@@ -157,6 +211,7 @@ function PageCalendarUI() {
|
|
|
157
211
|
setActiveStartDate(activeStart);
|
|
158
212
|
setActiveEndDate(activeEnd);
|
|
159
213
|
setViewType(viewType);
|
|
214
|
+
props.onChange?.(viewTypeToStr(viewType), (0, dayjs_1.default)(currentStart).tz(timezone).format('YYYY-MM-DD'));
|
|
160
215
|
};
|
|
161
216
|
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
162
217
|
display: 'flex',
|
|
@@ -165,5 +220,5 @@ function PageCalendarUI() {
|
|
|
165
220
|
gap: react_components_1.tokens.spacingVerticalM,
|
|
166
221
|
padding: react_components_1.tokens.spacingHorizontalM,
|
|
167
222
|
background: react_components_1.tokens.colorNeutralBackground2,
|
|
168
|
-
}, children: [(0, jsx_runtime_1.jsx)(Header_1.Header, { filterForm: filterForm, onCreateButtonClick: handleCreateButtonClick }), (0, jsx_runtime_1.jsx)(react_1.Suspense, { children: (0, jsx_runtime_1.jsx)(CalendarSection, { startDate: currentStartDate, endDate: currentEndDate, viewType: viewType, onRangeChange: onRangeChange, events: events ?? [], onDateSelect: handleDateSelect, loading: loading }) })] }));
|
|
223
|
+
}, children: [(0, jsx_runtime_1.jsx)(Header_1.Header, { filterForm: filterForm, onCreateButtonClick: handleCreateButtonClick }), (0, jsx_runtime_1.jsx)(react_1.Suspense, { children: (0, jsx_runtime_1.jsx)(CalendarSection, { startDate: currentStartDate, endDate: currentEndDate, viewType: viewType, onRangeChange: onRangeChange, events: events ?? [], onDateSelect: handleDateSelect, loading: loading, selectable: selectable, initialDate: initialDate }) })] }));
|
|
169
224
|
}
|
|
@@ -14,32 +14,35 @@ const navigation_1 = require("@headless-adminapp/app/navigation");
|
|
|
14
14
|
const route_1 = require("@headless-adminapp/app/route");
|
|
15
15
|
const icons_1 = require("@headless-adminapp/icons");
|
|
16
16
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
17
|
+
const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
|
|
18
|
+
const utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
17
19
|
const react_1 = require("react");
|
|
18
20
|
const EventDialog_1 = require("./EventDialog/EventDialog");
|
|
21
|
+
dayjs_1.default.extend(utc_1.default);
|
|
22
|
+
dayjs_1.default.extend(timezone_1.default);
|
|
19
23
|
function renderEventContent(eventInfo) {
|
|
20
24
|
return (0, jsx_runtime_1.jsx)(EventContent, { eventInfo: eventInfo });
|
|
21
25
|
}
|
|
22
26
|
const EventContent = ({ eventInfo }) => {
|
|
23
27
|
const [open, setOpen] = (0, react_1.useState)(false);
|
|
24
|
-
return ((0, jsx_runtime_1.jsxs)(react_components_1.Popover, { positioning: "after", withArrow: true, open: open, onOpenChange: (e, data) => setOpen(data.open), children: [(0, jsx_runtime_1.jsx)(react_components_1.PopoverTrigger, { children: (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}, children: [eventInfo.timeText && (0, jsx_runtime_1.jsx)("span", { children: eventInfo.timeText }), (0, jsx_runtime_1.jsx)("span", { style: { fontWeight: react_components_1.tokens.fontWeightSemibold }, children: eventInfo.event.title })] }) }), (0, jsx_runtime_1.jsx)(react_components_1.PopoverSurface, { style: { maxWidth: 600 }, children: (0, jsx_runtime_1.jsx)(PopoverContent, { eventInfo: eventInfo, onClose: () => setOpen(false) }) })] }));
|
|
28
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: { height: '100%', display: 'flex' }, children: (0, jsx_runtime_1.jsxs)(react_components_1.Popover, { positioning: "after", withArrow: true, open: open, onOpenChange: (e, data) => setOpen(data.open), children: [(0, jsx_runtime_1.jsx)(react_components_1.PopoverTrigger, { children: (0, jsx_runtime_1.jsxs)("div", { style: {
|
|
29
|
+
display: 'flex',
|
|
30
|
+
backgroundColor: react_components_1.tokens.colorBrandBackground2,
|
|
31
|
+
color: react_components_1.tokens.colorNeutralForeground1,
|
|
32
|
+
borderRadius: react_components_1.tokens.borderRadiusMedium,
|
|
33
|
+
paddingBlock: react_components_1.tokens.spacingVerticalXXS,
|
|
34
|
+
paddingInline: react_components_1.tokens.spacingHorizontalS,
|
|
35
|
+
border: `1px solid ${react_components_1.tokens.colorBrandStroke2}`,
|
|
36
|
+
gap: react_components_1.tokens.spacingHorizontalS,
|
|
37
|
+
overflow: 'hidden',
|
|
38
|
+
textOverflow: 'ellipsis',
|
|
39
|
+
height: '100%',
|
|
40
|
+
cursor: 'pointer',
|
|
41
|
+
}, children: [eventInfo.timeText && (0, jsx_runtime_1.jsx)("span", { children: eventInfo.timeText }), (0, jsx_runtime_1.jsx)("span", { style: { fontWeight: react_components_1.tokens.fontWeightSemibold }, children: eventInfo.event.title })] }) }), (0, jsx_runtime_1.jsx)(react_components_1.PopoverSurface, { style: { maxWidth: 480 }, children: (0, jsx_runtime_1.jsx)(PopoverContent, { eventInfo: eventInfo, onClose: () => setOpen(false) }) })] }) }));
|
|
39
42
|
};
|
|
40
43
|
const PopoverContent = ({ eventInfo, onClose }) => {
|
|
41
44
|
const config = (0, useConfig_1.useConfig)();
|
|
42
|
-
const { dateFormats, timeFormats } = (0, locale_1.useLocale)();
|
|
45
|
+
const { dateFormats, timeFormats, timezone } = (0, locale_1.useLocale)();
|
|
43
46
|
const deleteEvent = (0, useDeleteEvent_1.useDeleteEvent)();
|
|
44
47
|
const openEventDetailModel = (0, useOpenDetailDialog_1.useOpenDetailDialog)(EventDialog_1.EventDialog);
|
|
45
48
|
const router = (0, route_1.useRouter)();
|
|
@@ -92,7 +95,11 @@ const PopoverContent = ({ eventInfo, onClose }) => {
|
|
|
92
95
|
display: 'flex',
|
|
93
96
|
flexDirection: 'column',
|
|
94
97
|
gap: react_components_1.tokens.spacingVerticalM,
|
|
95
|
-
}, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, dayjs_1.default)(eventInfo.event.start).
|
|
96
|
-
? 'All Day'
|
|
97
|
-
:
|
|
98
|
+
}, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, dayjs_1.default)(eventInfo.event.start).tz(timezone).format(dateFormats.long), ' ', eventInfo.event.allDay
|
|
99
|
+
? '(All Day)'
|
|
100
|
+
: (0, dayjs_1.default)(eventInfo.event.start)
|
|
101
|
+
.tz(timezone)
|
|
102
|
+
.format(timeFormats.short) +
|
|
103
|
+
' - ' +
|
|
104
|
+
(0, dayjs_1.default)(eventInfo.event.end).tz(timezone).format(timeFormats.short)] }), (0, jsx_runtime_1.jsx)("div", { children: eventInfo.event.extendedProps.description })] })] }));
|
|
98
105
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@headless-adminapp/fluent",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@fullcalendar/core": "6.1.15",
|
|
33
33
|
"@fullcalendar/daygrid": "6.1.15",
|
|
34
34
|
"@fullcalendar/interaction": "6.1.15",
|
|
35
|
+
"@fullcalendar/moment-timezone": "6.1.15",
|
|
35
36
|
"@fullcalendar/react": "6.1.15",
|
|
36
37
|
"@fullcalendar/timegrid": "6.1.15",
|
|
37
38
|
"@hookform/resolvers": "^3.9.0",
|
|
@@ -50,5 +51,5 @@
|
|
|
50
51
|
"uuid": "11.0.3",
|
|
51
52
|
"yup": "^1.4.0"
|
|
52
53
|
},
|
|
53
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "ae232366aacd1153ee983d09b24f2f3e20548a68"
|
|
54
55
|
}
|