@sensolus/create-snt-agent-app 0.3.9 → 0.3.10
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/package.json +1 -1
- package/template/CLAUDE.md +25 -4
- package/template/README.md +1 -1
- package/template/src/i18n/translations/de.js +2 -0
- package/template/src/i18n/translations/en.js +2 -0
- package/template/src/i18n/translations/es.js +2 -0
- package/template/src/i18n/translations/fr.js +2 -0
- package/template/src/i18n/translations/nl.js +2 -0
- package/template/src/pages/Home.jsx +9 -8
- package/template/src/pages/Overview.jsx +30 -1
- package/template/src/pages/WidgetShowcase.jsx +57 -24
package/package.json
CHANGED
package/template/CLAUDE.md
CHANGED
|
@@ -89,10 +89,13 @@ import { SntButton, SntInput, SntBadge, SntTable } from '@sensolus/snt-agent-kit
|
|
|
89
89
|
|
|
90
90
|
| Component | Description |
|
|
91
91
|
|-----------|-------------|
|
|
92
|
-
| `SntButton` |
|
|
92
|
+
| `SntButton` | Button. Default (white, `secondary`) is the everyday primary action; use `emphasis` (dark blue) sparingly for the single most important action. Other variants: success, danger, warning, info. (`primary` is a deprecated alias for `emphasis`.) The first letter of the label is auto-capitalised. |
|
|
93
|
+
| `SntIcon` | Named SVG icon (`export`, `download`, `edit`, `settings`, `pdf`, `report`, …). Inherits text color via `currentColor`; `size` to scale. |
|
|
94
|
+
| `SntLink` | Brand-blue text link (underline on hover). `href` → `<a>`; `onClick` only → link-styled `<button>` for tertiary actions (e.g. a dialog's "Learn more"). |
|
|
93
95
|
| `SntInput` | Text input (onChange receives value directly, not event) |
|
|
94
96
|
| `SntBadge` | Status badge with color variants |
|
|
95
97
|
| `SntCard` | Card container with optional image, title, badge |
|
|
98
|
+
| `SntSection` | Titled page section (title + optional description + body) for grouping content. Use for page regions; `SntCard` is for content tiles. |
|
|
96
99
|
| `SntTable` | Sortable, paginated data table |
|
|
97
100
|
| `SntSpinner` | Loading spinner (sizes: small, medium, large) |
|
|
98
101
|
| `SntLoadingOverlay` | Centered spinner with optional message |
|
|
@@ -119,14 +122,17 @@ import { SntButton, SntInput, SntBadge, SntTable } from '@sensolus/snt-agent-kit
|
|
|
119
122
|
--snt-green: #39CB99; /* Success */
|
|
120
123
|
--snt-yellow: #FFCC66; /* Warning */
|
|
121
124
|
--snt-red: #E00000; /* Danger */
|
|
122
|
-
--snt-
|
|
125
|
+
--snt-ui-selected: #00A6ED; /* Info */
|
|
123
126
|
```
|
|
124
127
|
|
|
125
128
|
### Widget Examples
|
|
126
129
|
|
|
127
130
|
```jsx
|
|
128
|
-
// Button
|
|
129
|
-
<SntButton
|
|
131
|
+
// Button — the white default is the everyday primary action
|
|
132
|
+
<SntButton onClick={handleClick}>Save</SntButton>
|
|
133
|
+
|
|
134
|
+
// Use emphasis (dark blue) only for the single most important action on a screen
|
|
135
|
+
<SntButton variant="emphasis" onClick={handleConfirm}>Confirm</SntButton>
|
|
130
136
|
|
|
131
137
|
// Input
|
|
132
138
|
<SntInput value={query} onChange={setQuery} placeholder="Search..." />
|
|
@@ -163,6 +169,21 @@ import { SntButton, SntInput, SntBadge, SntTable } from '@sensolus/snt-agent-kit
|
|
|
163
169
|
2. **Import widgets** from `@sensolus/snt-agent-kit` - they're modular ES modules
|
|
164
170
|
3. **Follow existing patterns** in `src/App.jsx` for examples
|
|
165
171
|
4. **Reference the baseline** at `/sensolus/work/baseline/` for additional components not yet ported
|
|
172
|
+
5. **Put the matching `SntIcon` in the primary button** whenever a mockup has an Export, Download, Edit, Settings, PDF, or Report action — e.g. `<SntButton icon={<SntIcon name="export" />}>Export</SntButton>`.
|
|
173
|
+
6. **Button order in forms:** put the blue (`variant="emphasis"`) action **first** and the white (default) action **second** (e.g. Save before Cancel). This is a deliberate exception to the white-is-primary default and applies only to forms.
|
|
174
|
+
7. **Overlay / dialog footer order (always):** blue (`variant="emphasis"`) first → white (default) second → link (`SntLink`) third, in that sequence — e.g. Delete, Cancel, Learn more. The tertiary action is always an `SntLink`, never a button.
|
|
175
|
+
|
|
176
|
+
### Page layout rules
|
|
177
|
+
|
|
178
|
+
These govern how widgets are composed on a page. Follow them when building or editing pages.
|
|
179
|
+
|
|
180
|
+
1. **Page wrapper:** render page content inside `.page-root` — it carries the standard padding (24px top, 16px sides/bottom). Don't add your own outer padding.
|
|
181
|
+
2. **Page header:** start every page with `SntPageHeader` for the title (and back button / actions). Don't hand-roll an `h1` + back chevron.
|
|
182
|
+
3. **`SntSummaryStat` is never wrapped in a panel.** Place stat tiles directly in a `.summary-stats-row` on the page background — never inside an `SntCard`/panel. The row gaps give them enough white space to live on the page on their own. Non-clickable stats are flat white tiles (no border); clickable ones carry a grey fill + border, which is distinctive enough on its own — they don't need an enclosing card to set them apart. Reserve `SntCard` for content tiles further down.
|
|
183
|
+
4. **Group sections with `SntSection`, content tiles with `SntCard`.** Use `SntSection` for titled page regions (a heading + body); use `SntCard` for individual content tiles within a region. Don't nest a section inside a card.
|
|
184
|
+
5. **Avoid pie charts — use bar charts.** For part-to-whole or category comparisons, render a bar chart, not a pie/donut. Bars are easier to read and compare than angles/slices. Reserve pies for nothing by default.
|
|
185
|
+
6. **Every chart axis has a label.** Both the x- and y-axis must carry a name (with units where relevant, e.g. "Distance (km)"). Never ship a chart with unlabelled axes.
|
|
186
|
+
7. **Cards are auto-height; siblings in a row match the tallest.** A card sizes to its own content by default — don't set fixed heights. When cards sit side by side (e.g. an `SntGrid` row), they stretch to the height of the tallest card in that row so their tops and bottoms align (use `align-items: stretch`, the default for flex/grid rows). Don't hand-tune per-card heights to fake alignment.
|
|
166
187
|
|
|
167
188
|
## Internationalization (i18n)
|
|
168
189
|
|
package/template/README.md
CHANGED
|
@@ -462,7 +462,7 @@ Use CSS custom properties for consistent styling:
|
|
|
462
462
|
--snt-green: #39CB99; /* Success */
|
|
463
463
|
--snt-yellow: #FFCC66; /* Warning */
|
|
464
464
|
--snt-red: #E00000; /* Danger */
|
|
465
|
-
--snt-
|
|
465
|
+
--snt-ui-selected: #00A6ED; /* Info */
|
|
466
466
|
|
|
467
467
|
/* Semantic Aliases (preferred) */
|
|
468
468
|
--snt-color-primary: var(--snt-blue-darkest);
|
|
@@ -11,6 +11,8 @@ export default {
|
|
|
11
11
|
'overview.series.orgs': 'Organisationen',
|
|
12
12
|
'overview.series.trackers': 'Tracker',
|
|
13
13
|
'overview.series.users': 'Benutzer',
|
|
14
|
+
'overview.table.title': 'Verlauf der täglichen Momentaufnahmen',
|
|
15
|
+
'overview.table.date': 'Datum',
|
|
14
16
|
|
|
15
17
|
// Common
|
|
16
18
|
|
|
@@ -11,6 +11,8 @@ export default {
|
|
|
11
11
|
'overview.series.orgs': 'Organizaciones',
|
|
12
12
|
'overview.series.trackers': 'Rastreadores',
|
|
13
13
|
'overview.series.users': 'Usuarios',
|
|
14
|
+
'overview.table.title': 'Historial de instantáneas diarias',
|
|
15
|
+
'overview.table.date': 'Fecha',
|
|
14
16
|
|
|
15
17
|
// Common
|
|
16
18
|
|
|
@@ -11,6 +11,8 @@ export default {
|
|
|
11
11
|
'overview.series.orgs': 'Organisations',
|
|
12
12
|
'overview.series.trackers': 'Traceurs',
|
|
13
13
|
'overview.series.users': 'Utilisateurs',
|
|
14
|
+
'overview.table.title': 'Historique des instantanés quotidiens',
|
|
15
|
+
'overview.table.date': 'Date',
|
|
14
16
|
|
|
15
17
|
// Common
|
|
16
18
|
|
|
@@ -11,6 +11,8 @@ export default {
|
|
|
11
11
|
'overview.series.orgs': 'Organisaties',
|
|
12
12
|
'overview.series.trackers': 'Trackers',
|
|
13
13
|
'overview.series.users': 'Gebruikers',
|
|
14
|
+
'overview.table.title': 'Geschiedenis dagelijkse momentopname',
|
|
15
|
+
'overview.table.date': 'Datum',
|
|
14
16
|
|
|
15
17
|
// Common
|
|
16
18
|
|
|
@@ -87,7 +87,6 @@ export function Home() {
|
|
|
87
87
|
)}
|
|
88
88
|
{activeTab === 'explore' && (
|
|
89
89
|
<SntButton
|
|
90
|
-
variant="primary"
|
|
91
90
|
onClick={() => orgListReloadRef.current?.()}
|
|
92
91
|
disabled={orgListLoading || !authReady}
|
|
93
92
|
>
|
|
@@ -147,6 +146,15 @@ export function Home() {
|
|
|
147
146
|
gap: 8,
|
|
148
147
|
}}
|
|
149
148
|
>
|
|
149
|
+
{/* In forms the blue (emphasis) action comes first, white second —
|
|
150
|
+
an intentional exception to the white-is-primary guideline. */}
|
|
151
|
+
<SntButton
|
|
152
|
+
variant="emphasis"
|
|
153
|
+
onClick={submitApiKey}
|
|
154
|
+
disabled={submitting || !apiKeyInput.trim()}
|
|
155
|
+
>
|
|
156
|
+
{submitting ? t('common.loading') : t('common.save')}
|
|
157
|
+
</SntButton>
|
|
150
158
|
{authReady && (
|
|
151
159
|
<SntButton
|
|
152
160
|
variant="secondary"
|
|
@@ -156,13 +164,6 @@ export function Home() {
|
|
|
156
164
|
{t('common.cancel')}
|
|
157
165
|
</SntButton>
|
|
158
166
|
)}
|
|
159
|
-
<SntButton
|
|
160
|
-
variant="primary"
|
|
161
|
-
onClick={submitApiKey}
|
|
162
|
-
disabled={submitting || !apiKeyInput.trim()}
|
|
163
|
-
>
|
|
164
|
-
{submitting ? t('common.loading') : t('common.save')}
|
|
165
|
-
</SntButton>
|
|
166
167
|
</div>
|
|
167
168
|
</SntDialog>
|
|
168
169
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react'
|
|
2
|
-
import { SntCard, SntLoadingOverlay, SntSummaryStat } from '@sensolus/snt-agent-kit'
|
|
2
|
+
import { SntCard, SntLoadingOverlay, SntSummaryStat, SntTable } from '@sensolus/snt-agent-kit'
|
|
3
3
|
import { useLocale, formatNumber, formatShortDate } from '../i18n'
|
|
4
4
|
|
|
5
5
|
const SERIES = [
|
|
@@ -192,6 +192,35 @@ export function Overview({ authReady }) {
|
|
|
192
192
|
</div>
|
|
193
193
|
<LineChart data={data} intlLocale={intlLocale} timezone={timezone} t={t} />
|
|
194
194
|
</SntCard>
|
|
195
|
+
|
|
196
|
+
<SntCard title={t('overview.table.title')}>
|
|
197
|
+
<SntTable
|
|
198
|
+
data={[...data].reverse()}
|
|
199
|
+
rowKey="date"
|
|
200
|
+
columns={[
|
|
201
|
+
{
|
|
202
|
+
key: 'date',
|
|
203
|
+
header: t('overview.table.date'),
|
|
204
|
+
render: (row) => formatShortDate(row.date, intlLocale, timezone),
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
key: 'orgCount',
|
|
208
|
+
header: t('overview.series.orgs'),
|
|
209
|
+
render: (row) => formatNumber(row.orgCount, intlLocale),
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
key: 'trackerTotal',
|
|
213
|
+
header: t('overview.series.trackers'),
|
|
214
|
+
render: (row) => formatNumber(row.trackerTotal, intlLocale),
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
key: 'userTotal',
|
|
218
|
+
header: t('overview.series.users'),
|
|
219
|
+
render: (row) => formatNumber(row.userTotal, intlLocale),
|
|
220
|
+
},
|
|
221
|
+
]}
|
|
222
|
+
/>
|
|
223
|
+
</SntCard>
|
|
195
224
|
</>
|
|
196
225
|
)}
|
|
197
226
|
</div>
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
SntCard,
|
|
7
7
|
SntCheckboxList,
|
|
8
8
|
SntColors,
|
|
9
|
+
SntIcon,
|
|
10
|
+
SNT_ICON_NAMES,
|
|
9
11
|
SntDateRangePicker,
|
|
10
12
|
SntDialog,
|
|
11
13
|
SntGrid,
|
|
@@ -58,20 +60,20 @@ const BADGE_VARIANTS = [
|
|
|
58
60
|
'info', 'light', 'dark', 'orange', 'salmon', 'purple', 'emerald',
|
|
59
61
|
]
|
|
60
62
|
|
|
61
|
-
const BUTTON_VARIANTS = ['
|
|
63
|
+
const BUTTON_VARIANTS = ['secondary', 'emphasis', 'success', 'danger', 'warning', 'info']
|
|
62
64
|
|
|
63
65
|
const TABLE_DATA = [
|
|
64
|
-
{ id: 1, name: 'Alpha Logistics', trackers: 142, status: '
|
|
65
|
-
{ id: 2, name: 'Beta Transport', trackers: 56, status: '
|
|
66
|
-
{ id: 3, name: 'Gamma Couriers', trackers: 8, status: '
|
|
67
|
-
{ id: 4, name: 'Delta Freight', trackers: 231, status: '
|
|
68
|
-
{ id: 5, name: 'Epsilon Shipping', trackers: 17, status: '
|
|
66
|
+
{ id: 1, name: 'Alpha Logistics', trackers: 142, status: 'Active' },
|
|
67
|
+
{ id: 2, name: 'Beta Transport', trackers: 56, status: 'Active' },
|
|
68
|
+
{ id: 3, name: 'Gamma Couriers', trackers: 8, status: 'Inactive' },
|
|
69
|
+
{ id: 4, name: 'Delta Freight', trackers: 231, status: 'Active' },
|
|
70
|
+
{ id: 5, name: 'Epsilon Shipping', trackers: 17, status: 'Pending' },
|
|
69
71
|
]
|
|
70
72
|
|
|
71
73
|
const STATUS_VARIANT = {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
Active: 'success',
|
|
75
|
+
Inactive: 'secondary',
|
|
76
|
+
Pending: 'warning',
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
const HISTOGRAM_BUCKETS = [
|
|
@@ -95,6 +97,7 @@ export function WidgetShowcase() {
|
|
|
95
97
|
const [selectValue, setSelectValue] = useState('eu')
|
|
96
98
|
const [groupValue, setGroupValue] = useState('cards')
|
|
97
99
|
const [switchOn, setSwitchOn] = useState(true)
|
|
100
|
+
const [activeOnly, setActiveOnly] = useState(true)
|
|
98
101
|
const [checkboxSelected, setCheckboxSelected] = useState(['Trackers', 'Geozones'])
|
|
99
102
|
const [dateRange, setDateRange] = useState(() => getDefaultDateRange('week'))
|
|
100
103
|
const [dialogOpen, setDialogOpen] = useState(false)
|
|
@@ -115,20 +118,50 @@ export function WidgetShowcase() {
|
|
|
115
118
|
{/* ------------------------------------------------------------------ */}
|
|
116
119
|
<Section
|
|
117
120
|
title="SntButton"
|
|
118
|
-
description="
|
|
121
|
+
description="The default (white) button is the everyday primary action — reach for it almost always. Use 'emphasis' (dark blue) sparingly for the single most important action on a screen."
|
|
119
122
|
>
|
|
120
123
|
<Example label="Variants">
|
|
121
124
|
<div className="showcase-row">
|
|
122
125
|
{BUTTON_VARIANTS.map((v) => (
|
|
123
|
-
<SntButton key={v} variant={v}>{v}</SntButton>
|
|
126
|
+
<SntButton key={v} variant={v}>{v === 'secondary' ? 'Primary' : v}</SntButton>
|
|
124
127
|
))}
|
|
125
128
|
</div>
|
|
126
129
|
</Example>
|
|
127
130
|
<Example label="Disabled">
|
|
128
|
-
<SntButton
|
|
131
|
+
<SntButton disabled>Disabled</SntButton>
|
|
129
132
|
</Example>
|
|
130
133
|
<Example label="With icon">
|
|
131
|
-
<SntButton
|
|
134
|
+
<SntButton icon={<SntIcon name="export" />}>Export</SntButton>
|
|
135
|
+
</Example>
|
|
136
|
+
</Section>
|
|
137
|
+
|
|
138
|
+
{/* ------------------------------------------------------------------ */}
|
|
139
|
+
<Section
|
|
140
|
+
title="SntIcon"
|
|
141
|
+
description="Named SVG icons from the Sensolus set. Icons inherit the surrounding text color (currentColor), so they adapt to button variants, links, etc. Set size to scale. For action buttons (export, download, settings, PDF, report) put the matching icon in the button."
|
|
142
|
+
>
|
|
143
|
+
<Example label="All icons">
|
|
144
|
+
<div className="showcase-row" style={{ alignItems: 'center', gap: 20 }}>
|
|
145
|
+
{SNT_ICON_NAMES.map((name) => (
|
|
146
|
+
<div
|
|
147
|
+
key={name}
|
|
148
|
+
style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}
|
|
149
|
+
>
|
|
150
|
+
<SntIcon name={name} size={24} title={name} />
|
|
151
|
+
<code style={{ fontSize: 12, color: 'var(--snt-grey)' }}>{name}</code>
|
|
152
|
+
</div>
|
|
153
|
+
))}
|
|
154
|
+
</div>
|
|
155
|
+
</Example>
|
|
156
|
+
<Example label="In buttons">
|
|
157
|
+
<div className="showcase-row">
|
|
158
|
+
<SntButton icon={<SntIcon name="export" />}>Export</SntButton>
|
|
159
|
+
<SntButton icon={<SntIcon name="download" />}>Download</SntButton>
|
|
160
|
+
<SntButton icon={<SntIcon name="edit" />}>Edit</SntButton>
|
|
161
|
+
<SntButton icon={<SntIcon name="report" />}>Report</SntButton>
|
|
162
|
+
<SntButton icon={<SntIcon name="pdf" />}>PDF</SntButton>
|
|
163
|
+
<SntButton icon={<SntIcon name="settings" />}>Settings</SntButton>
|
|
164
|
+
</div>
|
|
132
165
|
</Example>
|
|
133
166
|
</Section>
|
|
134
167
|
|
|
@@ -145,7 +178,7 @@ export function WidgetShowcase() {
|
|
|
145
178
|
</div>
|
|
146
179
|
</Example>
|
|
147
180
|
<Example label="Compact">
|
|
148
|
-
<SntBadge variant="success" text="
|
|
181
|
+
<SntBadge variant="success" text="Active" compact />
|
|
149
182
|
</Example>
|
|
150
183
|
</Section>
|
|
151
184
|
|
|
@@ -207,9 +240,9 @@ export function WidgetShowcase() {
|
|
|
207
240
|
value={groupValue}
|
|
208
241
|
onChange={setGroupValue}
|
|
209
242
|
options={[
|
|
210
|
-
{ value: 'cards', label: 'Cards' },
|
|
211
|
-
{ value: '
|
|
212
|
-
{ value: 'map', label: 'Map' },
|
|
243
|
+
{ value: 'cards', label: 'Cards', icon: <SntIcon name="card" /> },
|
|
244
|
+
{ value: 'list', label: 'List', icon: <SntIcon name="list" /> },
|
|
245
|
+
{ value: 'map', label: 'Map', icon: <SntIcon name="map" /> },
|
|
213
246
|
]}
|
|
214
247
|
/>
|
|
215
248
|
</Example>
|
|
@@ -278,7 +311,7 @@ export function WidgetShowcase() {
|
|
|
278
311
|
<SntCard
|
|
279
312
|
title="Clickable"
|
|
280
313
|
onClick={() => alert('Card clicked')}
|
|
281
|
-
titleButton={<SntButton
|
|
314
|
+
titleButton={<SntButton>Open</SntButton>}
|
|
282
315
|
>
|
|
283
316
|
<p>onClick makes the whole card interactive.</p>
|
|
284
317
|
</SntCard>
|
|
@@ -306,13 +339,13 @@ export function WidgetShowcase() {
|
|
|
306
339
|
description="Horizontal row for grouping actions, with optional spacer."
|
|
307
340
|
>
|
|
308
341
|
<SntToolbar>
|
|
309
|
-
<SntButton variant="
|
|
342
|
+
<SntButton variant="emphasis">Save</SntButton>
|
|
310
343
|
<SntButton>Cancel</SntButton>
|
|
311
344
|
<SntToolbarSpacer />
|
|
312
345
|
<div style={{ width: 220 }}>
|
|
313
346
|
<SntInput value="" onChange={() => {}} placeholder="Search..." />
|
|
314
347
|
</div>
|
|
315
|
-
<SntButton
|
|
348
|
+
<SntButton icon={<SntIcon name="filter" />}>Filter</SntButton>
|
|
316
349
|
</SntToolbar>
|
|
317
350
|
</Section>
|
|
318
351
|
|
|
@@ -412,7 +445,7 @@ export function WidgetShowcase() {
|
|
|
412
445
|
</div>
|
|
413
446
|
</Example>
|
|
414
447
|
<Example label="Loading overlay (toggle)">
|
|
415
|
-
<SntButton
|
|
448
|
+
<SntButton onClick={() => {
|
|
416
449
|
setShowOverlay(true)
|
|
417
450
|
setTimeout(() => setShowOverlay(false), 1500)
|
|
418
451
|
}}>
|
|
@@ -431,7 +464,7 @@ export function WidgetShowcase() {
|
|
|
431
464
|
title="SntDialog"
|
|
432
465
|
description="Modal dialog. open + onClose are controlled by the caller."
|
|
433
466
|
>
|
|
434
|
-
<SntButton
|
|
467
|
+
<SntButton onClick={() => setDialogOpen(true)}>
|
|
435
468
|
Open dialog
|
|
436
469
|
</SntButton>
|
|
437
470
|
<SntDialog
|
|
@@ -442,8 +475,8 @@ export function WidgetShowcase() {
|
|
|
442
475
|
>
|
|
443
476
|
<p>This is a small modal dialog. Click the backdrop or × to close.</p>
|
|
444
477
|
<div style={{ marginTop: 16, display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
|
|
478
|
+
<SntButton variant="emphasis" onClick={() => setDialogOpen(false)}>OK</SntButton>
|
|
445
479
|
<SntButton onClick={() => setDialogOpen(false)}>Cancel</SntButton>
|
|
446
|
-
<SntButton variant="primary" onClick={() => setDialogOpen(false)}>OK</SntButton>
|
|
447
480
|
</div>
|
|
448
481
|
</SntDialog>
|
|
449
482
|
</Section>
|
|
@@ -461,7 +494,7 @@ export function WidgetShowcase() {
|
|
|
461
494
|
width={240}
|
|
462
495
|
>
|
|
463
496
|
<SntFilterSection label="Status">
|
|
464
|
-
<SntSwitch checked onChange={
|
|
497
|
+
<SntSwitch checked={activeOnly} onChange={setActiveOnly} label="Active only" />
|
|
465
498
|
</SntFilterSection>
|
|
466
499
|
<SntFilterSection label="Region">
|
|
467
500
|
<SntSelect
|