@headless-adminapp/fluent 1.1.12 → 1.2.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.
@@ -10,6 +10,7 @@ const react_1 = require("react");
10
10
  const AppStringContext_1 = require("../App/AppStringContext");
11
11
  const PageEntityViewStringContext_1 = require("../PageEntityView/PageEntityViewStringContext");
12
12
  const CustomizeColumns_1 = require("./CustomizeColumns");
13
+ const GridQuickFilterDesktop_1 = require("./GridQuickFilterDesktop");
13
14
  const GridHeaderDesktop = (props) => {
14
15
  const viewLookup = (0, hooks_1.useGridViewLookupData)();
15
16
  const selectedView = (0, hooks_1.useSelectedView)();
@@ -20,19 +21,23 @@ const GridHeaderDesktop = (props) => {
20
21
  const strings = (0, PageEntityViewStringContext_1.usePageEntityViewStrings)();
21
22
  const appStrings = (0, AppStringContext_1.useAppStrings)();
22
23
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
23
- alignItems: 'center',
24
- paddingInline: 8,
25
- gap: 16,
26
24
  display: 'flex',
27
- }, children: [(0, jsx_runtime_1.jsx)(CustomizeColumns_1.CustomizeColumns, { opened: isColumnCustomizationOpen, onClose: () => setIsColumnCustomizationOpen(false) }), (0, jsx_runtime_1.jsx)("div", { style: {
28
- flex: 1,
25
+ flexDirection: 'column',
26
+ gap: 8,
27
+ paddingInline: 8,
28
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
29
29
  alignItems: 'center',
30
30
  gap: 16,
31
- justifyContent: 'space-between',
32
31
  display: 'flex',
33
- }, children: (0, jsx_runtime_1.jsxs)(react_components_1.Menu, { children: [(0, jsx_runtime_1.jsx)(react_components_1.MenuTrigger, { children: (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.ChevronDown, {}), iconPosition: "after", style: {
34
- fontSize: react_components_1.tokens.fontSizeBase400,
35
- fontWeight: react_components_1.tokens.fontWeightMedium,
36
- }, children: selectedView.localizedNames?.[language] ?? selectedView.name }) }), (0, jsx_runtime_1.jsx)(react_components_1.MenuPopover, { children: (0, jsx_runtime_1.jsx)(react_components_1.MenuList, { children: viewLookup.map((view) => ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { onClick: () => changeView(view.id), children: view.localizedNames?.[language] ?? view.name }, view.id))) }) })] }) }), (0, jsx_runtime_1.jsxs)("div", { style: { alignItems: 'center', display: 'flex', gap: 16 }, children: [props.headingRight, (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.EditColumns, { size: 24 }), onClick: () => setIsColumnCustomizationOpen(true), children: strings.editColumns }), (0, jsx_runtime_1.jsx)(react_components_1.Input, { contentBefore: (0, jsx_runtime_1.jsx)(icons_1.Icons.Search, { size: 16 }), placeholder: appStrings.searchPlaceholder, value: searchText, onChange: (e) => setSearchText(e.target.value), appearance: "filled-darker" })] })] }));
32
+ }, children: [(0, jsx_runtime_1.jsx)(CustomizeColumns_1.CustomizeColumns, { opened: isColumnCustomizationOpen, onClose: () => setIsColumnCustomizationOpen(false) }), (0, jsx_runtime_1.jsx)("div", { style: {
33
+ flex: 1,
34
+ alignItems: 'center',
35
+ gap: 16,
36
+ justifyContent: 'space-between',
37
+ display: 'flex',
38
+ }, children: (0, jsx_runtime_1.jsxs)(react_components_1.Menu, { children: [(0, jsx_runtime_1.jsx)(react_components_1.MenuTrigger, { children: (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.ChevronDown, {}), iconPosition: "after", style: {
39
+ fontSize: react_components_1.tokens.fontSizeBase400,
40
+ fontWeight: react_components_1.tokens.fontWeightMedium,
41
+ }, children: selectedView.localizedNames?.[language] ?? selectedView.name }) }), (0, jsx_runtime_1.jsx)(react_components_1.MenuPopover, { children: (0, jsx_runtime_1.jsx)(react_components_1.MenuList, { children: viewLookup.map((view) => ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { onClick: () => changeView(view.id), children: view.localizedNames?.[language] ?? view.name }, view.id))) }) })] }) }), (0, jsx_runtime_1.jsxs)("div", { style: { alignItems: 'center', display: 'flex', gap: 16 }, children: [props.headingRight, (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.EditColumns, { size: 24 }), onClick: () => setIsColumnCustomizationOpen(true), children: strings.editColumns }), (0, jsx_runtime_1.jsx)(react_components_1.Input, { contentBefore: (0, jsx_runtime_1.jsx)(icons_1.Icons.Search, { size: 16 }), placeholder: appStrings.searchPlaceholder, value: searchText, onChange: (e) => setSearchText(e.target.value), appearance: "filled-darker" })] })] }), (0, jsx_runtime_1.jsx)(GridQuickFilterDesktop_1.GridQuickFilterDesktop, {})] }));
37
42
  };
38
43
  exports.GridHeaderDesktop = GridHeaderDesktop;
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const GridQuickFilterDesktop: FC;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GridQuickFilterDesktop = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_components_1 = require("@fluentui/react-components");
6
+ const useQuickFilter_1 = require("@headless-adminapp/app/datagrid/hooks/useQuickFilter");
7
+ const SectionControl_1 = require("../DataForm/SectionControl");
8
+ const StandardControl_1 = require("../PageEntityForm/StandardControl");
9
+ const GridQuickFilterDesktop = () => {
10
+ const [quickFilter, values, setValue] = (0, useQuickFilter_1.useQuickFilter)();
11
+ if (!quickFilter) {
12
+ return null;
13
+ }
14
+ return ((0, jsx_runtime_1.jsx)("div", { style: {
15
+ display: 'flex',
16
+ gap: react_components_1.tokens.spacingHorizontalS,
17
+ paddingInline: react_components_1.tokens.spacingHorizontalM,
18
+ }, children: Object.entries(quickFilter.attributes).map(([key, attribute]) => {
19
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelHidden: true, labelPosition: "top", children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: key, value: values[key] ?? null, onChange: (value) => setValue(key, value) }) }) }, key));
20
+ }) }));
21
+ };
22
+ exports.GridQuickFilterDesktop = GridQuickFilterDesktop;
@@ -287,7 +287,18 @@ function renderCellContent({ info, column, schema, schemaStore, locale, routeRes
287
287
  return ((0, jsx_runtime_1.jsx)(TableCell_1.TableCellText, { value: formattedValue, width: info.column.getSize() }, column.id));
288
288
  }
289
289
  if (column.component) {
290
- const Component = componentStore_1.componentStore.getComponent(column.component);
290
+ let Component;
291
+ if (column.component) {
292
+ if (typeof column.component === 'function') {
293
+ Component = column.component;
294
+ }
295
+ else if (typeof column.component === 'string') {
296
+ const OverrideControl = componentStore_1.componentStore.getComponent(column.component);
297
+ if (OverrideControl) {
298
+ Component = OverrideControl;
299
+ }
300
+ }
301
+ }
291
302
  if (!Component) {
292
303
  throw new Error(`Component with name ${column.component} not found`);
293
304
  }
@@ -29,7 +29,7 @@ function PieChart({ dataset, chartInfo, }) {
29
29
  overflow: 'auto',
30
30
  top: 5,
31
31
  bottom: 5,
32
- } })), (0, jsx_runtime_1.jsx)(recharts_1.Tooltip, { cursor: {
32
+ }, formatter: nameFormatter })), (0, jsx_runtime_1.jsx)(recharts_1.Tooltip, { cursor: {
33
33
  stroke: react_components_1.tokens.colorNeutralBackground6,
34
34
  opacity: 0.5,
35
35
  }, content: ({ payload }) => renderTooltipContent({
@@ -8,6 +8,7 @@ const hooks_2 = require("@headless-adminapp/app/hooks");
8
8
  const icons_1 = require("@headless-adminapp/icons");
9
9
  const react_query_1 = require("@tanstack/react-query");
10
10
  const AppStringContext_1 = require("../App/AppStringContext");
11
+ const HeaderQuickFilter_1 = require("./HeaderQuickFilter");
11
12
  const Header = ({ title, subtitle }) => {
12
13
  const client = (0, react_query_1.useQueryClient)();
13
14
  const schema = (0, hooks_1.useBoardSchema)();
@@ -21,13 +22,17 @@ const Header = ({ title, subtitle }) => {
21
22
  };
22
23
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
23
24
  display: 'flex',
24
- flexDirection: isMobile ? 'column' : 'row',
25
- alignItems: isMobile ? 'flex-start' : 'center',
26
- gap: react_components_1.tokens.spacingHorizontalM,
27
- }, 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: title }), (0, jsx_runtime_1.jsx)(react_components_1.Caption1, { style: { color: react_components_1.tokens.colorNeutralForeground2 }, children: subtitle })] }) }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
25
+ flexDirection: 'column',
26
+ gap: 16,
27
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
28
28
  display: 'flex',
29
- alignItems: 'center',
30
- gap: react_components_1.tokens.spacingHorizontalS,
31
- }, children: [(0, jsx_runtime_1.jsx)(react_components_1.SearchBox, { appearance: "filled-darker", placeholder: appStrings.searchPlaceholder, value: searchText, onChange: (e, data) => setSearchText(data.value) }), (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Refresh, { size: 20 }), onClick: refresh })] })] }));
29
+ flexDirection: isMobile ? 'column' : 'row',
30
+ alignItems: isMobile ? 'flex-start' : 'center',
31
+ gap: react_components_1.tokens.spacingHorizontalM,
32
+ }, 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: title }), (0, jsx_runtime_1.jsx)(react_components_1.Caption1, { style: { color: react_components_1.tokens.colorNeutralForeground2 }, children: subtitle })] }) }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
33
+ display: 'flex',
34
+ alignItems: 'center',
35
+ gap: react_components_1.tokens.spacingHorizontalS,
36
+ }, children: [(0, jsx_runtime_1.jsx)(react_components_1.SearchBox, { appearance: "filled-darker", placeholder: appStrings.searchPlaceholder, value: searchText, onChange: (e, data) => setSearchText(data.value) }), (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "subtle", icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Refresh, { size: 20 }), onClick: refresh })] })] }), (0, jsx_runtime_1.jsx)(HeaderQuickFilter_1.HeaderQuickFilter, {})] }));
32
37
  };
33
38
  exports.Header = Header;
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const HeaderQuickFilter: FC;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HeaderQuickFilter = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_components_1 = require("@fluentui/react-components");
6
+ const useQuickFilter_1 = require("@headless-adminapp/app/board/hooks/useQuickFilter");
7
+ const SectionControl_1 = require("../DataForm/SectionControl");
8
+ const StandardControl_1 = require("../PageEntityForm/StandardControl");
9
+ const HeaderQuickFilter = () => {
10
+ const [quickFilter, values, setValue] = (0, useQuickFilter_1.useQuickFilter)();
11
+ if (!quickFilter) {
12
+ return null;
13
+ }
14
+ return ((0, jsx_runtime_1.jsx)("div", { style: {
15
+ display: 'flex',
16
+ gap: react_components_1.tokens.spacingHorizontalS,
17
+ }, children: Object.entries(quickFilter.attributes).map(([key, attribute]) => {
18
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SectionControl_1.SectionControlWrapper, { label: attribute.label, labelHidden: true, labelPosition: "top", children: (0, jsx_runtime_1.jsx)(StandardControl_1.StandardControl, { attribute: attribute, name: key, value: values[key] ?? null, onChange: (value) => setValue(key, value) }) }) }, key));
19
+ }) }));
20
+ };
21
+ exports.HeaderQuickFilter = HeaderQuickFilter;
@@ -14,11 +14,13 @@ function PageBoard(props) {
14
14
  const contextValue = (0, context_2.useCreateContextStore)({
15
15
  config: props.config,
16
16
  searchText: '',
17
+ quickFilterValues: props.config.quickFilter?.defaultValues ?? {},
17
18
  });
18
19
  (0, react_1.useEffect)(() => {
19
20
  contextValue.setValue({
20
21
  config: props.config,
21
22
  searchText: '',
23
+ quickFilterValues: props.config.quickFilter?.defaultValues ?? {},
22
24
  });
23
25
  }, [contextValue, props.config]);
24
26
  return ((0, jsx_runtime_1.jsx)(context_1.BoardContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsx)(DndProvider_1.DndProvider, { children: (0, jsx_runtime_1.jsxs)("div", { style: {
@@ -1,4 +1,4 @@
1
- import { DateSelectArg, EventClickArg, EventInput } from '@fullcalendar/core';
1
+ import { DateSelectArg, EventInput } from '@fullcalendar/core';
2
2
  import { ViewType } from './types';
3
3
  interface CalendarSectionProps {
4
4
  startDate: Date | null;
@@ -12,9 +12,8 @@ interface CalendarSectionProps {
12
12
  viewType: ViewType;
13
13
  }) => void;
14
14
  events: EventInput[];
15
- onEventClick?: (event: EventClickArg) => void;
16
15
  onDateSelect?: (event: DateSelectArg) => void;
17
16
  loading?: boolean;
18
17
  }
19
- export declare const CalendarSection: ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, onEventClick, loading, }: Readonly<CalendarSectionProps>) => import("react/jsx-runtime").JSX.Element;
18
+ export declare const CalendarSection: ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, loading, }: Readonly<CalendarSectionProps>) => import("react/jsx-runtime").JSX.Element;
20
19
  export {};
@@ -26,7 +26,7 @@ const ViewSelector_1 = require("./ViewSelector");
26
26
  dayjs_1.default.extend(utc_1.default);
27
27
  dayjs_1.default.extend(timezone_1.default);
28
28
  dayjs_1.default.extend(isoWeek_1.default);
29
- const CalendarSection = ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, onEventClick, loading, }) => {
29
+ const CalendarSection = ({ startDate, endDate, viewType, onRangeChange, events, onDateSelect, loading, }) => {
30
30
  const calendarRef = (0, react_2.useRef)(null);
31
31
  const { timezone } = (0, locale_1.useLocale)();
32
32
  const isMobile = (0, hooks_1.useIsMobile)();
@@ -130,7 +130,7 @@ const CalendarSection = ({ startDate, endDate, viewType, onRangeChange, events,
130
130
  }, children: (0, jsx_runtime_1.jsx)(ViewSelector_1.ViewSelector, { viewType: viewType, onChange: (viewType) => {
131
131
  calendarRef.current?.getApi().changeView(viewType);
132
132
  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: [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%", nowIndicator: true, scrollTime: initialScrollTime, scrollTimeReset: false, editable: false, selectable: true, selectMirror: true, dayMaxEvents: true, eventMinHeight: 24, eventTimeFormat: (props) => {
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: [daygrid_1.default, timegrid_1.default, interaction_1.default], initialView: types_1.ViewType.Month, 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: true, selectMirror: true, dayMaxEvents: true, eventMinHeight: 24, eventTimeFormat: (props) => {
134
134
  return (0, dayjs_1.default)(props.start.marker).tz(timezone).format('hh:mm A');
135
135
  }, headerToolbar: false }) }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: loading })] })] }));
136
136
  };
@@ -15,9 +15,6 @@ interface EventDialogProps<SA1 extends SchemaAttributes = SchemaAttributes, SA2
15
15
  }) => Promise<void>;
16
16
  onCancel?: () => void;
17
17
  onDismiss?: () => void;
18
- allowOpenRecord?: boolean;
19
- onOpenRecord?: (id: string) => void;
20
- onDelete?: (id: string) => void;
21
18
  eventResolver?: CalendarEventResolverFn;
22
19
  config: CalendarConfig;
23
20
  }
@@ -17,5 +17,5 @@ function defineEventAttributes(beforeDescriptionAttributes, afterDescriptionAttr
17
17
  function EventDialog(props) {
18
18
  return ((0, jsx_runtime_1.jsx)(react_components_1.Dialog, { open: props.isOpen, onOpenChange: () => {
19
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 }) }) }));
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 }) }) }));
21
21
  }
@@ -9,9 +9,6 @@ interface EventFormBodyProps<SA1 extends SchemaAttributes = SchemaAttributes, SA
9
9
  values: Nullable<InferredSchemaType<BaseEventAttributes>>;
10
10
  }) => Promise<void>;
11
11
  onCancel?: () => void;
12
- allowOpenRecord?: boolean;
13
- onOpenRecord?: (id: string) => void;
14
- onDelete?: (id: string) => void;
15
12
  config: CalendarConfig;
16
13
  }
17
14
  export declare function EventFormBody(props: Readonly<EventFormBodyProps>): import("react/jsx-runtime").JSX.Element;
@@ -7,7 +7,6 @@ const baseEventAttributes_1 = require("@headless-adminapp/app/calendar/baseEvent
7
7
  const saveRecord_1 = require("@headless-adminapp/app/dataform/utils/saveRecord");
8
8
  const form_1 = require("@headless-adminapp/app/form");
9
9
  const locale_1 = require("@headless-adminapp/app/locale");
10
- const icons_fluent_1 = require("@headless-adminapp/icons-fluent");
11
10
  const react_query_1 = require("@tanstack/react-query");
12
11
  const react_1 = require("react");
13
12
  const react_hook_form_1 = require("react-hook-form");
@@ -54,22 +53,12 @@ function EventFormBody(props) {
54
53
  (0, react_1.useEffect)(() => {
55
54
  formRef.current.reset(defaultValues);
56
55
  }, [defaultValues]);
57
- const menuItems = [];
58
- if (props.allowOpenRecord) {
59
- menuItems.push((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" }, "open"));
60
- }
61
- if (!props.config.disableEdit) {
62
- menuItems.push((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" }, "delete"));
63
- }
64
56
  let title = (props.values.id ? 'Edit' : 'New') +
65
57
  ` ${props.config.eventLabel.toLowerCase()}`;
66
- if (props.values.id && props.config.disableEdit) {
58
+ if (props.values.id) {
67
59
  title = props.config.eventLabel;
68
60
  }
69
- let readOnly = props.values.id
70
- ? props.config.disableEdit
71
- : props.config.disableCreate;
72
- return ((0, jsx_runtime_1.jsxs)(react_components_1.DialogBody, { children: [(0, jsx_runtime_1.jsx)(react_components_1.DialogTitle, { action: props.values.id && menuItems.length > 0 ? ((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.jsx)(react_components_1.MenuList, { children: menuItems }) })] })) : null, children: title }), (0, jsx_runtime_1.jsx)(EventFormContent_1.EventFormContent, { form: form, afterDescriptionAttributes: props.config.afterDescriptionAttributes, beforeDescriptionAttributes: props.config.beforeDescriptionAttributes, readOnly: readOnly, config: props.config }), (0, jsx_runtime_1.jsxs)(react_components_1.DialogActions, { children: [!readOnly && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "primary", disabled: form.formState.submitCount > 0 && !form.formState.isValid, onClick: async () => {
61
+ return ((0, jsx_runtime_1.jsxs)(react_components_1.DialogBody, { children: [(0, jsx_runtime_1.jsx)(react_components_1.DialogTitle, { children: title }), (0, jsx_runtime_1.jsx)(EventFormContent_1.EventFormContent, { form: form, afterDescriptionAttributes: props.config.afterDescriptionAttributes, beforeDescriptionAttributes: props.config.beforeDescriptionAttributes, config: props.config }), (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 () => {
73
62
  await form.handleSubmit(async (values) => {
74
63
  await props.onSubmit?.({
75
64
  modifiedValues: values.id
@@ -78,7 +67,7 @@ function EventFormBody(props) {
78
67
  values,
79
68
  });
80
69
  })();
81
- }, children: props.values.id ? 'Save' : 'Create' })), (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "secondary", type: "button", onClick: () => {
70
+ }, children: props.values.id ? 'Save' : 'Create' }), (0, jsx_runtime_1.jsx)(react_components_1.Button, { appearance: "secondary", type: "button", onClick: () => {
82
71
  props.onCancel?.();
83
72
  }, children: props.values.id ? 'Close' : 'Cancel' })] }), (0, jsx_runtime_1.jsx)(BodyLoading_1.BodyLoading, { loading: isPending })] }));
84
73
  }
@@ -27,7 +27,8 @@ function Header({ filterForm, onCreateButtonClick, }) {
27
27
  display: 'flex',
28
28
  alignItems: 'center',
29
29
  gap: react_components_1.tokens.spacingHorizontalS,
30
- }, children: !config.disableCreate && ((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]) => {
30
+ }, children: !!config.createOptions && ((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 &&
31
+ Object.keys(config.filterAttributes).length > 0 && ((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
32
  return ((0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: filterForm.control, name: attributeName, render: ({ field }) => {
32
33
  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
34
  } }, attributeName));
@@ -1,56 +1,11 @@
1
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
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
2
  Object.defineProperty(exports, "__esModule", { value: true });
29
3
  exports.PageCalendar = PageCalendar;
30
4
  const jsx_runtime_1 = require("react/jsx-runtime");
31
- const react_components_1 = require("@fluentui/react-components");
32
- const auth_1 = require("@headless-adminapp/app/auth");
33
- const context_1 = require("@headless-adminapp/app/calendar/context");
34
- const dialog_1 = require("@headless-adminapp/app/dialog");
35
- const hooks_1 = require("@headless-adminapp/app/hooks");
5
+ const CalendarProvider_1 = require("@headless-adminapp/app/calendar/CalendarProvider");
36
6
  const mutable_1 = require("@headless-adminapp/app/mutable");
37
- const progress_indicator_1 = require("@headless-adminapp/app/progress-indicator");
38
- const toast_notification_1 = require("@headless-adminapp/app/toast-notification");
39
- const react_query_1 = require("@tanstack/react-query");
40
- const dayjs_1 = __importDefault(require("dayjs"));
41
- const isoWeek_1 = __importDefault(require("dayjs/plugin/isoWeek"));
42
- const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
43
- const utc_1 = __importDefault(require("dayjs/plugin/utc"));
44
7
  const react_1 = require("react");
45
- const react_hook_form_1 = require("react-hook-form");
46
- const EventDialog_1 = require("./EventDialog/EventDialog");
47
- const Header_1 = require("./Header");
48
- const types_1 = require("./types");
49
- const utils_1 = require("./utils");
50
- const CalendarSection = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./CalendarSection'))).then((mod) => ({ default: mod.CalendarSection })));
51
- dayjs_1.default.extend(utc_1.default);
52
- dayjs_1.default.extend(timezone_1.default);
53
- dayjs_1.default.extend(isoWeek_1.default);
8
+ const PageCalendarUI_1 = require("./PageCalendarUI");
54
9
  function PageCalendar(props) {
55
10
  const contextValue = (0, mutable_1.useCreateContextStore)({
56
11
  config: props.config,
@@ -61,176 +16,5 @@ function PageCalendar(props) {
61
16
  });
62
17
  }, [contextValue, props.config]);
63
18
  const config = props.config;
64
- const openDialog = (0, dialog_1.useOpenDialog)();
65
- const openConfirmDialog = (0, dialog_1.useOpenConfirmDialog)();
66
- const openToastNotification = (0, toast_notification_1.useOpenToastNotification)();
67
- const { hideProgressIndicator, showProgressIndicator } = (0, progress_indicator_1.useProgressIndicator)();
68
- const isMobile = (0, hooks_1.useIsMobile)();
69
- const [activeStartDate, setActiveStartDate] = (0, react_1.useState)(null);
70
- const [activeEndDate, setActiveEndDate] = (0, react_1.useState)(null);
71
- const [currentStartDate, setCurrentStartDate] = (0, react_1.useState)(null);
72
- const [currentEndDate, setCurrentEndDate] = (0, react_1.useState)(null);
73
- const [viewType, setViewType] = (0, react_1.useState)(isMobile ? types_1.ViewType.Day : types_1.ViewType.Month);
74
- const queryClient = (0, react_query_1.useQueryClient)();
75
- const filterForm = (0, react_hook_form_1.useForm)({
76
- mode: 'all',
77
- defaultValues: config.defaultFilter,
78
- shouldUnregister: false,
79
- });
80
- const filterValues = filterForm.watch();
81
- const auth = (0, auth_1.useAuthSession)();
82
- const { data: events, isPending: loading } = (0, react_query_1.useQuery)({
83
- queryKey: [
84
- 'calendar-events',
85
- 'list',
86
- activeStartDate,
87
- activeEndDate,
88
- filterValues,
89
- auth,
90
- ],
91
- queryFn: async () => {
92
- if (!activeStartDate || !activeEndDate) {
93
- return [];
94
- }
95
- try {
96
- const result = await config.eventsResolver({
97
- start: activeStartDate,
98
- end: activeEndDate,
99
- filter: filterValues,
100
- auth,
101
- });
102
- return result.map(utils_1.transformEvent);
103
- }
104
- catch (error) {
105
- openToastNotification({
106
- title: 'Error',
107
- text: error.message,
108
- type: 'error',
109
- });
110
- throw error;
111
- }
112
- },
113
- staleTime: 1000 * 60 * 5, // 5 minutes
114
- });
115
- function openEventDetailModel(values) {
116
- const { close } = openDialog({
117
- type: 'custom',
118
- Component: EventDialog_1.EventDialog,
119
- props: {
120
- onDismiss: () => {
121
- close();
122
- },
123
- config,
124
- values,
125
- onSubmit: async (data) => {
126
- try {
127
- const { id, end, start, title, allDay, description, ...rest } = data.values;
128
- await config.saveEvent({
129
- event: {
130
- id,
131
- title,
132
- start: start ? new Date(start) : null,
133
- end: end ? new Date(end) : null,
134
- allDay: allDay ?? false,
135
- description,
136
- ...rest,
137
- },
138
- modifiedValues: data.modifiedValues,
139
- });
140
- await queryClient.invalidateQueries({
141
- queryKey: ['calendar-events'],
142
- });
143
- close();
144
- }
145
- catch (error) {
146
- openToastNotification({
147
- title: 'Error',
148
- text: error.message,
149
- type: 'error',
150
- });
151
- }
152
- },
153
- onDelete: async (id) => {
154
- try {
155
- const confirmResult = await openConfirmDialog({
156
- title: 'Delete Event',
157
- text: 'Are you sure you want to delete this event?',
158
- });
159
- if (!confirmResult?.confirmed) {
160
- return;
161
- }
162
- showProgressIndicator('Deleting event...');
163
- await config.deleteEvent(id);
164
- await queryClient.invalidateQueries({
165
- queryKey: ['calendar-events'],
166
- });
167
- close();
168
- }
169
- catch (error) {
170
- openToastNotification({
171
- title: 'Error',
172
- text: error.message,
173
- type: 'error',
174
- });
175
- }
176
- finally {
177
- hideProgressIndicator();
178
- }
179
- },
180
- allowOpenRecord: !!config.openRecord,
181
- onOpenRecord: config.openRecord,
182
- onCancel: () => {
183
- close();
184
- },
185
- },
186
- });
187
- }
188
- function handleDateSelect(selectInfo) {
189
- if (config.disableCreate) {
190
- return;
191
- }
192
- openEventDetailModel({
193
- title: '',
194
- start: selectInfo.start.toISOString(),
195
- end: selectInfo.end.toISOString(),
196
- allDay: selectInfo.allDay,
197
- customer: null,
198
- description: '',
199
- });
200
- }
201
- function handleEventClick(clickInfo) {
202
- openEventDetailModel({
203
- id: clickInfo.event.id,
204
- title: clickInfo.event.title,
205
- start: clickInfo.event.start?.toISOString(),
206
- end: clickInfo.event.end?.toISOString(),
207
- allDay: clickInfo.event.allDay,
208
- description: '',
209
- ...clickInfo.event.extendedProps,
210
- });
211
- }
212
- function handleCreateButtonClick() {
213
- openEventDetailModel({
214
- title: '',
215
- start: null,
216
- end: null,
217
- allDay: false,
218
- description: '',
219
- });
220
- }
221
- const onRangeChange = ({ currentStart, currentEnd, activeStart, activeEnd, viewType, }) => {
222
- setCurrentStartDate(currentStart);
223
- setCurrentEndDate(currentEnd);
224
- setActiveStartDate(activeStart);
225
- setActiveEndDate(activeEnd);
226
- setViewType(viewType);
227
- };
228
- return ((0, jsx_runtime_1.jsx)(context_1.CalendarContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsxs)("div", { style: {
229
- display: 'flex',
230
- flexDirection: 'column',
231
- flex: 1,
232
- gap: react_components_1.tokens.spacingVerticalM,
233
- padding: react_components_1.tokens.spacingHorizontalM,
234
- background: react_components_1.tokens.colorNeutralBackground2,
235
- }, 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 ?? [], onEventClick: handleEventClick, onDateSelect: handleDateSelect, loading: loading }) })] }) }));
19
+ return ((0, jsx_runtime_1.jsx)(CalendarProvider_1.CalendarProvider, { config: config, children: (0, jsx_runtime_1.jsx)(PageCalendarUI_1.PageCalendarUI, {}) }));
236
20
  }
@@ -0,0 +1,2 @@
1
+ import { SchemaAttributes } from '@headless-adminapp/core/schema';
2
+ export declare function PageCalendarUI<SA3 extends SchemaAttributes = SchemaAttributes>(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,169 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.PageCalendarUI = PageCalendarUI;
30
+ const jsx_runtime_1 = require("react/jsx-runtime");
31
+ const react_components_1 = require("@fluentui/react-components");
32
+ const auth_1 = require("@headless-adminapp/app/auth");
33
+ const hooks_1 = require("@headless-adminapp/app/calendar/hooks");
34
+ const useOpenDetailDialog_1 = require("@headless-adminapp/app/calendar/hooks/useOpenDetailDialog");
35
+ const hooks_2 = require("@headless-adminapp/app/hooks");
36
+ const navigation_1 = require("@headless-adminapp/app/navigation");
37
+ const route_1 = require("@headless-adminapp/app/route");
38
+ const toast_notification_1 = require("@headless-adminapp/app/toast-notification");
39
+ const react_query_1 = require("@tanstack/react-query");
40
+ const dayjs_1 = __importDefault(require("dayjs"));
41
+ const isoWeek_1 = __importDefault(require("dayjs/plugin/isoWeek"));
42
+ const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
43
+ const utc_1 = __importDefault(require("dayjs/plugin/utc"));
44
+ const react_1 = require("react");
45
+ const react_hook_form_1 = require("react-hook-form");
46
+ const EventDialog_1 = require("./EventDialog/EventDialog");
47
+ const Header_1 = require("./Header");
48
+ const types_1 = require("./types");
49
+ const utils_1 = require("./utils");
50
+ const CalendarSection = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./CalendarSection'))).then((mod) => ({ default: mod.CalendarSection })));
51
+ dayjs_1.default.extend(utc_1.default);
52
+ dayjs_1.default.extend(timezone_1.default);
53
+ dayjs_1.default.extend(isoWeek_1.default);
54
+ function PageCalendarUI() {
55
+ const config = (0, hooks_1.useConfig)();
56
+ const openToastNotification = (0, toast_notification_1.useOpenToastNotification)();
57
+ const isMobile = (0, hooks_2.useIsMobile)();
58
+ const [activeStartDate, setActiveStartDate] = (0, react_1.useState)(null);
59
+ const [activeEndDate, setActiveEndDate] = (0, react_1.useState)(null);
60
+ const [currentStartDate, setCurrentStartDate] = (0, react_1.useState)(null);
61
+ const [currentEndDate, setCurrentEndDate] = (0, react_1.useState)(null);
62
+ const [viewType, setViewType] = (0, react_1.useState)(isMobile ? types_1.ViewType.Day : types_1.ViewType.Month);
63
+ const filterForm = (0, react_hook_form_1.useForm)({
64
+ mode: 'all',
65
+ defaultValues: config.defaultFilter,
66
+ shouldUnregister: false,
67
+ });
68
+ const filterValues = filterForm.watch();
69
+ const auth = (0, auth_1.useAuthSession)();
70
+ const { data: events, isPending: loading } = (0, react_query_1.useQuery)({
71
+ queryKey: [
72
+ 'calendar-events',
73
+ 'list',
74
+ activeStartDate,
75
+ activeEndDate,
76
+ filterValues,
77
+ auth,
78
+ ],
79
+ queryFn: async () => {
80
+ if (!activeStartDate || !activeEndDate) {
81
+ return [];
82
+ }
83
+ try {
84
+ const result = await config.eventsResolver({
85
+ start: activeStartDate,
86
+ end: activeEndDate,
87
+ filter: filterValues,
88
+ auth,
89
+ });
90
+ return result.map(utils_1.transformEvent);
91
+ }
92
+ catch (error) {
93
+ openToastNotification({
94
+ title: 'Error',
95
+ text: error.message,
96
+ type: 'error',
97
+ });
98
+ throw error;
99
+ }
100
+ },
101
+ staleTime: 1000 * 60 * 5, // 5 minutes
102
+ });
103
+ const openEventDetailModel = (0, useOpenDetailDialog_1.useOpenDetailDialog)(EventDialog_1.EventDialog);
104
+ const router = (0, route_1.useRouter)();
105
+ const routeResolver = (0, route_1.useRouteResolver)();
106
+ const openForm = (0, navigation_1.useOpenForm)();
107
+ const handleNewRecord = (values) => {
108
+ if (!config.createOptions) {
109
+ return;
110
+ }
111
+ if (config.createOptions.mode === 'dialog') {
112
+ if (!config.saveEvent) {
113
+ return;
114
+ }
115
+ openEventDetailModel(values);
116
+ }
117
+ else if (config.createOptions.mode === 'custom') {
118
+ config.createOptions.onClick(values, {
119
+ openForm,
120
+ router,
121
+ routeResolver,
122
+ });
123
+ }
124
+ };
125
+ function handleDateSelect(selectInfo) {
126
+ if (!config.createOptions) {
127
+ return;
128
+ }
129
+ if (config.createOptions.mode === 'custom' &&
130
+ !config.createOptions.allowQuickCreate) {
131
+ return;
132
+ }
133
+ if (config.disableAllDay && selectInfo.allDay) {
134
+ return;
135
+ }
136
+ handleNewRecord({
137
+ title: '',
138
+ start: selectInfo.start.toISOString(),
139
+ end: selectInfo.end.toISOString(),
140
+ allDay: selectInfo.allDay,
141
+ customer: null,
142
+ description: '',
143
+ });
144
+ }
145
+ function handleCreateButtonClick() {
146
+ handleNewRecord({
147
+ title: '',
148
+ start: null,
149
+ end: null,
150
+ allDay: false,
151
+ description: '',
152
+ });
153
+ }
154
+ const onRangeChange = ({ currentStart, currentEnd, activeStart, activeEnd, viewType, }) => {
155
+ setCurrentStartDate(currentStart);
156
+ setCurrentEndDate(currentEnd);
157
+ setActiveStartDate(activeStart);
158
+ setActiveEndDate(activeEnd);
159
+ setViewType(viewType);
160
+ };
161
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
162
+ display: 'flex',
163
+ flexDirection: 'column',
164
+ flex: 1,
165
+ gap: react_components_1.tokens.spacingVerticalM,
166
+ padding: react_components_1.tokens.spacingHorizontalM,
167
+ 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 }) })] }));
169
+ }
@@ -1,22 +1,98 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.renderEventContent = renderEventContent;
4
7
  const jsx_runtime_1 = require("react/jsx-runtime");
5
8
  const react_components_1 = require("@fluentui/react-components");
9
+ const useConfig_1 = require("@headless-adminapp/app/calendar/hooks/useConfig");
10
+ const useDeleteEvent_1 = require("@headless-adminapp/app/calendar/hooks/useDeleteEvent");
11
+ const useOpenDetailDialog_1 = require("@headless-adminapp/app/calendar/hooks/useOpenDetailDialog");
12
+ const locale_1 = require("@headless-adminapp/app/locale");
13
+ const navigation_1 = require("@headless-adminapp/app/navigation");
14
+ const route_1 = require("@headless-adminapp/app/route");
15
+ const icons_1 = require("@headless-adminapp/icons");
16
+ const dayjs_1 = __importDefault(require("dayjs"));
17
+ const react_1 = require("react");
18
+ const EventDialog_1 = require("./EventDialog/EventDialog");
6
19
  function renderEventContent(eventInfo) {
7
- return ((0, jsx_runtime_1.jsxs)("div", { style: {
8
- display: 'flex',
9
- backgroundColor: react_components_1.tokens.colorBrandBackground2,
10
- color: react_components_1.tokens.colorNeutralForeground1,
11
- borderRadius: react_components_1.tokens.borderRadiusMedium,
12
- paddingBlock: react_components_1.tokens.spacingVerticalXXS,
13
- paddingInline: react_components_1.tokens.spacingHorizontalS,
14
- border: `1px solid ${react_components_1.tokens.colorBrandStroke2}`,
15
- gap: react_components_1.tokens.spacingHorizontalS,
16
- width: '100%',
17
- overflow: 'hidden',
18
- textOverflow: 'ellipsis',
19
- height: '100%',
20
- cursor: 'pointer',
21
- }, 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 })] }));
20
+ return (0, jsx_runtime_1.jsx)(EventContent, { eventInfo: eventInfo });
22
21
  }
22
+ const EventContent = ({ eventInfo }) => {
23
+ 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
+ display: 'flex',
26
+ backgroundColor: react_components_1.tokens.colorBrandBackground2,
27
+ color: react_components_1.tokens.colorNeutralForeground1,
28
+ borderRadius: react_components_1.tokens.borderRadiusMedium,
29
+ paddingBlock: react_components_1.tokens.spacingVerticalXXS,
30
+ paddingInline: react_components_1.tokens.spacingHorizontalS,
31
+ border: `1px solid ${react_components_1.tokens.colorBrandStroke2}`,
32
+ gap: react_components_1.tokens.spacingHorizontalS,
33
+ width: '100%',
34
+ overflow: 'hidden',
35
+ textOverflow: 'ellipsis',
36
+ height: '100%',
37
+ cursor: 'pointer',
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) }) })] }));
39
+ };
40
+ const PopoverContent = ({ eventInfo, onClose }) => {
41
+ const config = (0, useConfig_1.useConfig)();
42
+ const { dateFormats, timeFormats } = (0, locale_1.useLocale)();
43
+ const deleteEvent = (0, useDeleteEvent_1.useDeleteEvent)();
44
+ const openEventDetailModel = (0, useOpenDetailDialog_1.useOpenDetailDialog)(EventDialog_1.EventDialog);
45
+ const router = (0, route_1.useRouter)();
46
+ const routeResolver = (0, route_1.useRouteResolver)();
47
+ const openForm = (0, navigation_1.useOpenForm)();
48
+ const handleEdit = () => {
49
+ if (!config.editOptions) {
50
+ return;
51
+ }
52
+ onClose();
53
+ if (config.editOptions.mode === 'dialog') {
54
+ openEventDetailModel({
55
+ id: eventInfo.event.id,
56
+ title: eventInfo.event.title,
57
+ start: eventInfo.event.start?.toISOString(),
58
+ end: eventInfo.event.end?.toISOString(),
59
+ allDay: eventInfo.event.allDay,
60
+ description: '',
61
+ ...eventInfo.event.extendedProps,
62
+ });
63
+ }
64
+ else if (config.editOptions.mode === 'custom') {
65
+ config.editOptions.onClick(eventInfo.event, {
66
+ openForm,
67
+ router,
68
+ routeResolver,
69
+ });
70
+ }
71
+ };
72
+ return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
73
+ display: 'flex',
74
+ alignItems: 'flex-start',
75
+ gap: react_components_1.tokens.spacingHorizontalM,
76
+ paddingBottom: react_components_1.tokens.spacingVerticalM,
77
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
78
+ fontWeight: react_components_1.tokens.fontWeightBold,
79
+ fontSize: react_components_1.tokens.fontSizeBase400,
80
+ flex: 1,
81
+ alignSelf: 'center',
82
+ }, children: eventInfo.event.title }), (0, jsx_runtime_1.jsxs)("div", { style: {
83
+ display: 'flex',
84
+ flexDirection: 'row',
85
+ alignItems: 'center',
86
+ gap: react_components_1.tokens.spacingHorizontalS,
87
+ }, children: [!!config.deleteEvent && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Delete, { size: 16 }), appearance: "subtle", onClick: async () => {
88
+ onClose();
89
+ await deleteEvent(eventInfo.event.id);
90
+ } })), !!config.editOptions && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Edit, { size: 16 }), appearance: "subtle", onClick: handleEdit })), (0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Close, { size: 16 }), appearance: "subtle", onClick: onClose })] })] }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.5 } }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
91
+ paddingTop: react_components_1.tokens.spacingVerticalM,
92
+ display: 'flex',
93
+ flexDirection: 'column',
94
+ gap: react_components_1.tokens.spacingVerticalM,
95
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, dayjs_1.default)(eventInfo.event.start).format(dateFormats.long), ' ', (0, dayjs_1.default)(eventInfo.event.start).format(timeFormats.short), ' ', eventInfo.event.allDay
96
+ ? 'All Day'
97
+ : '- ' + (0, dayjs_1.default)(eventInfo.event.end).format(timeFormats.short)] }), (0, jsx_runtime_1.jsx)("div", { children: eventInfo.event.extendedProps.description })] })] }));
98
+ };
@@ -4,7 +4,7 @@ exports.RecordCard = RecordCard;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_components_1 = require("@fluentui/react-components");
6
6
  const utils_1 = require("@headless-adminapp/app/utils");
7
- const color_1 = require("@headless-adminapp/app/utils/color");
7
+ const ChoiceBadge_1 = require("../components/ChoiceBadge");
8
8
  const useStyles = (0, react_components_1.makeStyles)({
9
9
  root: {
10
10
  width: '100%',
@@ -113,18 +113,5 @@ function SecondaryColumnContent({ record: _record, column, schema, }) {
113
113
  return ((0, jsx_runtime_1.jsxs)(react_components_1.Caption1, { style: { color: react_components_1.tokens.colorNeutralForeground4 }, children: [!!label && `${label}: `, (0, utils_1.getAttributeFormattedValue)(attribute, value)] }, column.name));
114
114
  }
115
115
  const ChoiceTag = ({ attribute, value, }) => {
116
- const choice = attribute.options.find((option) => option.value === value);
117
- if (!choice) {
118
- return null;
119
- }
120
- const bgColor = choice.color;
121
- let color;
122
- if (bgColor) {
123
- color = (0, color_1.isColorDark)(bgColor) ? '#FFFFFF' : '#000000';
124
- }
125
- return ((0, jsx_runtime_1.jsx)(react_components_1.Badge, { size: "small", appearance: "filled", style: {
126
- background: bgColor,
127
- color: color,
128
- fontWeight: react_components_1.tokens.fontWeightRegular,
129
- }, children: choice.label }));
116
+ return (0, jsx_runtime_1.jsx)(ChoiceBadge_1.ChoiceBadge, { attribute: attribute, value: value, size: "small" });
130
117
  };
@@ -28,6 +28,7 @@ const RecordSetNavigatorContainer = () => {
28
28
  const { data, cardView, schema } = (0, hooks_2.useRecordSetResult)();
29
29
  const [visible] = (0, hooks_2.useRecordSetVisibility)();
30
30
  const recordId = (0, hooks_1.useRecordId)();
31
+ const formSchema = (0, hooks_1.useDataFormSchema)();
31
32
  const styles = useStyles();
32
33
  const openForm = (0, navigation_1.useOpenForm)();
33
34
  const { language, direction } = (0, locale_1.useLocale)();
@@ -37,6 +38,9 @@ const RecordSetNavigatorContainer = () => {
37
38
  if (!visible) {
38
39
  return null;
39
40
  }
41
+ if (schema.logicalName !== formSchema?.logicalName) {
42
+ return null;
43
+ }
40
44
  return ((0, jsx_runtime_1.jsx)("div", { style: {
41
45
  [direction === 'rtl' ? 'paddingRight' : 'paddingLeft']: react_components_1.tokens.spacingVerticalM,
42
46
  paddingBlock: react_components_1.tokens.spacingVerticalM,
@@ -1,8 +1,9 @@
1
1
  import { ChoiceAttribute } from '@headless-adminapp/core/attributes';
2
+ import { ChoicesAttribute } from '@headless-adminapp/core/attributes/ChoiceAttribute';
2
3
  interface ChoiceBadgeProps {
3
4
  value: unknown;
4
- attribute: ChoiceAttribute<string | number>;
5
- formattedValue: string | null;
5
+ attribute: ChoiceAttribute<string | number> | ChoicesAttribute<string | number>;
6
+ formattedValue?: string | null;
6
7
  size?: 'small' | 'medium';
7
8
  }
8
9
  export declare function ChoiceBadge(props: Readonly<ChoiceBadgeProps>): import("react/jsx-runtime").JSX.Element | null;
@@ -18,12 +18,25 @@ function ChoiceBadge(props) {
18
18
  }
19
19
  return (0, color_1.isColorDark)(bgColor) ? '#FFFFFF' : '#000000';
20
20
  }, [bgColor]);
21
- if (!props.formattedValue) {
21
+ const formattedValue = (0, react_1.useMemo)(() => {
22
+ if (props.formattedValue) {
23
+ return props.formattedValue;
24
+ }
25
+ if (!props.value) {
26
+ return null;
27
+ }
28
+ const choice = props.attribute.options.find((option) => option.value === props.value);
29
+ if (!choice) {
30
+ return null;
31
+ }
32
+ return choice.label;
33
+ }, [props.attribute.options, props.formattedValue, props.value]);
34
+ if (!formattedValue) {
22
35
  return null;
23
36
  }
24
37
  return ((0, jsx_runtime_1.jsx)(react_components_1.Badge, { style: {
25
38
  backgroundColor: bgColor ?? react_components_1.tokens.colorNeutralBackground3,
26
39
  color: color ?? react_components_1.tokens.colorNeutralForeground2,
27
40
  fontWeight: react_components_1.tokens.fontWeightRegular,
28
- }, size: props.size, children: props.formattedValue }));
41
+ }, size: props.size, children: formattedValue }));
29
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-adminapp/fluent",
3
- "version": "1.1.12",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -50,5 +50,5 @@
50
50
  "uuid": "11.0.3",
51
51
  "yup": "^1.4.0"
52
52
  },
53
- "gitHead": "ead918f1f609c2a260ceae498368ddc2c4980725"
53
+ "gitHead": "3c59cbbf000e71e39b81c9440a71363b729e6e3c"
54
54
  }