@nocobase/app-template-default 1.0.0-beta.57 → 1.0.0-beta.59
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/AGENTS.md +26 -21
- package/README.MD +7 -53
- package/cli/plugins.ts +1 -7
- package/client/agent-annotations-host.ts +8 -2
- package/client/app.ts +0 -2
- package/client/components/brand-loading-mark.tsx +46 -0
- package/client/components/brand-mark-geometry.ts +7 -0
- package/client/components/brand-spinner.tsx +22 -0
- package/client/components/brand-watermark.tsx +32 -0
- package/client/components/loading.tsx +4 -3
- package/client/components/route-overlay.tsx +15 -4
- package/client/components/status-badge.tsx +29 -0
- package/client/components/ui/alert-dialog.tsx +186 -0
- package/client/components/ui/card.tsx +102 -0
- package/client/components/ui/dialog.tsx +2 -2
- package/client/components/ui/radio-group.tsx +35 -0
- package/client/components/ui/spinner.tsx +2 -20
- package/client/components/ui/toast.tsx +3 -2
- package/client/extensions/nocobase-file-component-ui/components/file-upload-field.tsx +3 -3
- package/client/extensions/nocobase-inbox/inbox-item.tsx +4 -3
- package/client/layouts/app-layout.tsx +8 -28
- package/client/layouts/components/app-sidebar.tsx +4 -4
- package/client/layouts/components/header-actions.tsx +3 -36
- package/client/layouts/index.ts +0 -1
- package/client/lib/toaster.ts +1 -1
- package/client/locales/en-US.ts +31 -17
- package/client/locales/zh-CN.ts +24 -14
- package/client/pages/auth/login.tsx +1 -0
- package/client/pages/auth/shared.tsx +9 -9
- package/client/pages/home.tsx +80 -7
- package/client/plugins.ts +2 -6
- package/client/routes.ts +4 -10
- package/client/routing/app-router.tsx +5 -55
- package/client/routing/route-navigation.ts +1 -1
- package/client/styles.css +244 -0
- package/client/theme/theme-settings.tsx +22 -20
- package/client/theme/themes/compact.css +34 -16
- package/client/theme/themes/default.css +34 -16
- package/config.example.yml +0 -16
- package/eslint.config.js +0 -13
- package/index.html +48 -16
- package/package.json +24 -30
- package/server/config/index.ts +0 -6
- package/server/plugins.ts +0 -4
- package/tests/components/app-layout-routes.test.tsx +1 -1
- package/tests/components/inbox.test.tsx +0 -19
- package/tests/components/layout-i18n.test.tsx +5 -92
- package/tests/components/primitive-labels.test.tsx +61 -1
- package/tests/fixtures/theme-tokens.html +1 -1
- package/tests/fixtures/theme-tokens.tsx +7 -0
- package/tests/logic/app-server.test.ts +0 -15
- package/tests/logic/client-plugin-registry.test.ts +0 -21
- package/tests/logic/client-routes.test.ts +2 -6
- package/tests/logic/client-shell.test.tsx +11 -107
- package/tests/logic/client-theme.test.tsx +17 -1
- package/tests/logic/config.test.ts +0 -1
- package/tests/logic/plugin-commands.test.ts +1 -1
- package/tsconfig.json +1 -4
- package/tsconfig.server.json +1 -6
- package/client/components/inbox-badge.ts +0 -49
- package/client/components/inbox-button.tsx +0 -132
- package/client/components/inbox-header-button.tsx +0 -25
- package/client/layouts/components/surface-empty.tsx +0 -35
- package/client/layouts/settings-layout.tsx +0 -172
- package/server/config/ai.ts +0 -27
- package/server/config/workflow.ts +0 -24
- package/tests/logic/client-settings.test.tsx +0 -841
- package/tests/logic/dev-routes-production-build.test.ts +0 -168
- package/tests/logic/plugin-page-authz.test.ts +0 -76
package/client/styles.css
CHANGED
|
@@ -8,6 +8,21 @@
|
|
|
8
8
|
|
|
9
9
|
@custom-variant dark (&:is(.dark *));
|
|
10
10
|
|
|
11
|
+
/* The stationary brand and a constant orbit read as loading at every size. */
|
|
12
|
+
@keyframes nocobase-loading-orbit {
|
|
13
|
+
to {
|
|
14
|
+
transform: rotate(360deg);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
.nocobase-loading-orbit {
|
|
18
|
+
transform-origin: 32px 32px;
|
|
19
|
+
}
|
|
20
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
21
|
+
.nocobase-loading-orbit {
|
|
22
|
+
animation: nocobase-loading-orbit 1.1s linear infinite;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
11
26
|
@theme {
|
|
12
27
|
--font-heading: var(--font-sans);
|
|
13
28
|
/* These names are implemented below as runtime-variable utilities. */
|
|
@@ -120,3 +135,232 @@
|
|
|
120
135
|
[data-slot='toast-viewport'] {
|
|
121
136
|
z-index: 100;
|
|
122
137
|
}
|
|
138
|
+
|
|
139
|
+
/* Application-wide interaction and badge treatment, outside generated primitives. */
|
|
140
|
+
@layer base {
|
|
141
|
+
:is(
|
|
142
|
+
button,
|
|
143
|
+
[role='button'],
|
|
144
|
+
[role='menuitem'],
|
|
145
|
+
[role='option'],
|
|
146
|
+
[role='tab'],
|
|
147
|
+
[role='checkbox'],
|
|
148
|
+
[role='radio'],
|
|
149
|
+
[role='switch'],
|
|
150
|
+
[role='combobox'],
|
|
151
|
+
a[href]
|
|
152
|
+
):not(:disabled):not([aria-disabled='true']):not([data-disabled]) {
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
[data-slot='badge'] {
|
|
158
|
+
border-radius: var(--radius-md);
|
|
159
|
+
min-height: calc(var(--spacing) * 7);
|
|
160
|
+
height: auto;
|
|
161
|
+
padding-inline: calc(var(--spacing) * 2.5);
|
|
162
|
+
line-height: 1.4;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* Shared overlay treatment lives outside generated shadcn primitives. */
|
|
166
|
+
:is(
|
|
167
|
+
[data-slot='dialog-overlay'],
|
|
168
|
+
[data-slot='alert-dialog-overlay'],
|
|
169
|
+
[data-slot='sheet-overlay']
|
|
170
|
+
) {
|
|
171
|
+
background: var(--overlay-backdrop);
|
|
172
|
+
}
|
|
173
|
+
:is(
|
|
174
|
+
[data-slot='dialog-content'],
|
|
175
|
+
[data-slot='alert-dialog-content'],
|
|
176
|
+
[data-slot='route-overlay-content']
|
|
177
|
+
) {
|
|
178
|
+
border: 1px solid var(--border);
|
|
179
|
+
box-shadow: var(--overlay-shadow);
|
|
180
|
+
}
|
|
181
|
+
[data-slot='route-overlay-content'][data-presentation='dialog'] {
|
|
182
|
+
border-radius: var(--radius-xl);
|
|
183
|
+
}
|
|
184
|
+
:is([data-slot='dialog-title'], [data-slot='alert-dialog-title']) {
|
|
185
|
+
font-size: var(--text-lg);
|
|
186
|
+
font-weight: 600;
|
|
187
|
+
line-height: 1.4;
|
|
188
|
+
}
|
|
189
|
+
:is([data-slot='dialog-description'], [data-slot='alert-dialog-description']) {
|
|
190
|
+
line-height: 1.65;
|
|
191
|
+
}
|
|
192
|
+
:is(
|
|
193
|
+
[data-slot='dialog-footer'],
|
|
194
|
+
[data-slot='alert-dialog-footer'],
|
|
195
|
+
[data-slot='route-overlay-footer']
|
|
196
|
+
)
|
|
197
|
+
> button {
|
|
198
|
+
min-height: calc(var(--spacing) * 10);
|
|
199
|
+
padding-inline: calc(var(--spacing) * 4);
|
|
200
|
+
}
|
|
201
|
+
[data-slot='dialog-content'] > [data-slot='dialog-close'] {
|
|
202
|
+
top: calc(var(--spacing) * 4);
|
|
203
|
+
right: calc(var(--spacing) * 4);
|
|
204
|
+
}
|
|
205
|
+
[data-slot='dialog-header'] {
|
|
206
|
+
padding-right: calc(var(--spacing) * 8);
|
|
207
|
+
}
|
|
208
|
+
[data-slot='alert-dialog-media'] {
|
|
209
|
+
border-radius: var(--radius-lg);
|
|
210
|
+
width: calc(var(--spacing) * 12);
|
|
211
|
+
height: calc(var(--spacing) * 12);
|
|
212
|
+
}
|
|
213
|
+
[data-slot='alert'] {
|
|
214
|
+
padding: calc(var(--spacing) * 4);
|
|
215
|
+
row-gap: calc(var(--spacing) * 1.5);
|
|
216
|
+
column-gap: calc(var(--spacing) * 3);
|
|
217
|
+
border-radius: var(--radius-lg);
|
|
218
|
+
}
|
|
219
|
+
[data-slot='alert'][data-tone='info'] {
|
|
220
|
+
background: color-mix(in srgb, var(--primary) 5%, var(--card));
|
|
221
|
+
border-color: color-mix(in srgb, var(--primary) 18%, var(--border));
|
|
222
|
+
}
|
|
223
|
+
[data-slot='alert'][data-tone='info'] > svg {
|
|
224
|
+
color: var(--primary);
|
|
225
|
+
}
|
|
226
|
+
[data-slot='alert-action'] {
|
|
227
|
+
top: calc(var(--spacing) * 4);
|
|
228
|
+
right: calc(var(--spacing) * 4);
|
|
229
|
+
}
|
|
230
|
+
[data-slot='toast'] {
|
|
231
|
+
border-radius: var(--radius-xl);
|
|
232
|
+
box-shadow: var(--shadow-lg);
|
|
233
|
+
}
|
|
234
|
+
[data-slot='toast-content'] {
|
|
235
|
+
padding: calc(var(--spacing) * 4);
|
|
236
|
+
align-items: center;
|
|
237
|
+
gap: calc(var(--spacing) * 3);
|
|
238
|
+
}
|
|
239
|
+
[data-slot='toast-viewport'] {
|
|
240
|
+
width: 22rem;
|
|
241
|
+
max-width: calc(100vw - 2rem);
|
|
242
|
+
}
|
|
243
|
+
[data-slot='toast-content']:has([data-slot='toast-description']:not(:empty)) {
|
|
244
|
+
align-items: flex-start;
|
|
245
|
+
}
|
|
246
|
+
:is([data-slot='toast-title'], [data-slot='toast-description']) {
|
|
247
|
+
line-height: 1.5;
|
|
248
|
+
overflow-wrap: anywhere;
|
|
249
|
+
}
|
|
250
|
+
[data-slot='toast-close'] {
|
|
251
|
+
width: calc(var(--spacing) * 6);
|
|
252
|
+
height: calc(var(--spacing) * 6);
|
|
253
|
+
opacity: 0.55;
|
|
254
|
+
transition:
|
|
255
|
+
opacity 150ms ease,
|
|
256
|
+
background-color 150ms ease;
|
|
257
|
+
}
|
|
258
|
+
[data-slot='toast-close']:is(:hover, :focus-visible) {
|
|
259
|
+
opacity: 1;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
[data-slot='toast-icon'] {
|
|
263
|
+
display: inline-flex;
|
|
264
|
+
align-items: center;
|
|
265
|
+
justify-content: center;
|
|
266
|
+
width: calc(var(--spacing) * 7);
|
|
267
|
+
height: calc(var(--spacing) * 7);
|
|
268
|
+
border-radius: var(--radius-lg);
|
|
269
|
+
background: var(--accent);
|
|
270
|
+
color: var(--primary);
|
|
271
|
+
}
|
|
272
|
+
[data-slot='toast-icon']:has(.lucide-circle-check) {
|
|
273
|
+
background: var(--status-success-background);
|
|
274
|
+
color: var(--status-success);
|
|
275
|
+
}
|
|
276
|
+
[data-slot='toast-icon']:has(.lucide-octagon-x) {
|
|
277
|
+
background: color-mix(in srgb, var(--destructive) 10%, var(--popover));
|
|
278
|
+
color: var(--destructive);
|
|
279
|
+
}
|
|
280
|
+
[data-slot='toast-icon']:has(.lucide-triangle-alert) {
|
|
281
|
+
background: var(--status-warning-background);
|
|
282
|
+
color: var(--status-warning);
|
|
283
|
+
}
|
|
284
|
+
[data-slot='alert'].text-destructive {
|
|
285
|
+
background: color-mix(in srgb, var(--destructive) 5%, var(--card));
|
|
286
|
+
border-color: color-mix(in srgb, var(--destructive) 20%, var(--border));
|
|
287
|
+
}
|
|
288
|
+
[data-slot='alert-dialog-header']:has([data-slot='alert-dialog-media']) {
|
|
289
|
+
grid-template-columns: max-content minmax(0, 1fr);
|
|
290
|
+
column-gap: calc(var(--spacing) * 4);
|
|
291
|
+
align-items: start;
|
|
292
|
+
justify-items: start;
|
|
293
|
+
text-align: left;
|
|
294
|
+
}
|
|
295
|
+
[data-slot='alert-dialog-header'] > [data-slot='alert-dialog-media'] {
|
|
296
|
+
grid-column: 1;
|
|
297
|
+
grid-row: 1 / span 2;
|
|
298
|
+
margin-bottom: 0;
|
|
299
|
+
}
|
|
300
|
+
[data-slot='alert-dialog-header']:has([data-slot='alert-dialog-media'])
|
|
301
|
+
> :is(
|
|
302
|
+
[data-slot='alert-dialog-title'],
|
|
303
|
+
[data-slot='alert-dialog-description']
|
|
304
|
+
) {
|
|
305
|
+
grid-column: 2;
|
|
306
|
+
}
|
|
307
|
+
[data-slot='alert']:has([data-slot='alert-action']) {
|
|
308
|
+
padding-right: calc(var(--spacing) * 24);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* Compact content can stay dense while the primary navigation remains comfortable.
|
|
312
|
+
The primitive's important icon-mode sizes still control the collapsed rail. */
|
|
313
|
+
:root[data-theme='compact'] .app-navigation [data-slot='sidebar-menu-button'] {
|
|
314
|
+
height: calc(var(--spacing) * 12);
|
|
315
|
+
padding-inline: calc(var(--spacing) * 4);
|
|
316
|
+
}
|
|
317
|
+
:root[data-theme='compact'] .app-navigation [data-slot='sidebar-menu'] {
|
|
318
|
+
gap: calc(var(--spacing) * 1.5);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/* Brand tint belongs to the application shell, independent of each page's content. */
|
|
322
|
+
.app-brand-surface {
|
|
323
|
+
background-image: radial-gradient(
|
|
324
|
+
ellipse at 100% 0%,
|
|
325
|
+
color-mix(in srgb, var(--primary) 6%, transparent),
|
|
326
|
+
transparent 70%
|
|
327
|
+
);
|
|
328
|
+
background-size: 100% 18rem;
|
|
329
|
+
background-repeat: no-repeat;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/* Shared table hierarchy stays neutral so semantic status colors remain distinct. */
|
|
333
|
+
[data-slot='table-header'] {
|
|
334
|
+
background: color-mix(in srgb, var(--muted) 70%, var(--card));
|
|
335
|
+
}
|
|
336
|
+
[data-slot='table-header'] [data-slot='table-row']:hover {
|
|
337
|
+
background: transparent;
|
|
338
|
+
}
|
|
339
|
+
[data-slot='table-head'] {
|
|
340
|
+
height: calc(var(--spacing) * 12);
|
|
341
|
+
padding-inline: calc(var(--spacing) * 3);
|
|
342
|
+
color: color-mix(in srgb, var(--foreground) 80%, var(--muted-foreground));
|
|
343
|
+
font-weight: 600;
|
|
344
|
+
}
|
|
345
|
+
[data-slot='table-cell'] {
|
|
346
|
+
padding-inline: calc(var(--spacing) * 3);
|
|
347
|
+
}
|
|
348
|
+
[data-slot='table-head'][aria-sort]:not([aria-sort='none']) {
|
|
349
|
+
color: var(--primary);
|
|
350
|
+
}
|
|
351
|
+
[data-slot='table-head'] button {
|
|
352
|
+
font-weight: inherit;
|
|
353
|
+
}
|
|
354
|
+
[data-slot='table-head'] button:hover {
|
|
355
|
+
color: var(--primary);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/* Nested items keep a comfortable rhythm independently of compact content. */
|
|
359
|
+
.app-navigation [data-slot='sidebar-menu-sub-button'] {
|
|
360
|
+
height: calc(var(--spacing) * 10);
|
|
361
|
+
padding-inline: calc(var(--spacing) * 3);
|
|
362
|
+
}
|
|
363
|
+
.app-navigation [data-slot='sidebar-menu-sub'] {
|
|
364
|
+
gap: calc(var(--spacing) * 1.5);
|
|
365
|
+
padding-block: calc(var(--spacing) * 1.5);
|
|
366
|
+
}
|
|
@@ -3,6 +3,7 @@ import { useTheme } from 'next-themes';
|
|
|
3
3
|
import { useTranslation } from '@nocobase/i18n/client';
|
|
4
4
|
import { useId, type ReactElement } from 'react';
|
|
5
5
|
import { Button } from '#components/ui/button';
|
|
6
|
+
import { RadioGroup, RadioGroupItem } from '#components/ui/radio-group';
|
|
6
7
|
import {
|
|
7
8
|
Popover,
|
|
8
9
|
PopoverTrigger,
|
|
@@ -56,7 +57,13 @@ export function ThemeSettings(): ReactElement {
|
|
|
56
57
|
<legend className='text-xs font-medium text-muted-foreground'>
|
|
57
58
|
{t('appearance.mode', { defaultValue: 'Color mode' })}
|
|
58
59
|
</legend>
|
|
59
|
-
<
|
|
60
|
+
<RadioGroup
|
|
61
|
+
name={id + '-mode'}
|
|
62
|
+
value={theme}
|
|
63
|
+
onValueChange={(value) => setTheme(String(value))}
|
|
64
|
+
aria-label={t('appearance.mode', { defaultValue: 'Color mode' })}
|
|
65
|
+
className='grid-cols-3 gap-1 rounded-lg bg-muted/70 p-1'
|
|
66
|
+
>
|
|
60
67
|
{COLOR_MODES.map(({ id: mode, icon: ModeIcon }) => {
|
|
61
68
|
const isSelected = theme === mode;
|
|
62
69
|
return (
|
|
@@ -69,14 +76,7 @@ export function ThemeSettings(): ReactElement {
|
|
|
69
76
|
: 'text-muted-foreground hover:bg-background/40 hover:text-foreground',
|
|
70
77
|
)}
|
|
71
78
|
>
|
|
72
|
-
<
|
|
73
|
-
type='radio'
|
|
74
|
-
name={id + '-mode'}
|
|
75
|
-
value={mode}
|
|
76
|
-
checked={isSelected}
|
|
77
|
-
onChange={() => setTheme(mode)}
|
|
78
|
-
className='sr-only'
|
|
79
|
-
/>
|
|
79
|
+
<RadioGroupItem value={mode} className='sr-only' />
|
|
80
80
|
<ModeIcon aria-hidden='true' className='size-3.5 shrink-0' />
|
|
81
81
|
<span className='whitespace-nowrap'>
|
|
82
82
|
{t('appearance.' + mode, {
|
|
@@ -86,14 +86,23 @@ export function ThemeSettings(): ReactElement {
|
|
|
86
86
|
</label>
|
|
87
87
|
);
|
|
88
88
|
})}
|
|
89
|
-
</
|
|
89
|
+
</RadioGroup>
|
|
90
90
|
</fieldset>
|
|
91
91
|
|
|
92
92
|
<fieldset className='space-y-2'>
|
|
93
93
|
<legend className='text-xs font-medium text-muted-foreground'>
|
|
94
94
|
{t('appearance.preset', { defaultValue: 'Theme' })}
|
|
95
95
|
</legend>
|
|
96
|
-
<
|
|
96
|
+
<RadioGroup
|
|
97
|
+
name={id + '-preset'}
|
|
98
|
+
value={preset}
|
|
99
|
+
onValueChange={(value) => {
|
|
100
|
+
const selected = themePresets.find((item) => item.id === value);
|
|
101
|
+
if (selected) setPreset(selected.id);
|
|
102
|
+
}}
|
|
103
|
+
aria-label={t('appearance.preset', { defaultValue: 'Theme' })}
|
|
104
|
+
className='grid-cols-2 gap-2.5'
|
|
105
|
+
>
|
|
97
106
|
{themePresets.map((item) => {
|
|
98
107
|
const isSelected = preset === item.id;
|
|
99
108
|
return (
|
|
@@ -106,14 +115,7 @@ export function ThemeSettings(): ReactElement {
|
|
|
106
115
|
: 'border-border/70 hover:border-border hover:bg-muted/30',
|
|
107
116
|
)}
|
|
108
117
|
>
|
|
109
|
-
<
|
|
110
|
-
type='radio'
|
|
111
|
-
name={id + '-preset'}
|
|
112
|
-
value={item.id}
|
|
113
|
-
checked={isSelected}
|
|
114
|
-
onChange={() => setPreset(item.id)}
|
|
115
|
-
className='sr-only'
|
|
116
|
-
/>
|
|
118
|
+
<RadioGroupItem value={item.id} className='sr-only' />
|
|
117
119
|
<div className='mb-2 h-16 w-full'>
|
|
118
120
|
<div
|
|
119
121
|
aria-hidden='true'
|
|
@@ -168,7 +170,7 @@ export function ThemeSettings(): ReactElement {
|
|
|
168
170
|
</label>
|
|
169
171
|
);
|
|
170
172
|
})}
|
|
171
|
-
</
|
|
173
|
+
</RadioGroup>
|
|
172
174
|
</fieldset>
|
|
173
175
|
</PopoverContent>
|
|
174
176
|
</Popover>
|
|
@@ -50,20 +50,31 @@
|
|
|
50
50
|
--foreground: oklch(0.16 0 0);
|
|
51
51
|
--card: oklch(1 0 0);
|
|
52
52
|
--card-foreground: oklch(0.16 0 0);
|
|
53
|
+
--overlay-backdrop: rgb(15 23 42 / 0.28);
|
|
54
|
+
--overlay-shadow:
|
|
55
|
+
0 24px 64px -16px rgb(15 23 42 / 0.22),
|
|
56
|
+
0 8px 24px -12px rgb(15 23 42 / 0.16);
|
|
53
57
|
--popover: oklch(1 0 0);
|
|
54
58
|
--popover-foreground: oklch(0.16 0 0);
|
|
55
|
-
--primary:
|
|
56
|
-
--
|
|
59
|
+
--primary: #002ad1;
|
|
60
|
+
--auth-brand-background: #101c3b;
|
|
61
|
+
--auth-brand-highlight: #8ca9ff;
|
|
62
|
+
--auth-brand-muted: #b8c4df;
|
|
63
|
+
--status-success: rgb(21 112 70);
|
|
64
|
+
--status-success-background: rgb(236 249 241);
|
|
65
|
+
--status-warning: rgb(150 79 10);
|
|
66
|
+
--status-warning-background: rgb(255 246 229);
|
|
67
|
+
--primary-foreground: rgb(255 255 255);
|
|
57
68
|
--secondary: oklch(0.96 0 0);
|
|
58
69
|
--secondary-foreground: oklch(0.22 0 0);
|
|
59
70
|
--muted: oklch(0.96 0 0);
|
|
60
71
|
--muted-foreground: oklch(0.52 0 0);
|
|
61
|
-
--accent:
|
|
62
|
-
--accent-foreground:
|
|
72
|
+
--accent: rgb(237 242 255);
|
|
73
|
+
--accent-foreground: rgb(0 42 209);
|
|
63
74
|
--destructive: oklch(0.577 0.245 27.325);
|
|
64
75
|
--border: oklch(0.9 0 0);
|
|
65
76
|
--input: oklch(0.9 0 0);
|
|
66
|
-
--ring:
|
|
77
|
+
--ring: var(--primary);
|
|
67
78
|
--chart-1: oklch(0.646 0.222 41.116);
|
|
68
79
|
--chart-2: oklch(0.6 0.118 184.704);
|
|
69
80
|
--chart-3: oklch(0.398 0.07 227.392);
|
|
@@ -71,10 +82,10 @@
|
|
|
71
82
|
--chart-5: oklch(0.769 0.188 70.08);
|
|
72
83
|
--sidebar: var(--card);
|
|
73
84
|
--sidebar-foreground: var(--card-foreground);
|
|
74
|
-
--sidebar-primary: color-mix(in
|
|
85
|
+
--sidebar-primary: color-mix(in srgb, var(--primary) 8%, var(--sidebar));
|
|
75
86
|
--sidebar-primary-foreground: var(--primary);
|
|
76
|
-
--sidebar-accent: var(--
|
|
77
|
-
--sidebar-accent-foreground: var(--foreground);
|
|
87
|
+
--sidebar-accent: var(--accent);
|
|
88
|
+
--sidebar-accent-foreground: var(--accent-foreground);
|
|
78
89
|
--sidebar-border: var(--border);
|
|
79
90
|
--sidebar-ring: var(--ring);
|
|
80
91
|
}
|
|
@@ -85,20 +96,27 @@
|
|
|
85
96
|
--foreground: oklch(0.96 0 0);
|
|
86
97
|
--card: oklch(0.18 0 0);
|
|
87
98
|
--card-foreground: oklch(0.985 0 0);
|
|
99
|
+
--overlay-backdrop: rgb(0 0 0 / 0.58);
|
|
100
|
+
--overlay-shadow:
|
|
101
|
+
0 24px 64px -16px rgb(0 0 0 / 0.6), 0 8px 24px -12px rgb(0 0 0 / 0.4);
|
|
88
102
|
--popover: oklch(0.18 0 0);
|
|
89
103
|
--popover-foreground: oklch(0.985 0 0);
|
|
90
|
-
--primary:
|
|
91
|
-
--
|
|
104
|
+
--primary: #8ca9ff;
|
|
105
|
+
--status-success: rgb(119 216 160);
|
|
106
|
+
--status-success-background: rgb(23 49 37);
|
|
107
|
+
--status-warning: rgb(242 190 103);
|
|
108
|
+
--status-warning-background: rgb(57 43 24);
|
|
109
|
+
--primary-foreground: rgb(10 24 64);
|
|
92
110
|
--secondary: oklch(0.24 0 0);
|
|
93
111
|
--secondary-foreground: oklch(0.985 0 0);
|
|
94
112
|
--muted: oklch(0.23 0 0);
|
|
95
113
|
--muted-foreground: oklch(0.7 0 0);
|
|
96
|
-
--accent:
|
|
97
|
-
--accent-foreground:
|
|
114
|
+
--accent: rgb(30 42 72);
|
|
115
|
+
--accent-foreground: rgb(174 194 255);
|
|
98
116
|
--destructive: oklch(0.704 0.191 22.216);
|
|
99
117
|
--border: oklch(1 0 0 / 10%);
|
|
100
118
|
--input: oklch(1 0 0 / 15%);
|
|
101
|
-
--ring:
|
|
119
|
+
--ring: var(--primary);
|
|
102
120
|
--chart-1: oklch(0.488 0.243 264.376);
|
|
103
121
|
--chart-2: oklch(0.696 0.17 162.48);
|
|
104
122
|
--chart-3: oklch(0.769 0.188 70.08);
|
|
@@ -106,10 +124,10 @@
|
|
|
106
124
|
--chart-5: oklch(0.645 0.246 16.439);
|
|
107
125
|
--sidebar: var(--card);
|
|
108
126
|
--sidebar-foreground: var(--card-foreground);
|
|
109
|
-
--sidebar-primary: color-mix(in
|
|
127
|
+
--sidebar-primary: color-mix(in srgb, var(--primary) 8%, var(--sidebar));
|
|
110
128
|
--sidebar-primary-foreground: var(--primary);
|
|
111
|
-
--sidebar-accent: var(--
|
|
112
|
-
--sidebar-accent-foreground: var(--foreground);
|
|
129
|
+
--sidebar-accent: var(--accent);
|
|
130
|
+
--sidebar-accent-foreground: var(--accent-foreground);
|
|
113
131
|
--sidebar-border: var(--border);
|
|
114
132
|
--sidebar-ring: var(--ring);
|
|
115
133
|
}
|
|
@@ -51,20 +51,31 @@
|
|
|
51
51
|
--foreground: oklch(0.16 0 0);
|
|
52
52
|
--card: oklch(1 0 0);
|
|
53
53
|
--card-foreground: oklch(0.16 0 0);
|
|
54
|
+
--overlay-backdrop: rgb(15 23 42 / 0.28);
|
|
55
|
+
--overlay-shadow:
|
|
56
|
+
0 24px 64px -16px rgb(15 23 42 / 0.22),
|
|
57
|
+
0 8px 24px -12px rgb(15 23 42 / 0.16);
|
|
54
58
|
--popover: oklch(1 0 0);
|
|
55
59
|
--popover-foreground: oklch(0.16 0 0);
|
|
56
|
-
--primary:
|
|
57
|
-
--
|
|
60
|
+
--primary: #002ad1;
|
|
61
|
+
--auth-brand-background: #101c3b;
|
|
62
|
+
--auth-brand-highlight: #8ca9ff;
|
|
63
|
+
--auth-brand-muted: #b8c4df;
|
|
64
|
+
--status-success: rgb(21 112 70);
|
|
65
|
+
--status-success-background: rgb(236 249 241);
|
|
66
|
+
--status-warning: rgb(150 79 10);
|
|
67
|
+
--status-warning-background: rgb(255 246 229);
|
|
68
|
+
--primary-foreground: rgb(255 255 255);
|
|
58
69
|
--secondary: oklch(0.96 0 0);
|
|
59
70
|
--secondary-foreground: oklch(0.22 0 0);
|
|
60
71
|
--muted: oklch(0.96 0 0);
|
|
61
72
|
--muted-foreground: oklch(0.52 0 0);
|
|
62
|
-
--accent:
|
|
63
|
-
--accent-foreground:
|
|
73
|
+
--accent: rgb(237 242 255);
|
|
74
|
+
--accent-foreground: rgb(0 42 209);
|
|
64
75
|
--destructive: oklch(0.577 0.245 27.325);
|
|
65
76
|
--border: oklch(0.9 0 0);
|
|
66
77
|
--input: oklch(0.9 0 0);
|
|
67
|
-
--ring:
|
|
78
|
+
--ring: var(--primary);
|
|
68
79
|
--chart-1: oklch(0.646 0.222 41.116);
|
|
69
80
|
--chart-2: oklch(0.6 0.118 184.704);
|
|
70
81
|
--chart-3: oklch(0.398 0.07 227.392);
|
|
@@ -72,10 +83,10 @@
|
|
|
72
83
|
--chart-5: oklch(0.769 0.188 70.08);
|
|
73
84
|
--sidebar: var(--card);
|
|
74
85
|
--sidebar-foreground: var(--card-foreground);
|
|
75
|
-
--sidebar-primary: color-mix(in
|
|
86
|
+
--sidebar-primary: color-mix(in srgb, var(--primary) 8%, var(--sidebar));
|
|
76
87
|
--sidebar-primary-foreground: var(--primary);
|
|
77
|
-
--sidebar-accent: var(--
|
|
78
|
-
--sidebar-accent-foreground: var(--foreground);
|
|
88
|
+
--sidebar-accent: var(--accent);
|
|
89
|
+
--sidebar-accent-foreground: var(--accent-foreground);
|
|
79
90
|
--sidebar-border: var(--border);
|
|
80
91
|
--sidebar-ring: var(--ring);
|
|
81
92
|
}
|
|
@@ -87,20 +98,27 @@
|
|
|
87
98
|
--foreground: oklch(0.96 0 0);
|
|
88
99
|
--card: oklch(0.18 0 0);
|
|
89
100
|
--card-foreground: oklch(0.985 0 0);
|
|
101
|
+
--overlay-backdrop: rgb(0 0 0 / 0.58);
|
|
102
|
+
--overlay-shadow:
|
|
103
|
+
0 24px 64px -16px rgb(0 0 0 / 0.6), 0 8px 24px -12px rgb(0 0 0 / 0.4);
|
|
90
104
|
--popover: oklch(0.18 0 0);
|
|
91
105
|
--popover-foreground: oklch(0.985 0 0);
|
|
92
|
-
--primary:
|
|
93
|
-
--
|
|
106
|
+
--primary: #8ca9ff;
|
|
107
|
+
--status-success: rgb(119 216 160);
|
|
108
|
+
--status-success-background: rgb(23 49 37);
|
|
109
|
+
--status-warning: rgb(242 190 103);
|
|
110
|
+
--status-warning-background: rgb(57 43 24);
|
|
111
|
+
--primary-foreground: rgb(10 24 64);
|
|
94
112
|
--secondary: oklch(0.24 0 0);
|
|
95
113
|
--secondary-foreground: oklch(0.985 0 0);
|
|
96
114
|
--muted: oklch(0.23 0 0);
|
|
97
115
|
--muted-foreground: oklch(0.7 0 0);
|
|
98
|
-
--accent:
|
|
99
|
-
--accent-foreground:
|
|
116
|
+
--accent: rgb(30 42 72);
|
|
117
|
+
--accent-foreground: rgb(174 194 255);
|
|
100
118
|
--destructive: oklch(0.704 0.191 22.216);
|
|
101
119
|
--border: oklch(1 0 0 / 10%);
|
|
102
120
|
--input: oklch(1 0 0 / 15%);
|
|
103
|
-
--ring:
|
|
121
|
+
--ring: var(--primary);
|
|
104
122
|
--chart-1: oklch(0.488 0.243 264.376);
|
|
105
123
|
--chart-2: oklch(0.696 0.17 162.48);
|
|
106
124
|
--chart-3: oklch(0.769 0.188 70.08);
|
|
@@ -108,10 +126,10 @@
|
|
|
108
126
|
--chart-5: oklch(0.645 0.246 16.439);
|
|
109
127
|
--sidebar: var(--card);
|
|
110
128
|
--sidebar-foreground: var(--card-foreground);
|
|
111
|
-
--sidebar-primary: color-mix(in
|
|
129
|
+
--sidebar-primary: color-mix(in srgb, var(--primary) 8%, var(--sidebar));
|
|
112
130
|
--sidebar-primary-foreground: var(--primary);
|
|
113
|
-
--sidebar-accent: var(--
|
|
114
|
-
--sidebar-accent-foreground: var(--foreground);
|
|
131
|
+
--sidebar-accent: var(--accent);
|
|
132
|
+
--sidebar-accent-foreground: var(--accent-foreground);
|
|
115
133
|
--sidebar-border: var(--border);
|
|
116
134
|
--sidebar-ring: var(--ring);
|
|
117
135
|
}
|
package/config.example.yml
CHANGED
|
@@ -84,22 +84,6 @@ notification:
|
|
|
84
84
|
# provider: dingtalk-webhook
|
|
85
85
|
# webhookUrl: https://oapi.dingtalk.com/robot/send?access_token=replace-with-the-token
|
|
86
86
|
|
|
87
|
-
# Declarative LLM services are loaded from application config, keyed by service name.
|
|
88
|
-
# The server reads this when it starts: restart it after editing, which `pnpm dev` does on its own.
|
|
89
|
-
# Keep the key out of this file. Write it into config.yml with
|
|
90
|
-
# `pnpm nocobase config set --from-env ai.llmServices.openai.options.apiKey=OPENAI_API_KEY`,
|
|
91
|
-
# or map an injected environment variable onto that path in server/config/ai.ts.
|
|
92
|
-
# ai:
|
|
93
|
-
# llmServices:
|
|
94
|
-
# openai:
|
|
95
|
-
# title: OpenAI
|
|
96
|
-
# provider: openai
|
|
97
|
-
# enabledModels:
|
|
98
|
-
# - label: GPT-4.1
|
|
99
|
-
# value: gpt-4.1
|
|
100
|
-
# enabled: true
|
|
101
|
-
# sort: 10
|
|
102
|
-
|
|
103
87
|
# DB_DIALECT, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_SSL and DB_FILENAME override the main
|
|
104
88
|
# connection's fields from the environment.
|
|
105
89
|
database:
|
package/eslint.config.js
CHANGED
|
@@ -8,17 +8,4 @@ export default createApplicationConfig({
|
|
|
8
8
|
'public/r/**',
|
|
9
9
|
'storage/**',
|
|
10
10
|
],
|
|
11
|
-
overrides: [
|
|
12
|
-
{
|
|
13
|
-
// Top-level workflow definitions and handlers use the server project.
|
|
14
|
-
files: ['workflows/**/*.ts'],
|
|
15
|
-
ignores: ['workflows/*/client/**'],
|
|
16
|
-
languageOptions: {
|
|
17
|
-
parserOptions: {
|
|
18
|
-
projectService: false,
|
|
19
|
-
project: './tsconfig.server.json',
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
11
|
});
|
package/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<link rel="icon" type="image/x-icon" href="/assets/favicon.ico" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
-
<meta name="theme-color" content="#
|
|
7
|
+
<meta name="theme-color" content="#002ad1" />
|
|
8
8
|
<meta name="description" content="NocoBase administration console" />
|
|
9
9
|
<meta data-rh="true" property="og:image" content="/assets/logo-mark.png" />
|
|
10
10
|
<meta data-rh="true" name="twitter:image" content="/assets/logo-mark.png" />
|
|
@@ -16,16 +16,24 @@
|
|
|
16
16
|
align-items: center;
|
|
17
17
|
justify-content: center;
|
|
18
18
|
background: oklch(0.985 0 0);
|
|
19
|
-
color:
|
|
19
|
+
color: #002ad1;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
gap: 0.75rem;
|
|
22
|
+
font:
|
|
23
|
+
14px system-ui,
|
|
24
|
+
sans-serif;
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
.app-bootstrap-loading [data-slot='loading-indicator'] {
|
|
23
|
-
width:
|
|
24
|
-
height:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
width: 3rem;
|
|
29
|
+
height: 3rem;
|
|
30
|
+
}
|
|
31
|
+
.app-bootstrap-loading .nocobase-loading-orbit {
|
|
32
|
+
transform-origin: 32px 32px;
|
|
33
|
+
animation: app-bootstrap-spin 1.1s linear infinite;
|
|
34
|
+
}
|
|
35
|
+
.app-bootstrap-loading span {
|
|
36
|
+
color: oklch(0.556 0 0);
|
|
29
37
|
}
|
|
30
38
|
|
|
31
39
|
html,
|
|
@@ -48,14 +56,18 @@
|
|
|
48
56
|
@media (prefers-color-scheme: dark) {
|
|
49
57
|
.app-bootstrap-loading {
|
|
50
58
|
background: oklch(0.145 0 0);
|
|
51
|
-
color:
|
|
59
|
+
color: #8ca9ff;
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
|
|
63
|
+
@media (prefers-color-scheme: dark) {
|
|
64
|
+
.app-bootstrap-loading span {
|
|
65
|
+
color: oklch(0.708 0 0);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
55
68
|
@media (prefers-reduced-motion: reduce) {
|
|
56
|
-
.app-bootstrap-loading
|
|
69
|
+
.app-bootstrap-loading .nocobase-loading-orbit {
|
|
57
70
|
animation: none;
|
|
58
|
-
opacity: 0.65;
|
|
59
71
|
}
|
|
60
72
|
}
|
|
61
73
|
</style>
|
|
@@ -71,18 +83,38 @@
|
|
|
71
83
|
>
|
|
72
84
|
<svg
|
|
73
85
|
data-slot="loading-indicator"
|
|
74
|
-
viewBox="0 0
|
|
86
|
+
viewBox="0 0 64 64"
|
|
75
87
|
fill="none"
|
|
76
88
|
aria-hidden="true"
|
|
77
89
|
>
|
|
78
|
-
<
|
|
79
|
-
|
|
90
|
+
<circle
|
|
91
|
+
cx="32"
|
|
92
|
+
cy="32"
|
|
93
|
+
r="28"
|
|
80
94
|
stroke="currentColor"
|
|
81
95
|
stroke-width="2"
|
|
82
|
-
|
|
83
|
-
stroke-linejoin="round"
|
|
96
|
+
opacity=".12"
|
|
84
97
|
/>
|
|
98
|
+
<g class="nocobase-loading-orbit">
|
|
99
|
+
<path
|
|
100
|
+
d="M32 4a28 28 0 0 1 28 28"
|
|
101
|
+
stroke="currentColor"
|
|
102
|
+
stroke-width="3"
|
|
103
|
+
stroke-linecap="round"
|
|
104
|
+
/>
|
|
105
|
+
</g>
|
|
106
|
+
<g
|
|
107
|
+
transform="translate(15 17.176475219726562) scale(.34)"
|
|
108
|
+
fill="currentColor"
|
|
109
|
+
>
|
|
110
|
+
<g transform="translate(0 -6.401886463165283)">
|
|
111
|
+
<path
|
|
112
|
+
d="M99.876 55.369c-.025-.045-.076-.072-.109-.111-.066-.078-.125-.168-.217-.221l-.014-.008-.001-.002h-.001L80.368 43.648v-24.67a.92.92 0 0 0-.124-.459c-.026-.045-.075-.072-.108-.111-.066-.08-.126-.168-.218-.221l-.014-.008-.001-.002h-.002L60.286 6.531a.92.92 0 0 0-.94 0L20.099 29.834h-.002l-.001.002-.014.006c-.092.055-.151.143-.218.221-.033.041-.082.068-.108.113a.907.907 0 0 0-.124.457v1.361L.466 43.373H.465l-.001.002c-.098.055-.162.143-.23.227-.034.041-.084.068-.109.113a.898.898 0 0 0-.125.457v25.195c0 .324.171.625.45.791l39.264 23.311c.002.002.006 0 .008.002l.007.008a.924.924 0 0 0 .911 0c.003-.002.004-.006.008-.008.001-.002.005 0 .007-.002l19.161-11.377 19.162 11.377c.002.002.006 0 .008.002.004.002.004.006.007.008a.924.924 0 0 0 .911 0c.003-.002.004-.006.008-.008.002-.002.005 0 .007-.002L99.55 81.812a.916.916 0 0 0 .45-.791V55.828a.92.92 0 0 0-.124-.459zM41.104 65.867V42.812l37.424-22.219v23.055L41.104 65.867zM59.815 8.391l17.83 10.588L59.82 29.561 40.185 41.219l-17.83-10.586 37.46-22.242zM39.264 42.812V65.866L21.472 55.305V32.248l17.792 10.564z"
|
|
113
|
+
/>
|
|
114
|
+
</g>
|
|
115
|
+
</g>
|
|
85
116
|
</svg>
|
|
117
|
+
<span>Loading application…</span>
|
|
86
118
|
</div>
|
|
87
119
|
</div>
|
|
88
120
|
<script type="module" src="/client/index.tsx"></script>
|