@headless-adminapp/fluent 1.4.12 → 1.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/App/AppHeaderContianer.js +105 -49
  2. package/App/QuickActionItem.d.ts +1 -0
  3. package/App/QuickActionItem.js +7 -3
  4. package/DataGrid/GridListContainer.js +61 -33
  5. package/DataGrid/MobileHeaderRightContainer.d.ts +2 -0
  6. package/DataGrid/MobileHeaderRightContainer.js +11 -0
  7. package/Header/MobileHeaderCommandContainer.d.ts +13 -0
  8. package/Header/MobileHeaderCommandContainer.js +168 -0
  9. package/Header/MobileHeaderQuickActionButton.d.ts +10 -0
  10. package/Header/MobileHeaderQuickActionButton.js +36 -0
  11. package/PageEntityForm/CommandContainer.js +3 -3
  12. package/PageEntityForm/MobileHeaderRightContainer.d.ts +2 -0
  13. package/PageEntityForm/MobileHeaderRightContainer.js +11 -0
  14. package/PageEntityForm/MobileHeaderTitleContainer.d.ts +2 -0
  15. package/PageEntityForm/MobileHeaderTitleContainer.js +38 -0
  16. package/PageEntityForm/PageEntityForm.js +2 -0
  17. package/PageEntityForm/PageEntityFormDesktopContainer.js +89 -74
  18. package/PageEntityForm/RecordCard.js +34 -36
  19. package/PageEntityForm/TabContainer.d.ts +2 -0
  20. package/PageEntityForm/TabContainer.js +35 -0
  21. package/PageEntityView/PageEntityView.js +4 -1
  22. package/PageEntityView/PageEntityViewMobileContainer.js +1 -2
  23. package/PageEntityView/PageEntityViewMobileFrame.d.ts +0 -1
  24. package/PageEntityView/PageEntityViewMobileFrame.js +25 -23
  25. package/ToastNotificationContainer/index.js +7 -5
  26. package/components/DialogLogin.js +1 -1
  27. package/components/PageLogin.js +22 -2
  28. package/form/layout/FormBody/FormBody.js +16 -1
  29. package/package.json +2 -2
@@ -7,8 +7,10 @@ const react_nav_preview_1 = require("@fluentui/react-nav-preview");
7
7
  const app_1 = require("@headless-adminapp/app/app");
8
8
  const hooks_1 = require("@headless-adminapp/app/auth/hooks");
9
9
  const useIsSkipAuthCheck_1 = require("@headless-adminapp/app/auth/hooks/useIsSkipAuthCheck");
10
+ const header_1 = require("@headless-adminapp/app/header");
10
11
  const hooks_2 = require("@headless-adminapp/app/hooks");
11
12
  const locale_1 = require("@headless-adminapp/app/locale");
13
+ const mutable_1 = require("@headless-adminapp/app/mutable");
12
14
  const route_1 = require("@headless-adminapp/app/route");
13
15
  const icons_1 = require("@headless-adminapp/icons");
14
16
  const react_1 = require("react");
@@ -16,14 +18,48 @@ const AppLogo_1 = require("./AppLogo");
16
18
  const AppStringContext_1 = require("./AppStringContext");
17
19
  const QuickActionItem_1 = require("./QuickActionItem");
18
20
  const AppHeaderContainer = ({ onNavToggle, }) => {
21
+ const isMobile = (0, hooks_2.useIsMobile)();
22
+ if (isMobile) {
23
+ return (0, jsx_runtime_1.jsx)(AppMobileHeader, { onNavToggle: onNavToggle });
24
+ }
25
+ return (0, jsx_runtime_1.jsx)(AppDesktopHeader, { onNavToggle: onNavToggle });
26
+ };
27
+ exports.AppHeaderContainer = AppHeaderContainer;
28
+ const NavHamburger = ({ onNavToggle }) => {
29
+ const isMobile = (0, hooks_2.useIsMobile)();
30
+ return ((0, jsx_runtime_1.jsx)(react_nav_preview_1.Hamburger, { style: {
31
+ color: 'inherit',
32
+ width: !isMobile ? 44 : undefined,
33
+ maxWidth: !isMobile ? 44 : undefined,
34
+ }, onClick: onNavToggle }));
35
+ };
36
+ const NavBackButton = () => {
37
+ const isMobile = (0, hooks_2.useIsMobile)();
38
+ const router = (0, route_1.useRouter)();
39
+ return ((0, jsx_runtime_1.jsx)(react_nav_preview_1.Hamburger, { style: {
40
+ color: 'inherit',
41
+ width: !isMobile ? 44 : undefined,
42
+ maxWidth: !isMobile ? 44 : undefined,
43
+ }, icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.ArrowLeft, {}), onClick: () => {
44
+ router.back();
45
+ } }));
46
+ };
47
+ const NavTitle = () => {
48
+ const { appExperience: app } = (0, app_1.useAppContext)();
49
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
50
+ display: 'flex',
51
+ alignItems: 'center',
52
+ cursor: 'pointer',
53
+ color: 'white',
54
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', paddingLeft: 4, paddingRight: 6 }, children: (0, jsx_runtime_1.jsx)(AppLogo_1.AppLogo, { logo: app.logo, title: app.title }) }), (0, jsx_runtime_1.jsx)(react_components_1.Subtitle2, { style: { paddingLeft: 4 }, children: app.title })] }));
55
+ };
56
+ const NavActions = () => {
19
57
  const { appExperience: app } = (0, app_1.useAppContext)();
20
58
  const authSession = (0, hooks_1.useAuthSession)();
21
59
  const isSkipAuthCheck = (0, useIsSkipAuthCheck_1.useIsSkipAuthCheck)();
22
60
  const logout = (0, hooks_1.useLogout)();
23
61
  const strings = (0, AppStringContext_1.useAppStrings)();
24
62
  const { language } = (0, locale_1.useLocale)();
25
- const isMobile = (0, hooks_2.useIsMobile)();
26
- const isTablet = (0, hooks_2.useIsTablet)();
27
63
  const initials = (0, react_1.useMemo)(() => {
28
64
  return authSession?.fullName
29
65
  .split(' ')
@@ -35,6 +71,60 @@ const AppHeaderContainer = ({ onNavToggle, }) => {
35
71
  const accountMenuItems = (0, hooks_2.useItemsWithKey)(app.accountMenuItems);
36
72
  const router = (0, route_1.useRouter)();
37
73
  const basePath = (0, route_1.useBasePath)();
74
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
75
+ paddingLeft: 8,
76
+ display: 'flex',
77
+ gap: 16,
78
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: 8 }, children: quickActionItems?.map((item) => {
79
+ if (item.type === 'custom') {
80
+ return (0, jsx_runtime_1.jsx)(item.Component, {}, item.__key);
81
+ }
82
+ return ((0, jsx_runtime_1.jsx)(QuickActionItem_1.QuickActionItem, { Icon: item.icon, label: item.localizedLabel?.[language] ?? item.label, onClick: () => item.onClick?.(), link: item.link }, item.__key));
83
+ }) }), (!isSkipAuthCheck || !!accountMenuItems?.length) && ((0, jsx_runtime_1.jsxs)(react_components_1.Popover, { children: [(0, jsx_runtime_1.jsx)(react_components_1.PopoverTrigger, { disableButtonEnhancement: true, children: (0, jsx_runtime_1.jsx)(react_components_1.Avatar, { initials: initials, color: "neutral", style: { cursor: 'pointer' }, image: {
84
+ src: authSession?.profilePicture,
85
+ } }) }), (0, jsx_runtime_1.jsxs)(react_components_1.PopoverSurface, { tabIndex: -1, style: { padding: 0 }, children: [!isSkipAuthCheck && ((0, jsx_runtime_1.jsxs)("div", { style: {
86
+ display: 'flex',
87
+ gap: 8,
88
+ padding: 8,
89
+ overflow: 'hidden',
90
+ width: 200,
91
+ }, children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(react_components_1.Avatar, { initials: initials, color: "neutral", image: {
92
+ src: authSession?.profilePicture,
93
+ } }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
94
+ display: 'flex',
95
+ flexDirection: 'column',
96
+ overflow: 'hidden',
97
+ flex: 1,
98
+ }, children: [(0, jsx_runtime_1.jsx)(react_components_1.Caption1Strong, { children: authSession?.fullName }), (0, jsx_runtime_1.jsx)(react_components_1.Caption1, { style: { textOverflow: 'ellipsis', overflow: 'hidden' }, children: authSession?.email })] })] })), !isSkipAuthCheck && (0, jsx_runtime_1.jsx)(react_components_1.MenuDivider, { style: { marginInline: 0 } }), (0, jsx_runtime_1.jsxs)(react_components_1.MenuList, { style: { width: 200, marginBottom: 4 }, children: [accountMenuItems?.map((item) => {
99
+ const Icon = item.icon;
100
+ return ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: (0, jsx_runtime_1.jsx)(Icon, { size: "inherit" }), onClick: () => {
101
+ if (item.onClick) {
102
+ item.onClick();
103
+ }
104
+ else if (item.link) {
105
+ router.push(basePath + item.link);
106
+ }
107
+ }, children: item.localizedLabel?.[language] ?? item.label }, item.__key));
108
+ }), !isSkipAuthCheck && ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.SignOut, {}), onClick: () => logout(), children: strings.logout }))] })] })] }))] }));
109
+ };
110
+ const AppDesktopHeader = ({ onNavToggle }) => {
111
+ const isTablet = (0, hooks_2.useIsTablet)();
112
+ return ((0, jsx_runtime_1.jsxs)("div", { style: {
113
+ display: 'flex',
114
+ alignItems: 'center',
115
+ height: 50,
116
+ minHeight: 50,
117
+ background: react_components_1.tokens.colorBrandBackground,
118
+ paddingInline: 8,
119
+ gap: 8,
120
+ color: 'white',
121
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flex: 1, alignItems: 'center', gap: 8 }, children: [isTablet && (0, jsx_runtime_1.jsx)(NavHamburger, { onNavToggle: onNavToggle }), (0, jsx_runtime_1.jsx)(NavTitle, {})] }), (0, jsx_runtime_1.jsx)(NavActions, {})] }));
122
+ };
123
+ const AppMobileHeader = ({ onNavToggle }) => {
124
+ const showCustomHeader = (0, mutable_1.useContextSelector)(header_1.HeaderContext, (state) => state.showBackButton.length > 0);
125
+ const headerTitle = (0, header_1.useHeaderValue)('title');
126
+ const rightComponent = (0, header_1.useHeaderValue)('rightComponent');
127
+ const showBackButton = (0, header_1.useHeaderValue)('showBackButton');
38
128
  return ((0, jsx_runtime_1.jsxs)("div", { style: {
39
129
  display: 'flex',
40
130
  alignItems: 'center',
@@ -43,52 +133,18 @@ const AppHeaderContainer = ({ onNavToggle, }) => {
43
133
  background: react_components_1.tokens.colorBrandBackground,
44
134
  paddingInline: 8,
45
135
  gap: 8,
46
- }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flex: 1, alignItems: 'center', gap: 8 }, children: [isTablet && ((0, jsx_runtime_1.jsx)("div", { role: "button", style: {
47
- cursor: 'pointer',
48
- width: !isMobile ? 44 : undefined,
49
- display: 'flex',
50
- flexDirection: 'row',
51
- justifyContent: 'center',
52
- alignItems: 'center',
53
- }, onClick: onNavToggle, children: (0, jsx_runtime_1.jsx)(react_nav_preview_1.Hamburger, { style: { color: 'white' } }) })), (0, jsx_runtime_1.jsxs)("div", { style: {
54
- display: 'flex',
55
- alignItems: 'center',
56
- cursor: 'pointer',
57
- color: 'white',
58
- }, children: [(0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', paddingLeft: 4, paddingRight: 6 }, children: (0, jsx_runtime_1.jsx)(AppLogo_1.AppLogo, { logo: app.logo, title: app.title }) }), (0, jsx_runtime_1.jsx)(react_components_1.Subtitle2, { style: { paddingLeft: 4 }, children: app.title })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: {
59
- paddingLeft: 8,
136
+ color: 'white',
137
+ zIndex: 10,
138
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
60
139
  display: 'flex',
61
- gap: 16,
62
- }, children: [(0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', gap: 8 }, children: quickActionItems?.map((item) => {
63
- if (item.type === 'custom') {
64
- return (0, jsx_runtime_1.jsx)(item.Component, {}, item.__key);
65
- }
66
- return ((0, jsx_runtime_1.jsx)(QuickActionItem_1.QuickActionItem, { Icon: item.icon, label: item.localizedLabel?.[language] ?? item.label, onClick: () => item.onClick?.(), link: item.link }, item.__key));
67
- }) }), (!isSkipAuthCheck || !!accountMenuItems?.length) && ((0, jsx_runtime_1.jsxs)(react_components_1.Popover, { children: [(0, jsx_runtime_1.jsx)(react_components_1.PopoverTrigger, { disableButtonEnhancement: true, children: (0, jsx_runtime_1.jsx)(react_components_1.Avatar, { initials: initials, color: "neutral", style: { cursor: 'pointer' }, image: {
68
- src: authSession?.profilePicture,
69
- } }) }), (0, jsx_runtime_1.jsxs)(react_components_1.PopoverSurface, { tabIndex: -1, style: { padding: 0 }, children: [!isSkipAuthCheck && ((0, jsx_runtime_1.jsxs)("div", { style: {
70
- display: 'flex',
71
- gap: 8,
72
- padding: 8,
73
- overflow: 'hidden',
74
- width: 200,
75
- }, children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(react_components_1.Avatar, { initials: initials, color: "neutral", image: {
76
- src: authSession?.profilePicture,
77
- } }) }), (0, jsx_runtime_1.jsxs)("div", { style: {
78
- display: 'flex',
79
- flexDirection: 'column',
80
- overflow: 'hidden',
81
- flex: 1,
82
- }, children: [(0, jsx_runtime_1.jsx)(react_components_1.Caption1Strong, { children: authSession?.fullName }), (0, jsx_runtime_1.jsx)(react_components_1.Caption1, { style: { textOverflow: 'ellipsis', overflow: 'hidden' }, children: authSession?.email })] })] })), !isSkipAuthCheck && (0, jsx_runtime_1.jsx)(react_components_1.MenuDivider, { style: { marginInline: 0 } }), (0, jsx_runtime_1.jsxs)(react_components_1.MenuList, { style: { width: 200, marginBottom: 4 }, children: [accountMenuItems?.map((item) => {
83
- const Icon = item.icon;
84
- return ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: (0, jsx_runtime_1.jsx)(Icon, { size: "inherit" }), onClick: () => {
85
- if (item.onClick) {
86
- item.onClick();
87
- }
88
- else if (item.link) {
89
- router.push(basePath + item.link);
90
- }
91
- }, children: item.localizedLabel?.[language] ?? item.label }, item.__key));
92
- }), !isSkipAuthCheck && ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.SignOut, {}), onClick: () => logout(), children: strings.logout }))] })] })] }))] })] }));
140
+ flex: 1,
141
+ alignItems: 'center',
142
+ gap: 8,
143
+ overflow: 'hidden',
144
+ }, children: [showBackButton ? ((0, jsx_runtime_1.jsx)(NavBackButton, {})) : ((0, jsx_runtime_1.jsx)(NavHamburger, { onNavToggle: onNavToggle })), showCustomHeader ? ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: typeof headerTitle === 'string' ? ((0, jsx_runtime_1.jsx)(react_components_1.Subtitle2, { style: {
145
+ textOverflow: 'ellipsis',
146
+ whiteSpace: 'nowrap',
147
+ overflow: 'hidden',
148
+ flex: 1,
149
+ }, children: headerTitle })) : (headerTitle) })) : ((0, jsx_runtime_1.jsx)(NavTitle, {}))] }), showCustomHeader ? rightComponent : (0, jsx_runtime_1.jsx)(NavActions, {})] }));
93
150
  };
94
- exports.AppHeaderContainer = AppHeaderContainer;
@@ -8,6 +8,7 @@ interface QuickActionItemProps {
8
8
  onClick?: () => void;
9
9
  badgeCount?: number;
10
10
  badgeColor?: BadgeProps['color'];
11
+ type?: 'button' | 'icon';
11
12
  }
12
13
  export declare const QuickActionItem: FC<QuickActionItemProps>;
13
14
  export {};
@@ -23,12 +23,16 @@ const useStyles = (0, react_components_1.makeStyles)({
23
23
  },
24
24
  },
25
25
  });
26
- const QuickActionItem = ({ label, Icon, onClick, link, badgeCount, badgeColor = 'informative', }) => {
26
+ const QuickActionItem = ({ label, Icon, onClick, link, badgeCount, badgeColor = 'informative', type = 'icon', }) => {
27
27
  const styles = useStyles();
28
28
  const router = (0, route_1.useRouter)();
29
29
  const basePath = (0, route_1.useBasePath)();
30
30
  const fullLink = link ? `${basePath}${link}` : undefined;
31
- return ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Icon, { size: "inherit" }), !!badgeCount && ((0, jsx_runtime_1.jsx)(react_components_1.Badge, { style: { position: 'absolute', top: 0, right: 0 }, color: badgeColor, size: "small", children: badgeCount }))] }), appearance: "transparent", style: { position: 'relative' }, as: "a", href: fullLink, title: label, className: styles.root, onClick: (event) => {
31
+ return ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Icon, { size: "inherit" }), !!badgeCount && ((0, jsx_runtime_1.jsx)(react_components_1.Badge, { style: { position: 'absolute', top: 0, right: 0 }, color: badgeColor, size: "small", children: badgeCount }))] }), appearance: "transparent", style: {
32
+ position: 'relative',
33
+ fontWeight: react_components_1.tokens.fontWeightRegular,
34
+ minWidth: 'unset',
35
+ }, as: "a", href: fullLink, title: label, className: styles.root, onClick: (event) => {
32
36
  event.preventDefault();
33
37
  if (fullLink) {
34
38
  router.push(fullLink);
@@ -36,6 +40,6 @@ const QuickActionItem = ({ label, Icon, onClick, link, badgeCount, badgeColor =
36
40
  else if (onClick) {
37
41
  onClick();
38
42
  }
39
- } }));
43
+ }, children: type === 'button' ? label : '' }));
40
44
  };
41
45
  exports.QuickActionItem = QuickActionItem;
@@ -6,12 +6,14 @@ const react_components_1 = require("@fluentui/react-components");
6
6
  const ScrollbarWithMoreDataRequest_1 = require("@headless-adminapp/app/components/ScrollbarWithMoreDataRequest");
7
7
  const datagrid_1 = require("@headless-adminapp/app/datagrid");
8
8
  const hooks_1 = require("@headless-adminapp/app/datagrid/hooks");
9
+ const hooks_2 = require("@headless-adminapp/app/hooks");
9
10
  const locale_1 = require("@headless-adminapp/app/locale");
10
11
  const mutable_1 = require("@headless-adminapp/app/mutable");
11
12
  const navigation_1 = require("@headless-adminapp/app/navigation");
12
13
  const react_virtual_1 = require("@tanstack/react-virtual");
13
14
  const react_1 = require("react");
14
15
  const uuid_1 = require("uuid");
16
+ const MobileHeaderCommandContainer_1 = require("../Header/MobileHeaderCommandContainer");
15
17
  const RecordCard_1 = require("../PageEntityForm/RecordCard");
16
18
  const RecordCardLoading_1 = require("../PageEntityForm/RecordCardLoading");
17
19
  const useStyles = (0, react_components_1.makeStyles)({
@@ -23,12 +25,13 @@ const useStyles = (0, react_components_1.makeStyles)({
23
25
  });
24
26
  const fallbackData = [];
25
27
  const GridListContainer = () => {
26
- const styles = useStyles();
27
28
  const data = (0, hooks_1.useGridData)();
28
29
  const dataState = (0, hooks_1.useGridDataState)();
29
30
  const fetchNextPage = (0, mutable_1.useContextSelector)(datagrid_1.GridContext, (state) => state.fetchNextPage);
30
31
  const schema = (0, hooks_1.useDataGridSchema)();
31
32
  const view = (0, hooks_1.useSelectedView)();
33
+ const [showContextMenu, setShowContextMenu] = (0, react_1.useState)(false);
34
+ const [selectedIds, setSelectedIds] = (0, hooks_1.useGridSelection)();
32
35
  const tableWrapperRef = (0, react_1.useRef)(null);
33
36
  const { direction } = (0, locale_1.useLocale)();
34
37
  const dataRef = (0, react_1.useRef)(data);
@@ -57,38 +60,63 @@ const GridListContainer = () => {
57
60
  recordSetIds: dataRef.current?.records.map((x) => x[schema.idAttribute]) ?? [],
58
61
  });
59
62
  }, [openFormInternal, schema.idAttribute, schema.logicalName]);
60
- return ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flex: 1, flexDirection: 'column' }, children: (0, jsx_runtime_1.jsx)(ScrollbarWithMoreDataRequest_1.ScrollbarWithMoreDataRequest, { data: data?.records, hasMore: dataState?.hasNextPage, rtl: direction === 'rtl', onRequestMore: () => {
63
+ const isSubgrid = (0, mutable_1.useContextSelector)(datagrid_1.GridContext, (state) => state.isSubGrid);
64
+ const contextCommands = isSubgrid
65
+ ? // eslint-disable-next-line react-hooks/rules-of-hooks
66
+ (0, hooks_1.useSubGridContextCommands)()
67
+ : // eslint-disable-next-line react-hooks/rules-of-hooks
68
+ (0, hooks_1.useMainGridContextCommands)();
69
+ return ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flex: 1, flexDirection: 'column' }, children: (0, jsx_runtime_1.jsxs)(ScrollbarWithMoreDataRequest_1.ScrollbarWithMoreDataRequest, { data: data?.records, hasMore: dataState?.hasNextPage, rtl: direction === 'rtl', onRequestMore: () => {
61
70
  fetchNextPage();
62
- }, children: (0, jsx_runtime_1.jsx)("div", { style: {
63
- position: 'relative',
64
- }, ref: tableWrapperRef, children: (0, jsx_runtime_1.jsxs)("div", { style: {
65
- display: 'flex',
66
- flexDirection: 'column',
67
- width: '100%',
68
- height: virtualizer.getTotalSize(),
69
- }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
70
- display: 'flex',
71
- flexDirection: 'column',
72
- }, children: virtualItems.map((virtualRow) => {
73
- const row = rows[virtualRow.index];
74
- return ((0, jsx_runtime_1.jsxs)("div", { ref: virtualizer.measureElement, "data-index": virtualRow.index, style: {
75
- width: '100%',
76
- position: 'absolute',
77
- transform: `translateY(${virtualRow.start}px)`,
78
- }, children: [virtualRow.index > 0 && ((0, jsx_runtime_1.jsx)("div", { style: { paddingBlock: 0 }, children: (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }) })), (0, jsx_runtime_1.jsx)("div", { className: (0, react_components_1.mergeClasses)(styles.root), style: {
79
- width: '100%',
80
- cursor: 'pointer',
81
- borderRadius: react_components_1.tokens.borderRadiusMedium,
82
- }, onClick: () => {
83
- const id = row[schema.idAttribute];
84
- openRecord(id);
85
- }, children: (0, jsx_runtime_1.jsx)(RecordCard_1.RecordCard, { cardView: view.experience.card, record: row, schema: schema, selected: false }) })] }, virtualRow.key));
86
- }) }), dataState.isFetching && ((0, jsx_runtime_1.jsx)("div", { style: {
87
- display: 'flex',
88
- flexDirection: 'column',
89
- width: '100%',
90
- position: 'absolute',
91
- transform: `translateY(${virtualSize}px)`,
92
- }, children: Array.from({ length: 10 }).map((_, index) => ((0, jsx_runtime_1.jsx)(RecordCardLoading_1.RecordCardLoading, { cardView: view.experience.card }, index))) }))] }) }) }) }));
71
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
72
+ position: 'relative',
73
+ }, ref: tableWrapperRef, children: (0, jsx_runtime_1.jsxs)("div", { style: {
74
+ display: 'flex',
75
+ flexDirection: 'column',
76
+ width: '100%',
77
+ height: virtualizer.getTotalSize(),
78
+ }, children: [(0, jsx_runtime_1.jsx)("div", { style: {
79
+ display: 'flex',
80
+ flexDirection: 'column',
81
+ }, children: virtualItems.map((virtualRow) => {
82
+ const row = rows[virtualRow.index];
83
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: virtualizer.measureElement, "data-index": virtualRow.index, style: {
84
+ width: '100%',
85
+ position: 'absolute',
86
+ transform: `translateY(${virtualRow.start}px)`,
87
+ }, children: [virtualRow.index > 0 && ((0, jsx_runtime_1.jsx)("div", { style: { paddingBlock: 0 }, children: (0, jsx_runtime_1.jsx)(react_components_1.Divider, { style: { opacity: 0.2 } }) })), (0, jsx_runtime_1.jsx)(Item, { card: view.experience.card, record: row, schema: schema, onClick: () => {
88
+ const id = row[schema.idAttribute];
89
+ openRecord(id);
90
+ }, onLongPress: () => {
91
+ const id = row[schema.idAttribute];
92
+ setSelectedIds([id]);
93
+ setShowContextMenu(true);
94
+ }, selected: selectedIds.includes(row[schema.idAttribute]) })] }, virtualRow.key));
95
+ }) }), dataState.isFetching && ((0, jsx_runtime_1.jsx)("div", { style: {
96
+ display: 'flex',
97
+ flexDirection: 'column',
98
+ width: '100%',
99
+ position: 'absolute',
100
+ transform: `translateY(${virtualSize}px)`,
101
+ }, children: Array.from({ length: 10 }).map((_, index) => ((0, jsx_runtime_1.jsx)(RecordCardLoading_1.RecordCardLoading, { cardView: view.experience.card }, index))) }))] }) }), (0, jsx_runtime_1.jsx)("div", { style: { height: 'env(safe-area-inset-bottom)' } }), (0, jsx_runtime_1.jsx)(MobileHeaderCommandContainer_1.BottomDrawerMenu, { open: showContextMenu, onClose: () => setShowContextMenu(false), actions: contextCommands })] }) }));
93
102
  };
94
103
  exports.GridListContainer = GridListContainer;
104
+ const Item = ({ onClick, onLongPress, card, record, schema, selected, }) => {
105
+ const styles = useStyles();
106
+ const isLongPress = (0, react_1.useRef)(false);
107
+ const onLongPressInternal = () => {
108
+ onLongPress?.();
109
+ isLongPress.current = true;
110
+ };
111
+ const longPressEvent = (0, hooks_2.useLongPress)(onLongPressInternal, {
112
+ isPreventDefault: false,
113
+ delay: 500,
114
+ });
115
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, react_components_1.mergeClasses)(styles.root), style: {
116
+ width: '100%',
117
+ cursor: 'pointer',
118
+ borderRadius: react_components_1.tokens.borderRadiusMedium,
119
+ userSelect: 'none',
120
+ WebkitUserSelect: 'none',
121
+ }, ...longPressEvent, onClick: onClick, children: (0, jsx_runtime_1.jsx)(RecordCard_1.RecordCard, { cardView: card, record: record, schema: schema, selected: selected }) }));
122
+ };
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const MobileHeaderRightContainer: FC;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MobileHeaderRightContainer = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const datagrid_1 = require("@headless-adminapp/app/datagrid");
6
+ const MobileHeaderCommandContainer_1 = require("../Header/MobileHeaderCommandContainer");
7
+ const MobileHeaderRightContainer = () => {
8
+ const commands = (0, datagrid_1.useMainGridCommands)();
9
+ return (0, jsx_runtime_1.jsx)(MobileHeaderCommandContainer_1.MobileHeaderCommandContainer, { commands: commands });
10
+ };
11
+ exports.MobileHeaderRightContainer = MobileHeaderRightContainer;
@@ -0,0 +1,13 @@
1
+ import { CommandItemState } from '@headless-adminapp/app/command';
2
+ import { FC } from 'react';
3
+ interface MobileHeaderCommandContainerProps {
4
+ commands: CommandItemState[][];
5
+ }
6
+ export declare const MobileHeaderCommandContainer: FC<MobileHeaderCommandContainerProps>;
7
+ interface BottomDrawerMenuProps {
8
+ open: boolean;
9
+ onClose: () => void;
10
+ actions: CommandItemState[][];
11
+ }
12
+ export declare const BottomDrawerMenu: FC<BottomDrawerMenuProps>;
13
+ export {};
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BottomDrawerMenu = exports.MobileHeaderCommandContainer = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_components_1 = require("@fluentui/react-components");
6
+ const MobileHeaderRightContent_1 = require("@headless-adminapp/app/header/components/MobileHeaderRightContent");
7
+ const icons_1 = require("@headless-adminapp/icons");
8
+ const react_1 = require("react");
9
+ const QuickActionItem_1 = require("../App/QuickActionItem");
10
+ const MobileHeaderQuickActionButton_1 = require("./MobileHeaderQuickActionButton");
11
+ const useStyles = (0, react_components_1.makeStyles)({
12
+ dangerMenuItem: {
13
+ color: react_components_1.tokens.colorStatusDangerForeground1,
14
+ '&:hover': {
15
+ backgroundColor: react_components_1.tokens.colorStatusDangerBackground3Hover,
16
+ },
17
+ '&:active': {
18
+ backgroundColor: react_components_1.tokens.colorStatusDangerBackground3Pressed,
19
+ },
20
+ },
21
+ });
22
+ function isQuickAction(command) {
23
+ if (command.type === 'button') {
24
+ return command.isQuickAction ?? false;
25
+ }
26
+ return false;
27
+ }
28
+ const MobileHeaderCommandContainer = ({ commands }) => {
29
+ const [showMoreActions, setShowMoreActions] = (0, react_1.useState)(false);
30
+ const quickActions = (0, react_1.useMemo)(() => {
31
+ return commands.flat().filter((command) => isQuickAction(command));
32
+ }, [commands]);
33
+ const moreActions = (0, react_1.useMemo)(() => {
34
+ return commands
35
+ .map((group) => {
36
+ return group.filter((command) => {
37
+ if (isQuickAction(command)) {
38
+ return false;
39
+ }
40
+ if (command.type === 'icon') {
41
+ return false;
42
+ }
43
+ return true;
44
+ });
45
+ })
46
+ .filter((group) => group.length > 0);
47
+ }, [commands]);
48
+ return ((0, jsx_runtime_1.jsxs)(MobileHeaderRightContent_1.MobileHeaderRightContent, { children: [(0, jsx_runtime_1.jsx)("div", { style: {
49
+ paddingLeft: 8,
50
+ display: 'flex',
51
+ gap: 16,
52
+ }, children: (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: 8 }, children: [quickActions.map((command, index) => {
53
+ if (command.hidden || command.type !== 'button') {
54
+ return null;
55
+ }
56
+ return ((0, jsx_runtime_1.jsx)(MobileHeaderQuickActionButton_1.MobileHeaderQuickActionButton, { title: command.text, Icon: command.Icon, onClick: command.onClick }, index));
57
+ }), moreActions.length > 0 && ((0, jsx_runtime_1.jsx)(QuickActionItem_1.QuickActionItem, { Icon: icons_1.Icons.MoreVertical, label: "More Actions", onClick: () => setShowMoreActions(true) }))] }) }), (0, jsx_runtime_1.jsx)(exports.BottomDrawerMenu, { open: showMoreActions, onClose: () => setShowMoreActions(false), actions: moreActions })] }));
58
+ };
59
+ exports.MobileHeaderCommandContainer = MobileHeaderCommandContainer;
60
+ const BottomDrawerMenu = ({ open, onClose, actions, }) => {
61
+ const [subMenuStack, setSubMenuStack] = (0, react_1.useState)([]);
62
+ (0, react_1.useEffect)(() => {
63
+ setSubMenuStack([]);
64
+ }, [open]);
65
+ const pushStack = (items) => {
66
+ setSubMenuStack((prev) => [items, ...prev]);
67
+ };
68
+ const popStack = () => {
69
+ setSubMenuStack((prev) => {
70
+ if (prev.length > 1) {
71
+ return prev.slice(1);
72
+ }
73
+ return [];
74
+ });
75
+ };
76
+ return ((0, jsx_runtime_1.jsx)(react_components_1.Drawer, { separator: true, open: open, position: "bottom", size: "small", style: {
77
+ borderTopLeftRadius: react_components_1.tokens.borderRadiusXLarge,
78
+ borderTopRightRadius: react_components_1.tokens.borderRadiusXLarge,
79
+ height: 'unset',
80
+ }, onOpenChange: () => { }, children: (0, jsx_runtime_1.jsxs)(react_components_1.DrawerBody, { style: {
81
+ maxHeight: '70vh',
82
+ padding: 0,
83
+ overflowY: 'hidden',
84
+ display: 'flex',
85
+ flexDirection: 'column',
86
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
87
+ paddingInline: react_components_1.tokens.spacingHorizontalM,
88
+ paddingBlock: react_components_1.tokens.spacingVerticalS,
89
+ boxShadow: react_components_1.tokens.shadow2,
90
+ zIndex: 1,
91
+ display: 'flex',
92
+ justifyContent: 'space-between',
93
+ alignItems: 'center',
94
+ }, children: [subMenuStack.length ? ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.ChevronLeft, { size: 20 }), appearance: "subtle", onClick: popStack })) : ((0, jsx_runtime_1.jsx)("div", {})), !subMenuStack.length && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.Close, { size: 20 }), appearance: "subtle", onClick: onClose }))] }), (0, jsx_runtime_1.jsxs)("div", { style: {
95
+ overflowY: 'auto',
96
+ overflowX: 'hidden',
97
+ }, children: [!subMenuStack.length && ((0, jsx_runtime_1.jsx)(react_components_1.MenuList, { hasIcons: true, style: { gap: 0 }, children: actions.map((group, groupIndex) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [groupIndex > 0 && ((0, jsx_runtime_1.jsx)(react_components_1.MenuDivider, { style: { opacity: 0.2, margin: '0px 5px' } })), group.map((item, index) => {
98
+ if (item.hidden) {
99
+ return null;
100
+ }
101
+ if (item.type === 'button') {
102
+ return ((0, jsx_runtime_1.jsx)(ButtonItem, { text: item.text, Icon: item.Icon, danger: item.danger, onClick: () => {
103
+ onClose();
104
+ item.onClick?.();
105
+ } }, `${groupIndex}-${index}`));
106
+ }
107
+ if (item.type === 'menu') {
108
+ return ((0, jsx_runtime_1.jsx)(NavigationMenu, { text: item.text, Icon: item.Icon, danger: item.danger, showDivider: item.items.length > 0 && !!item.onClick, showNavigateButton: item.items.length > 0, onNavigate: () => {
109
+ pushStack(item.items);
110
+ }, onClick: () => {
111
+ if (item.onClick) {
112
+ onClose();
113
+ item.onClick();
114
+ }
115
+ else {
116
+ pushStack(item.items);
117
+ }
118
+ } }, `${groupIndex}-${index}`));
119
+ }
120
+ })] }, groupIndex))) })), subMenuStack.length > 0 && ((0, jsx_runtime_1.jsx)(react_components_1.MenuList, { hasIcons: true, style: { gap: 0 }, children: subMenuStack[0].map((group, groupIndex) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [groupIndex > 0 && ((0, jsx_runtime_1.jsx)(react_components_1.MenuDivider, { style: { opacity: 0.2, margin: '0px 5px' } })), group.map((item, index) => {
121
+ if (item.hidden) {
122
+ return null;
123
+ }
124
+ return ((0, jsx_runtime_1.jsx)(NavigationMenu, { text: item.text, Icon: item.Icon, danger: item.danger, showDivider: !!item.items?.length && !!item.onClick, showNavigateButton: !!item.items?.length, onNavigate: () => {
125
+ if (!item.items?.length) {
126
+ return;
127
+ }
128
+ pushStack(item.items);
129
+ }, onClick: () => {
130
+ if (item.onClick) {
131
+ onClose();
132
+ item.onClick();
133
+ }
134
+ else if (item.items?.length) {
135
+ pushStack(item.items);
136
+ }
137
+ } }, `${groupIndex}-${index}`));
138
+ })] }, groupIndex))) }))] }), (0, jsx_runtime_1.jsx)("div", { style: { height: 'env(safe-area-inset-bottom)' } })] }) }));
139
+ };
140
+ exports.BottomDrawerMenu = BottomDrawerMenu;
141
+ const NavigationMenu = ({ Icon, danger, text, onClick, onNavigate, showDivider, showNavigateButton, }) => {
142
+ const styles = useStyles();
143
+ return ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: Icon ? (0, jsx_runtime_1.jsx)(Icon, { size: 20 }) : (0, jsx_runtime_1.jsx)(icons_1.IconPlaceholder, { size: 20 }), className: (0, react_components_1.mergeClasses)(danger && styles.dangerMenuItem), style: {
144
+ maxWidth: 'unset',
145
+ minHeight: 48,
146
+ alignItems: 'center',
147
+ paddingInline: react_components_1.tokens.spacingHorizontalM,
148
+ }, onClick: () => {
149
+ onClick?.();
150
+ }, children: (0, jsx_runtime_1.jsxs)("div", { style: {
151
+ display: 'flex',
152
+ flexDirection: 'row',
153
+ alignItems: 'center',
154
+ gap: 8,
155
+ }, children: [(0, jsx_runtime_1.jsx)("span", { style: { flex: 1 }, children: text }), showNavigateButton && showDivider && ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(react_components_1.Divider, { vertical: true, style: { opacity: 0.5, height: '100%' } }) })), showNavigateButton && ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(icons_1.Icons.ChevronRight, { size: 20 }), onClick: (e) => {
156
+ e.stopPropagation();
157
+ onNavigate?.();
158
+ }, appearance: "subtle" }))] }) }));
159
+ };
160
+ const ButtonItem = ({ Icon, danger, text, onClick }) => {
161
+ const styles = useStyles();
162
+ return ((0, jsx_runtime_1.jsx)(react_components_1.MenuItem, { icon: Icon ? (0, jsx_runtime_1.jsx)(Icon, { size: 20 }) : (0, jsx_runtime_1.jsx)(icons_1.IconPlaceholder, { size: 20 }), className: (0, react_components_1.mergeClasses)(danger && styles.dangerMenuItem), style: {
163
+ maxWidth: 'unset',
164
+ minHeight: 48,
165
+ alignItems: 'center',
166
+ paddingInline: react_components_1.tokens.spacingHorizontalM,
167
+ }, onClick: onClick, children: text }));
168
+ };
@@ -0,0 +1,10 @@
1
+ import { Icon } from '@headless-adminapp/icons';
2
+ import { FC } from 'react';
3
+ interface MobileHeaderQuickActionButtonProps {
4
+ disabled?: boolean;
5
+ title: string;
6
+ Icon: Icon;
7
+ onClick?: () => void;
8
+ }
9
+ export declare const MobileHeaderQuickActionButton: FC<MobileHeaderQuickActionButtonProps>;
10
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MobileHeaderQuickActionButton = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_components_1 = require("@fluentui/react-components");
6
+ const useStyles = (0, react_components_1.makeStyles)({
7
+ root: {
8
+ color: 'inherit !important',
9
+ background: 'rgba(0, 0, 0, 0)',
10
+ transition: 'background 0.3s',
11
+ '&:hover:enabled': {
12
+ color: 'rgba(255, 255, 255, 1)',
13
+ background: 'rgba(0, 0, 0, 0.1)',
14
+ },
15
+ '&:active:enabled': {
16
+ color: 'rgba(255, 255, 255, 1)',
17
+ background: 'rgba(0, 0, 0, 0.2)',
18
+ },
19
+ '&:focus:enabled': {
20
+ color: 'rgba(255, 255, 255, 1)',
21
+ background: 'rgba(0, 0, 0, 0.2)',
22
+ },
23
+ '&:disabled': {
24
+ color: `${react_components_1.tokens.colorNeutralForegroundDisabled} !important`,
25
+ },
26
+ },
27
+ });
28
+ const MobileHeaderQuickActionButton = ({ disabled, title, Icon, onClick }) => {
29
+ const styles = useStyles();
30
+ return ((0, jsx_runtime_1.jsx)(react_components_1.Button, { icon: (0, jsx_runtime_1.jsx)(Icon, { size: "inherit" }), disabled: disabled, appearance: "transparent", style: {
31
+ position: 'relative',
32
+ fontWeight: react_components_1.tokens.fontWeightRegular,
33
+ minWidth: 'unset',
34
+ }, className: styles.root, onClick: onClick, children: title }));
35
+ };
36
+ exports.MobileHeaderQuickActionButton = MobileHeaderQuickActionButton;
@@ -19,7 +19,7 @@ const CommandBar_1 = __importDefault(require("../CommandBar"));
19
19
  const OverflowCommandBar_1 = require("../OverflowCommandBar");
20
20
  const CommandContainer = ({ skeleton }) => {
21
21
  const { language } = (0, locale_1.useLocale)();
22
- const gridCommands = (0, hooks_1.useMainFormCommands)();
22
+ const formCommands = (0, hooks_1.useMainFormCommands)();
23
23
  const router = (0, hooks_4.useRouter)();
24
24
  const isMobile = (0, hooks_2.useIsMobile)();
25
25
  const schema = (0, hooks_1.useDataFormSchema)();
@@ -62,8 +62,8 @@ const CommandContainer = ({ skeleton }) => {
62
62
  setRecordSetVisible,
63
63
  ]);
64
64
  const extendedCommands = (0, react_1.useMemo)(() => {
65
- return [...navigationCommands, ...gridCommands];
66
- }, [gridCommands, navigationCommands]);
65
+ return [...navigationCommands, ...formCommands];
66
+ }, [formCommands, navigationCommands]);
67
67
  if (skeleton) {
68
68
  return ((0, jsx_runtime_1.jsxs)(CommandBar_1.default.Wrapper, { overflow: "hidden", children: [navigationCommands.map((group, groupIndex) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [groupIndex > 0 && (0, jsx_runtime_1.jsx)(CommandBar_1.default.Divider, {}), group.map((item, index) => {
69
69
  const commandType = item.type;
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const MobileHeaderRightContainer: FC;