@akinon/pz-theme 2.0.154-rc.6 → 2.0.154
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/CHANGELOG.md +7 -46
- package/package.json +4 -4
- package/src/__tests__/account-slot-coverage.test.ts +1 -0
- package/src/__tests__/custom-css.test.ts +12 -0
- package/src/__tests__/route-slug.test.ts +7 -0
- package/src/blocks/__tests__/group-order-items.test.ts +87 -0
- package/src/blocks/__tests__/order-detail-return.test.tsx +208 -0
- package/src/blocks/item-template.tsx +19 -25
- package/src/blocks/order-detail-block.tsx +273 -82
- package/src/blocks/order-list-block.tsx +2 -25
- package/src/blocks/product-block-utils.tsx +49 -13
- package/src/chrome/__tests__/page-context-builders.test.ts +1 -14
- package/src/chrome/page-context.ts +0 -4
- package/src/chrome/placeholder-slugs.ts +4 -0
- package/src/chrome/route-slug.ts +7 -3
- package/src/custom/README.md +0 -20
- package/src/utils/custom-css.ts +35 -2
- package/src/__tests__/row-scope.test.tsx +0 -118
- package/src/blocks/__tests__/order-line-actions.test.tsx +0 -54
- package/src/blocks/__tests__/order-list-rows.test.tsx +0 -112
- package/src/blocks/order-line-actions.ts +0 -45
- package/src/blocks/row-scope.tsx +0 -35
package/CHANGELOG.md
CHANGED
|
@@ -1,51 +1,12 @@
|
|
|
1
1
|
# @akinon/pz-theme
|
|
2
2
|
|
|
3
|
-
## 2.0.154
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
- @akinon/next@2.0.154
|
|
9
|
-
- @akinon/theme-contract@2.0.154
|
|
10
|
-
|
|
11
|
-
## 2.0.154-rc.5
|
|
12
|
-
|
|
13
|
-
### Patch Changes
|
|
14
|
-
|
|
15
|
-
- ad5240c4: ZERO-5254: add custom render and theme editor support to pz-rate-review
|
|
16
|
-
- Updated dependencies [219164a3]
|
|
17
|
-
- Updated dependencies [86187b1c2]
|
|
18
|
-
- Updated dependencies [0cf9ea239]
|
|
19
|
-
- Updated dependencies [97d29893]
|
|
20
|
-
- Updated dependencies [324f97d55]
|
|
21
|
-
- Updated dependencies [51ea06888]
|
|
22
|
-
- Updated dependencies
|
|
23
|
-
- Updated dependencies [2fea41430]
|
|
24
|
-
- Updated dependencies [b55acb768]
|
|
25
|
-
- Updated dependencies [760258c1c]
|
|
26
|
-
- Updated dependencies [143be2b9d]
|
|
27
|
-
- Updated dependencies [7889b08fe]
|
|
28
|
-
- Updated dependencies [9f8cd3bc5]
|
|
29
|
-
- Updated dependencies [bfafa3f49]
|
|
30
|
-
- Updated dependencies [57d7eb305]
|
|
31
|
-
- Updated dependencies [d99a6a7d5]
|
|
32
|
-
- Updated dependencies [9db81a714]
|
|
33
|
-
- Updated dependencies [591e345e1]
|
|
34
|
-
- Updated dependencies [4de5303c5]
|
|
35
|
-
- Updated dependencies [95b139dc1]
|
|
36
|
-
- Updated dependencies [1d00f2d06]
|
|
37
|
-
- Updated dependencies [4ac7b2a1e]
|
|
38
|
-
- Updated dependencies [4998a9631]
|
|
39
|
-
- Updated dependencies [804d2bd6c]
|
|
40
|
-
- Updated dependencies [3909d3224]
|
|
41
|
-
- Updated dependencies [6a3d8a631]
|
|
42
|
-
- Updated dependencies [e18836b20]
|
|
43
|
-
- Updated dependencies [b1111d7b1]
|
|
44
|
-
- Updated dependencies [1595d458e]
|
|
45
|
-
- Updated dependencies [dca128112]
|
|
46
|
-
- Updated dependencies [9c778307]
|
|
47
|
-
- @akinon/next@2.0.154-rc.5
|
|
48
|
-
- @akinon/theme-contract@2.0.154-rc.5
|
|
3
|
+
## 2.0.154
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 51a88b89: ZERO-5183: Give the order cancellation screen its own placeholder (`account-order-cancellation-body`) so it can be composed in the theme editor. The `order-detail` block gains an "Easy return" link for orders that can be returned and, per returned line, the return method (scheduled pickup or standard), the carrier and the pickup date, each behind its own switch. Order rows now keep units of one product together only while they share a status and cancellation/return request, so returning one of two units no longer reads as both returned.
|
|
8
|
+
- @akinon/next@2.0.154
|
|
9
|
+
- @akinon/theme-contract@2.0.154
|
|
49
10
|
|
|
50
11
|
## 2.0.153
|
|
51
12
|
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/pz-theme",
|
|
3
3
|
"description": "Theme package for Project Zero Next — ThemePlaceholder system and theme editor infrastructure",
|
|
4
|
-
"version": "2.0.154
|
|
4
|
+
"version": "2.0.154",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "jest"
|
|
9
9
|
},
|
|
10
10
|
"peerDependencies": {
|
|
11
|
-
"@akinon/next": "2.0.154
|
|
11
|
+
"@akinon/next": "2.0.154",
|
|
12
12
|
"react": "^18.0.0 || ^19.0.0",
|
|
13
13
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@akinon/theme-contract": "2.0.154
|
|
16
|
+
"@akinon/theme-contract": "2.0.154",
|
|
17
17
|
"clsx": "2.1.1",
|
|
18
18
|
"lottie-web": "^5.13.0",
|
|
19
19
|
"react-multi-carousel": "2.8.4",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"zod": "4.4.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@akinon/next": "2.0.154
|
|
24
|
+
"@akinon/next": "2.0.154",
|
|
25
25
|
"@testing-library/jest-dom": "5.16.4",
|
|
26
26
|
"@testing-library/react": "16.3.2",
|
|
27
27
|
"@testing-library/user-event": "14.1.1",
|
|
@@ -27,6 +27,7 @@ const EXPECTED_MOUNTS: Record<string, string> = {
|
|
|
27
27
|
accountDashboard: '(dashboard)/layout.tsx',
|
|
28
28
|
accountOrders: 'orders/(list)/layout.tsx',
|
|
29
29
|
accountOrderDetail: 'orders/[id]/(detail)/layout.tsx',
|
|
30
|
+
accountOrderCancellation: 'orders/[id]/cancellation/layout.tsx',
|
|
30
31
|
accountAddresses: 'address/layout.tsx',
|
|
31
32
|
accountProfile: 'profile/layout.tsx',
|
|
32
33
|
accountChangePassword: 'change-password/layout.tsx',
|
|
@@ -61,6 +61,18 @@ describe('scoped custom CSS', () => {
|
|
|
61
61
|
expect(css).toContain(`${SCOPE} button`);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
it('leaves commas inside :has(), :is() and attribute values alone', () => {
|
|
65
|
+
// ZERO-5183: the second half of `:has(a, b)` used to come out as
|
|
66
|
+
// `:has(a, <scope> b)` — a selector that can never match.
|
|
67
|
+
const css = scopeCustomCss(
|
|
68
|
+
'& li:has([data-a], [data-b]) { display: flex; }\n& :is(p, span)[title="x, y"], em { color: red; }',
|
|
69
|
+
SCOPE
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
expect(css).toContain(`${SCOPE} li:has([data-a], [data-b]) {`);
|
|
73
|
+
expect(css).toContain(`${SCOPE} :is(p, span)[title="x, y"], ${SCOPE} em {`);
|
|
74
|
+
});
|
|
75
|
+
|
|
64
76
|
it('scopes inside a media query and keeps the condition', () => {
|
|
65
77
|
const css = scopeCustomCss(
|
|
66
78
|
'@media (max-width: 768px) { & [data-part="option"] { flex: 1 1 100%; } }',
|
|
@@ -80,6 +80,13 @@ describe('resolveBodySlug', () => {
|
|
|
80
80
|
PLACEHOLDER_SLUGS.accountAddresses
|
|
81
81
|
);
|
|
82
82
|
expect(resolveBodySlug('/users/orders/5/cancellation')).toBe(
|
|
83
|
+
PLACEHOLDER_SLUGS.accountOrderCancellation
|
|
84
|
+
);
|
|
85
|
+
expect(resolveBodySlug('/account/orders/5/cancellation/')).toBe(
|
|
86
|
+
PLACEHOLDER_SLUGS.accountOrderCancellation
|
|
87
|
+
);
|
|
88
|
+
// Any other screen under an order stays on the detail body.
|
|
89
|
+
expect(resolveBodySlug('/account/orders/5/invoice')).toBe(
|
|
83
90
|
PLACEHOLDER_SLUGS.accountOrderDetail
|
|
84
91
|
);
|
|
85
92
|
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { groupOrderItems } from '../product-block-utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ZERO-5183 — pz writes one order line per unit and the order blocks collapse
|
|
5
|
+
* the units of a product into one row. A row shows its first unit's status and
|
|
6
|
+
* return details, so units only share it while they are in the same state:
|
|
7
|
+
* returning 1 of 2 must not read as both returned.
|
|
8
|
+
*/
|
|
9
|
+
const product = { pk: 7, name: 'Gömlek', image: '/x.jpg', absolute_url: '#' };
|
|
10
|
+
|
|
11
|
+
const unit = (id: number, extra: Record<string, unknown> = {}) => ({
|
|
12
|
+
id,
|
|
13
|
+
price: '100.00',
|
|
14
|
+
quantity: 1,
|
|
15
|
+
status: { value: '550', label: 'Teslim Edildi' },
|
|
16
|
+
active_cancellation_request: null,
|
|
17
|
+
product,
|
|
18
|
+
...extra
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('groupOrderItems', () => {
|
|
22
|
+
it('still collapses units of a product that share a state', () => {
|
|
23
|
+
const rows = groupOrderItems([unit(1), unit(2), unit(3)]);
|
|
24
|
+
|
|
25
|
+
expect(rows).toHaveLength(1);
|
|
26
|
+
expect(rows[0]).toMatchObject({ key: '7', quantity: 3, total: 300 });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('gives a returned unit its own row', () => {
|
|
30
|
+
const returned = unit(2, {
|
|
31
|
+
status: { value: '600', label: 'İade Edildi' },
|
|
32
|
+
active_cancellation_request: { easy_return: { code: 'R1' } }
|
|
33
|
+
});
|
|
34
|
+
const rows = groupOrderItems([unit(1), returned]);
|
|
35
|
+
|
|
36
|
+
expect(rows.map((row) => [row.key, row.quantity, row.item.id])).toEqual([
|
|
37
|
+
['7', 1, 1],
|
|
38
|
+
['7-2', 1, 2]
|
|
39
|
+
]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('splits on a pending request even before the status moves', () => {
|
|
43
|
+
const requested = unit(2, {
|
|
44
|
+
active_cancellation_request: [{ id: 31, easy_return: { code: 'R1' } }]
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(groupOrderItems([unit(1), requested])).toHaveLength(2);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('keeps units returned under the same request together, and separate requests apart', () => {
|
|
51
|
+
const returned = (id: number, code: string) =>
|
|
52
|
+
unit(id, {
|
|
53
|
+
status: { value: '600', label: 'İade Edildi' },
|
|
54
|
+
active_cancellation_request: { easy_return: { code } }
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(
|
|
58
|
+
groupOrderItems([returned(1, 'R1'), returned(2, 'R1')]).map(
|
|
59
|
+
(row) => row.quantity
|
|
60
|
+
)
|
|
61
|
+
).toEqual([2]);
|
|
62
|
+
expect(
|
|
63
|
+
groupOrderItems([returned(1, 'R1'), returned(2, 'R2')]).map(
|
|
64
|
+
(row) => row.key
|
|
65
|
+
)
|
|
66
|
+
).toEqual(['7', '7-2']);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('merges a later unit back into the row of its state', () => {
|
|
70
|
+
const cancelled = unit(2, { status: { value: '100', label: 'İptal' } });
|
|
71
|
+
const rows = groupOrderItems([unit(1), cancelled, unit(3)]);
|
|
72
|
+
|
|
73
|
+
expect(rows.map((row) => [row.key, row.quantity])).toEqual([
|
|
74
|
+
['7', 2],
|
|
75
|
+
['7-2', 1]
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('never merges lines without a product pk', () => {
|
|
80
|
+
const rows = groupOrderItems([
|
|
81
|
+
{ id: 1, price: '1', quantity: 1, product: { name: 'A' } },
|
|
82
|
+
{ id: 2, price: '1', quantity: 1, product: { name: 'A' } }
|
|
83
|
+
]);
|
|
84
|
+
|
|
85
|
+
expect(rows.map((row) => row.key)).toEqual(['1', '2']);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import OrderDetailBlock from '../order-detail-block';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ZERO-5183 — the order detail is where an easy return starts and where a
|
|
7
|
+
* returned line says how it goes back: a "Kolay iade" link on an order that
|
|
8
|
+
* can be returned, and per line the method (a booked pickup or a standard
|
|
9
|
+
* drop-off), the carrier and the pickup day, each behind its own switch.
|
|
10
|
+
*/
|
|
11
|
+
let order: Record<string, unknown> | null = null;
|
|
12
|
+
|
|
13
|
+
jest.mock('next/navigation', () => ({
|
|
14
|
+
useParams: () => ({ id: '42' }),
|
|
15
|
+
useSearchParams: () => null
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
jest.mock('next-auth/react', () => ({
|
|
19
|
+
useSession: () => ({ data: null, status: 'authenticated' })
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
jest.mock('@akinon/next/hooks', () => ({
|
|
23
|
+
__esModule: true,
|
|
24
|
+
useLocalization: () => ({ locale: 'tr', currency: 'try' })
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
jest.mock('@akinon/next/data/client/account', () => ({
|
|
28
|
+
__esModule: true,
|
|
29
|
+
useGetOrderQuery: () => ({ data: order, isLoading: false })
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
const line = (id: number, request: unknown) => ({
|
|
33
|
+
id,
|
|
34
|
+
price: '5499.00',
|
|
35
|
+
quantity: 1,
|
|
36
|
+
status: { value: '600', label: 'İade Edildi' },
|
|
37
|
+
active_cancellation_request: request,
|
|
38
|
+
product: { pk: id, name: `Gömlek ${id}`, image: '/x.jpg', absolute_url: '#' }
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const blockOf = (properties: Record<string, unknown>) => ({
|
|
42
|
+
id: 'order-detail-1',
|
|
43
|
+
type: 'order-detail',
|
|
44
|
+
properties,
|
|
45
|
+
styles: {},
|
|
46
|
+
blocks: []
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const ALL_ON = {
|
|
50
|
+
showReturnLink: { desktop: true },
|
|
51
|
+
returnLinkLabel: { desktop: 'Kolay iade' },
|
|
52
|
+
showReturnMethod: { desktop: true },
|
|
53
|
+
returnMethodLabel: { desktop: 'İade yöntemi:' },
|
|
54
|
+
appointmentReturnLabel: { desktop: 'Randevulu' },
|
|
55
|
+
standardReturnLabel: { desktop: 'Standart' },
|
|
56
|
+
showReturnCarrier: { desktop: true },
|
|
57
|
+
returnCarrierLabel: { desktop: 'Kargo:' },
|
|
58
|
+
showPickupDate: { desktop: true },
|
|
59
|
+
pickupDateLabel: { desktop: 'Randevu tarihi:' }
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const texts = (root: ParentNode, part: string) =>
|
|
63
|
+
Array.from(root.querySelectorAll(`[data-part="${part}"]`)).map((e) =>
|
|
64
|
+
(e.textContent || '').replace(/\s+/g, ' ').trim()
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
order = {
|
|
69
|
+
id: 42,
|
|
70
|
+
number: 'G-42',
|
|
71
|
+
amount: '10998.00',
|
|
72
|
+
is_cancellable: false,
|
|
73
|
+
is_refundable: true,
|
|
74
|
+
status: { value: '550', label: 'Teslim edildi' },
|
|
75
|
+
orderitem_set: [
|
|
76
|
+
line(1, [
|
|
77
|
+
{
|
|
78
|
+
pickup_date: { date: '2026-04-11' },
|
|
79
|
+
easy_return: {
|
|
80
|
+
code: 'R-1',
|
|
81
|
+
shipping_company: { label: 'Hepsijet' }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
]),
|
|
85
|
+
line(2, {
|
|
86
|
+
easy_return: {
|
|
87
|
+
code: 'R-2',
|
|
88
|
+
shipping_company: { label: 'Yurtiçi Kargo' }
|
|
89
|
+
}
|
|
90
|
+
}),
|
|
91
|
+
{ ...line(3, null), status: { value: '550', label: 'Teslim edildi' } }
|
|
92
|
+
]
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('order detail — easy returns', () => {
|
|
97
|
+
it('links a returnable order to the easy-return screen', () => {
|
|
98
|
+
const { container } = render(
|
|
99
|
+
<OrderDetailBlock
|
|
100
|
+
block={blockOf(ALL_ON) as never}
|
|
101
|
+
placeholderId="p1"
|
|
102
|
+
sectionId="s1"
|
|
103
|
+
isDesigner={false}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
const link = container.querySelector('[data-part="return-link"]');
|
|
107
|
+
|
|
108
|
+
expect(link?.textContent).toContain('Kolay iade');
|
|
109
|
+
expect(link?.getAttribute('href')).toBe('/account/orders/42/cancellation');
|
|
110
|
+
// The cancel link stays for orders that can still be cancelled.
|
|
111
|
+
expect(container.querySelector('[data-part="cancel-link"]')).toBeNull();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('says how each returned line goes back', () => {
|
|
115
|
+
const { container } = render(
|
|
116
|
+
<OrderDetailBlock
|
|
117
|
+
block={blockOf(ALL_ON) as never}
|
|
118
|
+
placeholderId="p1"
|
|
119
|
+
sectionId="s1"
|
|
120
|
+
isDesigner={false}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
expect(texts(container, 'item-return-method')).toEqual([
|
|
125
|
+
'İade yöntemi: Randevulu',
|
|
126
|
+
'İade yöntemi: Standart'
|
|
127
|
+
]);
|
|
128
|
+
expect(texts(container, 'item-return-carrier')).toEqual([
|
|
129
|
+
'Kargo: Hepsijet',
|
|
130
|
+
'Kargo: Yurtiçi Kargo'
|
|
131
|
+
]);
|
|
132
|
+
expect(texts(container, 'item-pickup-date')).toEqual([
|
|
133
|
+
'Randevu tarihi: 11.04.2026'
|
|
134
|
+
]);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('keeps every new line behind its switch', () => {
|
|
138
|
+
const { container } = render(
|
|
139
|
+
<OrderDetailBlock
|
|
140
|
+
block={blockOf({}) as never}
|
|
141
|
+
placeholderId="p1"
|
|
142
|
+
sectionId="s1"
|
|
143
|
+
isDesigner={false}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
expect(container.querySelector('[data-part="return-link"]')).toBeNull();
|
|
148
|
+
expect(texts(container, 'item-return-method')).toEqual([]);
|
|
149
|
+
expect(texts(container, 'item-return-carrier')).toEqual([]);
|
|
150
|
+
expect(texts(container, 'item-pickup-date')).toEqual([]);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('offers no return link on an order that cannot be returned', () => {
|
|
154
|
+
order = { ...order, is_refundable: false };
|
|
155
|
+
const { container } = render(
|
|
156
|
+
<OrderDetailBlock
|
|
157
|
+
block={blockOf(ALL_ON) as never}
|
|
158
|
+
placeholderId="p1"
|
|
159
|
+
sectionId="s1"
|
|
160
|
+
isDesigner={false}
|
|
161
|
+
/>
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
expect(container.querySelector('[data-part="return-link"]')).toBeNull();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('links only a delivered line that has no request yet', () => {
|
|
168
|
+
// As commerce answers after a return: the order and its lines stay
|
|
169
|
+
// refundable while the request is open.
|
|
170
|
+
const flagged: Record<string, unknown>[] = (
|
|
171
|
+
order.orderitem_set as Record<string, unknown>[]
|
|
172
|
+
).map((item) => ({ ...item, is_refundable: true }));
|
|
173
|
+
const returnLink = () =>
|
|
174
|
+
render(
|
|
175
|
+
<OrderDetailBlock
|
|
176
|
+
block={blockOf(ALL_ON) as never}
|
|
177
|
+
placeholderId="p1"
|
|
178
|
+
sectionId="s1"
|
|
179
|
+
isDesigner={false}
|
|
180
|
+
/>
|
|
181
|
+
).container.querySelector('[data-part="return-link"]');
|
|
182
|
+
|
|
183
|
+
// Line 3 has no request yet: it can still be returned.
|
|
184
|
+
order = { ...order, orderitem_set: flagged };
|
|
185
|
+
expect(returnLink()).not.toBeNull();
|
|
186
|
+
|
|
187
|
+
order = {
|
|
188
|
+
...order,
|
|
189
|
+
orderitem_set: flagged.map((item) =>
|
|
190
|
+
item.id === 3
|
|
191
|
+
? { ...item, active_cancellation_request: { id: 54766 } }
|
|
192
|
+
: item
|
|
193
|
+
)
|
|
194
|
+
};
|
|
195
|
+
expect(returnLink()).toBeNull();
|
|
196
|
+
|
|
197
|
+
// Commerce calls a shipped line refundable too; it is not returned yet.
|
|
198
|
+
order = {
|
|
199
|
+
...order,
|
|
200
|
+
orderitem_set: flagged.map((item) =>
|
|
201
|
+
item.id === 3
|
|
202
|
+
? { ...item, status: { value: '500', label: 'Gönderildi' } }
|
|
203
|
+
: item
|
|
204
|
+
)
|
|
205
|
+
};
|
|
206
|
+
expect(returnLink()).toBeNull();
|
|
207
|
+
});
|
|
208
|
+
});
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
resolveItemProduct
|
|
16
16
|
} from './item-template-utils';
|
|
17
17
|
import { ThemeItemScopeProvider } from './product-block-utils';
|
|
18
|
-
import { ThemeRowScopeProvider } from './row-scope';
|
|
19
18
|
|
|
20
19
|
export {
|
|
21
20
|
findItemTemplate,
|
|
@@ -121,15 +120,20 @@ export const ItemTemplateList = ({
|
|
|
121
120
|
const scopesProducts = publishesProductItems(block.type);
|
|
122
121
|
// The same slice the iterator applied, so clone N is handed the row it
|
|
123
122
|
// was built from rather than row N.
|
|
124
|
-
const
|
|
123
|
+
const scopedRows = scopesProducts
|
|
124
|
+
? sliceIteratorItems(block, rows).items
|
|
125
|
+
: rows;
|
|
125
126
|
|
|
126
127
|
return (
|
|
127
128
|
<>
|
|
128
129
|
{clones.map((clone, index) => {
|
|
129
130
|
const key = clone.id || `${template.id}-item-${index}`;
|
|
130
|
-
const rowData = slicedRows[index] ?? {};
|
|
131
131
|
const row = (
|
|
132
132
|
<ThemeBlock
|
|
133
|
+
// Keyed here so the non-scoped branch is the element it always
|
|
134
|
+
// was: wrapping it in anything, even a fragment, would change the
|
|
135
|
+
// element type at this position and remount every existing row.
|
|
136
|
+
key={key}
|
|
133
137
|
block={clone}
|
|
134
138
|
placeholderId={placeholderId}
|
|
135
139
|
sectionId={sectionId}
|
|
@@ -139,32 +143,22 @@ export const ItemTemplateList = ({
|
|
|
139
143
|
currentBreakpoint={currentBreakpoint}
|
|
140
144
|
/>
|
|
141
145
|
);
|
|
142
|
-
const scoped = scopesProducts
|
|
143
|
-
? resolveItemProduct(block.type, rowData)
|
|
144
|
-
: null;
|
|
145
146
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
if (!scopesProducts) return row;
|
|
148
|
+
|
|
149
|
+
const scoped = resolveItemProduct(block.type, scopedRows[index]);
|
|
150
|
+
|
|
151
|
+
// Context only — the provider renders no element, so the markup a
|
|
152
|
+
// published row produces is unchanged.
|
|
149
153
|
return (
|
|
150
|
-
<
|
|
154
|
+
<ThemeItemScopeProvider
|
|
151
155
|
key={key}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
product={
|
|
157
|
+
scoped ?? (isDesigner ? DESIGNER_SAMPLE_PRODUCT : null)
|
|
158
|
+
}
|
|
155
159
|
>
|
|
156
|
-
{
|
|
157
|
-
|
|
158
|
-
product={
|
|
159
|
-
scoped ?? (isDesigner ? DESIGNER_SAMPLE_PRODUCT : null)
|
|
160
|
-
}
|
|
161
|
-
>
|
|
162
|
-
{row}
|
|
163
|
-
</ThemeItemScopeProvider>
|
|
164
|
-
) : (
|
|
165
|
-
row
|
|
166
|
-
)}
|
|
167
|
-
</ThemeRowScopeProvider>
|
|
160
|
+
{row}
|
|
161
|
+
</ThemeItemScopeProvider>
|
|
168
162
|
);
|
|
169
163
|
})}
|
|
170
164
|
</>
|