@donotdev/ui 0.0.13 → 0.0.15
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/dist/components/auth/AuthMenu.d.ts.map +1 -1
- package/dist/components/auth/AuthMenu.js +19 -20
- package/dist/components/common/FeatureCard.d.ts +3 -1
- package/dist/components/common/FeatureCard.d.ts.map +1 -1
- package/dist/components/common/FeatureCard.js +2 -2
- package/dist/components/common/ProgressBar.js +2 -2
- package/dist/components/common/TechBento.d.ts +14 -2
- package/dist/components/common/TechBento.d.ts.map +1 -1
- package/dist/components/common/TechBento.js +8 -9
- package/dist/components/cookie-consent/CookieConsent.d.ts.map +1 -1
- package/dist/components/cookie-consent/CookieConsent.js +3 -4
- package/dist/components/layout/components/DropdownNavigation.d.ts.map +1 -1
- package/dist/components/layout/components/DropdownNavigation.js +3 -12
- package/dist/components/layout/components/FloatingLanguageSwitcher.js +1 -1
- package/dist/components/layout/components/Notifications.d.ts +1 -3
- package/dist/components/layout/components/Notifications.d.ts.map +1 -1
- package/dist/components/layout/components/Notifications.js +4 -2
- package/dist/components/layout/components/header/AppBranding.d.ts.map +1 -1
- package/dist/components/layout/components/header/AppBranding.js +2 -1
- package/dist/components/layout/components/header/AppIcon.d.ts.map +1 -1
- package/dist/components/layout/components/header/AppIcon.js +5 -2
- package/dist/components/layout/components/header/CacheSettings.d.ts.map +1 -1
- package/dist/components/layout/components/header/CacheSettings.js +3 -1
- package/dist/components/layout/components/header/HeaderNavigation.d.ts +6 -0
- package/dist/components/layout/components/header/HeaderNavigation.d.ts.map +1 -1
- package/dist/components/layout/components/header/HeaderNavigation.js +12 -2
- package/dist/components/layout/components/index.d.ts +3 -0
- package/dist/components/layout/components/index.d.ts.map +1 -1
- package/dist/components/layout/components/index.js +3 -0
- package/dist/components/license/LicenseWatermark.d.ts.map +1 -1
- package/dist/components/license/LicenseWatermark.js +3 -1
- package/dist/crud/components/CrudCardLink.d.ts +17 -0
- package/dist/crud/components/CrudCardLink.d.ts.map +1 -0
- package/dist/crud/components/CrudCardLink.js +17 -0
- package/dist/crud/components/EntityCardList.d.ts +1 -1
- package/dist/crud/components/EntityCardList.d.ts.map +1 -1
- package/dist/crud/components/EntityCardList.js +38 -90
- package/dist/crud/components/EntityDisplayRenderer.d.ts +1 -1
- package/dist/crud/components/EntityDisplayRenderer.d.ts.map +1 -1
- package/dist/crud/components/EntityDisplayRenderer.js +11 -3
- package/dist/crud/components/EntityFormRenderer.d.ts +1 -1
- package/dist/crud/components/EntityFormRenderer.d.ts.map +1 -1
- package/dist/crud/components/EntityFormRenderer.js +34 -40
- package/dist/crud/components/EntityList.d.ts +1 -1
- package/dist/crud/components/EntityList.d.ts.map +1 -1
- package/dist/crud/components/EntityList.js +1 -1
- package/dist/crud/components/EntityRecommendations.d.ts +29 -0
- package/dist/crud/components/EntityRecommendations.d.ts.map +1 -0
- package/dist/crud/components/EntityRecommendations.js +32 -0
- package/dist/crud/components/index.d.ts +2 -1
- package/dist/crud/components/index.d.ts.map +1 -1
- package/dist/crud/components/index.js +1 -0
- package/dist/dndev.css +1021 -196
- package/dist/index.js +4 -4
- package/dist/internal/common/RouteErrorFallback.d.ts.map +1 -1
- package/dist/internal/devtools/components/AuthDebugButton.js +1 -1
- package/dist/internal/devtools/components/DesignTab.d.ts.map +1 -1
- package/dist/internal/devtools/components/DesignTab.js +3 -2
- package/dist/internal/devtools/components/LayoutReset.d.ts.map +1 -1
- package/dist/internal/devtools/components/LayoutReset.js +2 -0
- package/dist/internal/devtools/components/StoresTab.d.ts.map +1 -1
- package/dist/internal/devtools/components/StoresTab.js +3 -0
- package/dist/internal/devtools/utils/envVarDiscovery.d.ts +1 -0
- package/dist/internal/devtools/utils/envVarDiscovery.d.ts.map +1 -1
- package/dist/internal/devtools/utils/envVarDiscovery.js +5 -0
- package/dist/internal/devtools/utils/virtualModuleInspector.d.ts.map +1 -1
- package/dist/internal/devtools/utils/virtualModuleInspector.js +27 -21
- package/dist/internal/initializers/BaseStoresInitializer.d.ts.map +1 -1
- package/dist/internal/initializers/BaseStoresInitializer.js +30 -6
- package/dist/internal/layout/components/AutoMetaTags.d.ts.map +1 -1
- package/dist/internal/layout/components/AutoMetaTags.js +10 -8
- package/dist/internal/layout/components/FontPreloadLinks.d.ts +16 -0
- package/dist/internal/layout/components/FontPreloadLinks.d.ts.map +1 -0
- package/dist/internal/layout/components/FontPreloadLinks.js +32 -0
- package/dist/internal/layout/components/PerformanceHints.d.ts +7 -12
- package/dist/internal/layout/components/PerformanceHints.d.ts.map +1 -1
- package/dist/internal/layout/components/PerformanceHints.js +8 -12
- package/dist/internal/layout/components/footer/useLegalLinks.d.ts +6 -5
- package/dist/internal/layout/components/footer/useLegalLinks.d.ts.map +1 -1
- package/dist/internal/layout/components/footer/useLegalLinks.js +6 -2
- package/dist/internal/layout/zones/DnDevFooter.d.ts +6 -0
- package/dist/internal/layout/zones/DnDevFooter.d.ts.map +1 -1
- package/dist/internal/layout/zones/DnDevFooter.js +10 -4
- package/dist/internal/layout/zones/DnDevHeader.d.ts +7 -0
- package/dist/internal/layout/zones/DnDevHeader.d.ts.map +1 -1
- package/dist/internal/layout/zones/DnDevHeader.js +7 -0
- package/dist/internal/layout/zones/DnDevMergedBar.d.ts +7 -0
- package/dist/internal/layout/zones/DnDevMergedBar.d.ts.map +1 -1
- package/dist/internal/layout/zones/DnDevMergedBar.js +9 -0
- package/dist/internal/layout/zones/DnDevSidebar.d.ts +4 -0
- package/dist/internal/layout/zones/DnDevSidebar.d.ts.map +1 -1
- package/dist/internal/layout/zones/DnDevSidebar.js +13 -1
- package/dist/internal/providers/NavigationProvider.d.ts.map +1 -1
- package/dist/internal/providers/NavigationProvider.js +3 -5
- package/dist/next.d.ts +1 -0
- package/dist/next.d.ts.map +1 -1
- package/dist/next.js +1 -0
- package/dist/providers/ViteAppProviders.d.ts.map +1 -1
- package/dist/providers/ViteAppProviders.js +3 -5
- package/dist/routing/AuthGuard.d.ts +1 -1
- package/dist/routing/AuthGuard.d.ts.map +1 -1
- package/dist/routing/AuthGuard.js +3 -1
- package/dist/routing/GoTo.d.ts.map +1 -1
- package/dist/routing/GoTo.js +3 -1
- package/dist/routing/GoToDialog.d.ts.map +1 -1
- package/dist/routing/GoToDialog.js +2 -7
- package/dist/routing/GoToInput.d.ts +0 -3
- package/dist/routing/GoToInput.d.ts.map +1 -1
- package/dist/routing/GoToInput.js +8 -7
- package/dist/routing/Link.js +1 -1
- package/dist/routing/NavigationItem.d.ts +29 -7
- package/dist/routing/NavigationItem.d.ts.map +1 -1
- package/dist/routing/NavigationItem.js +22 -6
- package/dist/routing/hooks/hooks.next.js +1 -1
- package/dist/routing/hooks/hooks.vite.js +1 -1
- package/dist/routing/hooks/useNavigate.next.d.ts +1 -1
- package/dist/routing/hooks/useNavigate.next.d.ts.map +1 -1
- package/dist/routing/hooks/useNavigate.next.js +1 -7
- package/dist/routing/hooks/useNavigate.vite.d.ts +1 -1
- package/dist/routing/hooks/useNavigate.vite.d.ts.map +1 -1
- package/dist/routing/hooks/useNavigate.vite.js +1 -7
- package/dist/routing/hooks/useRedirectGuard.next.d.ts.map +1 -1
- package/dist/routing/hooks/useRedirectGuard.next.js +9 -8
- package/dist/routing/hooks/useRedirectGuard.vite.d.ts.map +1 -1
- package/dist/routing/hooks/useRedirectGuard.vite.js +9 -8
- package/dist/routing/hooks/useSearchParams.next.d.ts +18 -1
- package/dist/routing/hooks/useSearchParams.next.d.ts.map +1 -1
- package/dist/routing/hooks/useSearchParams.next.js +16 -0
- package/dist/routing/hooks/useSearchParams.vite.d.ts +16 -0
- package/dist/routing/hooks/useSearchParams.vite.d.ts.map +1 -1
- package/dist/routing/hooks/useSearchParams.vite.js +17 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +2 -0
- package/dist/routing/useNavigation.d.ts +30 -0
- package/dist/routing/useNavigation.d.ts.map +1 -1
- package/dist/routing/useNavigation.js +40 -3
- package/dist/routing/useRouteDiscovery.d.ts +6 -17
- package/dist/routing/useRouteDiscovery.d.ts.map +1 -1
- package/dist/routing/useRouteDiscovery.js +16 -9
- package/dist/styles/index.css +284 -88
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/sanitizeSvg.d.ts +13 -0
- package/dist/utils/sanitizeSvg.d.ts.map +1 -0
- package/dist/utils/sanitizeSvg.js +47 -0
- package/dist/utils/useBillingVisibility.d.ts.map +1 -1
- package/dist/utils/useBillingVisibility.js +0 -7
- package/dist/utils/useCrudSafe.d.ts +0 -2
- package/dist/utils/useCrudSafe.d.ts.map +1 -1
- package/dist/utils/useFormStoreSafe.d.ts +5 -16
- package/dist/utils/useFormStoreSafe.d.ts.map +1 -1
- package/dist/utils/useFormStoreSafe.js +6 -37
- package/dist/vite-routing/AppRoutes.d.ts +19 -8
- package/dist/vite-routing/AppRoutes.d.ts.map +1 -1
- package/dist/vite-routing/AppRoutes.js +0 -3
- package/dist/vite-routing/RootLayout.d.ts.map +1 -1
- package/dist/vite-routing/RootLayout.js +10 -15
- package/package.json +16 -12
- package/assets/fonts/fonts.css +0 -206
- package/dist/routing/Navigate.d.ts +0 -10
- package/dist/routing/Navigate.d.ts.map +0 -1
- package/dist/routing/Navigate.js +0 -10
|
@@ -15,10 +15,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
15
15
|
*/
|
|
16
16
|
import { useMemo, useCallback } from 'react';
|
|
17
17
|
import { Heart } from 'lucide-react';
|
|
18
|
-
import {
|
|
19
|
-
import { useTranslation } from '@donotdev/core';
|
|
18
|
+
import { Card, Grid, Stack, Text, Spinner, Section, Button, } from '@donotdev/components';
|
|
19
|
+
import { useTranslation, getListCardFieldNames } from '@donotdev/core';
|
|
20
20
|
import { useNavigate } from '../../routing';
|
|
21
|
-
import {
|
|
21
|
+
import { useCrudCardList, EntityFilters, useEntityFavorites, matchesFilter, useCrudFilters, } from '@donotdev/crud';
|
|
22
|
+
import { CrudCard } from './CrudCardLink';
|
|
22
23
|
/**
|
|
23
24
|
* Entity Card List Component - Card grid view for public/user-facing browsing
|
|
24
25
|
*
|
|
@@ -31,7 +32,7 @@ import { translateFieldLabel, useCrudCardList, EntityFilters, useEntityFavorites
|
|
|
31
32
|
* - Auto-routing when handler not provided
|
|
32
33
|
*/
|
|
33
34
|
export function EntityCardList({ entity, basePath, onClick, cols = [1, 2, 3, 4], staleTime = 1000 * 60 * 30, // 30 minutes default cache
|
|
34
|
-
filter, hideFilters = false, }) {
|
|
35
|
+
filter, hideFilters = false, resultLabel, tone, }) {
|
|
35
36
|
const navigate = useNavigate();
|
|
36
37
|
const base = basePath ?? `/${entity.collection}`;
|
|
37
38
|
// useCrudCardList -> handles fetching optimized for cards automatically
|
|
@@ -43,11 +44,7 @@ filter, hideFilters = false, }) {
|
|
|
43
44
|
});
|
|
44
45
|
// Favorites toggle from CrudStore (persists across navigation)
|
|
45
46
|
// Note: EntityFilters now manages its own filters internally via useCrudFilters
|
|
46
|
-
const { showFavoritesOnly, setShowFavoritesOnly } = useCrudFilters({
|
|
47
|
-
collection: entity.collection,
|
|
48
|
-
});
|
|
49
|
-
// Get filters for applying to data (EntityFilters manages its own state)
|
|
50
|
-
const { filters } = useCrudFilters({
|
|
47
|
+
const { showFavoritesOnly, setShowFavoritesOnly, filters } = useCrudFilters({
|
|
51
48
|
collection: entity.collection,
|
|
52
49
|
});
|
|
53
50
|
// Apply filters from EntityFilters component
|
|
@@ -86,96 +83,47 @@ filter, hideFilters = false, }) {
|
|
|
86
83
|
navigate(`${base}/${id}`);
|
|
87
84
|
}
|
|
88
85
|
}, [base, navigate, onClick]);
|
|
89
|
-
//
|
|
90
|
-
const
|
|
91
|
-
const cardFields = entity.listCardFields ?? entity.listFields;
|
|
92
|
-
if (cardFields && cardFields.length > 0)
|
|
93
|
-
return cardFields;
|
|
94
|
-
return Object.keys(entity.fields).slice(0, 4);
|
|
95
|
-
}, [entity.listCardFields, entity.listFields, entity.fields]);
|
|
96
|
-
// Find image field
|
|
97
|
-
const imageField = useMemo(() => {
|
|
98
|
-
const imageFieldsInList = fieldsToShow.filter((fieldName) => {
|
|
99
|
-
const fieldConfig = entity.fields[fieldName];
|
|
100
|
-
return fieldConfig?.type === 'image' || fieldConfig?.type === 'images';
|
|
101
|
-
});
|
|
102
|
-
if (imageFieldsInList.length > 0)
|
|
103
|
-
return imageFieldsInList[0];
|
|
104
|
-
// Fallback: search all entity fields
|
|
105
|
-
const allImageFields = Object.keys(entity.fields).filter((fieldName) => {
|
|
106
|
-
const fieldConfig = entity.fields[fieldName];
|
|
107
|
-
return fieldConfig?.type === 'image' || fieldConfig?.type === 'images';
|
|
108
|
-
});
|
|
109
|
-
return allImageFields[0] || null;
|
|
110
|
-
}, [fieldsToShow, entity.fields]);
|
|
111
|
-
// Get other fields (non-image)
|
|
112
|
-
const otherFields = useMemo(() => {
|
|
113
|
-
return fieldsToShow.filter((fieldName) => fieldName !== imageField);
|
|
114
|
-
}, [fieldsToShow, imageField]);
|
|
86
|
+
// Flat field names for filters (works with both string[] and ListCardLayout)
|
|
87
|
+
const fieldsToFilter = useMemo(() => getListCardFieldNames(entity), [entity]);
|
|
115
88
|
const entityName = t('name', { defaultValue: entity.name });
|
|
116
89
|
return (_jsxs(_Fragment, { children: [!hideFilters && (_jsx(Section, { title: tCrud('filters.title', {
|
|
117
90
|
entity: entityName,
|
|
118
91
|
defaultValue: `Browse ${entityName} - Filters`,
|
|
119
|
-
}), collapsible: true, defaultOpen: true, children: _jsxs(Stack, { direction: "column", children: [_jsx(Button, { variant: showFavoritesOnly ? 'primary' : 'outline', icon: _jsx(Heart, { size: 18 }), onClick: () => setShowFavoritesOnly(!showFavoritesOnly), children: showFavoritesOnly
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
92
|
+
}), collapsible: true, defaultOpen: true, tone: tone, children: _jsx(Card, { children: _jsxs(Stack, { direction: "column", children: [_jsx(Button, { variant: showFavoritesOnly ? 'primary' : 'outline', icon: _jsx(Heart, { size: 18 }), onClick: () => setShowFavoritesOnly(!showFavoritesOnly), children: showFavoritesOnly
|
|
93
|
+
? tCrud('favorites.showAll', { defaultValue: 'Show All' })
|
|
94
|
+
: tCrud('favorites.showFavorites', {
|
|
95
|
+
defaultValue: 'Show Favorites',
|
|
96
|
+
}) }), _jsx(EntityFilters, { entity: entity, data: rawData, fieldsToFilter: fieldsToFilter })] }) }) })), _jsx(Section, { title: loading
|
|
124
97
|
? tCrud('results.title.fetching', { defaultValue: 'Fetching...' })
|
|
125
|
-
:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
:
|
|
130
|
-
|
|
98
|
+
: resultLabel
|
|
99
|
+
? resultLabel(data.length)
|
|
100
|
+
: tCrud('results.title.count', {
|
|
101
|
+
count: data.length,
|
|
102
|
+
defaultValue: data.length === 1
|
|
103
|
+
? 'Found 1 occurrence'
|
|
104
|
+
: `Found ${data.length} occurrences`,
|
|
105
|
+
}), collapsible: true, defaultOpen: true, tone: tone, children: loading ? (_jsx(Stack, { align: "center", justify: "center", style: { padding: 'var(--gap-3xl)' }, children: _jsx(Spinner, {}) })) : data.length === 0 ? (_jsxs(Stack, { align: "center", justify: "center", style: { padding: 'var(--gap-3xl)', textAlign: 'center' }, children: [_jsx(Text, { level: "h3", style: { color: 'var(--muted-foreground)' }, children: tCrud('emptyState.title', {
|
|
131
106
|
defaultValue: `No ${entity.name.toLowerCase()} found`,
|
|
132
107
|
}) }), _jsx(Text, { style: { color: 'var(--muted-foreground)' }, children: tCrud('emptyState.description', {
|
|
133
108
|
defaultValue: `No ${entity.name.toLowerCase()} available at this time.`,
|
|
134
109
|
}) })] })) : (_jsx(Grid, { cols: cols, children: data.map((item) => {
|
|
135
|
-
const imageValue = imageField ? item[imageField] : null;
|
|
136
|
-
// Backend optimizes picture fields for listCard: returns thumbUrl string directly
|
|
137
|
-
// (or fullUrl if thumbUrl missing, or null if no picture)
|
|
138
|
-
const imageUrl = typeof imageValue === 'string' ? imageValue : null;
|
|
139
|
-
// Title from first non-image field
|
|
140
|
-
const titleField = otherFields[0];
|
|
141
|
-
const titleValue = titleField ? item[titleField] : item.id;
|
|
142
110
|
const itemIsFavorite = isFavorite(item.id);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
defaultValue: 'Add to favorites',
|
|
161
|
-
}) }), _jsxs(Stack, { direction: "column", children: [imageUrl && (_jsx("div", { style: {
|
|
162
|
-
width: '100%',
|
|
163
|
-
aspectRatio: '16/9',
|
|
164
|
-
borderRadius: 'var(--radius-md)',
|
|
165
|
-
overflow: 'hidden',
|
|
166
|
-
backgroundColor: 'var(--muted)',
|
|
167
|
-
position: 'relative',
|
|
168
|
-
}, children: _jsx("img", { src: imageUrl, alt: String(titleValue || ''), style: {
|
|
169
|
-
width: '100%',
|
|
170
|
-
height: '100%',
|
|
171
|
-
objectFit: 'cover',
|
|
172
|
-
} }) })), _jsx(Stack, { direction: "column", gap: "tight", children: otherFields.slice(1, 4).map((fieldName) => {
|
|
173
|
-
const fieldConfig = entity.fields[fieldName];
|
|
174
|
-
if (!fieldConfig)
|
|
175
|
-
return null;
|
|
176
|
-
return (_jsxs("div", { children: [_jsx(Text, { level: "small", variant: "muted", children: translateFieldLabel(fieldName, fieldConfig, t) }), _jsx(Text, { children: formatValue(item[fieldName], fieldConfig, t, {
|
|
177
|
-
compact: true,
|
|
178
|
-
}) })] }, fieldName));
|
|
179
|
-
}) })] })] }, item.id));
|
|
111
|
+
const detailHref = onClick ? undefined : `${base}/${item.id}`;
|
|
112
|
+
return (_jsx(CrudCard, { item: item, entity: entity, detailHref: detailHref, onClick: onClick ? () => handleView(item.id) : undefined, renderActions: _jsx(Heart, { fill: itemIsFavorite ? '#ef4444' : '#ffffff', stroke: itemIsFavorite ? '#ef4444' : 'var(--muted-foreground)', onClick: (e) => {
|
|
113
|
+
e.preventDefault();
|
|
114
|
+
e.stopPropagation();
|
|
115
|
+
toggleFavorite(item.id);
|
|
116
|
+
}, style: {
|
|
117
|
+
cursor: 'pointer',
|
|
118
|
+
width: 'var(--icon-md)',
|
|
119
|
+
height: 'var(--icon-md)',
|
|
120
|
+
transition: 'fill 0.2s, stroke 0.2s',
|
|
121
|
+
}, "aria-label": itemIsFavorite
|
|
122
|
+
? tCrud('favorites.remove', {
|
|
123
|
+
defaultValue: 'Remove from favorites',
|
|
124
|
+
})
|
|
125
|
+
: tCrud('favorites.add', {
|
|
126
|
+
defaultValue: 'Add to favorites',
|
|
127
|
+
}) }) }, item.id));
|
|
180
128
|
}) })) })] }));
|
|
181
129
|
}
|
|
@@ -16,6 +16,6 @@ export type { EntityDisplayRendererProps };
|
|
|
16
16
|
* <EntityDisplayRenderer entity={carEntity} id={carId} />
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
export declare function EntityDisplayRenderer<T extends EntityRecord = EntityRecord>({ entity, id, t, className,
|
|
19
|
+
export declare function EntityDisplayRenderer<T extends EntityRecord = EntityRecord>({ entity, id, t, className, loadingMessage, notFoundMessage, viewerRole: viewerRoleProp, excludeFields, }: EntityDisplayRendererProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
export default EntityDisplayRenderer;
|
|
21
21
|
//# sourceMappingURL=EntityDisplayRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityDisplayRenderer.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityDisplayRenderer.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"EntityDisplayRenderer.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityDisplayRenderer.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI/E,YAAY,EAAE,0BAA0B,EAAE,CAAC;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EAC3E,MAAM,EACN,EAAE,EACF,CAAC,EACD,SAAc,EACd,cAAc,EACd,eAAe,EACf,UAAU,EAAE,cAAc,EAC1B,aAAa,GACd,EAAE,0BAA0B,CAAC,CAAC,CAAC,2CAuM/B;AAED,eAAe,qBAAqB,CAAC"}
|
|
@@ -14,6 +14,7 @@ import { useEffect, useState, useMemo } from 'react';
|
|
|
14
14
|
import { Stack, Spinner } from '@donotdev/components';
|
|
15
15
|
import { useTranslation, isFieldVisible } from '@donotdev/core';
|
|
16
16
|
import { useCrud, DisplayFieldRenderer } from '@donotdev/crud';
|
|
17
|
+
import { useAuthSafe } from '../../utils/useAuthSafe';
|
|
17
18
|
/**
|
|
18
19
|
* EntityDisplayRenderer - Automatically fetches and displays entity data
|
|
19
20
|
*
|
|
@@ -30,8 +31,11 @@ import { useCrud, DisplayFieldRenderer } from '@donotdev/crud';
|
|
|
30
31
|
* <EntityDisplayRenderer entity={carEntity} id={carId} />
|
|
31
32
|
* ```
|
|
32
33
|
*/
|
|
33
|
-
export function EntityDisplayRenderer({ entity, id, t, className = '',
|
|
34
|
-
|
|
34
|
+
export function EntityDisplayRenderer({ entity, id, t, className = '', loadingMessage, notFoundMessage, viewerRole: viewerRoleProp, excludeFields, }) {
|
|
35
|
+
// Auto-detect role from auth; prop overrides
|
|
36
|
+
const authRole = useAuthSafe('userRole');
|
|
37
|
+
const viewerRole = viewerRoleProp ?? authRole;
|
|
38
|
+
const { get, loading, data: storeData, error: storeError, isAvailable, } = useCrud(entity);
|
|
35
39
|
const [isFetching, setIsFetching] = useState(false);
|
|
36
40
|
const [fetchError, setFetchError] = useState(null);
|
|
37
41
|
const [data, setData] = useState(null);
|
|
@@ -91,6 +95,10 @@ export function EntityDisplayRenderer({ entity, id, t, className = '', backend =
|
|
|
91
95
|
if (!displayData)
|
|
92
96
|
return [];
|
|
93
97
|
return Object.entries(entity.fields).filter(([fieldName, fieldConfig]) => {
|
|
98
|
+
// Skip excluded fields
|
|
99
|
+
if (excludeFields?.includes(fieldName)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
94
102
|
// Check visibility first
|
|
95
103
|
if (!isFieldVisible(fieldConfig.visibility, viewerRole)) {
|
|
96
104
|
return false;
|
|
@@ -122,7 +130,7 @@ export function EntityDisplayRenderer({ entity, id, t, className = '', backend =
|
|
|
122
130
|
}
|
|
123
131
|
return true;
|
|
124
132
|
});
|
|
125
|
-
}, [entity.fields, viewerRole, displayData]);
|
|
133
|
+
}, [entity.fields, viewerRole, displayData, excludeFields]);
|
|
126
134
|
// Loading state
|
|
127
135
|
if (isLoading) {
|
|
128
136
|
return (_jsx("div", { style: {
|
|
@@ -13,6 +13,6 @@ export type { EntityFormRendererProps };
|
|
|
13
13
|
* @since 0.0.1
|
|
14
14
|
* @author AMBROISE PARK Consulting
|
|
15
15
|
*/
|
|
16
|
-
export declare function EntityFormRenderer<T extends EntityRecord = EntityRecord>({ entity, onSubmit, t, className, submitText, loading, defaultValues, submitVariant, secondaryButtonText, secondaryButtonVariant, onSecondarySubmit, viewerRole, operation,
|
|
16
|
+
export declare function EntityFormRenderer<T extends EntityRecord = EntityRecord>({ entity, onSubmit, t, className, submitText, loading, defaultValues, submitVariant, secondaryButtonText, secondaryButtonVariant, onSecondarySubmit, viewerRole: viewerRoleProp, operation, formId: externalFormId, cancelText, cancelPath, successPath, onCancel, warnOnUnsavedChanges, unsavedChangesMessage, hideVisibilityInfo, }: EntityFormRendererProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export default EntityFormRenderer;
|
|
18
18
|
//# sourceMappingURL=EntityFormRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityFormRenderer.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityFormRenderer.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EACV,uBAAuB,EACvB,YAAY,EAEb,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,uBAAuB,EAAE,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EACxE,MAAM,EACN,QAAQ,EACR,CAAC,EACD,SAAc,EACd,UAAU,EACV,OAAe,EACf,aAAa,EACb,aAAyB,EACzB,mBAAmB,EACnB,sBAAkC,EAClC,iBAAiB,EACjB,UAAU,
|
|
1
|
+
{"version":3,"file":"EntityFormRenderer.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityFormRenderer.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EACV,uBAAuB,EACvB,YAAY,EAEb,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,uBAAuB,EAAE,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EACxE,MAAM,EACN,QAAQ,EACR,CAAC,EACD,SAAc,EACd,UAAU,EACV,OAAe,EACf,aAAa,EACb,aAAyB,EACzB,mBAAmB,EACnB,sBAAkC,EAClC,iBAAiB,EACjB,UAAU,EAAE,cAAc,EAC1B,SAA6C,EAC7C,MAAM,EAAE,cAAc,EACtB,UAAU,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,oBAA2B,EAC3B,qBAAqB,EACrB,kBAA0B,GAC3B,EAAE,uBAAuB,CAAC,CAAC,CAAC,2CAkb5B;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -15,7 +15,8 @@ import { FormProvider } from 'react-hook-form';
|
|
|
15
15
|
import { Badge, Button, DropdownMenu, Grid, Stack, Spinner, } from '@donotdev/components';
|
|
16
16
|
import { hasRoleAccess, useTranslation } from '@donotdev/core';
|
|
17
17
|
import { useNavigate } from '../../routing';
|
|
18
|
-
import { DisplayFieldRenderer, FormFieldRenderer, UploadProvider, useEntityForm, useUnsavedChangesWarning,
|
|
18
|
+
import { DisplayFieldRenderer, FormFieldRenderer, UploadProvider, useEntityForm, useUnsavedChangesWarning, useFormStore, } from '@donotdev/crud';
|
|
19
|
+
import { useAuthSafe } from '../../utils/useAuthSafe';
|
|
19
20
|
/**
|
|
20
21
|
* EntityFormRenderer - Dumb component that renders a form from entity definition.
|
|
21
22
|
*
|
|
@@ -29,8 +30,11 @@ import { DisplayFieldRenderer, FormFieldRenderer, UploadProvider, useEntityForm,
|
|
|
29
30
|
* @since 0.0.1
|
|
30
31
|
* @author AMBROISE PARK Consulting
|
|
31
32
|
*/
|
|
32
|
-
export function EntityFormRenderer({ entity, onSubmit, t, className = '', submitText, loading = false, defaultValues, submitVariant = 'primary', secondaryButtonText, secondaryButtonVariant = 'outline', onSecondarySubmit, viewerRole, operation = defaultValues ? 'edit' : 'create',
|
|
33
|
+
export function EntityFormRenderer({ entity, onSubmit, t, className = '', submitText, loading = false, defaultValues, submitVariant = 'primary', secondaryButtonText, secondaryButtonVariant = 'outline', onSecondarySubmit, viewerRole: viewerRoleProp, operation = defaultValues ? 'edit' : 'create', formId: externalFormId, cancelText, cancelPath, successPath, onCancel, warnOnUnsavedChanges = true, unsavedChangesMessage, hideVisibilityInfo = false, }) {
|
|
33
34
|
const navigate = useNavigate();
|
|
35
|
+
// Auto-detect role from auth; prop overrides (e.g. View-As preview)
|
|
36
|
+
const authRole = useAuthSafe('userRole');
|
|
37
|
+
const viewerRole = viewerRoleProp ?? authRole;
|
|
34
38
|
// Generate stable form ID
|
|
35
39
|
const generatedFormId = useId();
|
|
36
40
|
const formId = externalFormId ?? `entity-form-${entity.name}-${generatedFormId}`;
|
|
@@ -81,7 +85,6 @@ export function EntityFormRenderer({ entity, onSubmit, t, className = '', submit
|
|
|
81
85
|
defaultValues,
|
|
82
86
|
viewerRole,
|
|
83
87
|
t: translate,
|
|
84
|
-
autoSave,
|
|
85
88
|
});
|
|
86
89
|
const { control, handleSubmit, formState: { errors }, fields: rawFields, formStatus, uploadProgress, cleanup, isDirty, hasUserInteracted, resetForm, } = form;
|
|
87
90
|
const isDirtyForBlocking = isDirty && hasUserInteracted;
|
|
@@ -102,6 +105,7 @@ export function EntityFormRenderer({ entity, onSubmit, t, className = '', submit
|
|
|
102
105
|
});
|
|
103
106
|
}, [rawFields, canPreviewRole, previewRole]);
|
|
104
107
|
// Sync isDirty to FormStore (single source of truth)
|
|
108
|
+
// Use getState() to avoid subscribing to the action reference (Zustand anti-pattern)
|
|
105
109
|
useEffect(() => {
|
|
106
110
|
if (formId) {
|
|
107
111
|
useFormStore.getState().setIsDirty(formId, isDirtyForBlocking);
|
|
@@ -116,57 +120,47 @@ export function EntityFormRenderer({ entity, onSubmit, t, className = '', submit
|
|
|
116
120
|
tCrud('messages.unsavedChangesLeave', {
|
|
117
121
|
defaultValue: 'You have unsaved changes. Are you sure you want to leave?',
|
|
118
122
|
}), [unsavedChangesMessage, tCrud]);
|
|
119
|
-
const unsavedChangesDiscardMessage = useMemo(() => unsavedChangesMessage ||
|
|
120
|
-
tCrud('messages.unsavedChangesDiscard', {
|
|
121
|
-
defaultValue: 'You have unsaved changes. Discard them?',
|
|
122
|
-
}), [unsavedChangesMessage, tCrud]);
|
|
123
123
|
// Warn about unsaved changes when navigating away (browser refresh/close)
|
|
124
|
-
//
|
|
124
|
+
// beforeunload is the only place we can't toast — browser requires native dialog
|
|
125
125
|
useUnsavedChangesWarning({
|
|
126
126
|
isDirty: isDirtyForBlocking,
|
|
127
127
|
enabled: warnOnUnsavedChanges,
|
|
128
128
|
message: unsavedChangesLeaveMessage,
|
|
129
129
|
});
|
|
130
|
-
//
|
|
131
|
-
const
|
|
132
|
-
// Handle cancel with confirmation
|
|
133
|
-
const handleCancel = async () => {
|
|
134
|
-
if (isDirtyForBlocking) {
|
|
135
|
-
const confirmed = await confirmNavigation();
|
|
136
|
-
if (!confirmed)
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
130
|
+
// Handle cancel — auto-save ensures draft is persisted, no confirm needed
|
|
131
|
+
const handleCancel = () => {
|
|
139
132
|
resetForm();
|
|
140
|
-
// If onCancel callback provided, use it (takes precedence)
|
|
141
133
|
if (onCancel) {
|
|
142
134
|
onCancel();
|
|
143
135
|
}
|
|
136
|
+
else if (cancelPath) {
|
|
137
|
+
navigate(cancelPath);
|
|
138
|
+
}
|
|
144
139
|
else {
|
|
145
|
-
|
|
146
|
-
if (cancelPath) {
|
|
147
|
-
navigate(cancelPath);
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
navigate('back');
|
|
151
|
-
}
|
|
140
|
+
navigate('back');
|
|
152
141
|
}
|
|
153
142
|
};
|
|
154
|
-
// Wrap onSubmit to
|
|
143
|
+
// Wrap onSubmit to await the result before navigating
|
|
155
144
|
// handleSubmit from react-hook-form expects: (data: EntityData) => void | Promise<void>
|
|
156
145
|
// Our onSubmit prop is (data: T) => void | Promise<void>, where T extends EntityRecord
|
|
157
146
|
// EntityData should be compatible with T, so we can safely pass it
|
|
158
|
-
const handleFormSubmit = (data) => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
147
|
+
const handleFormSubmit = async (data) => {
|
|
148
|
+
try {
|
|
149
|
+
// Await onSubmit so navigation only happens after successful submission
|
|
150
|
+
// Type assertion is safe: EntityData is the validated form data, T is EntityRecord
|
|
151
|
+
await onSubmit(data);
|
|
152
|
+
// Navigate only after successful submission
|
|
153
|
+
if (successPath) {
|
|
154
|
+
navigate(successPath);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Default: navigate back (user came from list, go back there)
|
|
158
|
+
navigate('back');
|
|
159
|
+
}
|
|
166
160
|
}
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
|
|
161
|
+
catch {
|
|
162
|
+
// onSubmit rejected — stay on form so user can correct errors
|
|
163
|
+
// Error display is handled by the caller's onSubmit implementation
|
|
170
164
|
}
|
|
171
165
|
};
|
|
172
166
|
// Determine if cancel button should show
|
|
@@ -274,13 +268,13 @@ export function EntityFormRenderer({ entity, onSubmit, t, className = '', submit
|
|
|
274
268
|
if (buttonCount === 1) {
|
|
275
269
|
return (_jsx(Stack, { direction: "column", gap: "tight", style: buttonContainerStyle, children: buttons[0] }));
|
|
276
270
|
}
|
|
277
|
-
// Multiple buttons:
|
|
278
|
-
const
|
|
271
|
+
// Multiple buttons: responsive stacked on mobile, proportional on tablet+
|
|
272
|
+
const colTemplate = buttonCount === 2
|
|
279
273
|
? '1fr 2fr' // Cancel/Preview + Submit
|
|
280
274
|
: buttonCount === 3
|
|
281
275
|
? '1fr 1fr 2fr' // Cancel + Preview + Submit
|
|
282
276
|
: '1fr 1fr 1fr 2fr'; // Cancel + Preview + Secondary + Submit
|
|
283
|
-
return (_jsx(Grid, { cols: [
|
|
277
|
+
return (_jsx(Grid, { cols: ['1fr', colTemplate, colTemplate, colTemplate], gap: "tight", style: buttonContainerStyle, children: buttons }));
|
|
284
278
|
})()] })] }) }) }));
|
|
285
279
|
}
|
|
286
280
|
export default EntityFormRenderer;
|
|
@@ -10,5 +10,5 @@ export type { EntityListProps };
|
|
|
10
10
|
* - Edit and Delete actions (admin only)
|
|
11
11
|
* - Auto-routing when handlers not provided
|
|
12
12
|
*/
|
|
13
|
-
export declare function EntityList({ entity,
|
|
13
|
+
export declare function EntityList({ entity, basePath, onClick, hideFilters, pagination, pageSize: pageSizeProp, queryOptions, exportable, }: EntityListProps): import("react/jsx-runtime").JSX.Element;
|
|
14
14
|
//# sourceMappingURL=EntityList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityList.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityList.tsx"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,
|
|
1
|
+
{"version":3,"file":"EntityList.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityList.tsx"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,OAAO,EACP,WAAmB,EACnB,UAAqB,EACrB,QAAQ,EAAE,YAAY,EACtB,YAAY,EACZ,UAAiB,GAClB,EAAE,eAAe,2CAiTjB"}
|
|
@@ -29,7 +29,7 @@ import { translateFieldLabel, useCrud, useCrudList, EntityFilters, matchesFilter
|
|
|
29
29
|
* - Edit and Delete actions (admin only)
|
|
30
30
|
* - Auto-routing when handlers not provided
|
|
31
31
|
*/
|
|
32
|
-
export function EntityList({ entity,
|
|
32
|
+
export function EntityList({ entity, basePath, onClick, hideFilters = false, pagination = 'client', pageSize: pageSizeProp, queryOptions, exportable = true, }) {
|
|
33
33
|
const navigate = useNavigate();
|
|
34
34
|
const base = basePath ?? `/${entity.collection}`;
|
|
35
35
|
// Server-side pagination state (only used when pagination='server')
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Reusable recommendations section for related entities
|
|
3
|
+
* @description Fetches and displays related entity cards in a grid.
|
|
4
|
+
* Caller defines "related by what" via queryOptions.
|
|
5
|
+
*
|
|
6
|
+
* @version 0.0.1
|
|
7
|
+
* @since 0.0.15
|
|
8
|
+
* @author AMBROISE PARK Consulting
|
|
9
|
+
*/
|
|
10
|
+
import type { EntityRecommendationsProps } from '@donotdev/core';
|
|
11
|
+
/**
|
|
12
|
+
* Displays a grid of related entity cards.
|
|
13
|
+
* Uses useCrudCardList (listCard schema) so cards render identically to EntityCardList.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* <EntityRecommendations
|
|
17
|
+
* entity={apartmentEntity}
|
|
18
|
+
* title={t('apartment.recommendations')}
|
|
19
|
+
* queryOptions={{
|
|
20
|
+
* where: [
|
|
21
|
+
* { field: 'district_code', operator: 'eq', value: current.district_code },
|
|
22
|
+
* { field: 'id', operator: 'neq', value: current.id },
|
|
23
|
+
* ],
|
|
24
|
+
* limit: 3,
|
|
25
|
+
* }}
|
|
26
|
+
* />
|
|
27
|
+
*/
|
|
28
|
+
export declare function EntityRecommendations({ entity, queryOptions, title, basePath, cols, className, }: EntityRecommendationsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
29
|
+
//# sourceMappingURL=EntityRecommendations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityRecommendations.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityRecommendations.tsx"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAMjE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,IAAQ,EACR,SAAS,GACV,EAAE,0BAA0B,kDAuB5B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Section } from '@donotdev/components';
|
|
4
|
+
import { useCrudCardList } from '@donotdev/crud';
|
|
5
|
+
import { CrudCard } from './CrudCardLink';
|
|
6
|
+
/**
|
|
7
|
+
* Displays a grid of related entity cards.
|
|
8
|
+
* Uses useCrudCardList (listCard schema) so cards render identically to EntityCardList.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* <EntityRecommendations
|
|
12
|
+
* entity={apartmentEntity}
|
|
13
|
+
* title={t('apartment.recommendations')}
|
|
14
|
+
* queryOptions={{
|
|
15
|
+
* where: [
|
|
16
|
+
* { field: 'district_code', operator: 'eq', value: current.district_code },
|
|
17
|
+
* { field: 'id', operator: 'neq', value: current.id },
|
|
18
|
+
* ],
|
|
19
|
+
* limit: 3,
|
|
20
|
+
* }}
|
|
21
|
+
* />
|
|
22
|
+
*/
|
|
23
|
+
export function EntityRecommendations({ entity, queryOptions, title, basePath, cols = 3, className, }) {
|
|
24
|
+
const { items, loading } = useCrudCardList(entity, {
|
|
25
|
+
queryOptions,
|
|
26
|
+
});
|
|
27
|
+
if (!loading && items.length === 0) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const resolvedBasePath = basePath ?? `/${entity.collection}`;
|
|
31
|
+
return (_jsx(Section, { title: title, gridCols: cols, className: className, children: items.map((item) => (_jsx(CrudCard, { item: item, entity: entity, detailHref: `${resolvedBasePath}/${item.id}` }, item.id))) }));
|
|
32
|
+
}
|
|
@@ -10,6 +10,7 @@ export { EntityDisplayRenderer } from './EntityDisplayRenderer';
|
|
|
10
10
|
export { EntityList } from './EntityList';
|
|
11
11
|
export { EntityCardList } from './EntityCardList';
|
|
12
12
|
export { EntityFormRenderer } from './EntityFormRenderer';
|
|
13
|
+
export { EntityRecommendations } from './EntityRecommendations';
|
|
13
14
|
export * from './Form';
|
|
14
|
-
export type { EntityListProps, EntityCardListProps, EntityFormRendererProps, EntityDisplayRendererProps, } from '@donotdev/core';
|
|
15
|
+
export type { EntityListProps, EntityCardListProps, EntityRecommendationsProps, EntityFormRendererProps, EntityDisplayRendererProps, } from '@donotdev/core';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crud/components/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,cAAc,QAAQ,CAAC;AAEvB,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crud/components/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,cAAc,QAAQ,CAAC;AAEvB,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC"}
|
|
@@ -11,4 +11,5 @@ export { EntityDisplayRenderer } from './EntityDisplayRenderer';
|
|
|
11
11
|
export { EntityList } from './EntityList';
|
|
12
12
|
export { EntityCardList } from './EntityCardList';
|
|
13
13
|
export { EntityFormRenderer } from './EntityFormRenderer';
|
|
14
|
+
export { EntityRecommendations } from './EntityRecommendations';
|
|
14
15
|
export * from './Form';
|