@spree/docs 0.1.299 → 0.1.300
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/api-reference/store.yaml +1 -1
- package/dist/developer/dashboard/customization/navigation.md +3 -3
- package/dist/developer/dashboard/customization/permissions.md +8 -8
- package/dist/developer/dashboard/customization/routes.md +1 -1
- package/dist/developer/dashboard/customization/slots.md +1 -1
- package/dist/developer/dashboard/recipes/page-action-button.md +2 -2
- package/dist/developer/dashboard/recipes/sidebar-widget.md +1 -1
- package/dist/developer/dashboard/slots-catalog.md +1 -1
- package/dist/developer/upgrades/5.6-to-6.0.md +1 -1
- package/package.json +1 -1
|
@@ -11738,7 +11738,7 @@ components:
|
|
|
11738
11738
|
type: array
|
|
11739
11739
|
items:
|
|
11740
11740
|
type: string
|
|
11741
|
-
description: Subject
|
|
11741
|
+
description: Subject short names, e.g. ["product"] or ["all"]
|
|
11742
11742
|
has_conditions:
|
|
11743
11743
|
type: boolean
|
|
11744
11744
|
description: True if the server-side rule has per-record conditions. The
|
|
@@ -22,7 +22,7 @@ nav.add({
|
|
|
22
22
|
path: '/analytics', // prefixed with /$storeId at render time
|
|
23
23
|
icon: BarChartIcon,
|
|
24
24
|
position: 650,
|
|
25
|
-
subject: '
|
|
25
|
+
subject: 'order', // optional permission subject — hides item without read permission
|
|
26
26
|
})
|
|
27
27
|
```
|
|
28
28
|
|
|
@@ -70,7 +70,7 @@ nav.addChild('products', {
|
|
|
70
70
|
key: 'products.brands',
|
|
71
71
|
label: 'Brands',
|
|
72
72
|
path: '/products/brands',
|
|
73
|
-
subject: '
|
|
73
|
+
subject: 'brand',
|
|
74
74
|
})
|
|
75
75
|
```
|
|
76
76
|
|
|
@@ -177,7 +177,7 @@ settingsNav.add({
|
|
|
177
177
|
path: '/integrations/stripe-tax', // prefixed with /$storeId/settings
|
|
178
178
|
group: 'integrations',
|
|
179
179
|
position: 100,
|
|
180
|
-
subject: '
|
|
180
|
+
subject: 'tax_rate',
|
|
181
181
|
})
|
|
182
182
|
```
|
|
183
183
|
|
|
@@ -33,10 +33,10 @@ interface Permissions {
|
|
|
33
33
|
It mirrors the backend ability at the **class level**:
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
|
-
permissions.can('read', '
|
|
36
|
+
permissions.can('read', 'order')
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Subjects are
|
|
39
|
+
Subjects are short names: the model's class name without its namespace, underscored (`'order'`, `'product'`, or `'report'` for your own `MyApp::Report`). Use the `Subject` constants from `@spree/dashboard-core` for Spree's own models. There is no client-side record-level check — when a rule is conditional on record attributes, `isConditional` returns `true` and the API is the arbiter: render the control and handle a possible 403.
|
|
40
40
|
|
|
41
41
|
## `subject` shortcut
|
|
42
42
|
|
|
@@ -47,7 +47,7 @@ nav.add({
|
|
|
47
47
|
key: 'reports',
|
|
48
48
|
label: 'Reports',
|
|
49
49
|
path: '/reports',
|
|
50
|
-
subject: '
|
|
50
|
+
subject: 'order', // hides nav item without read:order
|
|
51
51
|
})
|
|
52
52
|
```
|
|
53
53
|
|
|
@@ -58,7 +58,7 @@ routes: [{
|
|
|
58
58
|
key: 'reports',
|
|
59
59
|
path: '/reports',
|
|
60
60
|
component: ReportsPage,
|
|
61
|
-
subject: '
|
|
61
|
+
subject: 'order',
|
|
62
62
|
}],
|
|
63
63
|
```
|
|
64
64
|
|
|
@@ -76,7 +76,7 @@ nav.add({
|
|
|
76
76
|
label: 'Reports',
|
|
77
77
|
path: '/reports',
|
|
78
78
|
if: ({ permissions, store }) =>
|
|
79
|
-
permissions.can('read', '
|
|
79
|
+
permissions.can('read', 'order') &&
|
|
80
80
|
!!(store as Store | null)?.setup_tasks?.every((task) => task.done),
|
|
81
81
|
})
|
|
82
82
|
```
|
|
@@ -94,18 +94,18 @@ import { usePermissions } from '@spree/dashboard'
|
|
|
94
94
|
|
|
95
95
|
function ReportsPage() {
|
|
96
96
|
const { permissions } = usePermissions()
|
|
97
|
-
if (!permissions.can('read', '
|
|
97
|
+
if (!permissions.can('read', 'order')) {
|
|
98
98
|
return <Forbidden />
|
|
99
99
|
}
|
|
100
100
|
return <ReportsList />
|
|
101
101
|
}
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
The same `permissions` object backs the nav registry's `if` predicate, so you can move logic between the two without changing behaviour. For declarative gating, `<Can I="update" a="
|
|
104
|
+
The same `permissions` object backs the nav registry's `if` predicate, so you can move logic between the two without changing behaviour. For declarative gating, `<Can I="update" a="order">…</Can>` (also from `@spree/dashboard-core`) renders children only when the check passes.
|
|
105
105
|
|
|
106
106
|
## Custom permissions
|
|
107
107
|
|
|
108
|
-
If your customization introduces a new model on the backend, register it as a permission catalog scope there (`Spree.permissions.register_scope` in your engine's initializer). Its keys then appear in the role editor and the API-key scope picker, and any role granted them makes `permissions.can('read', '
|
|
108
|
+
If your customization introduces a new model on the backend, register it as a permission catalog scope there (`Spree.permissions.register_scope` in your engine's initializer). Its keys then appear in the role editor and the API-key scope picker, and any role granted them makes `permissions.can('read', 'report')` resolve in the dashboard exactly like a first-party check — the abilities ship with the current-user response (`GET /api/v3/admin/me`) at sign-in, alongside `permission_keys`, the flat key list the role editor grants from.
|
|
109
109
|
|
|
110
110
|
## Reference
|
|
111
111
|
|
|
@@ -68,7 +68,7 @@ import { usePermissions } from '@spree/dashboard'
|
|
|
68
68
|
|
|
69
69
|
function AdminOnlyMenuItem() {
|
|
70
70
|
const { permissions } = usePermissions()
|
|
71
|
-
if (!permissions.can('manage', '
|
|
71
|
+
if (!permissions.can('manage', 'customer')) return null
|
|
72
72
|
return <DropdownMenuItem>…</DropdownMenuItem>
|
|
73
73
|
}
|
|
74
74
|
```
|
|
@@ -33,7 +33,7 @@ export function SendInvoiceButton({ resource }: Props) {
|
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
// Only show to users who can act, and only on completed orders.
|
|
36
|
-
if (!permissions.can('update', '
|
|
36
|
+
if (!permissions.can('update', 'order')) return null
|
|
37
37
|
if (resource.status !== 'placed') return null
|
|
38
38
|
|
|
39
39
|
return (
|
|
@@ -95,7 +95,7 @@ export function SyncToErpItem({ resource }: Props) {
|
|
|
95
95
|
successMessage: 'Synced',
|
|
96
96
|
})
|
|
97
97
|
|
|
98
|
-
if (!permissions.can('manage', '
|
|
98
|
+
if (!permissions.can('manage', 'order')) return null
|
|
99
99
|
|
|
100
100
|
return (
|
|
101
101
|
<DropdownMenuItem
|
|
@@ -42,7 +42,7 @@ interface Props {
|
|
|
42
42
|
export function LoyaltyStatusCard({ customer }: Props) {
|
|
43
43
|
const { storeId } = useStore()
|
|
44
44
|
const { permissions } = usePermissions()
|
|
45
|
-
const canRead = permissions.can('read', '
|
|
45
|
+
const canRead = permissions.can('read', 'loyalty_record')
|
|
46
46
|
const { data, isLoading } = useQuery({
|
|
47
47
|
queryKey: ['loyalty', storeId, customer.id],
|
|
48
48
|
queryFn: () =>
|
|
@@ -44,7 +44,7 @@ import { usePermissions, useStore } from '@spree/dashboard'
|
|
|
44
44
|
function MyWidget({ product }: { product: Product }) {
|
|
45
45
|
const { permissions } = usePermissions()
|
|
46
46
|
const { store } = useStore()
|
|
47
|
-
if (!permissions.can('read', '
|
|
47
|
+
if (!permissions.can('read', 'loyalty_record')) return null
|
|
48
48
|
// ...
|
|
49
49
|
}
|
|
50
50
|
```
|
|
@@ -506,7 +506,7 @@ If your storefront or webhook receiver reads any of these fields, compare agains
|
|
|
506
506
|
| `payment_source_type` | Store API payment setup sessions, `payment_setup_session.*` webhooks | `Spree::CreditCard` | `credit_card` |
|
|
507
507
|
| `type` | Custom fields on products, variants, categories and collections | `Spree::CustomFields::ShortText` | removed — read `field_type` (`short_text`) |
|
|
508
508
|
|
|
509
|
-
The Admin API follows the same rule everywhere: providers and strategies (`fulfillment_provider: 'manual'`, `preferred_order_routing_strategy: 'rules'`), custom field definition `resource_type` (`product`, `category`), tag `taggable_type`, the owner and originator types on records, and filters such as `q[type_eq]=orders`. An integration written against the Admin API preview sends and expects these short names; the [Admin SDK](../sdk/admin/resources.md) types list them.
|
|
509
|
+
The Admin API follows the same rule everywhere: providers and strategies (`fulfillment_provider: 'manual'`, `preferred_order_routing_strategy: 'rules'`), custom field definition `resource_type` (`product`, `category`), tag `taggable_type`, the owner and originator types on records, the permission subjects `/me` returns (`product`, `category`), and filters such as `q[type_eq]=orders`. An integration written against the Admin API preview sends and expects these short names; the [Admin SDK](../sdk/admin/resources.md) types list them.
|
|
510
510
|
|
|
511
511
|
## Every event is declared
|
|
512
512
|
|