@deenruv/admin-dashboard 1.0.17-dev.18 → 1.0.17-dev.23
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/DeenruvAdminPanel.js +14 -8
- package/dist/access/admin-router.js +42 -3
- package/dist/access/built-in-route-permissions.js +44 -0
- package/dist/access/built-in-routes.js +22 -21
- package/dist/access/channel-selection.js +9 -0
- package/dist/components/Menu/ChannelSwitcher.js +8 -1
- package/dist/graphql/scalars.js +4 -0
- package/dist/locales/en/orders.json +9 -1
- package/dist/locales/pl/orders.json +9 -1
- package/dist/pages/Root.js +24 -19
- package/dist/pages/assets/List.js +1 -1
- package/dist/pages/collections/Detail.js +5 -0
- package/dist/pages/collections/List.js +1 -1
- package/dist/pages/collections/_components/ContentsCard.js +1 -1
- package/dist/pages/countries/Detail.js +5 -0
- package/dist/pages/countries/List.js +1 -1
- package/dist/pages/facets/Detail.js +5 -0
- package/dist/pages/facets/List.js +1 -1
- package/dist/pages/facets/_components/FacetDetailView.js +1 -1
- package/dist/pages/orders/_components/CancelAndRefundDialog.js +80 -19
- package/dist/pages/orders/_components/Payments.js +39 -23
- package/dist/pages/orders/_components/ProductsTable.js +13 -25
- package/dist/pages/orders/_components/TopActions.js +14 -8
- package/dist/pages/payment-methods/Detail.js +5 -0
- package/dist/pages/payment-methods/List.js +1 -1
- package/dist/pages/product-variants/List.js +4 -3
- package/dist/pages/products/Detail.js +3 -3
- package/dist/pages/products/List.js +3 -2
- package/dist/pages/shipping-methods/Detail.js +5 -0
- package/dist/pages/shipping-methods/List.js +1 -1
- package/dist/pages/tax-categories/Detail.js +3 -3
- package/dist/pages/tax-categories/List.js +1 -1
- package/dist/pages/tax-rates/Detail.js +5 -0
- package/dist/pages/tax-rates/List.js +1 -1
- package/dist/pages/zones/Detail.js +5 -0
- package/dist/pages/zones/List.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// eslint-disable-next-line no-restricted-imports
|
|
3
3
|
import { I18nextProvider } from 'react-i18next';
|
|
4
|
-
import { useEffect, useMemo } from 'react';
|
|
4
|
+
import { useCallback, useEffect, useMemo } from 'react';
|
|
5
5
|
import { createBrowserRouter, RouterProvider } from 'react-router';
|
|
6
6
|
import { AnimatePresence } from 'framer-motion';
|
|
7
7
|
import { Toaster } from 'sonner';
|
|
@@ -17,7 +17,7 @@ import { ADMIN_DASHBOARD_VERSION } from "./version.js";
|
|
|
17
17
|
import { ORDER_STATUS_NOTIFICATION } from "./notifications/OrderStatusNotification.js";
|
|
18
18
|
import { SYSTEM_STATUS_NOTIFICATION } from "./notifications/SystemStatusNotification.js";
|
|
19
19
|
import { AdminAccessProvider, builtInAdminRoutes, getDefaultAdminRoute, getPermittedAdminRoutes, } from "./access/index.js";
|
|
20
|
-
import { createAdminRouterRoutes } from "./access/admin-router.js";
|
|
20
|
+
import { CommittedRouterOwner, createAdminRouterRoutes } from "./access/admin-router.js";
|
|
21
21
|
const loadTranslations = () => {
|
|
22
22
|
Object.entries(resources).forEach(([lang, value]) => {
|
|
23
23
|
Object.entries(value).forEach(([, translations]) => {
|
|
@@ -54,7 +54,10 @@ export const DeenruvAdminPanel = ({ plugins, settings }) => {
|
|
|
54
54
|
language: p.language,
|
|
55
55
|
translationsLanguage: p.translationsLanguage,
|
|
56
56
|
})));
|
|
57
|
-
const userPermissions = useServer((p) =>
|
|
57
|
+
const { administratorAccessState, userPermissions } = useServer(useShallow((p) => ({
|
|
58
|
+
administratorAccessState: p.administratorAccessState,
|
|
59
|
+
userPermissions: p.userPermissions,
|
|
60
|
+
})));
|
|
58
61
|
const pluginRoutes = useMemo(() => pluginsStore.routes.map((route) => ({
|
|
59
62
|
id: `plugin.${route.plugin.name}.${route.path}`,
|
|
60
63
|
path: route.path,
|
|
@@ -62,14 +65,17 @@ export const DeenruvAdminPanel = ({ plugins, settings }) => {
|
|
|
62
65
|
...route.access,
|
|
63
66
|
search: { menuKey: `${route.plugin.name} - ${route.path}`, type: 'plugin' },
|
|
64
67
|
})), [plugins]);
|
|
65
|
-
const permittedRoutes = useMemo(() =>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
const permittedRoutes = useMemo(() => administratorAccessState === 'ready'
|
|
69
|
+
? getPermittedAdminRoutes([...builtInAdminRoutes, ...pluginRoutes], userPermissions)
|
|
70
|
+
: [], [administratorAccessState, pluginRoutes, userPermissions]);
|
|
71
|
+
const defaultRoute = administratorAccessState === 'ready' ? getDefaultAdminRoute(permittedRoutes) : undefined;
|
|
72
|
+
const createRouter = useCallback(() => createBrowserRouter(createAdminRouterRoutes({
|
|
68
73
|
permittedRoutes,
|
|
69
74
|
defaultRoute,
|
|
75
|
+
administratorAccessState,
|
|
70
76
|
rootElement: _jsx(Root, { allPaths: permittedRoutes.map((route) => route.path).filter(Boolean) }),
|
|
71
77
|
errorElement: _jsx(ErrorPage, {}),
|
|
72
|
-
})), [defaultRoute, permittedRoutes]);
|
|
78
|
+
})), [administratorAccessState, defaultRoute, permittedRoutes]);
|
|
73
79
|
useEffect(() => {
|
|
74
80
|
const root = window.document.documentElement;
|
|
75
81
|
root.classList.remove('light', 'dark');
|
|
@@ -81,7 +87,7 @@ export const DeenruvAdminPanel = ({ plugins, settings }) => {
|
|
|
81
87
|
root.classList.add(theme);
|
|
82
88
|
}
|
|
83
89
|
}, [theme]);
|
|
84
|
-
return (_jsx(GlobalStoreProvider, { ...settings, children: _jsxs(I18nextProvider, { i18n: i18n, defaultNS: 'common', children: [_jsx(AnimatePresence, { children: isLoggedIn ? (_jsx(AdminAccessProvider, { value: { routes: permittedRoutes, defaultRoute }, children: _jsx(PluginProvider, { plugins: pluginsStore, context: context, children: _jsx(NotificationProvider, { notifications: [ORDER_STATUS_NOTIFICATION, SYSTEM_STATUS_NOTIFICATION].concat(pluginsStore.notifications), children: _jsx(RouterProvider, { router: router }) }) }) })) : (_jsx(LoginScreen, {})) }), _jsx(Toaster, { theme: theme, className: "toaster group", richColors: true, expand: true, position: "bottom-right", toastOptions: {
|
|
90
|
+
return (_jsx(GlobalStoreProvider, { ...settings, children: _jsxs(I18nextProvider, { i18n: i18n, defaultNS: 'common', children: [_jsx(AnimatePresence, { children: isLoggedIn ? (_jsx(AdminAccessProvider, { value: { routes: permittedRoutes, defaultRoute }, children: _jsx(PluginProvider, { plugins: pluginsStore, context: context, children: _jsx(NotificationProvider, { notifications: [ORDER_STATUS_NOTIFICATION, SYSTEM_STATUS_NOTIFICATION].concat(pluginsStore.notifications), children: _jsx(CommittedRouterOwner, { createRouter: createRouter, children: (router) => _jsx(RouterProvider, { router: router }) }) }) }) })) : (_jsx(LoginScreen, {})) }), _jsx(Toaster, { theme: theme, className: "toaster group", richColors: true, expand: true, position: "bottom-right", toastOptions: {
|
|
85
91
|
classNames: {
|
|
86
92
|
toast: 'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg group-[.toaster]:p-4',
|
|
87
93
|
title: 'group-[.toast]:font-semibold group-[.toast]:text-foreground',
|
|
@@ -1,21 +1,60 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
2
3
|
import { Routes } from '@deenruv/react-ui-devkit';
|
|
3
4
|
import { Navigate } from 'react-router';
|
|
4
|
-
export const
|
|
5
|
+
export const CommittedRouterOwner = ({ createRouter, children, }) => {
|
|
6
|
+
const [router, setRouter] = useState();
|
|
7
|
+
const activeRouter = useRef(undefined);
|
|
8
|
+
const disposedRouters = useRef(new WeakSet());
|
|
9
|
+
useLayoutEffect(() => {
|
|
10
|
+
const nextRouter = createRouter();
|
|
11
|
+
activeRouter.current = nextRouter;
|
|
12
|
+
setRouter(nextRouter);
|
|
13
|
+
return () => {
|
|
14
|
+
if (activeRouter.current === nextRouter) {
|
|
15
|
+
activeRouter.current = undefined;
|
|
16
|
+
}
|
|
17
|
+
globalThis.queueMicrotask(() => {
|
|
18
|
+
if (activeRouter.current !== nextRouter && !disposedRouters.current.has(nextRouter)) {
|
|
19
|
+
disposedRouters.current.add(nextRouter);
|
|
20
|
+
nextRouter.dispose();
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
}, [createRouter]);
|
|
25
|
+
return router && activeRouter.current === router ? children(router) : null;
|
|
26
|
+
};
|
|
27
|
+
export const createAdminRouterRoutes = ({ permittedRoutes, defaultRoute, administratorAccessState, rootElement, errorElement, }) => {
|
|
5
28
|
const children = permittedRoutes.map(({ id, path, element }) => ({ id, path, element }));
|
|
6
|
-
if (
|
|
29
|
+
if (administratorAccessState === 'ready' &&
|
|
30
|
+
defaultRoute &&
|
|
31
|
+
!permittedRoutes.some((route) => route.path === Routes.dashboard)) {
|
|
7
32
|
children.push({
|
|
8
33
|
id: 'admin.fallback.dashboard',
|
|
9
34
|
path: Routes.dashboard,
|
|
10
35
|
element: _jsx(Navigate, { to: defaultRoute.path, replace: true }),
|
|
11
36
|
});
|
|
12
37
|
}
|
|
13
|
-
if (defaultRoute) {
|
|
38
|
+
if (administratorAccessState === 'ready' && defaultRoute) {
|
|
14
39
|
children.push({
|
|
15
40
|
id: 'admin.fallback.wildcard',
|
|
16
41
|
path: '*',
|
|
17
42
|
element: _jsx(Navigate, { to: defaultRoute.path, replace: true }),
|
|
18
43
|
});
|
|
19
44
|
}
|
|
45
|
+
else if (administratorAccessState === 'pending') {
|
|
46
|
+
children.push({
|
|
47
|
+
id: 'admin.fallback.pending-access',
|
|
48
|
+
path: '*',
|
|
49
|
+
element: null,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
children.push({
|
|
54
|
+
id: 'admin.fallback.unavailable-access',
|
|
55
|
+
path: '*',
|
|
56
|
+
element: errorElement,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
20
59
|
return [{ id: 'admin.root', element: rootElement, errorElement, children }];
|
|
21
60
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Permission } from '@deenruv/admin-types';
|
|
2
|
+
export const catalogRoutePermissions = {
|
|
3
|
+
products: {
|
|
4
|
+
read: [Permission.ReadProduct, Permission.ReadCatalog],
|
|
5
|
+
create: [Permission.CreateProduct, Permission.CreateCatalog],
|
|
6
|
+
},
|
|
7
|
+
collections: {
|
|
8
|
+
read: [Permission.ReadCollection, Permission.ReadCatalog],
|
|
9
|
+
create: [Permission.CreateCollection, Permission.CreateCatalog],
|
|
10
|
+
},
|
|
11
|
+
facets: {
|
|
12
|
+
read: [Permission.ReadFacet, Permission.ReadCatalog],
|
|
13
|
+
create: [Permission.CreateFacet, Permission.CreateCatalog],
|
|
14
|
+
},
|
|
15
|
+
assets: {
|
|
16
|
+
read: [Permission.ReadAsset, Permission.ReadCatalog],
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
export const settingsRoutePermissions = {
|
|
20
|
+
paymentMethods: {
|
|
21
|
+
read: [Permission.ReadPaymentMethod, Permission.ReadSettings],
|
|
22
|
+
create: [Permission.CreatePaymentMethod, Permission.CreateSettings],
|
|
23
|
+
},
|
|
24
|
+
shippingMethods: {
|
|
25
|
+
read: [Permission.ReadShippingMethod, Permission.ReadSettings],
|
|
26
|
+
create: [Permission.CreateShippingMethod, Permission.CreateSettings],
|
|
27
|
+
},
|
|
28
|
+
zones: {
|
|
29
|
+
read: [Permission.ReadZone, Permission.ReadSettings],
|
|
30
|
+
create: [Permission.CreateZone, Permission.CreateSettings],
|
|
31
|
+
},
|
|
32
|
+
countries: {
|
|
33
|
+
read: [Permission.ReadCountry, Permission.ReadSettings],
|
|
34
|
+
create: [Permission.CreateCountry, Permission.CreateSettings],
|
|
35
|
+
},
|
|
36
|
+
taxCategories: {
|
|
37
|
+
read: [Permission.ReadTaxCategory, Permission.ReadSettings],
|
|
38
|
+
create: [Permission.CreateTaxCategory, Permission.CreateSettings],
|
|
39
|
+
},
|
|
40
|
+
taxRates: {
|
|
41
|
+
read: [Permission.ReadTaxRate, Permission.ReadSettings],
|
|
42
|
+
create: [Permission.CreateTaxRate, Permission.CreateSettings],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
@@ -3,6 +3,7 @@ import { Permission } from '@deenruv/admin-types';
|
|
|
3
3
|
import { Routes } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { BarChart, Barcode, BadgePercent, Coins, Cog, CreditCard, Flag, Folder, Globe, Globe2, Images, MapPin, Percent, ScanBarcode, Server, ShoppingCart, Store, Tag, Truck, UserCog, UserRoundSearch, Users, UsersRound, } from 'lucide-react';
|
|
5
5
|
import { AdminsDetailPage, AdminsListPage, AdminsProvisionPage, AssetsListPage, ChannelsDetailPage, ChannelsListPage, CollectionsDetailPage, CollectionsListPage, CountriesDetailPage, CountriesListPage, CustomerGroupsDetailPage, CustomerGroupsListPage, CustomersDetailPage, CustomersListPage, Dashboard, Extensions, FacetsDetailPage, FacetsListPage, GlobalSettings, OrdersDetailPage, OrdersListPage, PaymentMethodsDetailPage, PaymentMethodsListPage, ProductVariantDetailPage, ProductVariantsListPage, ProductsDetailPage, ProductsListPage, PromotionsDetailPage, PromotionsListPage, RolesDetailPage, RolesListPage, SellersDetailPage, SellersListPage, ShippingMethodsDetailPage, ShippingMethodsListPage, Status, StockLocationsDetailPage, StockLocationsListPage, TaxCategoriesDetailPage, TaxCategoriesListPage, TaxRatesDetailPage, TaxRatesListPage, ZonesDetailPage, ZonesListPage, } from "../pages/index.js";
|
|
6
|
+
import { catalogRoutePermissions, settingsRoutePermissions } from './built-in-route-permissions.js';
|
|
6
7
|
export const adminNavigationGroups = [
|
|
7
8
|
{ id: 'shop-group', labelKey: 'shop' },
|
|
8
9
|
{ id: 'assortment-group', labelKey: 'assortment' },
|
|
@@ -85,8 +86,8 @@ export const builtInAdminRoutes = [
|
|
|
85
86
|
routes: Routes.products,
|
|
86
87
|
listElement: () => _jsx(ProductsListPage, {}),
|
|
87
88
|
detailElement: () => _jsx(ProductsDetailPage, {}),
|
|
88
|
-
readPermissions:
|
|
89
|
-
createPermissions:
|
|
89
|
+
readPermissions: catalogRoutePermissions.products.read,
|
|
90
|
+
createPermissions: catalogRoutePermissions.products.create,
|
|
90
91
|
nav: { groupId: 'assortment-group', linkId: 'link-products', menuKey: 'products', icon: Barcode },
|
|
91
92
|
}),
|
|
92
93
|
...createCrudRouteDefinitions({
|
|
@@ -95,8 +96,8 @@ export const builtInAdminRoutes = [
|
|
|
95
96
|
routes: Routes.productVariants,
|
|
96
97
|
listElement: () => _jsx(ProductVariantsListPage, {}),
|
|
97
98
|
detailElement: () => _jsx(ProductVariantDetailPage, {}),
|
|
98
|
-
readPermissions:
|
|
99
|
-
createPermissions:
|
|
99
|
+
readPermissions: catalogRoutePermissions.products.read,
|
|
100
|
+
createPermissions: catalogRoutePermissions.products.create,
|
|
100
101
|
nav: {
|
|
101
102
|
groupId: 'assortment-group',
|
|
102
103
|
linkId: 'link-product-variants',
|
|
@@ -110,8 +111,8 @@ export const builtInAdminRoutes = [
|
|
|
110
111
|
routes: Routes.collections,
|
|
111
112
|
listElement: () => _jsx(CollectionsListPage, {}),
|
|
112
113
|
detailElement: () => _jsx(CollectionsDetailPage, {}),
|
|
113
|
-
readPermissions:
|
|
114
|
-
createPermissions:
|
|
114
|
+
readPermissions: catalogRoutePermissions.collections.read,
|
|
115
|
+
createPermissions: catalogRoutePermissions.collections.create,
|
|
115
116
|
nav: { groupId: 'assortment-group', linkId: 'link-collections', menuKey: 'collections', icon: Folder },
|
|
116
117
|
}),
|
|
117
118
|
...createCrudRouteDefinitions({
|
|
@@ -120,15 +121,15 @@ export const builtInAdminRoutes = [
|
|
|
120
121
|
routes: Routes.facets,
|
|
121
122
|
listElement: () => _jsx(FacetsListPage, {}),
|
|
122
123
|
detailElement: () => _jsx(FacetsDetailPage, {}),
|
|
123
|
-
readPermissions:
|
|
124
|
-
createPermissions:
|
|
124
|
+
readPermissions: catalogRoutePermissions.facets.read,
|
|
125
|
+
createPermissions: catalogRoutePermissions.facets.create,
|
|
125
126
|
nav: { groupId: 'assortment-group', linkId: 'link-facets', menuKey: 'facets', icon: Tag },
|
|
126
127
|
}),
|
|
127
128
|
{
|
|
128
129
|
id: 'assets.list',
|
|
129
130
|
path: Routes.assets.list,
|
|
130
131
|
element: _jsx(AssetsListPage, {}),
|
|
131
|
-
requiredPermissions:
|
|
132
|
+
requiredPermissions: catalogRoutePermissions.assets.read,
|
|
132
133
|
nav: { groupId: 'assortment-group', linkId: 'link-assets', menuKey: 'assets', icon: Images },
|
|
133
134
|
search: { menuKey: 'assets', type: 'list' },
|
|
134
135
|
},
|
|
@@ -185,8 +186,8 @@ export const builtInAdminRoutes = [
|
|
|
185
186
|
routes: Routes.paymentMethods,
|
|
186
187
|
listElement: () => _jsx(PaymentMethodsListPage, {}),
|
|
187
188
|
detailElement: () => _jsx(PaymentMethodsDetailPage, {}),
|
|
188
|
-
readPermissions:
|
|
189
|
-
createPermissions:
|
|
189
|
+
readPermissions: settingsRoutePermissions.paymentMethods.read,
|
|
190
|
+
createPermissions: settingsRoutePermissions.paymentMethods.create,
|
|
190
191
|
nav: {
|
|
191
192
|
groupId: 'shipping-group',
|
|
192
193
|
linkId: 'link-payment-methods',
|
|
@@ -200,8 +201,8 @@ export const builtInAdminRoutes = [
|
|
|
200
201
|
routes: Routes.shippingMethods,
|
|
201
202
|
listElement: () => _jsx(ShippingMethodsListPage, {}),
|
|
202
203
|
detailElement: () => _jsx(ShippingMethodsDetailPage, {}),
|
|
203
|
-
readPermissions:
|
|
204
|
-
createPermissions:
|
|
204
|
+
readPermissions: settingsRoutePermissions.shippingMethods.read,
|
|
205
|
+
createPermissions: settingsRoutePermissions.shippingMethods.create,
|
|
205
206
|
nav: {
|
|
206
207
|
groupId: 'shipping-group',
|
|
207
208
|
linkId: 'link-shipping-methods',
|
|
@@ -235,8 +236,8 @@ export const builtInAdminRoutes = [
|
|
|
235
236
|
routes: Routes.zones,
|
|
236
237
|
listElement: () => _jsx(ZonesListPage, {}),
|
|
237
238
|
detailElement: () => _jsx(ZonesDetailPage, {}),
|
|
238
|
-
readPermissions:
|
|
239
|
-
createPermissions:
|
|
239
|
+
readPermissions: settingsRoutePermissions.zones.read,
|
|
240
|
+
createPermissions: settingsRoutePermissions.zones.create,
|
|
240
241
|
nav: { groupId: 'settings-group', linkId: 'link-zones', menuKey: 'zones', icon: Globe },
|
|
241
242
|
}),
|
|
242
243
|
...createCrudRouteDefinitions({
|
|
@@ -245,8 +246,8 @@ export const builtInAdminRoutes = [
|
|
|
245
246
|
routes: Routes.countries,
|
|
246
247
|
listElement: () => _jsx(CountriesListPage, {}),
|
|
247
248
|
detailElement: () => _jsx(CountriesDetailPage, {}),
|
|
248
|
-
readPermissions:
|
|
249
|
-
createPermissions:
|
|
249
|
+
readPermissions: settingsRoutePermissions.countries.read,
|
|
250
|
+
createPermissions: settingsRoutePermissions.countries.create,
|
|
250
251
|
nav: { groupId: 'settings-group', linkId: 'link-countries', menuKey: 'countries', icon: Flag },
|
|
251
252
|
}),
|
|
252
253
|
...createCrudRouteDefinitions({
|
|
@@ -255,8 +256,8 @@ export const builtInAdminRoutes = [
|
|
|
255
256
|
routes: Routes.taxCategories,
|
|
256
257
|
listElement: () => _jsx(TaxCategoriesListPage, {}),
|
|
257
258
|
detailElement: () => _jsx(TaxCategoriesDetailPage, {}),
|
|
258
|
-
readPermissions:
|
|
259
|
-
createPermissions:
|
|
259
|
+
readPermissions: settingsRoutePermissions.taxCategories.read,
|
|
260
|
+
createPermissions: settingsRoutePermissions.taxCategories.create,
|
|
260
261
|
nav: {
|
|
261
262
|
groupId: 'settings-group',
|
|
262
263
|
linkId: 'link-tax-categories',
|
|
@@ -270,8 +271,8 @@ export const builtInAdminRoutes = [
|
|
|
270
271
|
routes: Routes.taxRates,
|
|
271
272
|
listElement: () => _jsx(TaxRatesListPage, {}),
|
|
272
273
|
detailElement: () => _jsx(TaxRatesDetailPage, {}),
|
|
273
|
-
readPermissions:
|
|
274
|
-
createPermissions:
|
|
274
|
+
readPermissions: settingsRoutePermissions.taxRates.read,
|
|
275
|
+
createPermissions: settingsRoutePermissions.taxRates.create,
|
|
275
276
|
nav: { groupId: 'settings-group', linkId: 'link-tax-rates', menuKey: 'taxRates', icon: Percent },
|
|
276
277
|
}),
|
|
277
278
|
{
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const switchSelectedChannel = (channel, actions) => {
|
|
2
|
+
actions.clearPermissions();
|
|
3
|
+
actions.selectChannel(channel);
|
|
4
|
+
actions.setPermissionsForChannel(channel.id);
|
|
5
|
+
};
|
|
6
|
+
export const selectPreferredChannel = (channels, retainedChannel, configuredDefaultCode, builtInDefaultCode) => channels.find((channel) => channel.id === retainedChannel?.id) ??
|
|
7
|
+
channels.find((channel) => channel.code === configuredDefaultCode) ??
|
|
8
|
+
channels.find((channel) => channel.code === builtInDefaultCode) ??
|
|
9
|
+
channels[0];
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, useServer, useSettings, DEFAULT_CHANNEL_CODE, cn, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
|
+
import { switchSelectedChannel } from "../../access/channel-selection.js";
|
|
4
5
|
export function ChannelSwitcher({ className }) {
|
|
5
6
|
const channels = useServer((p) => p.channels);
|
|
6
7
|
const setSelectedChannel = useSettings((p) => p.setSelectedChannel);
|
|
7
8
|
const selectedChannel = useSettings((p) => p.selectedChannel);
|
|
9
|
+
const setUserPermissions = useServer((p) => p.setUserPermissions);
|
|
10
|
+
const setSelectedChannelPermissions = useServer((p) => p.setSelectedChannelPermissions);
|
|
8
11
|
const { t } = useTranslation('common');
|
|
9
12
|
const onChannelChange = (id) => {
|
|
10
13
|
const channel = channels.find((channel) => channel.id === id);
|
|
11
14
|
if (!channel)
|
|
12
15
|
return;
|
|
13
|
-
|
|
16
|
+
switchSelectedChannel(channel, {
|
|
17
|
+
clearPermissions: () => setUserPermissions([]),
|
|
18
|
+
selectChannel: setSelectedChannel,
|
|
19
|
+
setPermissionsForChannel: setSelectedChannelPermissions,
|
|
20
|
+
});
|
|
14
21
|
};
|
|
15
22
|
const getChannelLabel = useCallback((code) => (code === DEFAULT_CHANNEL_CODE ? t('defaultChannel') : code), [t]);
|
|
16
23
|
if (!channels || channels.length === 0) {
|
package/dist/graphql/scalars.js
CHANGED
|
@@ -383,7 +383,15 @@
|
|
|
383
383
|
"title": "Cancel and refund the order",
|
|
384
384
|
"refund": "Refund",
|
|
385
385
|
"returnToStock": "Return to warehouse",
|
|
386
|
-
"refundShipping": "
|
|
386
|
+
"refundShipping": "Refund shipping",
|
|
387
|
+
"cancelShipping": "Return shipping to stock",
|
|
388
|
+
"cancelShippingRequiresLines": "Select at least one item to return before returning shipping.",
|
|
389
|
+
"refundQuantity": "Refund quantity",
|
|
390
|
+
"reason": "Reason",
|
|
391
|
+
"suggestedAmount": "Calculated refund",
|
|
392
|
+
"auto": "Automatic",
|
|
393
|
+
"submit": "Apply cancellation and refund",
|
|
394
|
+
"error": "Could not apply cancellation or refund"
|
|
387
395
|
},
|
|
388
396
|
"create": {
|
|
389
397
|
"addModal": {
|
|
@@ -383,7 +383,15 @@
|
|
|
383
383
|
"title": "Anuluj i refunduj zamówienie",
|
|
384
384
|
"refund": "Refunduj",
|
|
385
385
|
"returnToStock": "Zwróć do magazynu",
|
|
386
|
-
"refundShipping": "Zwróć
|
|
386
|
+
"refundShipping": "Zwróć koszt przesyłki",
|
|
387
|
+
"cancelShipping": "Zwróć przesyłkę do magazynu",
|
|
388
|
+
"cancelShippingRequiresLines": "Wybierz co najmniej jeden produkt do zwrotu przed zwrotem przesyłki.",
|
|
389
|
+
"refundQuantity": "Ilość do refundacji",
|
|
390
|
+
"reason": "Powód",
|
|
391
|
+
"suggestedAmount": "Wyliczony zwrot",
|
|
392
|
+
"auto": "Automatycznie",
|
|
393
|
+
"submit": "Zastosuj anulowanie i zwrot",
|
|
394
|
+
"error": "Nie udało się anulować lub zwrócić płatności"
|
|
387
395
|
},
|
|
388
396
|
"create": {
|
|
389
397
|
"addModal": {
|
package/dist/pages/Root.js
CHANGED
|
@@ -10,6 +10,8 @@ import { GlobalSearch } from "../components/GlobalSearch.js";
|
|
|
10
10
|
import { ContentAreaSkeleton } from "../components/ContentAreaSkeleton.js";
|
|
11
11
|
import { DeenruvDeveloperIndicator } from "../DeenruvDeveloperIndicator.js";
|
|
12
12
|
import { Permission } from '@deenruv/admin-types';
|
|
13
|
+
import { selectPreferredChannel } from "../access/channel-selection.js";
|
|
14
|
+
import { ErrorPage } from "./Custom404.js";
|
|
13
15
|
const TAKE = 100;
|
|
14
16
|
const getAllPaginatedCountries = async () => {
|
|
15
17
|
let countries = [];
|
|
@@ -45,14 +47,17 @@ const getAllPaymentMethods = async () => {
|
|
|
45
47
|
export const Root = ({ allPaths }) => {
|
|
46
48
|
const isLocalhost = window.location.hostname === 'localhost';
|
|
47
49
|
const { t } = useTranslation('common');
|
|
48
|
-
const
|
|
50
|
+
const failAdministratorAccess = useServer((p) => p.failAdministratorAccess);
|
|
51
|
+
const beginAdministratorAccessInitialization = useServer((p) => p.beginAdministratorAccessInitialization);
|
|
49
52
|
const setAdministratorAccess = useServer((p) => p.setAdministratorAccess);
|
|
53
|
+
const setSelectedChannelPermissions = useServer((p) => p.setSelectedChannelPermissions);
|
|
50
54
|
const setServerConfig = useServer((p) => p.setServerConfig);
|
|
51
55
|
const setCountries = useServer((p) => p.setCountries);
|
|
52
56
|
const setFulfillmentHandlers = useServer((p) => p.setFulfillmentHandlers);
|
|
53
57
|
const setPaymentMethodsType = useServer((p) => p.setPaymentMethodsType);
|
|
54
58
|
const fetchPendingJobs = useServer((p) => p.fetchPendingJobs);
|
|
55
59
|
const loaded = useServer((p) => p.loaded);
|
|
60
|
+
const administratorAccessState = useServer((p) => p.administratorAccessState);
|
|
56
61
|
const setLoaded = useServer((p) => p.setLoaded);
|
|
57
62
|
const setAvailableLanguages = useSettings((p) => p.setAvailableLanguages);
|
|
58
63
|
const setLanguage = useSettings((p) => p.setLanguage);
|
|
@@ -69,6 +74,9 @@ export const Root = ({ allPaths }) => {
|
|
|
69
74
|
const location = useLocation();
|
|
70
75
|
const [searchParams] = useSearchParams();
|
|
71
76
|
const hasInitializedAdministratorAccess = useRef(false);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
setSelectedChannelPermissions(selectedChannel?.id);
|
|
79
|
+
}, [selectedChannel?.id, setSelectedChannelPermissions]);
|
|
72
80
|
const managePageTitle = useCallback(() => {
|
|
73
81
|
const pathname = location.pathname;
|
|
74
82
|
const isDeenruvPath = allPaths.some((path) => pathname.startsWith(path));
|
|
@@ -144,22 +152,23 @@ export const Root = ({ allPaths }) => {
|
|
|
144
152
|
};
|
|
145
153
|
}, [notifications.map((n) => n.id).join(','), loaded]);
|
|
146
154
|
useEffect(() => {
|
|
147
|
-
if (hasInitializedAdministratorAccess.current)
|
|
155
|
+
if (administratorAccessState !== 'pending' || hasInitializedAdministratorAccess.current)
|
|
148
156
|
return;
|
|
149
157
|
hasInitializedAdministratorAccess.current = true;
|
|
150
|
-
|
|
158
|
+
beginAdministratorAccessInitialization();
|
|
151
159
|
const init = async () => {
|
|
152
160
|
const activeAdministratorResponse = await apiClient('query')({
|
|
153
161
|
activeAdministrator: activeAdministratorSelector,
|
|
154
162
|
});
|
|
155
163
|
const roles = activeAdministratorResponse.activeAdministrator?.user.roles || [];
|
|
156
164
|
if (!activeAdministratorResponse.activeAdministrator) {
|
|
157
|
-
|
|
165
|
+
failAdministratorAccess();
|
|
166
|
+
setLoaded(true);
|
|
158
167
|
toast.error(t('setup.failedAdmin'));
|
|
159
168
|
return;
|
|
160
169
|
}
|
|
161
170
|
else {
|
|
162
|
-
|
|
171
|
+
let administratorChannelId = selectedChannel?.id;
|
|
163
172
|
if ([Permission.ReadChannel].some((p) => roles.some((r) => r.permissions.includes(p)))) {
|
|
164
173
|
const { channels: { items: allChannels = [] }, } = await apiClient('query')({
|
|
165
174
|
channels: [
|
|
@@ -177,25 +186,20 @@ export const Root = ({ allPaths }) => {
|
|
|
177
186
|
],
|
|
178
187
|
});
|
|
179
188
|
setChannels(allChannels);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
setSelectedChannel(foundChannel || allChannels[0]);
|
|
184
|
-
}
|
|
185
|
-
const existingChannel = allChannels.find((ch) => ch.code === window?.__DEENRUV_SETTINGS__?.ui?.defaultChannelCode);
|
|
186
|
-
if (existingChannel) {
|
|
187
|
-
setSelectedChannel(existingChannel);
|
|
188
|
-
}
|
|
189
|
-
const defaultChannel = allChannels.find((ch) => ch.code === DEFAULT_CHANNEL_CODE) || allChannels[0];
|
|
190
|
-
setSelectedChannel(defaultChannel);
|
|
189
|
+
const preferredChannel = selectPreferredChannel(allChannels, selectedChannel, window?.__DEENRUV_SETTINGS__?.ui?.defaultChannelCode, DEFAULT_CHANNEL_CODE);
|
|
190
|
+
if (preferredChannel && preferredChannel.id !== channel?.id) {
|
|
191
|
+
setSelectedChannel(preferredChannel);
|
|
191
192
|
}
|
|
193
|
+
administratorChannelId = preferredChannel?.id;
|
|
192
194
|
}
|
|
193
195
|
else {
|
|
194
196
|
const possibleChannels = roles.flatMap((role) => role.channels);
|
|
195
197
|
if (possibleChannels.length > 0) {
|
|
196
198
|
setSelectedChannel(possibleChannels[0]);
|
|
199
|
+
administratorChannelId = possibleChannels[0].id;
|
|
197
200
|
}
|
|
198
201
|
}
|
|
202
|
+
setAdministratorAccess(activeAdministratorResponse.activeAdministrator, administratorChannelId);
|
|
199
203
|
}
|
|
200
204
|
// WE NEED TO CHECK IF LOCALSTORAGE HAS LANGUAGE SET
|
|
201
205
|
if (window?.__DEENRUV_SETTINGS__?.ui?.defaultLanguageCode) {
|
|
@@ -261,8 +265,9 @@ export const Root = ({ allPaths }) => {
|
|
|
261
265
|
await init();
|
|
262
266
|
})
|
|
263
267
|
.catch(() => {
|
|
264
|
-
|
|
268
|
+
failAdministratorAccess();
|
|
269
|
+
setLoaded(true);
|
|
265
270
|
});
|
|
266
|
-
}, []);
|
|
267
|
-
return (_jsx(_Fragment, { children: _jsxs("div", { className: "flex max-h-screen w-full max-w-full overflow-hidden bg-background text-foreground antialiased", children: [_jsx(Menu, { children:
|
|
271
|
+
}, [administratorAccessState]);
|
|
272
|
+
return (_jsx(_Fragment, { children: _jsxs("div", { className: "flex max-h-screen w-full max-w-full overflow-hidden bg-background text-foreground antialiased", children: [_jsx(Menu, { children: administratorAccessState === 'unavailable' ? (_jsx(ErrorPage, {})) : administratorAccessState === 'pending' || !loaded ? (_jsx(ContentAreaSkeleton, {})) : (_jsx(Outlet, {})) }), loaded && administratorAccessState === 'ready' && (_jsxs(_Fragment, { children: [_jsx(GlobalSearch, {}), _jsx(CanLeaveRouteDialog, {}), isLocalhost ? _jsx(DeenruvDeveloperIndicator, {}) : null] }))] }) }));
|
|
268
273
|
};
|
|
@@ -78,5 +78,5 @@ export const AssetsListPage = () => {
|
|
|
78
78
|
return (_jsx("div", { className: "flex flex-wrap gap-1", children: tags.length ? (tags.map((tag, index) => (_jsx(Badge, { variant: "secondary", className: "text-xs", children: tag.value }, index)))) : (_jsx(Badge, { variant: "secondary", className: "text-xs", children: "No Tags" })) }));
|
|
79
79
|
},
|
|
80
80
|
},
|
|
81
|
-
], createPermissions: [Permission.CreateAsset], deletePermissions: [Permission.DeleteAsset] }));
|
|
81
|
+
], createPermissions: [Permission.CreateAsset, Permission.CreateCatalog], deletePermissions: [Permission.DeleteAsset, Permission.DeleteCatalog] }));
|
|
82
82
|
};
|
|
@@ -4,6 +4,7 @@ import { useParams } from 'react-router';
|
|
|
4
4
|
import { useValidators, DetailView, createDeenruvForm, getMutation, useMutation, useSettings, } from '@deenruv/react-ui-devkit';
|
|
5
5
|
import { CollectionsDetailView } from "./_components/CollectionDetailView.js";
|
|
6
6
|
import { CollectionStorefrontAction } from "./_components/collectionStorefrontAction";
|
|
7
|
+
import { Permission } from '@deenruv/admin-types';
|
|
7
8
|
const CreateCollectionMutation = getMutation('createCollection');
|
|
8
9
|
const EditCollectionMutation = getMutation('updateCollection');
|
|
9
10
|
const DeleteCollectionMutation = getMutation('deleteCollection');
|
|
@@ -76,5 +77,9 @@ export const CollectionsDetailPage = () => {
|
|
|
76
77
|
}),
|
|
77
78
|
}, topActions: {
|
|
78
79
|
inline: [_jsx(CollectionStorefrontAction, {}, "collection-storefront-action")],
|
|
80
|
+
}, permissions: {
|
|
81
|
+
create: [Permission.CreateCollection, Permission.CreateCatalog],
|
|
82
|
+
edit: [Permission.UpdateCollection, Permission.UpdateCatalog],
|
|
83
|
+
delete: [Permission.DeleteCollection, Permission.DeleteCatalog],
|
|
79
84
|
} }) }));
|
|
80
85
|
};
|
|
@@ -197,5 +197,5 @@ export const CollectionsListPage = () => {
|
|
|
197
197
|
return { success: '' };
|
|
198
198
|
},
|
|
199
199
|
},
|
|
200
|
-
], entityName: 'Collection', route: Routes['collections'], tableId: tableId, fetch: fetch, onRemove: onRemove, createPermissions: [Permission.CreateCollection], deletePermissions: [Permission.DeleteCollection] }));
|
|
200
|
+
], entityName: 'Collection', route: Routes['collections'], tableId: tableId, fetch: fetch, onRemove: onRemove, createPermissions: [Permission.CreateCollection, Permission.CreateCatalog], deletePermissions: [Permission.DeleteCollection, Permission.DeleteCatalog] }));
|
|
201
201
|
};
|
|
@@ -31,7 +31,7 @@ export const ContentsCard = ({ collectionId }) => {
|
|
|
31
31
|
totalItems: 0,
|
|
32
32
|
});
|
|
33
33
|
}, [collectionId]);
|
|
34
|
-
return (_jsx(CustomCard, { title: t('details.contents.title'), color: "green", icon: _jsx(CardIcons.group, {}), children: _jsx(DetailList, { noPaddings: true, detailLinkColumn: "id", filterFields: [{ key: 'id', operator: 'IDOperators' }], searchFields: ['code', 'name'], hideColumns: ['customFields', 'product', 'updatedAt', 'createdAt'], entityName: 'Product', route: Routes['products'], tableId: "products-list-view", fetch: fetch, noCreateButton: true, createPermissions: [Permission.CreateProduct], deletePermissions: [Permission.DeleteProduct], additionalColumns: [
|
|
34
|
+
return (_jsx(CustomCard, { title: t('details.contents.title'), color: "green", icon: _jsx(CardIcons.group, {}), children: _jsx(DetailList, { noPaddings: true, detailLinkColumn: "id", filterFields: [{ key: 'id', operator: 'IDOperators' }], searchFields: ['code', 'name'], hideColumns: ['customFields', 'product', 'updatedAt', 'createdAt'], entityName: 'Product', route: Routes['products'], tableId: "products-list-view", fetch: fetch, noCreateButton: true, createPermissions: [Permission.CreateProduct, Permission.CreateCatalog], deletePermissions: [Permission.DeleteProduct, Permission.DeleteCatalog], additionalColumns: [
|
|
35
35
|
{
|
|
36
36
|
accessorKey: 'product',
|
|
37
37
|
enableSorting: false,
|
|
@@ -3,6 +3,7 @@ import { useParams } from 'react-router';
|
|
|
3
3
|
import { useValidators, DetailView, createDeenruvForm, getMutation, useMutation, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { CountryDetailView } from "./_components/CountryDetailView.js";
|
|
5
5
|
import { useCallback } from 'react';
|
|
6
|
+
import { Permission } from '@deenruv/admin-types';
|
|
6
7
|
const CreateCountryMutation = getMutation('createCountry');
|
|
7
8
|
const EditCountryMutation = getMutation('updateCountry');
|
|
8
9
|
const DeleteCountryMutation = getMutation('deleteCountry');
|
|
@@ -53,5 +54,9 @@ export const CountriesDetailPage = () => {
|
|
|
53
54
|
onSubmitted: onSubmitHandler,
|
|
54
55
|
onDeleted: onDeleteHandler,
|
|
55
56
|
}),
|
|
57
|
+
}, permissions: {
|
|
58
|
+
create: [Permission.CreateCountry, Permission.CreateSettings],
|
|
59
|
+
edit: [Permission.UpdateCountry, Permission.UpdateSettings],
|
|
60
|
+
delete: [Permission.DeleteCountry, Permission.DeleteSettings],
|
|
56
61
|
} }) }));
|
|
57
62
|
};
|
|
@@ -43,5 +43,5 @@ export const CountriesListPage = () => {
|
|
|
43
43
|
{ key: 'name', operator: 'StringOperators' },
|
|
44
44
|
{ key: 'enabled', operator: 'BooleanOperators' },
|
|
45
45
|
{ key: 'code', operator: 'StringOperators' },
|
|
46
|
-
], detailLinkColumn: "id", searchFields: ['name', 'code'], hideColumns: ['customFields', 'translations'], entityName: 'Country', route: Routes['countries'], tableId: tableId, fetch: fetch, onRemove: onRemove, createPermissions: [Permission.CreateCountry], deletePermissions: [Permission.DeleteCountry] }));
|
|
46
|
+
], detailLinkColumn: "id", searchFields: ['name', 'code'], hideColumns: ['customFields', 'translations'], entityName: 'Country', route: Routes['countries'], tableId: tableId, fetch: fetch, onRemove: onRemove, createPermissions: [Permission.CreateCountry, Permission.CreateSettings], deletePermissions: [Permission.DeleteCountry, Permission.DeleteSettings] }));
|
|
47
47
|
};
|
|
@@ -3,6 +3,7 @@ import { useParams } from 'react-router';
|
|
|
3
3
|
import { useValidators, DetailView, createDeenruvForm, getMutation, useMutation, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { FacetsDetailView } from "./_components/FacetDetailView.js";
|
|
5
5
|
import { useCallback } from 'react';
|
|
6
|
+
import { Permission } from '@deenruv/admin-types';
|
|
6
7
|
const CreateFacetMutation = getMutation('createFacet');
|
|
7
8
|
const EditFacetMutation = getMutation('updateFacet');
|
|
8
9
|
const DeleteFacetMutation = getMutation('deleteFacet');
|
|
@@ -52,5 +53,9 @@ export const FacetsDetailPage = () => {
|
|
|
52
53
|
onSubmitted: onSubmitHandler,
|
|
53
54
|
onDeleted: onDeleteHandler,
|
|
54
55
|
}),
|
|
56
|
+
}, permissions: {
|
|
57
|
+
create: [Permission.CreateFacet, Permission.CreateCatalog],
|
|
58
|
+
edit: [Permission.UpdateFacet, Permission.UpdateCatalog],
|
|
59
|
+
delete: [Permission.DeleteFacet, Permission.DeleteCatalog],
|
|
55
60
|
} }) }));
|
|
56
61
|
};
|
|
@@ -44,5 +44,5 @@ export const FacetsListPage = () => {
|
|
|
44
44
|
header: () => _jsx(TableLabel, { children: t('table.isPrivate') }),
|
|
45
45
|
cell: ({ row }) => row.original.isPrivate ? (_jsx(ListBadge, { className: "flex items-center justify-center border-orange-200 bg-orange-200 text-orange-800", children: t('visibility.private') })) : (_jsx(ListBadge, { className: "flex items-center justify-center border-green-200 bg-green-200 text-green-800", children: t('visibility.public') })),
|
|
46
46
|
},
|
|
47
|
-
], route: Routes['facets'], tableId: tableId, fetch: fetch, onRemove: onRemove, createPermissions: [Permission.CreateFacet], deletePermissions: [Permission.DeleteFacet] }));
|
|
47
|
+
], route: Routes['facets'], tableId: tableId, fetch: fetch, onRemove: onRemove, createPermissions: [Permission.CreateFacet, Permission.CreateCatalog], deletePermissions: [Permission.DeleteFacet, Permission.DeleteCatalog] }));
|
|
48
48
|
};
|
|
@@ -101,5 +101,5 @@ export const FacetsDetailView = () => {
|
|
|
101
101
|
setFacetValueIdInModal(null);
|
|
102
102
|
setOpen(true);
|
|
103
103
|
},
|
|
104
|
-
}, searchFields: ['name'], tableId: tableId, noPaddings: true, createPermissions: [Permission.CreateFacet], deletePermissions: [Permission.DeleteFacet] }) }))] }) }));
|
|
104
|
+
}, searchFields: ['name'], tableId: tableId, noPaddings: true, createPermissions: [Permission.CreateFacet, Permission.CreateCatalog], deletePermissions: [Permission.DeleteFacet, Permission.DeleteCatalog] }) }))] }) }));
|
|
105
105
|
};
|