@deenruv/admin-dashboard 1.0.16 → 1.0.17-dev.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/DeenruvAdminPanel.js +35 -46
- package/dist/access/access-context.js +10 -0
- package/dist/access/built-in-routes.js +300 -0
- package/dist/access/index.js +6 -0
- package/dist/access/navigation.js +33 -0
- package/dist/access/permission-access.js +9 -0
- package/dist/access/permission-routes.js +3 -0
- package/dist/access/types.js +1 -0
- package/dist/components/GlobalSearch.js +37 -62
- package/dist/components/Menu/ActiveAdmins.js +1 -1
- package/dist/components/Menu/ChannelSwitcher.js +1 -1
- package/dist/components/Menu/LanguagesDropdown.js +1 -1
- package/dist/components/Menu/Navigation.js +68 -229
- package/dist/components/Menu/NavigationFooter.js +7 -4
- package/dist/components/Menu/Notifications.js +1 -1
- package/dist/components/Menu/index.js +50 -16
- package/dist/components/storefrontAction/StorefrontAction.js +9 -0
- package/dist/components/storefrontAction/StorefrontAction.logic.js +27 -0
- package/dist/components/storefrontAction/index.js +2 -0
- package/dist/index.css +54 -44
- package/dist/locales/en/admins.json +62 -0
- package/dist/locales/en/collections.json +21 -0
- package/dist/locales/en/common.json +2 -0
- package/dist/locales/en/orders.json +8 -0
- package/dist/locales/en/products.json +29 -2
- package/dist/locales/en/promotions.json +4 -0
- package/dist/locales/pl/admins.json +62 -0
- package/dist/locales/pl/collections.json +21 -0
- package/dist/locales/pl/common.json +2 -0
- package/dist/locales/pl/orders.json +8 -0
- package/dist/locales/pl/products.json +29 -2
- package/dist/locales/pl/promotions.json +4 -0
- package/dist/pages/Root.js +31 -15
- package/dist/pages/admins/Detail.js +1 -1
- package/dist/pages/admins/List.js +8 -3
- package/dist/pages/admins/Provision.js +173 -0
- package/dist/pages/admins/Provision.logic.js +53 -0
- package/dist/pages/admins/index.js +1 -0
- package/dist/pages/assets/List.js +3 -3
- package/dist/pages/channels/Detail.js +1 -1
- package/dist/pages/collections/Detail.js +24 -6
- package/dist/pages/collections/List.js +87 -20
- package/dist/pages/collections/_components/CollectionDetailView.js +15 -2
- package/dist/pages/collections/_components/FiltersCard.js +51 -11
- package/dist/pages/collections/_components/collectionStorefrontAction/CollectionStorefrontAction.js +41 -0
- package/dist/pages/collections/_components/collectionStorefrontAction/CollectionStorefrontAction.logic.js +44 -0
- package/dist/pages/collections/_components/collectionStorefrontAction/index.js +2 -0
- package/dist/pages/countries/Detail.js +1 -1
- package/dist/pages/customers/_components/PersonalDataCard.js +2 -1
- package/dist/pages/extensions/Extensions.js +3 -7
- package/dist/pages/facets/Detail.js +1 -1
- package/dist/pages/orders/Detail.js +38 -5
- package/dist/pages/orders/List.js +1 -16
- package/dist/pages/orders/_components/CancelAndRefundDialog.js +1 -2
- package/dist/pages/orders/_components/OrderLineCustomFields.js +1 -1
- package/dist/pages/orders/_components/ProductsTable.js +1 -2
- package/dist/pages/orders/_components/RefundPaymentCard.js +1 -2
- package/dist/pages/payment-methods/Detail.js +1 -1
- package/dist/pages/product-variants/List.js +3 -3
- package/dist/pages/products/Detail.js +62 -5
- package/dist/pages/products/_components/AssetsCard.js +15 -2
- package/dist/pages/products/_components/OptionsCard.js +7 -5
- package/dist/pages/products/_components/PriceCard.js +21 -8
- package/dist/pages/products/_components/ProductDetailView.js +7 -3
- package/dist/pages/products/_components/Variant.js +53 -26
- package/dist/pages/products/_components/VariantsTab.js +1 -1
- package/dist/pages/products/_components/productStorefrontAction/ProductStorefrontAction.js +42 -0
- package/dist/pages/products/_components/productStorefrontAction/ProductStorefrontAction.logic.js +39 -0
- package/dist/pages/products/_components/productStorefrontAction/index.js +2 -0
- package/dist/pages/promotions/Detail.js +34 -3
- package/dist/pages/promotions/_components/EnabledCard.js +2 -2
- package/dist/pages/promotions/_components/PromotionDetailSidebar.js +2 -1
- package/dist/pages/roles/Detail.js +1 -1
- package/dist/pages/roles/_components/PermissionsTable.js +0 -1
- package/dist/pages/sellers/Detail.js +1 -1
- package/dist/pages/shipping-methods/Detail.js +10 -6
- package/dist/pages/shipping-methods/_components/CalculatorCard.js +27 -11
- package/dist/pages/shipping-methods/_components/CheckerCard.js +28 -12
- package/dist/pages/stock-locations/Detail.js +1 -1
- package/dist/pages/tax-rates/Detail.js +1 -1
- package/dist/pages/zones/Detail.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +68 -68
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useMemo, useState } from 'react';
|
|
3
3
|
import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbSeparator, Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, ScrollArea, TooltipProvider, Routes, useSettings, useServer, usePluginStore, cn, dashToCamelCase, apiClient, useGlobalSearch, useTranslation, DropdownMenuGroup, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuPortal, DropdownMenuSubContent, createDialog, buildURL, } from '@deenruv/react-ui-devkit';
|
|
4
|
+
import { Permission } from '@deenruv/admin-types';
|
|
4
5
|
import { useShallow } from 'zustand/react/shallow';
|
|
5
6
|
import { GripVertical, LogOutIcon, MenuIcon, Moon, Slash, Sun, SunMoon, RotateCwSquare, SearchIcon, } from 'lucide-react';
|
|
6
7
|
import * as ResizablePrimitive from 'react-resizable-panels';
|
|
@@ -11,15 +12,17 @@ import { BrandLogo } from "../BrandLogo.js";
|
|
|
11
12
|
import { LanguagesDropdown } from './LanguagesDropdown.js';
|
|
12
13
|
import { Notifications } from './Notifications.js';
|
|
13
14
|
import { NavigationFooter } from "./NavigationFooter.js";
|
|
14
|
-
|
|
15
|
+
import { canAccessAdminItem, useAdminAccess } from "../../access/index.js";
|
|
16
|
+
const ResizablePanelGroup = ({ className, ...props }) => (_jsx(ResizablePrimitive.Group, { className: cn('flex h-full w-full data-[orientation=vertical]:flex-col', className), ...props }));
|
|
15
17
|
const ResizablePanel = ResizablePrimitive.Panel;
|
|
16
|
-
const ResizableHandle = ({ withHandle, className, ...props }) => (_jsx(ResizablePrimitive.
|
|
18
|
+
const ResizableHandle = ({ withHandle, className, ...props }) => (_jsx(ResizablePrimitive.Separator, { className: cn('relative flex w-px items-center justify-center bg-border/70 after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:left-0 data-[orientation=vertical]:after:h-1 data-[orientation=vertical]:after:w-full data-[orientation=vertical]:after:translate-x-0 data-[orientation=vertical]:after:-translate-y-1/2 [&[data-orientation=vertical]>div]:rotate-90', className), ...props, children: withHandle && (_jsx("div", { className: "z-10 flex h-4 w-3 items-center justify-center border bg-background text-muted-foreground", children: _jsx(GripVertical, { className: "size-2.5" }) })) }));
|
|
17
19
|
const removableCrumbs = ['draft', 'admin-ui'];
|
|
18
20
|
export const Menu = ({ children }) => {
|
|
19
21
|
const openGlobalSearch = useGlobalSearch((state) => state.open);
|
|
20
22
|
const linkPath = [];
|
|
21
23
|
const { t } = useTranslation('common');
|
|
22
24
|
const { topNavigationActionsMenu, topNavigationComponents } = usePluginStore();
|
|
25
|
+
const { routes, defaultRoute } = useAdminAccess();
|
|
23
26
|
const { logOut, theme, setTheme } = useSettings(useShallow((p) => ({
|
|
24
27
|
logOut: p.logOut,
|
|
25
28
|
theme: p.theme,
|
|
@@ -29,7 +32,36 @@ export const Menu = ({ children }) => {
|
|
|
29
32
|
})));
|
|
30
33
|
const navigate = useNavigate();
|
|
31
34
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
32
|
-
const { activeAdministrator, setJobQueue } = useServer();
|
|
35
|
+
const { activeAdministrator, clearAdministratorAccess, setJobQueue, userPermissions } = useServer();
|
|
36
|
+
const defaultRoutePath = defaultRoute?.path || Routes.dashboard;
|
|
37
|
+
const defaultRouteMenuKey = defaultRoute?.nav?.menuKey || defaultRoute?.search?.menuKey || 'dashboard';
|
|
38
|
+
const globalSearchEnabled = true;
|
|
39
|
+
const languageSwitcherEnabled = true;
|
|
40
|
+
const channelSwitcherEnabled = true;
|
|
41
|
+
const notificationsEnabled = true;
|
|
42
|
+
const reindexEnabled = canAccessAdminItem({
|
|
43
|
+
item: { requiredPermissions: [Permission.UpdateCatalog, Permission.UpdateProduct] },
|
|
44
|
+
userPermissions,
|
|
45
|
+
});
|
|
46
|
+
const canAccessPluginSurface = (entry) => canAccessAdminItem({ item: entry.access, userPermissions });
|
|
47
|
+
const allowedTopNavigationComponents = topNavigationComponents?.filter(canAccessPluginSurface);
|
|
48
|
+
const allowedTopNavigationActions = topNavigationActionsMenu?.filter(canAccessPluginSurface);
|
|
49
|
+
const systemStatusRoute = routes.find((route) => route.id === 'system.status');
|
|
50
|
+
const globalSettingsRoute = routes.find((route) => route.id === 'settings.global');
|
|
51
|
+
const fastLinks = [
|
|
52
|
+
systemStatusRoute &&
|
|
53
|
+
canAccessAdminItem({ item: systemStatusRoute, userPermissions }) && {
|
|
54
|
+
key: 'systemStatus',
|
|
55
|
+
label: t('systemStatus'),
|
|
56
|
+
path: systemStatusRoute.path,
|
|
57
|
+
},
|
|
58
|
+
globalSettingsRoute &&
|
|
59
|
+
canAccessAdminItem({ item: globalSettingsRoute, userPermissions }) && {
|
|
60
|
+
key: 'globalSettings',
|
|
61
|
+
label: t('globalSettings'),
|
|
62
|
+
path: globalSettingsRoute.path,
|
|
63
|
+
},
|
|
64
|
+
].filter(Boolean);
|
|
33
65
|
const rebuildSearchIndex = async () => {
|
|
34
66
|
await apiClient('mutation')({ reindex: { id: true, queueName: true, state: true } }).then(({ reindex: { queueName, state } }) => {
|
|
35
67
|
setJobQueue(queueName, state === 'RUNNING');
|
|
@@ -42,18 +74,18 @@ export const Menu = ({ children }) => {
|
|
|
42
74
|
.flatMap((p) => p.split('/'))
|
|
43
75
|
.filter(Boolean)
|
|
44
76
|
.filter((crumb) => !removableCrumbs.includes(crumb)), [matches]);
|
|
45
|
-
return (_jsx("div", { className: "w-full
|
|
46
|
-
document.cookie = `react-resizable-panels:layout=${JSON.stringify(
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
document.cookie = `react-resizable-panels:collapsed=${JSON.stringify(true)}`;
|
|
53
|
-
}, className: cn(isCollapsed && 'min-w-[50px] transition-all duration-300 ease-in-out'), children: [_jsx("div", { className: cn('flex h-[80px] flex-col items-center justify-center gap-4 border-b'), children: _jsx("div", { className: `flex h-full items-center justify-center ${!isCollapsed && 'w-full'} cursor-pointer p-4`, onClick: () => navigate(Routes.dashboard, { viewTransition: true }), children: _jsx(BrandLogo, { isCollapsed: isCollapsed }) }) }), _jsxs("div", { className: "flex h-[calc(100vh-80px)] flex-col justify-between", children: [_jsx(Navigation, { isCollapsed: isCollapsed }), _jsx(NavigationFooter, { isCollapsed: isCollapsed })] })] }), _jsx(ResizableHandle, { withHandle: true }), _jsxs(ResizablePanel, { children: [_jsxs("div", { className: "flex h-[70px] items-center border-b p-4 lg:h-[80px] lg:px-6", children: [_jsxs("div", { className: "flex flex-col items-start justify-center", children: [_jsx(Breadcrumb, { children: _jsx(BreadcrumbList, { children: crumbs.length ? (crumbs.map((c, i) => {
|
|
77
|
+
return (_jsx("div", { className: "w-full bg-background", children: _jsx("div", { className: "flex h-full max-h-screen flex-col", children: _jsx("div", { className: "flex-1", children: _jsx(TooltipProvider, { delayDuration: 100, children: _jsxs(ResizablePanelGroup, { onLayoutChanged: (layout) => {
|
|
78
|
+
document.cookie = `react-resizable-panels:layout=${JSON.stringify(Object.values(layout))}`;
|
|
79
|
+
}, orientation: "horizontal", className: "size-full", children: [_jsxs(ResizablePanel, { id: "navigation", defaultSize: "16%", collapsedSize: "4%", collapsible: true, minSize: "11%", maxSize: "18%", onResize: (size) => {
|
|
80
|
+
const collapsed = size.asPercentage <= 4;
|
|
81
|
+
setIsCollapsed(collapsed);
|
|
82
|
+
document.cookie = `react-resizable-panels:collapsed=${JSON.stringify(collapsed)}`;
|
|
83
|
+
}, className: cn(isCollapsed && 'min-w-[50px] transition-all duration-300 ease-in-out'), children: [_jsx("div", { className: cn('flex h-[72px] flex-col items-center justify-center gap-4 border-b bg-card/80'), children: _jsx("div", { className: `flex h-full items-center justify-center ${!isCollapsed && 'w-full'} cursor-pointer px-4 py-3`, onClick: () => navigate(defaultRoutePath, { viewTransition: true }), children: _jsx(BrandLogo, { isCollapsed: isCollapsed }) }) }), _jsxs("div", { className: "flex h-[calc(100vh-72px)] flex-col justify-between bg-card/70", children: [_jsx(Navigation, { isCollapsed: isCollapsed }), _jsx(NavigationFooter, { isCollapsed: isCollapsed })] })] }), _jsx(ResizableHandle, { withHandle: true }), _jsxs(ResizablePanel, { id: "content", children: [_jsxs("div", { className: "flex h-[64px] items-center border-b bg-background/95 px-3 backdrop-blur lg:h-[72px] lg:px-5", children: [_jsxs("div", { className: "flex flex-col items-start justify-center", children: [_jsx(Breadcrumb, { children: _jsx(BreadcrumbList, { children: crumbs.length ? (crumbs.map((c, i) => {
|
|
54
84
|
linkPath.push(c);
|
|
55
|
-
return (_jsxs(React.Fragment, { children: [_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to: buildURL(linkPath), viewTransition: true, children: _jsx("p", { className: cn('text-
|
|
56
|
-
})) : (_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to:
|
|
85
|
+
return (_jsxs(React.Fragment, { children: [_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to: buildURL(linkPath), viewTransition: true, children: _jsx("p", { className: cn('text-sm font-semibold tracking-tight text-foreground capitalize'), children: i === 0 ? t('menu.' + dashToCamelCase(c)) : c }) }) }), i !== crumbs.length - 1 && (_jsx(BreadcrumbSeparator, { children: _jsx(Slash, { className: "text-muted-foreground" }) }))] }, c));
|
|
86
|
+
})) : (_jsx(BreadcrumbItem, { children: _jsx(NavLink, { to: defaultRoutePath, viewTransition: true, children: _jsx("p", { className: "text-xl font-semibold tracking-tight text-foreground", children: t(defaultRouteMenuKey === 'dashboard'
|
|
87
|
+
? 'dashboard'
|
|
88
|
+
: `menu.${dashToCamelCase(defaultRouteMenuKey)}`) }) }) })) }) }), _jsx("div", { className: "flex items-center gap-2" })] }), _jsxs("div", { className: "flex flex-1 items-center justify-end gap-1.5", children: [allowedTopNavigationComponents && allowedTopNavigationComponents.length > 0 ? (_jsx("div", { className: "flex items-center gap-2", children: allowedTopNavigationComponents.map(({ component: Component }, index) => (_jsx(Component, {}, index))) })) : null, languageSwitcherEnabled && _jsx(LanguagesDropdown, {}), channelSwitcherEnabled && _jsx(ChannelSwitcher, { className: "min-w-44" }), globalSearchEnabled && (_jsx(Button, { onClick: openGlobalSearch, variant: "outline", size: "icon", className: "relative size-9", children: _jsx(SearchIcon, { className: "size-4" }) })), notificationsEnabled && _jsx(Notifications, {}), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "icon", className: "size-9", children: [theme === 'light' ? (_jsx(Sun, { className: "size-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" })) : theme === 'dark' ? (_jsx(Moon, { className: "absolute size-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" })) : (_jsx(SunMoon, { className: "absolute size-[1.2rem] rotate-90 transition-all" })), _jsx("span", { className: "sr-only", children: t('toggleTheme') })] }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuItem, { onClick: () => setTheme('light'), children: t('themeLight') }), _jsx(DropdownMenuItem, { onClick: () => setTheme('dark'), children: t('themeDark') }), _jsx(DropdownMenuItem, { onClick: () => setTheme('system'), children: t('themeSystem') })] })] }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "icon", className: "size-9", children: _jsx(MenuIcon, { className: "size-4" }) }) }), _jsxs(DropdownMenuContent, { className: "z-[150] mr-6 min-w-40", children: [activeAdministrator?.emailAddress && (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuLabel, { className: "flex items-center gap-2 px-3 py-2 font-medium", children: [_jsx("div", { className: "flex size-6 items-center justify-center bg-primary/10 text-xs font-semibold text-primary", children: activeAdministrator.firstName.charAt(0).toUpperCase() }), _jsxs("div", { className: "truncate text-sm", children: [activeAdministrator.firstName, " ", activeAdministrator.lastName] })] }), _jsx(DropdownMenuSeparator, { className: "my-1" })] })), reindexEnabled && (_jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-nowrap", onSelect: rebuildSearchIndex, children: [_jsx(RotateCwSquare, { className: "size-4" }), t('rebuildSerachIndex')] })), reindexEnabled && fastLinks.length > 0 && _jsx(DropdownMenuSeparator, {}), fastLinks.length > 0 && (_jsx(DropdownMenuGroup, { children: _jsxs(DropdownMenuSub, { children: [_jsx(DropdownMenuSubTrigger, { children: t('fastLinks') }), _jsx(DropdownMenuPortal, { children: _jsx(DropdownMenuSubContent, { children: fastLinks.map((link, index) => (_jsxs(React.Fragment, { children: [index > 0 && _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-nowrap", onSelect: () => navigate(link.path, { viewTransition: true }), children: [_jsx(RotateCwSquare, { className: "size-4" }), link.label] })] }, link.key))) }) })] }) })), allowedTopNavigationActions?.length && allowedTopNavigationActions.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), allowedTopNavigationActions.map((action) => (_jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2", onSelect: action.onClick, children: [action.icon && _jsx(action.icon, { className: "size-4" }), action.label] }, action.label)))] })) : null, _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { className: "flex cursor-pointer items-center gap-2 text-red-500", onSelect: async () => {
|
|
57
89
|
const result = await createDialog({
|
|
58
90
|
title: t('logOutConfirmation'),
|
|
59
91
|
description: t('logOutConfirmationDescription'),
|
|
@@ -62,7 +94,9 @@ export const Menu = ({ children }) => {
|
|
|
62
94
|
{ label: t('logOut'), variant: 'destructive', returnValue: true },
|
|
63
95
|
],
|
|
64
96
|
});
|
|
65
|
-
if (result)
|
|
97
|
+
if (result) {
|
|
98
|
+
clearAdministratorAccess();
|
|
66
99
|
logOut();
|
|
67
|
-
|
|
100
|
+
}
|
|
101
|
+
}, children: [_jsx(LogOutIcon, { className: "size-4" }), t('logOut')] })] })] })] })] }), _jsx(ScrollArea, { className: "relative h-[calc(100vh-64px)] overflow-y-hidden lg:h-[calc(100vh-72px)]", children: children })] })] }) }) }) }) }));
|
|
68
102
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, SimpleTooltip } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { ExternalLink } from 'lucide-react';
|
|
4
|
+
export const StorefrontAction = ({ label, state }) => {
|
|
5
|
+
if (state.kind === 'ready') {
|
|
6
|
+
return (_jsx(Button, { asChild: true, variant: "secondary", size: "sm", children: _jsxs("a", { href: state.url, target: "_blank", rel: "noopener noreferrer", className: "gap-2", children: [_jsx(ExternalLink, { className: "size-4", "aria-hidden": "true" }), label] }) }));
|
|
7
|
+
}
|
|
8
|
+
return (_jsx(SimpleTooltip, { content: state.tooltip, children: _jsxs(Button, { type: "button", variant: "secondary", size: "sm", className: "gap-2", disabled: true, children: [_jsx(ExternalLink, { className: "size-4", "aria-hidden": "true" }), label] }) }));
|
|
9
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const getStorefrontEntityUrlState = (context, resolver) => {
|
|
2
|
+
let resolvedUrl;
|
|
3
|
+
try {
|
|
4
|
+
resolvedUrl = resolver(context);
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return { kind: 'disabled', reason: 'resolverFailed' };
|
|
8
|
+
}
|
|
9
|
+
if (resolvedUrl === undefined)
|
|
10
|
+
return { kind: 'hidden' };
|
|
11
|
+
if (resolvedUrl === null)
|
|
12
|
+
return { kind: 'disabled', reason: 'resolverEmpty' };
|
|
13
|
+
let urlString;
|
|
14
|
+
let protocol;
|
|
15
|
+
try {
|
|
16
|
+
const url = new globalThis.URL(resolvedUrl);
|
|
17
|
+
urlString = url.href;
|
|
18
|
+
protocol = url.protocol;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { kind: 'disabled', reason: 'urlNotAbsolute' };
|
|
22
|
+
}
|
|
23
|
+
if (protocol !== 'http:' && protocol !== 'https:') {
|
|
24
|
+
return { kind: 'disabled', reason: 'unsupportedProtocol' };
|
|
25
|
+
}
|
|
26
|
+
return { kind: 'ready', url: urlString };
|
|
27
|
+
};
|
package/dist/index.css
CHANGED
|
@@ -24,47 +24,47 @@
|
|
|
24
24
|
@plugin "@tailwindcss/typography";
|
|
25
25
|
|
|
26
26
|
:root {
|
|
27
|
-
--background: hsl(
|
|
28
|
-
--foreground: hsl(
|
|
27
|
+
--background: hsl(225 33% 97%);
|
|
28
|
+
--foreground: hsl(230 20% 7%);
|
|
29
29
|
|
|
30
30
|
--card: hsl(0 0% 100%);
|
|
31
|
-
--card-foreground: hsl(
|
|
31
|
+
--card-foreground: hsl(230 20% 7%);
|
|
32
32
|
|
|
33
33
|
--popover: hsl(0 0% 100%);
|
|
34
|
-
--popover-foreground: hsl(
|
|
34
|
+
--popover-foreground: hsl(230 20% 7%);
|
|
35
35
|
|
|
36
|
-
--primary: hsl(
|
|
37
|
-
--primary-foreground: hsl(0 0%
|
|
36
|
+
--primary: hsl(238 70% 58%);
|
|
37
|
+
--primary-foreground: hsl(0 0% 100%);
|
|
38
38
|
|
|
39
|
-
--secondary: hsl(
|
|
40
|
-
--secondary-foreground: hsl(
|
|
39
|
+
--secondary: hsl(225 28% 94%);
|
|
40
|
+
--secondary-foreground: hsl(230 18% 12%);
|
|
41
41
|
|
|
42
|
-
--muted: hsl(
|
|
43
|
-
--muted-foreground: hsl(
|
|
42
|
+
--muted: hsl(225 24% 95%);
|
|
43
|
+
--muted-foreground: hsl(228 10% 41%);
|
|
44
44
|
|
|
45
|
-
--accent: hsl(
|
|
46
|
-
--accent-foreground: hsl(
|
|
45
|
+
--accent: hsl(238 80% 96%);
|
|
46
|
+
--accent-foreground: hsl(238 70% 42%);
|
|
47
47
|
|
|
48
48
|
--destructive: hsl(0 84.2% 60.2%);
|
|
49
49
|
--destructive-foreground: hsl(0 0% 98%);
|
|
50
50
|
|
|
51
|
-
--border: hsl(
|
|
52
|
-
--input: hsl(
|
|
53
|
-
--ring: hsl(
|
|
51
|
+
--border: hsl(225 18% 88%);
|
|
52
|
+
--input: hsl(225 18% 86%);
|
|
53
|
+
--ring: hsl(238 70% 58%);
|
|
54
54
|
|
|
55
|
-
--radius:
|
|
55
|
+
--radius: 0rem;
|
|
56
56
|
|
|
57
57
|
--warning: hsl(38 92% 50%);
|
|
58
58
|
--warning-foreground: hsl(48 96% 89%);
|
|
59
59
|
|
|
60
|
-
--navigation-link: hsl(
|
|
60
|
+
--navigation-link: hsl(228 14% 28%);
|
|
61
61
|
|
|
62
|
-
--topbar-height:
|
|
63
|
-
--topbar-height-lg:
|
|
62
|
+
--topbar-height: 64px;
|
|
63
|
+
--topbar-height-lg: 72px;
|
|
64
64
|
|
|
65
|
-
--page-padding-total-y:
|
|
66
|
-
--page-padding-total-y-md:
|
|
67
|
-
--page-padding-total-y-lg:
|
|
65
|
+
--page-padding-total-y: 2rem;
|
|
66
|
+
--page-padding-total-y-md: 3.25rem;
|
|
67
|
+
--page-padding-total-y-lg: 1.5rem;
|
|
68
68
|
|
|
69
69
|
--page-content-h: calc(100vh - var(--topbar-height) - var(--page-padding-total-y));
|
|
70
70
|
--page-content-h-md: calc(100vh - var(--topbar-height) - var(--page-padding-total-y-md));
|
|
@@ -72,38 +72,38 @@
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
.dark {
|
|
75
|
-
--background: hsl(
|
|
76
|
-
--foreground: hsl(
|
|
75
|
+
--background: hsl(230 22% 5%);
|
|
76
|
+
--foreground: hsl(220 22% 96%);
|
|
77
77
|
|
|
78
|
-
--card: hsl(
|
|
79
|
-
--card-foreground: hsl(
|
|
78
|
+
--card: hsl(228 18% 8%);
|
|
79
|
+
--card-foreground: hsl(220 22% 96%);
|
|
80
80
|
|
|
81
|
-
--popover: hsl(
|
|
82
|
-
--popover-foreground: hsl(
|
|
81
|
+
--popover: hsl(228 18% 9%);
|
|
82
|
+
--popover-foreground: hsl(220 22% 96%);
|
|
83
83
|
|
|
84
|
-
--primary: hsl(
|
|
85
|
-
--primary-foreground: hsl(
|
|
84
|
+
--primary: hsl(238 80% 66%);
|
|
85
|
+
--primary-foreground: hsl(0 0% 100%);
|
|
86
86
|
|
|
87
|
-
--secondary: hsl(
|
|
88
|
-
--secondary-foreground: hsl(
|
|
87
|
+
--secondary: hsl(228 16% 14%);
|
|
88
|
+
--secondary-foreground: hsl(220 22% 96%);
|
|
89
89
|
|
|
90
|
-
--muted: hsl(
|
|
91
|
-
--muted-foreground: hsl(
|
|
90
|
+
--muted: hsl(228 16% 14%);
|
|
91
|
+
--muted-foreground: hsl(225 10% 65%);
|
|
92
92
|
|
|
93
|
-
--accent: hsl(
|
|
94
|
-
--accent-foreground: hsl(
|
|
93
|
+
--accent: hsl(238 34% 18%);
|
|
94
|
+
--accent-foreground: hsl(238 100% 82%);
|
|
95
95
|
|
|
96
96
|
--destructive: hsl(0 62.8% 30.6%);
|
|
97
97
|
--destructive-foreground: hsl(0 0% 98%);
|
|
98
98
|
|
|
99
|
-
--border: hsl(
|
|
100
|
-
--input: hsl(
|
|
101
|
-
--ring: hsl(
|
|
99
|
+
--border: hsl(228 14% 20%);
|
|
100
|
+
--input: hsl(228 14% 22%);
|
|
101
|
+
--ring: hsl(238 80% 66%);
|
|
102
102
|
|
|
103
103
|
--warning: hsl(48 96% 89%);
|
|
104
104
|
--warning-foreground: hsl(38 92% 50%);
|
|
105
105
|
|
|
106
|
-
--navigation-link: hsl(
|
|
106
|
+
--navigation-link: hsl(220 18% 86%);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
@theme inline {
|
|
@@ -140,9 +140,9 @@
|
|
|
140
140
|
|
|
141
141
|
--color-navigation-link: var(--navigation-link);
|
|
142
142
|
|
|
143
|
-
--radius-lg:
|
|
144
|
-
--radius-md:
|
|
145
|
-
--radius-sm:
|
|
143
|
+
--radius-lg: 0rem;
|
|
144
|
+
--radius-md: 0rem;
|
|
145
|
+
--radius-sm: 0rem;
|
|
146
146
|
|
|
147
147
|
--animate-accordion-down: accordion-down 0.2s ease-out;
|
|
148
148
|
--animate-accordion-up: accordion-up 0.2s ease-out;
|
|
@@ -176,6 +176,16 @@
|
|
|
176
176
|
background-color: var(--background);
|
|
177
177
|
color: var(--foreground);
|
|
178
178
|
box-sizing: border-box;
|
|
179
|
+
font-family:
|
|
180
|
+
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
181
|
+
font-feature-settings:
|
|
182
|
+
"cv02", "cv03", "cv04", "cv11";
|
|
183
|
+
text-rendering: geometricPrecision;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
::selection {
|
|
187
|
+
background-color: var(--accent);
|
|
188
|
+
color: var(--accent-foreground);
|
|
179
189
|
}
|
|
180
190
|
}
|
|
181
191
|
|
|
@@ -200,7 +210,7 @@
|
|
|
200
210
|
}
|
|
201
211
|
|
|
202
212
|
*::-webkit-scrollbar-thumb {
|
|
203
|
-
background-color: var(--
|
|
213
|
+
background-color: color-mix(in srgb, var(--foreground) 18%, transparent);
|
|
204
214
|
position: relative;
|
|
205
215
|
border-radius: 9999px;
|
|
206
216
|
}
|
|
@@ -32,6 +32,68 @@
|
|
|
32
32
|
"placeholder": "Adding roles to a user"
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
|
+
"provision": {
|
|
36
|
+
"action": "Create with role",
|
|
37
|
+
"title": "Create administrator with role",
|
|
38
|
+
"description": "Use a business preset to create a role and assign it to a new administrator in one flow.",
|
|
39
|
+
"submit": "Create administrator",
|
|
40
|
+
"submitting": "Creating...",
|
|
41
|
+
"admin": {
|
|
42
|
+
"title": "Administrator account",
|
|
43
|
+
"description": "Credentials and contact details for the new administrator."
|
|
44
|
+
},
|
|
45
|
+
"role": {
|
|
46
|
+
"title": "Role setup",
|
|
47
|
+
"description": "Create a new role from the selected preset or reuse an existing role by code.",
|
|
48
|
+
"code": "Role code",
|
|
49
|
+
"descriptionLabel": "Role name",
|
|
50
|
+
"reuseExisting": "Use existing role with this code",
|
|
51
|
+
"reuseExistingHint": "When enabled, permissions and channels below are ignored and the administrator gets the existing role.",
|
|
52
|
+
"channels": "Channels",
|
|
53
|
+
"channelsPlaceholder": "Add channel"
|
|
54
|
+
},
|
|
55
|
+
"permissions": {
|
|
56
|
+
"title": "Permissions",
|
|
57
|
+
"description": "Review the preset and tweak permissions before creating the role.",
|
|
58
|
+
"reuseExisting": "Permissions are taken from the existing role when reuse mode is enabled."
|
|
59
|
+
},
|
|
60
|
+
"presets": {
|
|
61
|
+
"title": "Business preset",
|
|
62
|
+
"description": "Start from a safe operational role and adjust it if needed.",
|
|
63
|
+
"defaultBadge": "Default",
|
|
64
|
+
"backendNote": "The backend still enforces every permission. This wizard only provisions roles and administrator accounts.",
|
|
65
|
+
"shopManager": {
|
|
66
|
+
"title": "Shop manager",
|
|
67
|
+
"description": "Order handling, customer support, catalog visibility, payment/shipping lookup and stock-location visibility.",
|
|
68
|
+
"roleDescription": "Shop manager"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"summary": {
|
|
72
|
+
"title": "Summary",
|
|
73
|
+
"description": "What will be submitted.",
|
|
74
|
+
"role": "Role",
|
|
75
|
+
"channels": "Channels",
|
|
76
|
+
"permissions": "Permissions",
|
|
77
|
+
"mode": "Mode",
|
|
78
|
+
"create": "Create role",
|
|
79
|
+
"reuse": "Reuse role"
|
|
80
|
+
},
|
|
81
|
+
"validation": {
|
|
82
|
+
"emailRequired": "Email is required",
|
|
83
|
+
"emailInvalid": "Enter a valid email address",
|
|
84
|
+
"roleCodeRequired": "Role code is required",
|
|
85
|
+
"channelsRequired": "Select at least one channel",
|
|
86
|
+
"permissionsRequired": "Select at least one permission",
|
|
87
|
+
"roleCodeExists": "A role with this code already exists. Enable reuse or choose another code.",
|
|
88
|
+
"roleNotFound": "No existing role with this code was found."
|
|
89
|
+
},
|
|
90
|
+
"toasts": {
|
|
91
|
+
"success": "Administrator and role were created successfully",
|
|
92
|
+
"error": "Could not create administrator with role",
|
|
93
|
+
"roleCodeExists": "A role with this code already exists",
|
|
94
|
+
"roleNotFound": "No existing role with this code was found"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
35
97
|
"toasts": {
|
|
36
98
|
"adminLoadingError": "Failed to load administrator with ID {{value}}",
|
|
37
99
|
"adminUpdateSuccess": "Administrator successfully updated",
|
|
@@ -7,6 +7,20 @@
|
|
|
7
7
|
"baseInfoUpdated": "Updated: {{value}}",
|
|
8
8
|
"buttonDisabledTooltip": "Fill in all required fields",
|
|
9
9
|
"noChangesTooltip": "No changes have been made",
|
|
10
|
+
"storefrontAction": {
|
|
11
|
+
"label": "Open in storefront",
|
|
12
|
+
"disabled": {
|
|
13
|
+
"collectionPrivate": "Make the collection public and save it before opening it in the storefront.",
|
|
14
|
+
"missingChannel": "Select a channel before opening the collection in the storefront.",
|
|
15
|
+
"missingSlug": "The saved collection has no slug for the selected language.",
|
|
16
|
+
"unsavedPrivate": "Save the current visibility before opening the collection in the storefront.",
|
|
17
|
+
"unsavedSlug": "Save the current slug before opening the collection in the storefront.",
|
|
18
|
+
"resolverFailed": "The storefront URL could not be resolved.",
|
|
19
|
+
"resolverEmpty": "The storefront URL resolver returned no URL.",
|
|
20
|
+
"urlNotAbsolute": "The storefront URL must be absolute.",
|
|
21
|
+
"unsupportedProtocol": "The storefront URL must use HTTP or HTTPS."
|
|
22
|
+
}
|
|
23
|
+
},
|
|
10
24
|
"table": {
|
|
11
25
|
"id": "Id",
|
|
12
26
|
"name": "Name",
|
|
@@ -38,6 +52,7 @@
|
|
|
38
52
|
"inherit": "Filter inheritance",
|
|
39
53
|
"condition": "Condition",
|
|
40
54
|
"addCondition": "Add condition",
|
|
55
|
+
"noAvailableConditions": "Filter conditions are still loading",
|
|
41
56
|
"addFacets": "Adding aspect values",
|
|
42
57
|
"labels": {
|
|
43
58
|
"codes": {
|
|
@@ -55,6 +70,12 @@
|
|
|
55
70
|
},
|
|
56
71
|
"contents": {
|
|
57
72
|
"title": "Content"
|
|
73
|
+
},
|
|
74
|
+
"channels": {
|
|
75
|
+
"title": "Additional channels",
|
|
76
|
+
"description": "Select additional channels to assign after creating the collection. The current channel is assigned automatically.",
|
|
77
|
+
"currentChannel": "Current channel",
|
|
78
|
+
"noChannels": "No channels available"
|
|
58
79
|
}
|
|
59
80
|
},
|
|
60
81
|
"visibility": {
|
|
@@ -582,6 +582,7 @@
|
|
|
582
582
|
"globalSettings": "global settings",
|
|
583
583
|
"roles": "roles",
|
|
584
584
|
"admins": "administrators",
|
|
585
|
+
"adminProvision": "administrator provisioning",
|
|
585
586
|
"stock": "storage locations",
|
|
586
587
|
"sellers": "retailers",
|
|
587
588
|
"assets": "assets",
|
|
@@ -962,6 +963,7 @@
|
|
|
962
963
|
"tags": "Filter by tag",
|
|
963
964
|
"perPageValue": "{{value}} per page",
|
|
964
965
|
"confirmButton": "Add resource",
|
|
966
|
+
"uploadButton": "Upload from disk",
|
|
965
967
|
"cancel": "Cancel",
|
|
966
968
|
"noImages": "No resources for a specific search",
|
|
967
969
|
"description": "Uploading and managing resources that can be used in content"
|
|
@@ -40,6 +40,14 @@
|
|
|
40
40
|
"confirm": "Delete draft",
|
|
41
41
|
"cancel": "Cancel"
|
|
42
42
|
},
|
|
43
|
+
"createDraftOrder": {
|
|
44
|
+
"title": "Create a new draft order",
|
|
45
|
+
"description": "A draft order will only be created after you confirm. You can then add products, a customer, and shipping details.",
|
|
46
|
+
"startButton": "Start draft order",
|
|
47
|
+
"cancelButton": "Back to orders",
|
|
48
|
+
"creating": "Creating draft...",
|
|
49
|
+
"error": "Failed to create draft order"
|
|
50
|
+
},
|
|
43
51
|
"searchProduct": {
|
|
44
52
|
"id": "ID",
|
|
45
53
|
"image": "Image",
|
|
@@ -42,6 +42,29 @@
|
|
|
42
42
|
"removeVariant": "Usuń wariant",
|
|
43
43
|
"removeVariantFromChannel": "Usuń wariant z kanału"
|
|
44
44
|
},
|
|
45
|
+
"storefrontAction": {
|
|
46
|
+
"label": "Open in storefront",
|
|
47
|
+
"disabled": {
|
|
48
|
+
"productDisabled": "Enable and save the product before opening it in the storefront.",
|
|
49
|
+
"missingChannel": "Select a channel before opening the product in the storefront.",
|
|
50
|
+
"channelNotAssigned": "The saved product is not assigned to the selected channel.",
|
|
51
|
+
"missingSlug": "The saved product has no slug for the selected language.",
|
|
52
|
+
"unsavedSlug": "Save the current slug before opening the product in the storefront.",
|
|
53
|
+
"unsavedEnabled": "Save the current availability status before opening the product in the storefront.",
|
|
54
|
+
"resolverFailed": "The storefront URL could not be resolved.",
|
|
55
|
+
"resolverEmpty": "The storefront URL resolver returned no URL.",
|
|
56
|
+
"urlNotAbsolute": "The storefront URL must be absolute.",
|
|
57
|
+
"unsupportedProtocol": "The storefront URL must use HTTP or HTTPS."
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"initialVariant": {
|
|
61
|
+
"title": "Initial variant",
|
|
62
|
+
"description": "Create one default variant together with this product. If the variant name is empty, the product name will be used.",
|
|
63
|
+
"sku": "SKU",
|
|
64
|
+
"price": "Price",
|
|
65
|
+
"name": "Variant name",
|
|
66
|
+
"namePlaceholder": "Use the product name"
|
|
67
|
+
},
|
|
45
68
|
"optionsTab": {
|
|
46
69
|
"placeholder": "Wpisz, aby dodać nową wartość opcji",
|
|
47
70
|
"groupName": "Nazwa grupy",
|
|
@@ -53,6 +76,7 @@
|
|
|
53
76
|
"noOptionValues": "Dodaj opcje powyżej, aby znaleźć je tutaj"
|
|
54
77
|
},
|
|
55
78
|
"variantsTab": {
|
|
79
|
+
"unnamedVariant": "Unnamed variant",
|
|
56
80
|
"emptyState": {
|
|
57
81
|
"title": "Nic tutaj nie ma",
|
|
58
82
|
"description": "Nie ma jeszcze żadnych wariantów. Użyj przycisku powyżej, aby je dodać, pod warunkiem, że dodałeś już jakieś opcje. Jeśli nie, utwórz je najpierw w zakładce Opcje."
|
|
@@ -128,6 +152,7 @@
|
|
|
128
152
|
"noAssets": "Nie ma jeszcze żadnych aktywów",
|
|
129
153
|
"setAsFeatured": "Ustaw jako polecane",
|
|
130
154
|
"editAsset": "Edytuj zdjęcie",
|
|
155
|
+
"uploadAsset": "Upload image",
|
|
131
156
|
"removeAsset": "Usuń zasób",
|
|
132
157
|
"usedForColorsDesc": "Użyj tego atrybutu dla facetów, którzy są kolorami",
|
|
133
158
|
"colorsCollectionDesc": "Użyj tego dla ścieżek produktu w KOLORZE (BLAT/CORPUS)",
|
|
@@ -186,9 +211,11 @@
|
|
|
186
211
|
"new": "Nowy wariant",
|
|
187
212
|
"selectOption": "Wybierz opcję",
|
|
188
213
|
"createBasic": "Dane podstawowe",
|
|
189
|
-
"createOptions": "Opcje"
|
|
214
|
+
"createOptions": "Opcje",
|
|
215
|
+
"createOptionsHint": "Add an option group from this panel to start choosing variant options. You can refine option values later in the Options tab."
|
|
190
216
|
},
|
|
191
217
|
"validation": {
|
|
192
|
-
"nameSlugRequired": "Pola nazwy i slug są wymagane"
|
|
218
|
+
"nameSlugRequired": "Pola nazwy i slug są wymagane",
|
|
219
|
+
"initialVariantSkuRequired": "Variant SKU is required"
|
|
193
220
|
}
|
|
194
221
|
}
|
|
@@ -32,6 +32,68 @@
|
|
|
32
32
|
"placeholder": "Dodawanie ról do użytkownika"
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
|
+
"provision": {
|
|
36
|
+
"action": "Utwórz z rolą",
|
|
37
|
+
"title": "Utwórz administratora z rolą",
|
|
38
|
+
"description": "Użyj biznesowego presetu, żeby w jednym przepływie utworzyć rolę i przypisać ją do nowego administratora.",
|
|
39
|
+
"submit": "Utwórz administratora",
|
|
40
|
+
"submitting": "Tworzenie...",
|
|
41
|
+
"admin": {
|
|
42
|
+
"title": "Konto administratora",
|
|
43
|
+
"description": "Dane logowania i kontaktowe nowego administratora."
|
|
44
|
+
},
|
|
45
|
+
"role": {
|
|
46
|
+
"title": "Konfiguracja roli",
|
|
47
|
+
"description": "Utwórz nową rolę z wybranego presetu albo użyj istniejącej roli po kodzie.",
|
|
48
|
+
"code": "Kod roli",
|
|
49
|
+
"descriptionLabel": "Nazwa roli",
|
|
50
|
+
"reuseExisting": "Użyj istniejącej roli o tym kodzie",
|
|
51
|
+
"reuseExistingHint": "Po włączeniu tej opcji uprawnienia i kanały poniżej są ignorowane, a administrator otrzyma istniejącą rolę.",
|
|
52
|
+
"channels": "Kanały",
|
|
53
|
+
"channelsPlaceholder": "Dodaj kanał"
|
|
54
|
+
},
|
|
55
|
+
"permissions": {
|
|
56
|
+
"title": "Uprawnienia",
|
|
57
|
+
"description": "Przejrzyj preset i dostosuj uprawnienia przed utworzeniem roli.",
|
|
58
|
+
"reuseExisting": "Uprawnienia są pobierane z istniejącej roli, gdy włączone jest użycie istniejącej roli."
|
|
59
|
+
},
|
|
60
|
+
"presets": {
|
|
61
|
+
"title": "Preset biznesowy",
|
|
62
|
+
"description": "Zacznij od bezpiecznej roli operacyjnej i dostosuj ją, jeśli trzeba.",
|
|
63
|
+
"defaultBadge": "Domyślny",
|
|
64
|
+
"backendNote": "Backend nadal egzekwuje każde uprawnienie. Ten wizard tylko zakłada role i konta administratorów.",
|
|
65
|
+
"shopManager": {
|
|
66
|
+
"title": "Shop manager",
|
|
67
|
+
"description": "Obsługa zamówień, wsparcie klienta, widoczność katalogu, podgląd płatności/wysyłki i lokalizacji magazynowych.",
|
|
68
|
+
"roleDescription": "Shop manager"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"summary": {
|
|
72
|
+
"title": "Podsumowanie",
|
|
73
|
+
"description": "To zostanie wysłane.",
|
|
74
|
+
"role": "Rola",
|
|
75
|
+
"channels": "Kanały",
|
|
76
|
+
"permissions": "Uprawnienia",
|
|
77
|
+
"mode": "Tryb",
|
|
78
|
+
"create": "Utwórz rolę",
|
|
79
|
+
"reuse": "Użyj roli"
|
|
80
|
+
},
|
|
81
|
+
"validation": {
|
|
82
|
+
"emailRequired": "Adres e-mail jest wymagany",
|
|
83
|
+
"emailInvalid": "Podaj poprawny adres e-mail",
|
|
84
|
+
"roleCodeRequired": "Kod roli jest wymagany",
|
|
85
|
+
"channelsRequired": "Wybierz co najmniej jeden kanał",
|
|
86
|
+
"permissionsRequired": "Wybierz co najmniej jedno uprawnienie",
|
|
87
|
+
"roleCodeExists": "Rola o tym kodzie już istnieje. Włącz użycie istniejącej roli albo wybierz inny kod.",
|
|
88
|
+
"roleNotFound": "Nie znaleziono istniejącej roli o tym kodzie."
|
|
89
|
+
},
|
|
90
|
+
"toasts": {
|
|
91
|
+
"success": "Administrator i rola zostały utworzone pomyślnie",
|
|
92
|
+
"error": "Nie udało się utworzyć administratora z rolą",
|
|
93
|
+
"roleCodeExists": "Rola o tym kodzie już istnieje",
|
|
94
|
+
"roleNotFound": "Nie znaleziono istniejącej roli o tym kodzie"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
35
97
|
"toasts": {
|
|
36
98
|
"adminLoadingError": "Nie udało się załadować administratora o identyfikatorze {{value}}",
|
|
37
99
|
"adminUpdateSuccess": "Administrator został pomyślnie zaktualizowany",
|