@deenruv/admin-dashboard 1.0.16 → 1.0.17-dev.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/index.css +54 -44
- package/dist/locales/en/admins.json +62 -0
- package/dist/locales/en/collections.json +7 -0
- package/dist/locales/en/common.json +2 -0
- package/dist/locales/en/orders.json +8 -0
- package/dist/locales/en/products.json +14 -2
- package/dist/locales/en/promotions.json +4 -0
- package/dist/locales/pl/admins.json +62 -0
- package/dist/locales/pl/collections.json +7 -0
- package/dist/locales/pl/common.json +2 -0
- package/dist/locales/pl/orders.json +8 -0
- package/dist/locales/pl/products.json +14 -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 +21 -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/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 +58 -4
- 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/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,39 +1,108 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ArrowDownSquareIcon, ArrowUpSquareIcon, Folder, FolderOpen
|
|
2
|
+
import { ArrowDownSquareIcon, ArrowRight, ArrowUpSquareIcon, CornerDownRight, Folder, FolderOpen } from 'lucide-react';
|
|
3
3
|
import { Permission, SortOrder } from '@deenruv/admin-types';
|
|
4
4
|
import { CollectionProductVariantsDrawer } from './_components/CollectionProductVariantsDrawer.js';
|
|
5
|
-
import { DrawerTrigger, Routes, apiClient, ListBadge, DetailList, deepMerge, ListLocations, EntityChannelManagementBulkAction, EntityFacetManagementBulkAction, } from '@deenruv/react-ui-devkit';
|
|
6
|
-
import {
|
|
5
|
+
import { Button, DrawerTrigger, Routes, apiClient, ListBadge, DetailList, deepMerge, ListLocations, EntityChannelManagementBulkAction, EntityFacetManagementBulkAction, useDetailList, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
6
|
+
import { useNavigate } from 'react-router';
|
|
7
7
|
const tableId = 'collections-list-view';
|
|
8
8
|
const { selector } = ListLocations[tableId];
|
|
9
|
+
const COLLECTION_TREE_FETCH_LIMIT = 1000;
|
|
10
|
+
const hasActiveFilter = (filter) => {
|
|
11
|
+
if (!filter) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return Object.values(filter).some((value) => {
|
|
15
|
+
if (value === null || value === undefined || value === '') {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
return value.length > 0;
|
|
20
|
+
}
|
|
21
|
+
if (typeof value === 'object') {
|
|
22
|
+
return Object.values(value).some((operatorValue) => operatorValue !== null && operatorValue !== undefined && operatorValue !== '');
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
const buildCollectionTree = (items) => {
|
|
28
|
+
const itemsById = new Map();
|
|
29
|
+
items.forEach((item) => {
|
|
30
|
+
itemsById.set(item.id, { ...item, children: [] });
|
|
31
|
+
});
|
|
32
|
+
const roots = [];
|
|
33
|
+
itemsById.forEach((item) => {
|
|
34
|
+
const parent = item.parentId ? itemsById.get(item.parentId) : undefined;
|
|
35
|
+
if (parent && parent.id !== item.id) {
|
|
36
|
+
parent.children?.push(item);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
roots.push(item);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return roots;
|
|
43
|
+
};
|
|
44
|
+
const withoutNestedChildren = (items) => {
|
|
45
|
+
return items.map((item) => ({ ...item, children: [] }));
|
|
46
|
+
};
|
|
47
|
+
const CollectionNameHeader = () => {
|
|
48
|
+
const { sortButton } = useDetailList();
|
|
49
|
+
const { t } = useTranslation('table');
|
|
50
|
+
return sortButton('name', t('columns.name'));
|
|
51
|
+
};
|
|
9
52
|
const fetch = async ({ page, perPage, filter, filterOperator, sort }, additionalSelector) => {
|
|
53
|
+
const isFiltered = hasActiveFilter(filter);
|
|
10
54
|
const response = await apiClient('query')({
|
|
11
55
|
['collections']: [
|
|
12
56
|
{
|
|
13
57
|
options: {
|
|
14
|
-
take: perPage,
|
|
15
|
-
skip: (page - 1) * perPage,
|
|
58
|
+
take: isFiltered ? perPage : COLLECTION_TREE_FETCH_LIMIT,
|
|
59
|
+
skip: isFiltered ? (page - 1) * perPage : 0,
|
|
16
60
|
filterOperator: filterOperator,
|
|
17
|
-
sort: sort ? { [sort.key]: sort.sortDir } : {
|
|
61
|
+
sort: sort ? { [sort.key]: sort.sortDir } : { position: SortOrder.ASC },
|
|
18
62
|
...(filter && { filter }),
|
|
19
|
-
topLevelOnly:
|
|
63
|
+
...(!isFiltered && { topLevelOnly: false }),
|
|
20
64
|
},
|
|
21
65
|
},
|
|
22
66
|
{ items: deepMerge(selector, additionalSelector ?? {}), totalItems: true },
|
|
23
67
|
],
|
|
24
68
|
});
|
|
25
|
-
|
|
69
|
+
const collections = response['collections'];
|
|
70
|
+
const items = collections.items;
|
|
71
|
+
if (isFiltered) {
|
|
72
|
+
return {
|
|
73
|
+
...collections,
|
|
74
|
+
items: withoutNestedChildren(items),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const rootCollections = buildCollectionTree(items);
|
|
78
|
+
const pageStart = (page - 1) * perPage;
|
|
79
|
+
return {
|
|
80
|
+
...collections,
|
|
81
|
+
items: rootCollections.slice(pageStart, pageStart + perPage),
|
|
82
|
+
totalItems: rootCollections.length,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
const onRemove = async (items) => {
|
|
86
|
+
const ids = items.map((item) => item.id);
|
|
87
|
+
const { deleteCollections } = await apiClient('mutation')({
|
|
88
|
+
deleteCollections: [{ ids }, { message: true, result: true }],
|
|
89
|
+
});
|
|
90
|
+
return !!deleteCollections.length;
|
|
26
91
|
};
|
|
27
92
|
export const CollectionsListPage = () => {
|
|
28
|
-
|
|
93
|
+
const navigate = useNavigate();
|
|
94
|
+
return (_jsx(DetailList, { filterFields: [], detailLinkColumn: "id", searchFields: ['name', 'code'], hideColumns: ['translations', 'breadcrumbs', 'description', 'children'], getSubRows: (row) => row.children, additionalColumns: [
|
|
29
95
|
{
|
|
30
|
-
accessorKey: '
|
|
31
|
-
header:
|
|
32
|
-
cell: ({ row
|
|
33
|
-
const value = getValue();
|
|
96
|
+
accessorKey: 'name',
|
|
97
|
+
header: () => _jsx(CollectionNameHeader, {}),
|
|
98
|
+
cell: ({ row }) => {
|
|
34
99
|
const isExpanded = row.getIsExpanded();
|
|
35
|
-
|
|
36
|
-
|
|
100
|
+
const canExpand = row.getCanExpand();
|
|
101
|
+
return (_jsxs("div", { className: "flex items-center gap-2", style: { paddingLeft: `${row.depth * 1.5}rem` }, children: [canExpand ? (_jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "size-7 shrink-0 text-stone-700 hover:text-stone-950", onClick: row.getToggleExpandedHandler(), "aria-expanded": isExpanded, "aria-label": `${isExpanded ? 'Collapse' : 'Expand'} ${row.original.name}`, children: isExpanded ? _jsx(FolderOpen, { size: 16 }) : _jsx(Folder, { size: 16 }) })) : (_jsx("span", { className: "flex size-7 shrink-0 items-center justify-center text-stone-400", "aria-hidden": "true", children: row.depth > 0 && _jsx(CornerDownRight, { size: 14 }) })), _jsxs(Button, { type: "button", variant: "outline", className: "h-7 min-w-0 justify-start gap-1 px-2 text-left", title: row.original.name, onClick: () => {
|
|
102
|
+
navigate(Routes.collections.to(row.original.id), {
|
|
103
|
+
viewTransition: true,
|
|
104
|
+
});
|
|
105
|
+
}, children: [_jsx("span", { className: "truncate", children: row.original.name }), _jsx(ArrowRight, { className: "shrink-0 pl-1", size: 16 })] })] }));
|
|
37
106
|
},
|
|
38
107
|
},
|
|
39
108
|
{
|
|
@@ -50,7 +119,7 @@ export const CollectionsListPage = () => {
|
|
|
50
119
|
{
|
|
51
120
|
icon: _jsx(FolderOpen, { size: 16 }),
|
|
52
121
|
label: 'Przenieś zaznaczone kolekcje',
|
|
53
|
-
onClick: async ({ table
|
|
122
|
+
onClick: async ({ table }) => {
|
|
54
123
|
const selectedRows = table.getSelectedRowModel().flatRows.map((row) => row);
|
|
55
124
|
if (selectedRows.length === 0) {
|
|
56
125
|
return { error: 'Nie zaznaczono żadnej kolekcji' };
|
|
@@ -118,7 +187,7 @@ export const CollectionsListPage = () => {
|
|
|
118
187
|
{
|
|
119
188
|
icon: _jsx(FolderOpen, { size: 16 }),
|
|
120
189
|
label: 'Przenieś kolekcje',
|
|
121
|
-
onClick: async (
|
|
190
|
+
onClick: async () => {
|
|
122
191
|
try {
|
|
123
192
|
// const result = await createDialogFromComponent(MoveCollectionsToCollections, [row]);
|
|
124
193
|
}
|
|
@@ -128,7 +197,5 @@ export const CollectionsListPage = () => {
|
|
|
128
197
|
return { success: '' };
|
|
129
198
|
},
|
|
130
199
|
},
|
|
131
|
-
], entityName: 'Collection', route: Routes['collections'], tableId: tableId, fetch: fetch, onRemove:
|
|
132
|
-
return true;
|
|
133
|
-
}, createPermissions: [Permission.CreateCollection], deletePermissions: [Permission.DeleteCollection] }));
|
|
200
|
+
], entityName: 'Collection', route: Routes['collections'], tableId: tableId, fetch: fetch, onRemove: onRemove, createPermissions: [Permission.CreateCollection], deletePermissions: [Permission.DeleteCollection] }));
|
|
134
201
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useRef } from 'react';
|
|
3
|
-
import { EntityCustomFields, Input, Label, Switch, CustomCard, CardIcons, useDetailView, useSettings, RichTextEditor, useTranslation, setInArrayBy, EntityChannelManager, Routes, normalizeString, } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { EntityCustomFields, Input, Label, Switch, Checkbox, CustomCard, CardIcons, useDetailView, useSettings, useServer, RichTextEditor, useTranslation, setInArrayBy, EntityChannelManager, Routes, normalizeString, } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { FiltersCard } from "./FiltersCard";
|
|
5
5
|
import { ContentsCard } from "./ContentsCard";
|
|
6
6
|
import { AssetsCard } from "../../products/_components/AssetsCard.js";
|
|
@@ -9,6 +9,7 @@ export const CollectionsDetailView = () => {
|
|
|
9
9
|
const { t } = useTranslation('collections');
|
|
10
10
|
const contentLng = useSettings((p) => p.translationsLanguage);
|
|
11
11
|
const selectedChannel = useSettings((p) => p.selectedChannel);
|
|
12
|
+
const channels = useServer((p) => p.channels);
|
|
12
13
|
const navigate = useNavigate();
|
|
13
14
|
const { form, fetchEntity, entity, id } = useDetailView('collections-detail-view', 'CreateCollectionInput', 'translations', 'assetIds', 'featuredAssetId', 'isPrivate', 'inheritFilters', 'filters', 'customFields');
|
|
14
15
|
const { base } = form;
|
|
@@ -40,7 +41,15 @@ export const CollectionsDetailView = () => {
|
|
|
40
41
|
})();
|
|
41
42
|
}, [contentLng, selectedChannel?.id]);
|
|
42
43
|
const translations = base.watch('translations') || [];
|
|
44
|
+
const additionalChannelIds = base.watch('additionalChannelIds') ?? [];
|
|
43
45
|
const currentTranslationValue = translations.find((v) => v.languageCode === contentLng);
|
|
46
|
+
const toggleAdditionalChannel = useCallback((channelId, checked) => {
|
|
47
|
+
if (channelId === selectedChannel?.id)
|
|
48
|
+
return;
|
|
49
|
+
const currentIds = base.watch('additionalChannelIds') ?? [];
|
|
50
|
+
const nextIds = checked ? [...new Set([...currentIds, channelId])] : currentIds.filter((id) => id !== channelId);
|
|
51
|
+
base.setField('additionalChannelIds', nextIds);
|
|
52
|
+
}, [base, selectedChannel?.id]);
|
|
44
53
|
const handleAddAsset = useCallback((newId) => {
|
|
45
54
|
if (!newId)
|
|
46
55
|
return;
|
|
@@ -85,7 +94,11 @@ export const CollectionsDetailView = () => {
|
|
|
85
94
|
: undefined, required: true }) }), _jsx("div", { className: "flex basis-full md:basis-1/3", children: _jsx(Input, { label: t('details.basic.slug'), value: currentTranslationValue?.slug ?? '', onChange: (e) => {
|
|
86
95
|
handleSlugManualEdit();
|
|
87
96
|
setTranslationField('slug', e.target.value);
|
|
88
|
-
}, required: true }) }), _jsxs("div", { className: "mt-7 flex basis-full items-center gap-3 md:basis-1/3", children: [_jsx(Switch, { checked: base.watch('isPrivate') ?? false, onCheckedChange: (e) => base.setField('isPrivate', e) }), _jsx(Label, { children: t('details.basic.isPrivate') })] })] }), _jsxs("div", { className: "flex basis-full flex-col", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.description') }), _jsx(RichTextEditor, { content: currentTranslationValue?.description ?? '', onContentChanged: (e) => setTranslationField('description', e) })] })] }) }), _jsx(AssetsCard, { onAddAsset: handleAddAsset, featuredAssetId: base.watch('featuredAssetId') ?? undefined, assetsIds: base.watch('assetIds') ?? undefined, onFeaturedAssetChange: (id) => base.setField('featuredAssetId', id), onAssetsChange: (ids) => base.setField('assetIds', ids) }), _jsx(EntityChannelManager, { entity: "collection", entityId: id, entityChannels: [{ id: selectedChannel?.id, code: selectedChannel?.code }], onRemoveSuccess: () => navigate(Routes.collections.list) })
|
|
97
|
+
}, required: true }) }), _jsxs("div", { className: "mt-7 flex basis-full items-center gap-3 md:basis-1/3", children: [_jsx(Switch, { checked: base.watch('isPrivate') ?? false, onCheckedChange: (e) => base.setField('isPrivate', e) }), _jsx(Label, { children: t('details.basic.isPrivate') })] })] }), _jsxs("div", { className: "flex basis-full flex-col", children: [_jsx(Label, { className: "mb-2", children: t('details.basic.description') }), _jsx(RichTextEditor, { content: currentTranslationValue?.description ?? '', onContentChanged: (e) => setTranslationField('description', e) })] })] }) }), _jsx(AssetsCard, { onAddAsset: handleAddAsset, featuredAssetId: base.watch('featuredAssetId') ?? undefined, assetsIds: base.watch('assetIds') ?? undefined, onFeaturedAssetChange: (id) => base.setField('featuredAssetId', id), onAssetsChange: (ids) => base.setField('assetIds', ids) }), id ? (_jsx(EntityChannelManager, { entity: "collection", entityId: id, entityChannels: [{ id: selectedChannel?.id, code: selectedChannel?.code }], onRemoveSuccess: () => navigate(Routes.collections.list) })) : (_jsx(CustomCard, { title: t('details.channels.title'), icon: _jsx(CardIcons.shipping, {}), color: "green", children: _jsxs("div", { className: "flex flex-col gap-4 pt-4", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: t('details.channels.description') }), _jsx("div", { className: "grid gap-3 md:grid-cols-2", children: channels.map((channel) => {
|
|
98
|
+
const isCurrentChannel = channel.id === selectedChannel?.id;
|
|
99
|
+
const checked = isCurrentChannel || additionalChannelIds.includes(channel.id);
|
|
100
|
+
return (_jsxs("label", { className: "flex items-center gap-3 rounded-md border p-3 text-sm transition-colors hover:bg-muted/50", children: [_jsx(Checkbox, { checked: checked, disabled: isCurrentChannel, onCheckedChange: (value) => toggleAdditionalChannel(channel.id, !!value) }), _jsx("span", { className: "font-medium", children: channel.code }), isCurrentChannel && (_jsx("span", { className: "ml-auto rounded-full bg-muted px-2 py-1 text-xs text-muted-foreground", children: t('details.channels.currentChannel') }))] }, channel.id));
|
|
101
|
+
}) }), !channels.length && _jsx("p", { className: "text-sm text-muted-foreground", children: t('details.channels.noChannels') })] }) })), _jsx(FiltersCard, { currentFiltersValue: base.watch('filters') ?? undefined, onFiltersValueChange: (filters) => base.setField('filters', filters ?? []), inheritValue: base.watch('inheritFilters') ?? false, onInheritChange: (e) => base.setField('inheritFilters', e), errors: base.formState.errors?.filters?.message ? [base.formState.errors.filters.message] : undefined }), _jsx(EntityCustomFields, { entityName: "collection", id: id, hideButton: true, onChange: (customFields, translations) => {
|
|
89
102
|
base.setField('customFields', customFields);
|
|
90
103
|
if (translations)
|
|
91
104
|
base.setField('translations', translations);
|
|
@@ -5,6 +5,44 @@ import { X } from 'lucide-react';
|
|
|
5
5
|
import { FacetsSelector } from "./FacetsSelector";
|
|
6
6
|
import { CombinationMode } from "./CombinationMode";
|
|
7
7
|
import { VariantsSelector } from "./VariantsSelector";
|
|
8
|
+
const getArgumentComponent = (argument) => argument?.ui?.component;
|
|
9
|
+
const getArgumentOptions = (argument) => argument?.ui?.options ?? [];
|
|
10
|
+
const stringifyDefaultValue = (value) => {
|
|
11
|
+
if (Array.isArray(value) || (typeof value === 'object' && value !== null)) {
|
|
12
|
+
return JSON.stringify(value);
|
|
13
|
+
}
|
|
14
|
+
if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string') {
|
|
15
|
+
return String(value);
|
|
16
|
+
}
|
|
17
|
+
return '';
|
|
18
|
+
};
|
|
19
|
+
const getDefaultArgumentValue = (argument) => {
|
|
20
|
+
if (argument.defaultValue !== undefined && argument.defaultValue !== null) {
|
|
21
|
+
return stringifyDefaultValue(argument.defaultValue);
|
|
22
|
+
}
|
|
23
|
+
const component = getArgumentComponent(argument);
|
|
24
|
+
if (argument.list || component === 'facet-value-form-input' || component === 'product-multi-form-input') {
|
|
25
|
+
return '[]';
|
|
26
|
+
}
|
|
27
|
+
if (component === 'select-form-input') {
|
|
28
|
+
return getArgumentOptions(argument)[0]?.value ?? '';
|
|
29
|
+
}
|
|
30
|
+
if (argument.type === 'boolean') {
|
|
31
|
+
return 'false';
|
|
32
|
+
}
|
|
33
|
+
return '';
|
|
34
|
+
};
|
|
35
|
+
const parseStringArrayValue = (value) => {
|
|
36
|
+
if (!value)
|
|
37
|
+
return [];
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(value);
|
|
40
|
+
return Array.isArray(parsed) ? parsed.filter((item) => typeof item === 'string') : [];
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
};
|
|
8
46
|
export const FiltersCard = ({ currentFiltersValue, onFiltersValueChange, inheritValue, onInheritChange, errors, }) => {
|
|
9
47
|
const { t } = useTranslation('collections');
|
|
10
48
|
const codesTranslations = t('details.filters.labels.codes', { returnObjects: true });
|
|
@@ -27,14 +65,14 @@ export const FiltersCard = ({ currentFiltersValue, onFiltersValueChange, inherit
|
|
|
27
65
|
}, [fetchOptions]);
|
|
28
66
|
const handleFiltersValueChange = useCallback((index, code, args) => {
|
|
29
67
|
const correspondingFilter = filters.find((h) => h?.code === code);
|
|
30
|
-
if (correspondingFilter
|
|
31
|
-
const newFiltersValue = [...currentFiltersValue];
|
|
68
|
+
if (correspondingFilter) {
|
|
69
|
+
const newFiltersValue = [...(currentFiltersValue || [])];
|
|
32
70
|
newFiltersValue[index] = {
|
|
33
71
|
code: correspondingFilter.code,
|
|
34
72
|
arguments: args ||
|
|
35
73
|
correspondingFilter.args.map((a) => ({
|
|
36
74
|
name: a.name,
|
|
37
|
-
value:
|
|
75
|
+
value: getDefaultArgumentValue(a),
|
|
38
76
|
})),
|
|
39
77
|
};
|
|
40
78
|
onFiltersValueChange(newFiltersValue);
|
|
@@ -49,38 +87,40 @@ export const FiltersCard = ({ currentFiltersValue, onFiltersValueChange, inherit
|
|
|
49
87
|
}, [onFiltersValueChange, currentFiltersValue]);
|
|
50
88
|
const handleAddFilter = useCallback(() => {
|
|
51
89
|
const defaultFilter = filters[0];
|
|
90
|
+
if (!defaultFilter)
|
|
91
|
+
return;
|
|
52
92
|
const newFiltersValue = [
|
|
53
93
|
...(currentFiltersValue || []),
|
|
54
94
|
{
|
|
55
95
|
code: defaultFilter.code,
|
|
56
96
|
arguments: defaultFilter.args.map((a) => ({
|
|
57
97
|
name: a.name,
|
|
58
|
-
value:
|
|
98
|
+
value: getDefaultArgumentValue(a),
|
|
59
99
|
})),
|
|
60
100
|
},
|
|
61
101
|
];
|
|
62
102
|
onFiltersValueChange(newFiltersValue);
|
|
63
|
-
}, [onFiltersValueChange, currentFiltersValue]);
|
|
64
|
-
return (_jsx(CustomCard, { title: t('details.filters.title'), upperRight: _jsx(ErrorMessage, { errors: errors }), color: "orange", icon: _jsx(CardIcons.filter, {}), children: _jsx("div", { className: "flex- flex flex-wrap gap-4 xl:flex-nowrap", children: _jsxs("div", { className: "flex basis-full flex-col gap-4", children: [_jsxs("div", { className: "mb-2 flex basis-full", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Switch, { checked: inheritValue, onCheckedChange: onInheritChange }), _jsx(Label, { children: t('details.filters.inherit') })] }), _jsx(Button, { className: "ml-auto", onClick: handleAddFilter, children: t('details.filters.addCondition') })] }), currentFiltersValue?.map((filter, index) => {
|
|
103
|
+
}, [filters, onFiltersValueChange, currentFiltersValue]);
|
|
104
|
+
return (_jsx(CustomCard, { title: t('details.filters.title'), upperRight: _jsx(ErrorMessage, { errors: errors }), color: "orange", icon: _jsx(CardIcons.filter, {}), children: _jsx("div", { className: "flex- flex flex-wrap gap-4 xl:flex-nowrap", children: _jsxs("div", { className: "flex basis-full flex-col gap-4", children: [_jsxs("div", { className: "mb-2 flex basis-full", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Switch, { checked: inheritValue, onCheckedChange: onInheritChange }), _jsx(Label, { children: t('details.filters.inherit') })] }), _jsx(Button, { className: "ml-auto", onClick: handleAddFilter, disabled: filters.length === 0, title: filters.length === 0 ? t('details.filters.noAvailableConditions') : undefined, children: t('details.filters.addCondition') })] }), currentFiltersValue?.map((filter, index) => {
|
|
65
105
|
return (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(Separator, {}), _jsxs("div", { className: "flex w-1/2 items-end gap-1", children: [_jsx(SimpleSelect, { label: t('details.filters.condition'), value: filter ? filter.code : '', onValueChange: (e) => handleFiltersValueChange(index, e), options: allFiltersOptions }), filter?.code && (_jsx(Button, { variant: 'secondary', className: "p-2", onClick: (e) => {
|
|
66
106
|
e.preventDefault();
|
|
67
107
|
handleRemoveFilter(filter.code);
|
|
68
108
|
}, children: _jsx(X, { size: 20 }) }))] }), _jsx("div", { className: "flex items-start justify-center gap-4", children: filter?.arguments.map((e, i) => {
|
|
69
109
|
const _filter = filters?.find((f) => f.code === filter.code);
|
|
70
110
|
const argument = _filter?.args.find((a) => a.name === e.name);
|
|
71
|
-
return argument
|
|
111
|
+
return getArgumentComponent(argument) === 'facet-value-form-input' ? (_jsx(FacetsSelector, { value: parseStringArrayValue(filter?.arguments[i].value), onChange: (e) => {
|
|
72
112
|
filter.arguments[i] = { name: argument?.name || '', value: JSON.stringify(e) };
|
|
73
113
|
handleFiltersValueChange(index, filter?.code, filter.arguments);
|
|
74
|
-
} })) : argument
|
|
114
|
+
} })) : getArgumentComponent(argument) === 'select-form-input' ? (_jsx(SimpleSelect, { label: argument?.label || argument?.name || '', value: filter?.arguments[i].value, onValueChange: (e) => {
|
|
75
115
|
filter.arguments[i] = { name: argument?.name || '', value: e };
|
|
76
116
|
handleFiltersValueChange(index, filter?.code, filter.arguments);
|
|
77
|
-
}, options: (argument
|
|
117
|
+
}, options: getArgumentOptions(argument).map((o) => ({
|
|
78
118
|
label: o.value,
|
|
79
119
|
value: o.value,
|
|
80
|
-
})) || [] }, i)) : argument
|
|
120
|
+
})) || [] }, i)) : getArgumentComponent(argument) === 'combination-mode-form-input' ? (_jsx(CombinationMode, { label: t('details.filters.labels.arguments.combination-mode'), value: filter?.arguments[i].value, onChange: (e) => {
|
|
81
121
|
filter.arguments[i] = { name: argument?.name || '', value: e };
|
|
82
122
|
handleFiltersValueChange(index, filter?.code, filter.arguments);
|
|
83
|
-
} })) : argument
|
|
123
|
+
} })) : getArgumentComponent(argument) === 'product-multi-form-input' ? (_jsx(VariantsSelector, { type: argument?.ui?.selectionMode, label: argument?.label || argument?.name || '', value: parseStringArrayValue(filter?.arguments[i].value), onChange: (e) => {
|
|
84
124
|
filter.arguments[i] = { name: argument?.name || '', value: JSON.stringify(e) };
|
|
85
125
|
handleFiltersValueChange(index, filter?.code, filter.arguments);
|
|
86
126
|
} })) : argument?.type === 'int' ? (_jsx("div", { className: "flex basis-full", children: _jsx(Input, { type: "number", step: 0.01, label: argument?.label || argument.name, value: filter?.arguments[i].value, onChange: (e) => {
|
|
@@ -34,7 +34,7 @@ export const CountriesDetailPage = () => {
|
|
|
34
34
|
if (!id) {
|
|
35
35
|
throw new Error('Could not find the id.');
|
|
36
36
|
}
|
|
37
|
-
return remove({
|
|
37
|
+
return remove({ id });
|
|
38
38
|
}, [remove, id]);
|
|
39
39
|
return (_jsx("div", { className: "relative flex flex-col gap-y-4", children: _jsx(DetailView, { id: id, locationId: "countries-detail-view", main: {
|
|
40
40
|
name: 'country',
|
|
@@ -2,5 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useTranslation, CardIcons, CustomCard, Input } from '@deenruv/react-ui-devkit';
|
|
3
3
|
export const PersonalDataCard = ({ setField, state }) => {
|
|
4
4
|
const { t } = useTranslation('customers');
|
|
5
|
-
|
|
5
|
+
const getFieldErrors = (fieldName) => state.formState.errors?.[fieldName]?.message ? [state.formState.errors[fieldName].message] : undefined;
|
|
6
|
+
return (_jsx(CustomCard, { title: t('personalData.header'), icon: _jsx(CardIcons.basic, {}), color: "blue", children: _jsxs("div", { className: "flex flex-col gap-4", children: [_jsx("div", { className: "flex w-1/4 gap-3", children: _jsx(Input, { label: t('personalData.title'), value: state.watch('title') ?? undefined, onChange: (e) => setField('title', e.target.value) }) }), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Input, { label: t('personalData.firstName'), value: state.watch('firstName') ?? undefined, onChange: (e) => setField('firstName', e.target.value), errors: getFieldErrors('firstName'), required: true }), _jsx(Input, { label: t('personalData.lastName'), value: state.watch('lastName') ?? undefined, onChange: (e) => setField('lastName', e.target.value), errors: getFieldErrors('lastName'), required: true })] }), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Input, { label: t('personalData.emailAddress'), value: state.watch('emailAddress') ?? undefined, onChange: (e) => setField('emailAddress', e.target.value), errors: getFieldErrors('emailAddress'), required: true }), _jsx(Input, { label: t('personalData.phoneNumber'), value: state.watch('phoneNumber') ?? undefined, onChange: (e) => setField('phoneNumber', e.target.value) })] })] }) }));
|
|
6
7
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from 'react';
|
|
3
|
-
import { Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Input, PageBlock, Separator,
|
|
3
|
+
import { Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Input, PageBlock, Separator, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, usePluginStore, } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { BarChart3, Box, Check, ChevronDown, Code2, Cog, FileCode, Filter, Grid3X3, Info, LayoutDashboard, List, MessageSquare, Puzzle, RefreshCw, Search, Settings, Table, X, } from 'lucide-react';
|
|
5
5
|
const getCategoryIcon = (category) => {
|
|
6
6
|
switch (category) {
|
|
@@ -33,7 +33,7 @@ const getStatusBadge = (status) => {
|
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
export const Extensions = () => {
|
|
36
|
-
const { allPlugins: _plugins
|
|
36
|
+
const { allPlugins: _plugins } = usePluginStore();
|
|
37
37
|
const [searchTerm, setSearchTerm] = useState('');
|
|
38
38
|
const [categoryFilter, setCategoryFilter] = useState('all');
|
|
39
39
|
const [statusFilter, setStatusFilter] = useState('all');
|
|
@@ -65,9 +65,5 @@ export const Extensions = () => {
|
|
|
65
65
|
setCategoryFilter('all');
|
|
66
66
|
setStatusFilter('all');
|
|
67
67
|
setSearchTerm('');
|
|
68
|
-
}, children: "Reset filters" })] })) : view === 'grid' ? (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filteredPlugins.map((plugin) => (_jsxs(Card, { className: "overflow-hidden", children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsx(CardTitle, { className: "text-lg", children: plugin.name })] }), getStatusBadge(plugin.status)] }), _jsx(CardDescription, { className: "mt-2", children: plugin.description })] }), _jsxs(CardContent, { className: "pb-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Version:" }), _jsx("span", { children: plugin.version })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Author:" }), _jsx("span", { children: plugin.author })] })] }), _jsx(Separator, { className: "my-3" }), _jsxs("div", { className: "grid grid-cols-4 gap-2 text-center text-sm", children: [_jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tables?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tables" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tabs?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tabs" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.components?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Components" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.widgets?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Widgets" })] })] })] }),
|
|
69
|
-
changePluginStatus(plugin.name, checked ? 'active' : 'inactive');
|
|
70
|
-
} }) })] })] }, plugin.name))) })) : (_jsxs("div", { className: "rounded-md border", children: [_jsxs("div", { className: "grid grid-cols-12 gap-4 p-4 font-medium", children: [_jsx("div", { className: "col-span-4", children: "Name" }), _jsx("div", { className: "col-span-3", children: "Author" }), _jsx("div", { className: "col-span-1 text-center", children: "Version" }), _jsx("div", { className: "col-span-1 text-center", children: "Status" }), _jsx("div", { className: "col-span-3 text-right", children: "Actions" })] }), _jsx(Separator, {}), filteredPlugins.map((plugin, index) => (_jsxs("div", { children: [_jsxs("div", { className: "grid grid-cols-12 items-center gap-4 p-4", children: [_jsx("div", { className: "col-span-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.name }), _jsx("div", { className: "text-xs text-muted-foreground", children: plugin.description })] })] }) }), _jsx("div", { className: "col-span-3", children: plugin.author }), _jsx("div", { className: "col-span-1 text-center", children: plugin.version }), _jsx("div", { className: "col-span-1 text-center", children: getStatusBadge(plugin.status) }), _jsxs("div", { className: "col-span-3 flex justify-end gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(Settings, { className: "mr-2 size-3" }), "Configure"] }), _jsx(Switch, { checked: plugin.status === 'active', onCheckedChange: (checked) => {
|
|
71
|
-
changePluginStatus(plugin.name, checked ? 'active' : 'inactive');
|
|
72
|
-
} })] })] }), index < filteredPlugins.length - 1 && _jsx(Separator, {})] }, plugin.name)))] }))] }) }));
|
|
68
|
+
}, children: "Reset filters" })] })) : view === 'grid' ? (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filteredPlugins.map((plugin) => (_jsxs(Card, { className: "overflow-hidden", children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsx(CardTitle, { className: "text-lg", children: plugin.name })] }), getStatusBadge(plugin.status)] }), _jsx(CardDescription, { className: "mt-2", children: plugin.description })] }), _jsxs(CardContent, { className: "pb-2", children: [_jsxs("div", { className: "grid grid-cols-2 gap-2 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Version:" }), _jsx("span", { children: plugin.version })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-muted-foreground", children: "Author:" }), _jsx("span", { children: plugin.author })] })] }), _jsx(Separator, { className: "my-3" }), _jsxs("div", { className: "grid grid-cols-4 gap-2 text-center text-sm", children: [_jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tables?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tables" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.tabs?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Tabs" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.components?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Components" })] }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.widgets?.length || 0 }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Widgets" })] })] })] }), _jsx(CardFooter, { className: "flex justify-between pt-2", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "size-8", children: _jsx(Info, { className: "size-4" }) }) }), _jsx(TooltipContent, { children: "View details" })] }) }) })] }, plugin.name))) })) : (_jsxs("div", { className: "rounded-md border", children: [_jsxs("div", { className: "grid grid-cols-12 gap-4 p-4 font-medium", children: [_jsx("div", { className: "col-span-4", children: "Name" }), _jsx("div", { className: "col-span-3", children: "Author" }), _jsx("div", { className: "col-span-1 text-center", children: "Version" }), _jsx("div", { className: "col-span-1 text-center", children: "Status" }), _jsx("div", { className: "col-span-3 text-right", children: "Actions" })] }), _jsx(Separator, {}), filteredPlugins.map((plugin, index) => (_jsxs("div", { children: [_jsxs("div", { className: "grid grid-cols-12 items-center gap-4 p-4", children: [_jsx("div", { className: "col-span-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "rounded-md bg-primary/10 p-2", children: getCategoryIcon(plugin.category) }), _jsxs("div", { children: [_jsx("div", { className: "font-medium", children: plugin.name }), _jsx("div", { className: "text-xs text-muted-foreground", children: plugin.description })] })] }) }), _jsx("div", { className: "col-span-3", children: plugin.author }), _jsx("div", { className: "col-span-1 text-center", children: plugin.version }), _jsx("div", { className: "col-span-1 text-center", children: getStatusBadge(plugin.status) }), _jsx("div", { className: "col-span-3 flex justify-end gap-2", children: _jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(Settings, { className: "mr-2 size-3" }), "Configure"] }) })] }), index < filteredPlugins.length - 1 && _jsx(Separator, {})] }, plugin.name)))] }))] }) }));
|
|
73
69
|
};
|
|
@@ -35,7 +35,7 @@ export const FacetsDetailPage = () => {
|
|
|
35
35
|
if (!id) {
|
|
36
36
|
throw new Error('Could not find the id.');
|
|
37
37
|
}
|
|
38
|
-
return remove({
|
|
38
|
+
return remove({ id });
|
|
39
39
|
}, [remove, id]);
|
|
40
40
|
return (_jsx("div", { className: "relative flex flex-col gap-y-4", children: _jsx(DetailView, { id: id, locationId: "facets-detail-view", main: {
|
|
41
41
|
name: 'facet',
|
|
@@ -1,17 +1,50 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect } from 'react';
|
|
3
|
-
import { useParams } from 'react-router';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useNavigate, useParams } from 'react-router';
|
|
4
4
|
import { OrderSummary, RealizationCard, CustomerSelectCard, AddressCard, ShippingMethod, TaxSummary, OrderHistory, ProductsCard, TopActions, Payments, SurchargeCard, } from "./_components";
|
|
5
|
-
import { useTranslation, useOrder, ORDER_STATE, EntityCustomFields, LoadingMask, DetailViewMarker, } from '@deenruv/react-ui-devkit';
|
|
5
|
+
import { useTranslation, useOrder, ORDER_STATE, EntityCustomFields, LoadingMask, DetailViewMarker, apiClient, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Routes, } from '@deenruv/react-ui-devkit';
|
|
6
6
|
import { PromotionsList } from "./_components/PromotionsList.js";
|
|
7
|
+
import { toast } from 'sonner';
|
|
8
|
+
const createDraftOrder = async () => {
|
|
9
|
+
const response = await apiClient('mutation')({
|
|
10
|
+
createDraftOrder: { id: true },
|
|
11
|
+
});
|
|
12
|
+
return response.createDraftOrder.id;
|
|
13
|
+
};
|
|
14
|
+
const DraftOrderCreateStart = () => {
|
|
15
|
+
const { t } = useTranslation('orders');
|
|
16
|
+
const navigate = useNavigate();
|
|
17
|
+
const [isCreating, setIsCreating] = useState(false);
|
|
18
|
+
const onCreate = async () => {
|
|
19
|
+
try {
|
|
20
|
+
setIsCreating(true);
|
|
21
|
+
const id = await createDraftOrder();
|
|
22
|
+
if (!id) {
|
|
23
|
+
toast.error(t('createDraftOrder.error'));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
navigate(Routes.orders.to(id), { viewTransition: true });
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
toast.error(t('createDraftOrder.error'));
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
setIsCreating(false);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return (_jsx("main", { className: "my-4", children: _jsx("div", { className: "mx-auto flex min-h-[70vh] w-full max-w-[720px] items-center px-4 2xl:px-8", children: _jsxs(Card, { className: "w-full", children: [_jsxs(CardHeader, { className: "space-y-2 text-center sm:text-left", children: [_jsx(CardTitle, { children: t('createDraftOrder.title') }), _jsx(CardDescription, { children: t('createDraftOrder.description') })] }), _jsx(CardContent, { children: _jsxs("div", { className: "flex flex-col-reverse gap-3 sm:flex-row sm:justify-end", children: [_jsx(Button, { variant: "outline", onClick: () => navigate(Routes.orders.list, { viewTransition: true }), disabled: isCreating, children: t('createDraftOrder.cancelButton') }), _jsx(Button, { onClick: onCreate, disabled: isCreating, children: isCreating ? (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-current border-r-transparent" }), t('createDraftOrder.creating')] })) : (t('createDraftOrder.startButton')) })] }) })] }) }) }));
|
|
36
|
+
};
|
|
7
37
|
export const OrdersDetailPage = () => {
|
|
8
38
|
const { id } = useParams();
|
|
9
39
|
const { t } = useTranslation('orders');
|
|
10
40
|
const { order, mode, fetchOrder, loading } = useOrder();
|
|
41
|
+
const isCreateRoute = id === 'new';
|
|
11
42
|
useEffect(() => {
|
|
12
|
-
if (id)
|
|
43
|
+
if (id && !isCreateRoute)
|
|
13
44
|
fetchOrder(id);
|
|
14
|
-
}, [id]);
|
|
45
|
+
}, [id, isCreateRoute]);
|
|
46
|
+
if (isCreateRoute)
|
|
47
|
+
return _jsx(DraftOrderCreateStart, {});
|
|
15
48
|
if (loading)
|
|
16
49
|
return _jsx(LoadingMask, {});
|
|
17
50
|
if (!order || !mode) {
|
|
@@ -4,15 +4,8 @@ import { Routes, apiClient, DetailList, deepMerge, OrderStateBadge, priceFormatt
|
|
|
4
4
|
import { useCallback } from 'react';
|
|
5
5
|
import { useShallow } from 'zustand/react/shallow';
|
|
6
6
|
import { useNavigate } from 'react-router';
|
|
7
|
-
import { toast } from 'sonner';
|
|
8
7
|
const tableId = 'orders-list-view';
|
|
9
8
|
const { selector } = ListLocations[tableId];
|
|
10
|
-
const createDraftOrder = async () => {
|
|
11
|
-
const response = await apiClient('mutation')({
|
|
12
|
-
createDraftOrder: { id: true },
|
|
13
|
-
});
|
|
14
|
-
return response.createDraftOrder.id;
|
|
15
|
-
};
|
|
16
9
|
const fetch = async ({ page, perPage, filter, filterOperator, sort }, additionalSelector) => {
|
|
17
10
|
const response = await apiClient('query')({
|
|
18
11
|
['orders']: [
|
|
@@ -71,15 +64,7 @@ export const OrdersListPage = () => {
|
|
|
71
64
|
},
|
|
72
65
|
},
|
|
73
66
|
], detailLinkColumn: "id", searchFields: ['code', 'customerLastName'], entityName: "Order", route: {
|
|
74
|
-
create: () => {
|
|
75
|
-
createDraftOrder()
|
|
76
|
-
.then((id) => {
|
|
77
|
-
if (!id)
|
|
78
|
-
toast.error('Failed to create draft order');
|
|
79
|
-
navigate(Routes.orders.to(id), { viewTransition: true });
|
|
80
|
-
})
|
|
81
|
-
.catch(() => toast.error('Failed to create draft order'));
|
|
82
|
-
},
|
|
67
|
+
create: () => navigate(Routes.orders.new, { viewTransition: true }),
|
|
83
68
|
edit: (id) => navigate(Routes.orders.to(id), { viewTransition: true }),
|
|
84
69
|
}, tableId: tableId, fetch: fetch, createPermissions: [Permission.CreateOrder], deletePermissions: [Permission.DeleteOrder], hideColumns: ['active', 'totalQuantity', 'currencyCode'], additionalColumns: [
|
|
85
70
|
{
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from 'react';
|
|
3
|
-
import { Button, Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DropdownMenuItem, useOrder, } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { Button, Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DropdownMenuItem, useOrder, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { Undo2 } from 'lucide-react';
|
|
5
|
-
import { useTranslation } from 'react-i18next';
|
|
6
5
|
import { ProductsTable } from "./";
|
|
7
6
|
import { RefundPaymentCard } from "./RefundPaymentCard.js";
|
|
8
7
|
export const CancelAndRefundDialog = ({ refundReason, setRefundReason, onConfirm, }) => {
|
|
@@ -3,7 +3,7 @@ import { Button, Dialog, DialogContent, DialogTitle, ScrollArea, useOrder, useSe
|
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import { useShallow } from 'zustand/react/shallow';
|
|
5
5
|
export const OrderLineCustomFields = ({ line, order, mode }) => {
|
|
6
|
-
const
|
|
6
|
+
const setModifiedOrder = useOrder(({ setModifiedOrder }) => setModifiedOrder);
|
|
7
7
|
const orderLineCustomFields = useServer(useShallow((p) => p.serverConfig?.entityCustomFields?.find((el) => el.entityName === 'OrderLine')?.customFields || []));
|
|
8
8
|
const { t } = useTranslation('common');
|
|
9
9
|
const [open, setOpen] = useState(false);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { OrderLineCustomFields } from "./OrderLineCustomFields.js";
|
|
3
|
-
import { Checkbox, ImageWithPreview, Input, Label, priceFormatter, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, useOrder, } from '@deenruv/react-ui-devkit';
|
|
3
|
+
import { Checkbox, ImageWithPreview, Input, Label, priceFormatter, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, useOrder, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
4
4
|
import { Tag } from 'lucide-react';
|
|
5
5
|
import { useCallback } from 'react';
|
|
6
|
-
import { useTranslation } from 'react-i18next';
|
|
7
6
|
export const ProductsTable = ({ setRefundLines, refundLines }) => {
|
|
8
7
|
const { t } = useTranslation('orders');
|
|
9
8
|
const { mode, currentOrder } = useOrder();
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Checkbox, CustomCard, Input, Label, priceFormatter, Textarea, useOrder } from '@deenruv/react-ui-devkit';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
2
|
+
import { Checkbox, CustomCard, Input, Label, priceFormatter, Textarea, useOrder, useTranslation, } from '@deenruv/react-ui-devkit';
|
|
4
3
|
export const RefundPaymentCard = ({ refundReason, setRefundReason, cancelShipping, setCancelShipping, refundAmount, setRefundAmount, }) => {
|
|
5
4
|
const { t } = useTranslation('orders');
|
|
6
5
|
const { modifiedOrder } = useOrder();
|
|
@@ -44,7 +44,7 @@ export const PaymentMethodsDetailPage = () => {
|
|
|
44
44
|
if (!id) {
|
|
45
45
|
throw new Error('Could not find the id.');
|
|
46
46
|
}
|
|
47
|
-
return remove({
|
|
47
|
+
return remove({ id });
|
|
48
48
|
}, [remove, id]);
|
|
49
49
|
return (_jsx("div", { className: "relative flex flex-col gap-y-4", children: _jsx(DetailView, { id: id, locationId: "paymentMethods-detail-view", main: {
|
|
50
50
|
name: 'paymentMethod',
|
|
@@ -24,10 +24,10 @@ const fetch = async ({ page, perPage, filter, filterOperator, sort }, additional
|
|
|
24
24
|
const onRemove = async (items) => {
|
|
25
25
|
try {
|
|
26
26
|
const ids = items.map((item) => item.id);
|
|
27
|
-
const {
|
|
28
|
-
|
|
27
|
+
const { deleteProductVariants } = await apiClient('mutation')({
|
|
28
|
+
deleteProductVariants: [{ ids }, { message: true, result: true }],
|
|
29
29
|
});
|
|
30
|
-
return !!
|
|
30
|
+
return !!deleteProductVariants.length;
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
33
|
return error;
|