@owlmeans/web-panel 0.1.18-rc.30 → 0.1.18-rc.32
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/README.md +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/web-panel/SKILL.md +118 -19
- package/build/@/components/ui/button.d.ts +2 -2
- package/build/auth/context.d.ts.map +1 -1
- package/build/auth/entrypoints.d.ts +1 -1
- package/build/auth/entrypoints.d.ts.map +1 -1
- package/build/components/form/button/component.js.map +1 -1
- package/build/components/form/component.js.map +1 -1
- package/build/components/helper.d.ts.map +1 -1
- package/build/components/login/append.d.ts.map +1 -1
- package/build/context.d.ts.map +1 -1
- package/build/entrypoints.d.ts +1 -1
- package/build/entrypoints.d.ts.map +1 -1
- package/build/hooks/index.d.ts +2 -0
- package/build/hooks/index.d.ts.map +1 -0
- package/build/hooks/index.js +2 -0
- package/build/hooks/index.js.map +1 -0
- package/build/hooks/use-mobile.d.ts +16 -0
- package/build/hooks/use-mobile.d.ts.map +1 -0
- package/build/hooks/use-mobile.js +30 -0
- package/build/hooks/use-mobile.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/jobs/component.d.ts +19 -0
- package/build/jobs/component.d.ts.map +1 -0
- package/build/jobs/component.js +55 -0
- package/build/jobs/component.js.map +1 -0
- package/build/jobs/index.d.ts +4 -0
- package/build/jobs/index.d.ts.map +1 -0
- package/build/jobs/index.js +3 -0
- package/build/jobs/index.js.map +1 -0
- package/build/jobs/toasts.d.ts +14 -0
- package/build/jobs/toasts.d.ts.map +1 -0
- package/build/jobs/toasts.js +39 -0
- package/build/jobs/toasts.js.map +1 -0
- package/build/jobs/types.d.ts +21 -0
- package/build/jobs/types.d.ts.map +1 -0
- package/build/jobs/types.js +2 -0
- package/build/jobs/types.js.map +1 -0
- package/build/main.d.ts.map +1 -1
- package/build/utils.d.ts +13 -0
- package/build/utils.d.ts.map +1 -0
- package/build/utils.js +14 -0
- package/build/utils.js.map +1 -0
- package/package.json +35 -27
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-mobile.ts +35 -0
- package/src/index.ts +2 -0
- package/src/jobs/component.tsx +78 -0
- package/src/jobs/index.ts +4 -0
- package/src/jobs/toasts.ts +41 -0
- package/src/jobs/types.ts +23 -0
- package/src/utils.ts +14 -0
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ instead of Material UI.
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
|
-
bun add @owlmeans/web-panel
|
|
18
|
+
bun add @owlmeans/web-panel@^0.1.18-rc.31
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Peer requirements (the consuming app provides these): `react`, `react-dom`,
|
|
@@ -213,7 +213,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
213
213
|
your project's skill store (`.agents/skills/`):
|
|
214
214
|
|
|
215
215
|
```sh
|
|
216
|
-
npx @owlmeans/agent-skills
|
|
216
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.12
|
|
217
217
|
```
|
|
218
218
|
|
|
219
219
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/web-panel",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.32",
|
|
5
|
+
"generatedAt": "2026-09-04T22:43:25.453Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/web-panel
|
|
9
9
|
|
|
10
10
|
**Layer:** Web (React)
|
|
11
|
-
**Install:** `"@owlmeans/web-panel": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/web-panel": "^0.1.18-rc.32"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
## Key Exports
|
|
14
14
|
|
|
@@ -20,15 +20,28 @@ user-invocable: false
|
|
|
20
20
|
| `Toaster` | The application's toast surface — mounted once, in the layout |
|
|
21
21
|
| `Link` | An `<a>` addressing an entrypoint alias (or a literal `src`), with the label taken from i18n |
|
|
22
22
|
| `LoginScreen` / `LocalizedLoginScreen` / `appendLoginScreen` | The identity-provider choice screen — see `login-methods` |
|
|
23
|
-
| `
|
|
23
|
+
| `render(context, opts?)` | Mounts the tree inside `PanelApp`, with the browser language detector installed on the i18n instance. `opts` is `RenderOptions` plus `rootClassName` |
|
|
24
|
+
| `PanelApp` | That wrapper on its own — the themed root `div` plus the i18n provider — for a host that mounts the tree itself |
|
|
25
|
+
| `useContext<C, T>()` | The current context, from React. `AppContext` adds `context.flow()` over `@owlmeans/web-client`'s |
|
|
26
|
+
| `entrypoints` | The base declaration list — `@owlmeans/web-client`'s plus `@owlmeans/api-config-client`'s. Compose the app's own over it |
|
|
27
|
+
| `Block` / `Text` / `Status` | The shadcn `Card` panel with an optional `Actions` footer, a heading/paragraph whose copy comes from the panel namespace, and the shadcn `Alert` resolving a `ResilientError` to a translated message |
|
|
28
|
+
| `Form` / `TextInput` / `Button` / `SubmitButton` / `ButtonSelector` | The web form family. `Form` builds its own `useForm` + `ajvResolver` and borrows only `FormContext` and `schemaToFormDefault` from `@owlmeans/client-panel`; `TextInput` drives `react-hook-form`'s `Controller` directly, and the buttons call `handleSubmit` directly — none of them wraps `ClientForm`, `InputCtrl` or `ActionCtrl` |
|
|
29
|
+
| `ImageUploader` / `Layout` | The uploader in a drop target with a preview, and a plain content wrapper (the shell is `NavLayout`) |
|
|
30
|
+
| `scalingToStyles(h, v)` | `BlockScaling` → the width/height utility classes the panels share |
|
|
31
|
+
| `cn(...inputs)` | The class-name merger the components are written against — an app never re-declares it |
|
|
32
|
+
| `useIsMobile()` / `MOBILE_BREAKPOINT` | Viewport narrower than Tailwind's `md` (768), matched with `matchMedia` |
|
|
33
|
+
| `useBreakPoint()` | The current Tailwind breakpoint name, tracked on `resize` (`lg` when there is no `window`) |
|
|
34
|
+
| `useMapBreakpoint(map, def?, breakpoint?)` | The `map` entry for the current breakpoint (or for the `breakpoint` passed), falling back to `def`. It **throws a `SyntaxError`** when neither yields a value, so give it a `def` or cover every breakpoint |
|
|
24
35
|
| Re-exports from `@owlmeans/client-panel` | Cross-platform panel primitives, incl. `usePanelNav` and the `PanelNav*` types |
|
|
25
|
-
| Re-exports from `@owlmeans/client` / `@owlmeans/client-entrypoint` | `entrypoint`, `elevate`, `handler`, `route`, `frontend`, `guard`, `useNavigate`, `useEntrypoint`, `useValue` |
|
|
26
|
-
| `
|
|
36
|
+
| Re-exports from `@owlmeans/client` / `@owlmeans/client-entrypoint` / `@owlmeans/route` | `entrypoint`, `elevate`, `handler`, `provideRequest`, `stab`, `route`, `croute`, `frontend`, `guard`, `useNavigate`, `useEntrypoint`, `useValue` |
|
|
37
|
+
| Re-exports from the surrounding layers | `config`, `service`, `addWebService`, `AppType` / `HOME` / `ROOT` / `BASE` / `GUEST`, `DISPATCHER`, `CAUTHEN_FLOW_ENTER`, `DAUTH_GUARD`, `setupExternalAuthentication`, `Dispatcher`, `appendWebAuthService`, `flow` / `configureFlows` / `useFlow` / `FLOW_PARAM` / `SERVICE_PARAM`, `useI18n*` / `useLanguage` / `composePrefix`, `addI18nApp` / `addI18nLib` / `SUPPORTED_LNGS` |
|
|
27
38
|
|
|
28
39
|
## Subpath Exports
|
|
29
40
|
|
|
30
41
|
- `./auth` — auth panel components for web
|
|
31
42
|
- `./auth/entrypoints` — auth panel entrypoint declarations
|
|
43
|
+
- `./consent` — the cookie consent dialog and policy, bound to this app's i18n
|
|
44
|
+
- `./jobs` — `JobProgress`, `JobStatus`, `useJobToasts` over `@owlmeans/queue` records
|
|
32
45
|
|
|
33
46
|
## Usage
|
|
34
47
|
|
|
@@ -94,7 +107,7 @@ header. Both render the same items; only one is visible at a time.
|
|
|
94
107
|
| `NavLayout` | `nav: PanelNavConfig`, `translate?`, `title?: ReactNode`, `home?: string` (brand target — defaults to the first section's first item), `actions?: ReactNode`, `footer?: PanelNavLink[] \| ReactNode`, `headerClassName?`, `contentClassName?`, `containerClassName?`, `className?`, `style?` |
|
|
95
108
|
| `TopNav` | `config: PanelNavConfig`, `translate?`, `ariaLabel?`, `className?`, `style?` |
|
|
96
109
|
| `SideNav` | the same, plus `variant?: 'side' \| 'bar'` |
|
|
97
|
-
| `Footer` | `links?: PanelNavLink[]`, `translate?`, `children?`, `className?`, `style?` |
|
|
110
|
+
| `Footer` | `links?: PanelNavLink[]`, `translate?`, `containerClassName?` (the shell's rhythm, so the footer row lines up with the header and content), `children?`, `className?`, `style?` |
|
|
98
111
|
|
|
99
112
|
**The style slots are REGIONS, and each region is its own SURFACE.** `className` is the root —
|
|
100
113
|
the full-height page *behind* the header, side menu and footer. `headerClassName` is the sticky
|
|
@@ -126,12 +139,13 @@ width-only override permanently.
|
|
|
126
139
|
(`bg-secondary text-secondary-foreground`) — never by colouring the root and expecting the bar
|
|
127
140
|
to follow.
|
|
128
141
|
|
|
129
|
-
**The shell reads exactly
|
|
130
|
-
`--foreground` (active section link), `--muted-foreground` (resting section links)
|
|
131
|
-
`--accent`/`--accent-foreground` (active side-menu item)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
muted
|
|
142
|
+
**The shell reads exactly these colour variables**: `--background` (page and top bar),
|
|
143
|
+
`--foreground` (active section link), `--muted-foreground` (resting section links),
|
|
144
|
+
`--accent`/`--accent-foreground` (active side-menu item), `--border` (the header, side-menu and
|
|
145
|
+
footer rules) and `--primary` — the footer renders its entries through `Link`, which paints
|
|
146
|
+
`text-primary`. It reads **no `--sidebar*` variable at all**. So `--muted-foreground` is not merely
|
|
147
|
+
the text colour of the `--muted` surface — it is secondary text sitting directly on `--background`,
|
|
148
|
+
and a theme that lightens it to suit a dark muted panel loses its top menu.
|
|
135
149
|
|
|
136
150
|
Rules that make the shell behave:
|
|
137
151
|
|
|
@@ -201,14 +215,85 @@ known — so never key a test or a layout on the anchor having an `href` synchro
|
|
|
201
215
|
falls back to `modules.<alias>` when neither `name` nor `children` is given, `open` adds
|
|
202
216
|
`target="_blank"` with `rel="noopener noreferrer"`, and `center` centres the text.
|
|
203
217
|
|
|
218
|
+
### Forms — `Form`, `TextInput`, the buttons
|
|
219
|
+
|
|
220
|
+
`WebFormProps` is `@owlmeans/client-panel`'s `FormProps` plus `className` and `style`. `Form` holds
|
|
221
|
+
the whole model itself — `useForm` with `mode: 'all'`, `delayError: 300`, an `ajvResolver` over
|
|
222
|
+
`validation` with `coerceTypes` and the `ajv-formats` formats — and publishes it through
|
|
223
|
+
`FormProvider` plus `FormContext`, so every control below reads one form.
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
import { Form, TextInput, SubmitButton, Button } from '@owlmeans/web-panel'
|
|
227
|
+
|
|
228
|
+
<Form decorate validation={schema} onSubmit={async (data, update) => { await save(data); update(data) }}>
|
|
229
|
+
<TextInput name="email" label placeholder hint />
|
|
230
|
+
<TextInput name="password" type="password" label="Password" />
|
|
231
|
+
</Form>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
- **`decorate` switches the whole rendering.** With `decorate={true}` the fields go inside a shadcn
|
|
235
|
+
`Card`, the root error surfaces through `Status`, and a `SubmitButton` is rendered in the
|
|
236
|
+
`CardFooter` **whenever `onSubmit` is given** — the caller writes no action. Without it (the
|
|
237
|
+
default) `Form` is a bare flex column: no card, no root-error surface, no submit button, so the
|
|
238
|
+
caller renders its own action. `horizontal`/`vertical` scaling, `className` and `style` land on
|
|
239
|
+
the `Card` when decorated and on that column otherwise.
|
|
240
|
+
- **`formRef`** — a `useFormRef()` ref filled with `{ form, update, loader, error }`, which is how a
|
|
241
|
+
caller drives the form, flips the loader, or plants a field/root error from outside.
|
|
242
|
+
- **`TextInput` takes `label`, `placeholder` and `hint` as `string | boolean`.** `true` resolves
|
|
243
|
+
`<name>.label` / `<name>.placeholder` / `<name>.hint` from the form namespace; a string is used
|
|
244
|
+
verbatim; anything else renders nothing. It also takes `name`, `def`, `type` (any HTML input type,
|
|
245
|
+
default `text`) and `disableAutocomplete`. A field error replaces the hint line.
|
|
246
|
+
- **`Button`** takes a required `label`, `onClick`, `loader` (a `Toggleable` — open disables the
|
|
247
|
+
button and shows the spinner), `size` (`small`/`medium`/`large`), `fullWidth`, and `variant`,
|
|
248
|
+
which maps the MUI vocabulary onto shadcn (`contained` → `default`, `outlined` → `outline`,
|
|
249
|
+
`text` → `ghost`) and forwards a shadcn variant name unchanged.
|
|
250
|
+
- **`SubmitButton`** is that button bound to `handleSubmit`, taking `onSubmit` (or `onClick`) and a
|
|
251
|
+
`label` defaulting to `submit`. It resolves the label with the form `t` itself and passes it down
|
|
252
|
+
with `i18n.suppress` set, so the label is translated once.
|
|
253
|
+
- **`ButtonSelector`** renders one `Button` per entry of `options`, the one equal to `current`
|
|
254
|
+
`contained` and the rest `outlined`, calling `onSelect(option)`. `name` prefixes each option's
|
|
255
|
+
label key as `<name>.<option>`.
|
|
256
|
+
|
|
257
|
+
## Subpath: `./jobs`
|
|
258
|
+
|
|
259
|
+
Three presentational pieces for a queue job, over `JobRecord` from `@owlmeans/queue`. They take
|
|
260
|
+
records — `@owlmeans/client-job`'s `useJobs()` maps straight onto them — and hold no store, no
|
|
261
|
+
socket and no strings of their own.
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
import { JobProgress, JobStatus, useJobToasts } from '@owlmeans/web-panel/jobs'
|
|
265
|
+
|
|
266
|
+
const jobs = useJobs().map(model => model.record)
|
|
267
|
+
useJobToasts(jobs)
|
|
268
|
+
|
|
269
|
+
<JobStatus job={job} labels={{ [JobState.Active]: t('jobs.running') }} />
|
|
270
|
+
<JobProgress job={job} />
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
| Export | Description |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `JobProgress` | The shadcn `Progress` bar. `job.progress` is read as a number, `{ percent }` or `{ done, total }`; anything else animates INDETERMINATE, because zero and "the processor never called `progress()`" look identical otherwise |
|
|
276
|
+
| `JobStatus` | The state pill. `data-state` carries the raw state, so a test never keys on the wording |
|
|
277
|
+
| `jobProgressValue(job)` | The percentage the bar shows, or `undefined` |
|
|
278
|
+
| `useJobToasts(jobs, opts?)` | One toast per job the first time it settles, on the `Toaster` the layout already mounts |
|
|
279
|
+
|
|
280
|
+
- **No packaged wording.** The states are broker vocabulary; the sentence an app wants for them
|
|
281
|
+
("Queued", "Rendering", "Ready") is its own copy in its own namespace, so `JobStatus` takes a
|
|
282
|
+
`labels` map and otherwise renders the raw state — data, not an untranslated string.
|
|
283
|
+
- **`useJobToasts` never toasts on its first pass.** A screen opening onto a store seeded with
|
|
284
|
+
yesterday's finished jobs would fire a stack of them at once, so everything already settled at
|
|
285
|
+
mount is recorded as announced and only what settles afterwards is reported.
|
|
286
|
+
- It needs the same single `Toaster` as everything else — see above.
|
|
287
|
+
|
|
204
288
|
## Subpath: `./consent`
|
|
205
289
|
|
|
206
290
|
`PanelCookieConsent` and `PanelCookiePolicy` — `@owlmeans/web-consent`'s components bound to this
|
|
207
291
|
app's language and translations, falling through to the package's own seven-language bundle for
|
|
208
292
|
every key the app has not overridden. See the `consent` skill.
|
|
209
293
|
|
|
210
|
-
A re-export does not move Tailwind class strings, so a consumer
|
|
211
|
-
`@owlmeans/web-consent
|
|
294
|
+
A re-export does not move Tailwind class strings, so a consumer adds a second `@source` for
|
|
295
|
+
`@owlmeans/web-consent` alongside this package's — pointing at **`src`**, for the reason spelled out
|
|
296
|
+
under *Consumer setup* below. Without it the dialog renders half-styled.
|
|
212
297
|
|
|
213
298
|
## Consumer setup — the `@` contract and Tailwind
|
|
214
299
|
|
|
@@ -217,22 +302,36 @@ its own shadcn copy. Vendor every primitive the package imports: `alert`, `butto
|
|
|
217
302
|
`label`, `navigation-menu`, `progress` (plus `separator` if you use it), and add
|
|
218
303
|
`@radix-ui/react-navigation-menu` alongside the other Radix peers.
|
|
219
304
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
305
|
+
The vendored `@/lib/utils` stays — the package's own components resolve `cn` through it — but the
|
|
306
|
+
app's own components import `cn` from `@owlmeans/web-panel` instead of declaring a third copy. The
|
|
307
|
+
public export is a package-owned function, deliberately not a re-export of `@/lib/utils`: that
|
|
308
|
+
specifier is emitted verbatim and would resolve back to the consumer's file.
|
|
309
|
+
|
|
310
|
+
Then point Tailwind at the installed package's **`src`**. Its oxide scanner reads the CSS root
|
|
311
|
+
plus `@source` directives only, and excludes `node_modules` — so classes that exist **only** inside
|
|
312
|
+
`web-panel` components (the whole navigation shell and footer) never reach the stylesheet, and the
|
|
313
|
+
app renders an unstyled menu. In the app's Tailwind entry:
|
|
224
314
|
|
|
225
315
|
```css
|
|
226
316
|
@import "tailwindcss";
|
|
227
317
|
|
|
228
|
-
@source "../../../node_modules/@owlmeans/web-panel/
|
|
318
|
+
@source "../../../node_modules/@owlmeans/web-panel/src";
|
|
229
319
|
```
|
|
230
320
|
|
|
231
|
-
Adjust the relative depth to your own layout
|
|
321
|
+
Adjust the relative depth to your own layout. **Point at `src`, never at `build`:** the scanner
|
|
322
|
+
applies the `.gitignore` of whatever repository a path resolves into, and a linked `node_modules`
|
|
323
|
+
entry resolves into a monorepo whose `.gitignore` covers every package build directory — a `build`
|
|
324
|
+
source there scans zero files and reports nothing, while the shell renders unstyled with nothing to
|
|
325
|
+
blame. `src` is tracked in the repository and ships in the published tarball, so one path serves a
|
|
326
|
+
linked checkout and an npm install alike.
|
|
232
327
|
|
|
233
328
|
## Depends On
|
|
234
329
|
|
|
235
330
|
- `@owlmeans/web-client`, `@owlmeans/client-panel`, `@owlmeans/client-i18n`, `@owlmeans/web-router`
|
|
331
|
+
- `@owlmeans/queue` — `JobRecord` / `JobState`, read by the `./jobs` subpath
|
|
236
332
|
- Peers (app-provided): `react`, `react-dom`, `react-hook-form`, `tailwindcss`, `tailwind-merge`,
|
|
237
333
|
`clsx`, `class-variance-authority`, `lucide-react`, `ajv`, and the `@radix-ui/react-*` primitives
|
|
238
334
|
(`label`, `navigation-menu`, `progress`, `separator`, `slot`). No MUI, no react-router.
|
|
335
|
+
- `ajv-formats` is imported at module scope by the form model but is declared in no dependency
|
|
336
|
+
section of the manifest, which lists `ajv` alone. An install that does not otherwise pull it in
|
|
337
|
+
fails at import time, so declare `ajv-formats` next to `ajv` in the consuming application.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
3
|
declare const buttonVariants: (props?: ({
|
|
4
|
-
variant?: "default" | "destructive" | "
|
|
5
|
-
size?: "default" | "
|
|
4
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
5
|
+
size?: "default" | "icon" | "lg" | "sm" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
|
|
8
8
|
asChild?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,IAAI,MAAM,EAAE,UAAU,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIlD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,IAAI,MAAM,EAAE,UAAU,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIlD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAG,CAY5E,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,OAAK,CAC9E,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const entrypoints:
|
|
1
|
+
export declare const entrypoints: import("@owlmeans/entrypoint").CommonEntrypoint[];
|
|
2
2
|
//# sourceMappingURL=entrypoints.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../../src/auth/entrypoints.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../../src/auth/entrypoints.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,mDAAuB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/components/form/button/component.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAa,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CAAC,CAAqB,EAA0E,EAAE;IACnH,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,SAAS,CAAC;QACf,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/components/form/button/component.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/form/component.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEzE,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,aAAa,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAEhC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAC1C,aAAa,CAAC,GAAG,CAAC,CAAA;AAElB,MAAM,CAAC,MAAM,IAAI,GAAqB,CAAC,KAAK,EAAE,EAAE;IAC9C,MAAM,EACJ,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EACnE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAC3C,GAAG,KAAK,CAAA;IACT,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,QAAQ,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EACpF,CAAC,IAAI,EAAE,QAAQ,IAAI,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC,CAC7C,CAAA;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC;QACnB,IAAI,EAAE,KAAK;QACX,aAAa,EAAE,SAAS;QACxB,QAAQ,EAAE,UAAU;YAClB,CAAC,CAAC,WAAW,CAAC,UAAqC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YACjG,CAAC,CAAC,SAAS;QACb,UAAU,EAAE,GAAG;KAChB,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,IAAyB,EAAE,EAAE;QACxD,MAAM,MAAM,GAAG,UAAU,IAAI,IAAI;YAC/B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAE,UAAkC,CAAC,UAAU,CAAC;YAC7D,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACnB,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/B,CAAC,CAAC,CAAA;IACJ,CAAC,CAAyB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEnC,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,KAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/components/form/component.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/components/helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAErD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/components/helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAErD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,gBACb,YAAY,aACd,YAAY,KACtB,MA4BF,CAAA;AAwBD,eAAO,MAAM,aAAa,QAAO,MAchC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,CAAC,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,eAAe,MAAM,KAAG,CAQ1F,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../../../src/components/login/append.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGlE,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC;IAC3E,0DAA0D;IAC1D,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAA;CACzD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../../../src/components/login/append.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGlE,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC;IAC3E,0DAA0D;IAC1D,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAA;CACzD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,OAC3E,CAAC,UAAU,gBAAgB,KAC/B,CASF,CAAA"}
|
package/build/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAG,UAAU,EAAE,MAAM,YAAY,CAAA;AAKxD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAG,UAAU,EAAE,MAAM,YAAY,CAAA;AAKxD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,KAAG,CAalF,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,SAAS,GAAG,SAAS,EAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,QACnF,CAAA"}
|
package/build/entrypoints.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const entrypoints:
|
|
1
|
+
export declare const entrypoints: import("@owlmeans/entrypoint").CommonEntrypoint[];
|
|
2
2
|
//# sourceMappingURL=entrypoints.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../src/entrypoints.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,mDAAuB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Tailwind's `md` — the width at which the navigation shell swaps its side menu for the bar. */
|
|
2
|
+
export declare const MOBILE_BREAKPOINT = 768;
|
|
3
|
+
/**
|
|
4
|
+
* Whether the viewport is narrower than Tailwind's `md`, for a component that has to pick a tree
|
|
5
|
+
* rather than render both and hide one with `md:hidden`.
|
|
6
|
+
*
|
|
7
|
+
* It matches a media query instead of listening for `resize` the way `useBreakPoint` does: the
|
|
8
|
+
* browser evaluates the query itself and notifies only when the answer flips, so dragging a window
|
|
9
|
+
* across the whole width costs one render rather than one per frame.
|
|
10
|
+
*
|
|
11
|
+
* The answer is `false` before the first effect and on a server render, because `window` is the
|
|
12
|
+
* only thing that knows the width. That makes the desktop tree the one server-rendered HTML and
|
|
13
|
+
* the first client paint agree on, so hydration never mismatches.
|
|
14
|
+
*/
|
|
15
|
+
export declare const useIsMobile: () => boolean;
|
|
16
|
+
//# sourceMappingURL=use-mobile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mobile.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mobile.ts"],"names":[],"mappings":"AAEA,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,QAAO,OAiB9B,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
/** Tailwind's `md` — the width at which the navigation shell swaps its side menu for the bar. */
|
|
3
|
+
export const MOBILE_BREAKPOINT = 768;
|
|
4
|
+
/**
|
|
5
|
+
* Whether the viewport is narrower than Tailwind's `md`, for a component that has to pick a tree
|
|
6
|
+
* rather than render both and hide one with `md:hidden`.
|
|
7
|
+
*
|
|
8
|
+
* It matches a media query instead of listening for `resize` the way `useBreakPoint` does: the
|
|
9
|
+
* browser evaluates the query itself and notifies only when the answer flips, so dragging a window
|
|
10
|
+
* across the whole width costs one render rather than one per frame.
|
|
11
|
+
*
|
|
12
|
+
* The answer is `false` before the first effect and on a server render, because `window` is the
|
|
13
|
+
* only thing that knows the width. That makes the desktop tree the one server-rendered HTML and
|
|
14
|
+
* the first client paint agree on, so hydration never mismatches.
|
|
15
|
+
*/
|
|
16
|
+
export const useIsMobile = () => {
|
|
17
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (typeof window === 'undefined' || window.matchMedia == null) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const query = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
23
|
+
const read = () => setIsMobile(query.matches);
|
|
24
|
+
read();
|
|
25
|
+
query.addEventListener('change', read);
|
|
26
|
+
return () => query.removeEventListener('change', read);
|
|
27
|
+
}, []);
|
|
28
|
+
return isMobile;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=use-mobile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mobile.js","sourceRoot":"","sources":["../../src/hooks/use-mobile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE3C,iGAAiG;AACjG,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAEpC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAY,EAAE;IACvC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE/C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;YAC/D,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,iBAAiB,GAAG,CAAC,KAAK,CAAC,CAAA;QAC1E,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC7C,IAAI,EAAE,CAAA;QACN,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAEtC,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACxD,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA"}
|
package/build/index.d.ts
CHANGED
|
@@ -4,5 +4,7 @@ export * from './exports.js';
|
|
|
4
4
|
export * from './context.js';
|
|
5
5
|
export * from './entrypoints.js';
|
|
6
6
|
export * from './components/index.js';
|
|
7
|
+
export * from './hooks/index.js';
|
|
8
|
+
export * from './utils.js';
|
|
7
9
|
export * from '@owlmeans/client-panel';
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAE1B,cAAc,wBAAwB,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -3,5 +3,7 @@ export * from './exports.js';
|
|
|
3
3
|
export * from './context.js';
|
|
4
4
|
export * from './entrypoints.js';
|
|
5
5
|
export * from './components/index.js';
|
|
6
|
+
export * from './hooks/index.js';
|
|
7
|
+
export * from './utils.js';
|
|
6
8
|
export * from '@owlmeans/client-panel';
|
|
7
9
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAE1B,cAAc,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import type { JobRecord } from '@owlmeans/queue';
|
|
3
|
+
import type { JobProps, JobStatusProps } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* A job's progress as a percentage, or `undefined` when there is nothing to show yet.
|
|
6
|
+
*
|
|
7
|
+
* `JobRecord.progress` is deliberately `unknown` — a processor reports whatever it counts — so the
|
|
8
|
+
* three shapes worth understanding are read here and everything else falls through to the
|
|
9
|
+
* indeterminate bar, which is the honest answer for "running, no idea how far".
|
|
10
|
+
*/
|
|
11
|
+
export declare const jobProgressValue: (job: JobRecord) => number | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The bar for one job. A job with nothing to report animates indeterminately rather than sitting
|
|
14
|
+
* at zero, because zero and "the processor never called `progress()`" look identical otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export declare const JobProgress: FC<JobProps>;
|
|
17
|
+
/** The state pill. `data-state` carries the raw state, so a test never keys on the wording. */
|
|
18
|
+
export declare const JobStatus: FC<JobStatusProps>;
|
|
19
|
+
//# sourceMappingURL=component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/jobs/component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAG/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAGhD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,QAAS,SAAS,KAAG,MAAM,GAAG,SAW1D,CAAA;AAcD;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,QAAQ,CASpC,CAAA;AAWD,+FAA+F;AAC/F,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAYxC,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { JobState } from '@owlmeans/queue';
|
|
4
|
+
import { Progress } from '@/components/ui/progress';
|
|
5
|
+
import { cn } from '@/lib/utils';
|
|
6
|
+
/**
|
|
7
|
+
* A job's progress as a percentage, or `undefined` when there is nothing to show yet.
|
|
8
|
+
*
|
|
9
|
+
* `JobRecord.progress` is deliberately `unknown` — a processor reports whatever it counts — so the
|
|
10
|
+
* three shapes worth understanding are read here and everything else falls through to the
|
|
11
|
+
* indeterminate bar, which is the honest answer for "running, no idea how far".
|
|
12
|
+
*/
|
|
13
|
+
export const jobProgressValue = (job) => {
|
|
14
|
+
if (job.state === JobState.Completed) {
|
|
15
|
+
return 100;
|
|
16
|
+
}
|
|
17
|
+
const progress = job.progress;
|
|
18
|
+
const value = typeof progress === 'number' ? progress
|
|
19
|
+
: typeof progress === 'object' && progress != null
|
|
20
|
+
? percentOf(progress)
|
|
21
|
+
: undefined;
|
|
22
|
+
return value == null ? undefined : Math.max(0, Math.min(100, value));
|
|
23
|
+
};
|
|
24
|
+
const percentOf = (progress) => {
|
|
25
|
+
if (typeof progress.percent === 'number') {
|
|
26
|
+
return progress.percent;
|
|
27
|
+
}
|
|
28
|
+
const { done, total } = progress;
|
|
29
|
+
if (typeof done === 'number' && typeof total === 'number' && total > 0) {
|
|
30
|
+
return (done / total) * 100;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The bar for one job. A job with nothing to report animates indeterminately rather than sitting
|
|
36
|
+
* at zero, because zero and "the processor never called `progress()`" look identical otherwise.
|
|
37
|
+
*/
|
|
38
|
+
export const JobProgress = ({ job, className, style }) => {
|
|
39
|
+
const value = useMemo(() => jobProgressValue(job), [job.state, job.progress]);
|
|
40
|
+
return _jsx(Progress, { "data-slot": "job-progress", value: value, className: cn('w-full', className), style: style });
|
|
41
|
+
};
|
|
42
|
+
const STATE_STYLE = {
|
|
43
|
+
[JobState.Waiting]: 'border-border bg-muted text-muted-foreground',
|
|
44
|
+
[JobState.Delayed]: 'border-border bg-muted text-muted-foreground',
|
|
45
|
+
[JobState.Active]: 'border-border bg-accent text-accent-foreground',
|
|
46
|
+
[JobState.Completed]: 'border-primary/40 bg-primary/10 text-primary',
|
|
47
|
+
[JobState.Failed]: 'border-destructive/40 bg-destructive/10 text-destructive',
|
|
48
|
+
[JobState.Unknown]: 'border-border bg-muted text-muted-foreground',
|
|
49
|
+
};
|
|
50
|
+
/** The state pill. `data-state` carries the raw state, so a test never keys on the wording. */
|
|
51
|
+
export const JobStatus = ({ job, labels, className, style }) => {
|
|
52
|
+
const state = job.state ?? JobState.Unknown;
|
|
53
|
+
return _jsx("span", { "data-slot": "job-status", "data-state": state, className: cn('inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium', STATE_STYLE[state], className), style: style, children: labels?.[state] ?? state });
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../src/jobs/component.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAE/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAEA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JobRecord } from '@owlmeans/queue';
|
|
2
|
+
import type { JobToastOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Announce jobs as they finish, on the `Toaster` the layout already mounts.
|
|
5
|
+
*
|
|
6
|
+
* Hand it whatever the screen is already showing — `useJobs()` from `@owlmeans/client-job` maps
|
|
7
|
+
* straight onto it — and it raises one toast per job the first time that job settles.
|
|
8
|
+
*
|
|
9
|
+
* **The first pass never toasts.** A screen opening onto a store seeded with yesterday's finished
|
|
10
|
+
* jobs would otherwise fire a stack of them at once, so everything already settled when this
|
|
11
|
+
* mounts is recorded as announced and only what settles afterwards is reported.
|
|
12
|
+
*/
|
|
13
|
+
export declare const useJobToasts: (jobs: JobRecord[], opts?: JobToastOptions) => void;
|
|
14
|
+
//# sourceMappingURL=toasts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toasts.d.ts","sourceRoot":"","sources":["../../src/jobs/toasts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,SAAU,SAAS,EAAE,SAAS,eAAe,KAAG,IAwBxE,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { toast } from 'sonner';
|
|
3
|
+
import { isSettled, JobState } from '@owlmeans/queue';
|
|
4
|
+
/**
|
|
5
|
+
* Announce jobs as they finish, on the `Toaster` the layout already mounts.
|
|
6
|
+
*
|
|
7
|
+
* Hand it whatever the screen is already showing — `useJobs()` from `@owlmeans/client-job` maps
|
|
8
|
+
* straight onto it — and it raises one toast per job the first time that job settles.
|
|
9
|
+
*
|
|
10
|
+
* **The first pass never toasts.** A screen opening onto a store seeded with yesterday's finished
|
|
11
|
+
* jobs would otherwise fire a stack of them at once, so everything already settled when this
|
|
12
|
+
* mounts is recorded as announced and only what settles afterwards is reported.
|
|
13
|
+
*/
|
|
14
|
+
export const useJobToasts = (jobs, opts) => {
|
|
15
|
+
const announced = useRef(new Set());
|
|
16
|
+
const primed = useRef(false);
|
|
17
|
+
// Re-run on what actually decides a toast, not on the array identity a caller rebuilds per render.
|
|
18
|
+
const settlement = jobs.map(job => `${job.id}:${job.state}`).join(',');
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
jobs.forEach(job => {
|
|
21
|
+
if (job.id == null || !isSettled(job.state) || announced.current.has(job.id)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
announced.current.add(job.id);
|
|
25
|
+
if (!primed.current) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const message = opts?.message?.(job) ?? job.name;
|
|
29
|
+
if (job.state === JobState.Completed) {
|
|
30
|
+
toast.success(message);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
toast.error(job.error != null && job.error !== '' ? `${String(message)}: ${job.error}` : message);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
primed.current = true;
|
|
37
|
+
}, [settlement]);
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=toasts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toasts.js","sourceRoot":"","sources":["../../src/jobs/toasts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAIrD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAiB,EAAE,IAAsB,EAAQ,EAAE;IAC9E,MAAM,SAAS,GAAG,MAAM,CAAc,IAAI,GAAG,EAAE,CAAC,CAAA;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC5B,mGAAmG;IACnG,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEtE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACjB,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC7E,OAAM;YACR,CAAC;YACD,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC7B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAM;YACR,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAA;YAChD,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACrC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;YACxB,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;YACnG,CAAC;QACH,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;IACvB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;AAClB,CAAC,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { JobRecord, JobState } from '@owlmeans/queue';
|
|
3
|
+
import type { StyledProps } from '../components/types.js';
|
|
4
|
+
export interface JobProps extends StyledProps {
|
|
5
|
+
job: JobRecord;
|
|
6
|
+
}
|
|
7
|
+
export interface JobStatusProps extends JobProps {
|
|
8
|
+
/**
|
|
9
|
+
* What each state is called on screen.
|
|
10
|
+
*
|
|
11
|
+
* There is no packaged wording: the states are broker vocabulary, and the sentence an app wants
|
|
12
|
+
* for them ("Queued", "Rendering", "Ready") is the app's own copy in the app's own namespace.
|
|
13
|
+
* Absent a label the raw state is rendered, which is data rather than an untranslated string.
|
|
14
|
+
*/
|
|
15
|
+
labels?: Partial<Record<JobState, ReactNode>>;
|
|
16
|
+
}
|
|
17
|
+
export interface JobToastOptions {
|
|
18
|
+
/** What the toast says. The job's own name when omitted. */
|
|
19
|
+
message?: (job: JobRecord) => ReactNode;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/jobs/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEzD,MAAM,WAAW,QAAS,SAAQ,WAAW;IAC3C,GAAG,EAAE,SAAS,CAAA;CACf;AAED,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;CAC9C;AAED,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,SAAS,CAAA;CACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/jobs/types.ts"],"names":[],"mappings":""}
|
package/build/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAO3E,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAO3E,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,gBAAgB,SAE7G,CAAA"}
|
package/build/utils.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ClassValue } from 'clsx';
|
|
2
|
+
/**
|
|
3
|
+
* The class-name merger every component in this package is written against, exported so a
|
|
4
|
+
* consuming application doesn't declare its own copy.
|
|
5
|
+
*
|
|
6
|
+
* This is deliberately NOT a re-export of `@/lib/utils`. That specifier is left verbatim in the
|
|
7
|
+
* build and resolves to the CONSUMER's vendored file, so re-exporting it would hand an app back
|
|
8
|
+
* its own function and fail outright wherever the `@` alias isn't configured. The vendored copy
|
|
9
|
+
* under `src/@/lib/` stays exactly as shadcn emits it, because the package's own components must
|
|
10
|
+
* keep resolving through the `@` contract.
|
|
11
|
+
*/
|
|
12
|
+
export declare const cn: (...inputs: ClassValue[]) => string;
|
|
13
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;GASG;AACH,eAAO,MAAM,EAAE,cAAe,UAAU,EAAE,KAAG,MAA+B,CAAA"}
|
package/build/utils.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
/**
|
|
4
|
+
* The class-name merger every component in this package is written against, exported so a
|
|
5
|
+
* consuming application doesn't declare its own copy.
|
|
6
|
+
*
|
|
7
|
+
* This is deliberately NOT a re-export of `@/lib/utils`. That specifier is left verbatim in the
|
|
8
|
+
* build and resolves to the CONSUMER's vendored file, so re-exporting it would hand an app back
|
|
9
|
+
* its own function and fail outright wherever the `@` alias isn't configured. The vendored copy
|
|
10
|
+
* under `src/@/lib/` stays exactly as shadcn emits it, because the package's own components must
|
|
11
|
+
* keep resolving through the `@` contract.
|
|
12
|
+
*/
|
|
13
|
+
export const cn = (...inputs) => twMerge(clsx(inputs));
|
|
14
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAoB,EAAU,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/web-panel",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.32",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -40,35 +40,43 @@
|
|
|
40
40
|
"default": "./build/consent/index.js",
|
|
41
41
|
"module": "./build/consent/index.js",
|
|
42
42
|
"types": "./build/consent/index.d.ts"
|
|
43
|
+
},
|
|
44
|
+
"./jobs": {
|
|
45
|
+
"import": "./build/jobs/index.js",
|
|
46
|
+
"require": "./build/jobs/index.js",
|
|
47
|
+
"default": "./build/jobs/index.js",
|
|
48
|
+
"module": "./build/jobs/index.js",
|
|
49
|
+
"types": "./build/jobs/index.d.ts"
|
|
43
50
|
}
|
|
44
51
|
},
|
|
45
52
|
"dependencies": {
|
|
46
53
|
"@hookform/resolvers": "^5.2.2",
|
|
47
|
-
"@owlmeans/api-config-client": "^0.1.18-rc.
|
|
48
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
49
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
50
|
-
"@owlmeans/basic-envelope": "^0.1.18-rc.
|
|
51
|
-
"@owlmeans/client": "^0.1.18-rc.
|
|
52
|
-
"@owlmeans/client-auth": "^0.1.18-rc.
|
|
53
|
-
"@owlmeans/client-config": "^0.1.18-rc.
|
|
54
|
-
"@owlmeans/client-context": "^0.1.18-rc.
|
|
55
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
56
|
-
"@owlmeans/client-flow": "^0.1.18-rc.
|
|
57
|
-
"@owlmeans/client-i18n": "^0.1.18-rc.
|
|
58
|
-
"@owlmeans/client-panel": "^0.1.18-rc.
|
|
59
|
-
"@owlmeans/client-route": "^0.1.18-rc.
|
|
60
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
61
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
62
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
63
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
64
|
-
"@owlmeans/flow": "^0.1.18-rc.
|
|
65
|
-
"@owlmeans/i18n": "^0.1.18-rc.
|
|
66
|
-
"@owlmeans/
|
|
67
|
-
"@owlmeans/
|
|
68
|
-
"@owlmeans/web-
|
|
69
|
-
"@owlmeans/web-
|
|
70
|
-
"@owlmeans/web-
|
|
71
|
-
"@owlmeans/web-
|
|
54
|
+
"@owlmeans/api-config-client": "^0.1.18-rc.13",
|
|
55
|
+
"@owlmeans/auth": "^0.1.18-rc.9",
|
|
56
|
+
"@owlmeans/auth-common": "^0.1.18-rc.13",
|
|
57
|
+
"@owlmeans/basic-envelope": "^0.1.18-rc.12",
|
|
58
|
+
"@owlmeans/client": "^0.1.18-rc.16",
|
|
59
|
+
"@owlmeans/client-auth": "^0.1.18-rc.20",
|
|
60
|
+
"@owlmeans/client-config": "^0.1.18-rc.12",
|
|
61
|
+
"@owlmeans/client-context": "^0.1.18-rc.13",
|
|
62
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.13",
|
|
63
|
+
"@owlmeans/client-flow": "^0.1.18-rc.17",
|
|
64
|
+
"@owlmeans/client-i18n": "^0.1.18-rc.15",
|
|
65
|
+
"@owlmeans/client-panel": "^0.1.18-rc.23",
|
|
66
|
+
"@owlmeans/client-route": "^0.1.18-rc.13",
|
|
67
|
+
"@owlmeans/config": "^0.1.18-rc.12",
|
|
68
|
+
"@owlmeans/context": "^0.1.18-rc.8",
|
|
69
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.11",
|
|
70
|
+
"@owlmeans/error": "^0.1.18-rc.8",
|
|
71
|
+
"@owlmeans/flow": "^0.1.18-rc.14",
|
|
72
|
+
"@owlmeans/i18n": "^0.1.18-rc.8",
|
|
73
|
+
"@owlmeans/queue": "^0.1.18-rc.9",
|
|
74
|
+
"@owlmeans/route": "^0.1.18-rc.9",
|
|
75
|
+
"@owlmeans/web-client": "^0.1.18-rc.24",
|
|
76
|
+
"@owlmeans/web-consent": "^0.1.18-rc.7",
|
|
77
|
+
"@owlmeans/web-db": "^0.1.18-rc.14",
|
|
78
|
+
"@owlmeans/web-flow": "^0.1.18-rc.17",
|
|
79
|
+
"@owlmeans/web-router": "^0.1.18-rc.14",
|
|
72
80
|
"i18next-browser-languagedetector": "^8.0.0",
|
|
73
81
|
"qrcode.react": "^4.2.0",
|
|
74
82
|
"react-google-recaptcha": "^3.1.0",
|
|
@@ -92,7 +100,7 @@
|
|
|
92
100
|
},
|
|
93
101
|
"devDependencies": {
|
|
94
102
|
"@owlmeans/dep-config": "workspace:*",
|
|
95
|
-
"@owlmeans/test-ui": "^0.1.18-rc.
|
|
103
|
+
"@owlmeans/test-ui": "^0.1.18-rc.15",
|
|
96
104
|
"@radix-ui/react-label": "^2.1.0",
|
|
97
105
|
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
98
106
|
"@radix-ui/react-progress": "^1.1.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-mobile.js'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
/** Tailwind's `md` — the width at which the navigation shell swaps its side menu for the bar. */
|
|
4
|
+
export const MOBILE_BREAKPOINT = 768
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Whether the viewport is narrower than Tailwind's `md`, for a component that has to pick a tree
|
|
8
|
+
* rather than render both and hide one with `md:hidden`.
|
|
9
|
+
*
|
|
10
|
+
* It matches a media query instead of listening for `resize` the way `useBreakPoint` does: the
|
|
11
|
+
* browser evaluates the query itself and notifies only when the answer flips, so dragging a window
|
|
12
|
+
* across the whole width costs one render rather than one per frame.
|
|
13
|
+
*
|
|
14
|
+
* The answer is `false` before the first effect and on a server render, because `window` is the
|
|
15
|
+
* only thing that knows the width. That makes the desktop tree the one server-rendered HTML and
|
|
16
|
+
* the first client paint agree on, so hydration never mismatches.
|
|
17
|
+
*/
|
|
18
|
+
export const useIsMobile = (): boolean => {
|
|
19
|
+
const [isMobile, setIsMobile] = useState(false)
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (typeof window === 'undefined' || window.matchMedia == null) {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const query = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
|
|
27
|
+
const read = () => setIsMobile(query.matches)
|
|
28
|
+
read()
|
|
29
|
+
query.addEventListener('change', read)
|
|
30
|
+
|
|
31
|
+
return () => query.removeEventListener('change', read)
|
|
32
|
+
}, [])
|
|
33
|
+
|
|
34
|
+
return isMobile
|
|
35
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { FC } from 'react'
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { JobState } from '@owlmeans/queue'
|
|
4
|
+
import type { JobRecord } from '@owlmeans/queue'
|
|
5
|
+
import { Progress } from '@/components/ui/progress'
|
|
6
|
+
import { cn } from '@/lib/utils'
|
|
7
|
+
import type { JobProps, JobStatusProps } from './types.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A job's progress as a percentage, or `undefined` when there is nothing to show yet.
|
|
11
|
+
*
|
|
12
|
+
* `JobRecord.progress` is deliberately `unknown` — a processor reports whatever it counts — so the
|
|
13
|
+
* three shapes worth understanding are read here and everything else falls through to the
|
|
14
|
+
* indeterminate bar, which is the honest answer for "running, no idea how far".
|
|
15
|
+
*/
|
|
16
|
+
export const jobProgressValue = (job: JobRecord): number | undefined => {
|
|
17
|
+
if (job.state === JobState.Completed) {
|
|
18
|
+
return 100
|
|
19
|
+
}
|
|
20
|
+
const progress = job.progress
|
|
21
|
+
const value = typeof progress === 'number' ? progress
|
|
22
|
+
: typeof progress === 'object' && progress != null
|
|
23
|
+
? percentOf(progress as Record<string, unknown>)
|
|
24
|
+
: undefined
|
|
25
|
+
|
|
26
|
+
return value == null ? undefined : Math.max(0, Math.min(100, value))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const percentOf = (progress: Record<string, unknown>): number | undefined => {
|
|
30
|
+
if (typeof progress.percent === 'number') {
|
|
31
|
+
return progress.percent
|
|
32
|
+
}
|
|
33
|
+
const { done, total } = progress
|
|
34
|
+
if (typeof done === 'number' && typeof total === 'number' && total > 0) {
|
|
35
|
+
return (done / total) * 100
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The bar for one job. A job with nothing to report animates indeterminately rather than sitting
|
|
43
|
+
* at zero, because zero and "the processor never called `progress()`" look identical otherwise.
|
|
44
|
+
*/
|
|
45
|
+
export const JobProgress: FC<JobProps> = ({ job, className, style }) => {
|
|
46
|
+
const value = useMemo(() => jobProgressValue(job), [job.state, job.progress])
|
|
47
|
+
|
|
48
|
+
return <Progress
|
|
49
|
+
data-slot="job-progress"
|
|
50
|
+
value={value}
|
|
51
|
+
className={cn('w-full', className)}
|
|
52
|
+
style={style}
|
|
53
|
+
/>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const STATE_STYLE: Record<JobState, string> = {
|
|
57
|
+
[JobState.Waiting]: 'border-border bg-muted text-muted-foreground',
|
|
58
|
+
[JobState.Delayed]: 'border-border bg-muted text-muted-foreground',
|
|
59
|
+
[JobState.Active]: 'border-border bg-accent text-accent-foreground',
|
|
60
|
+
[JobState.Completed]: 'border-primary/40 bg-primary/10 text-primary',
|
|
61
|
+
[JobState.Failed]: 'border-destructive/40 bg-destructive/10 text-destructive',
|
|
62
|
+
[JobState.Unknown]: 'border-border bg-muted text-muted-foreground',
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The state pill. `data-state` carries the raw state, so a test never keys on the wording. */
|
|
66
|
+
export const JobStatus: FC<JobStatusProps> = ({ job, labels, className, style }) => {
|
|
67
|
+
const state = job.state ?? JobState.Unknown
|
|
68
|
+
|
|
69
|
+
return <span
|
|
70
|
+
data-slot="job-status"
|
|
71
|
+
data-state={state}
|
|
72
|
+
className={cn(
|
|
73
|
+
'inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium',
|
|
74
|
+
STATE_STYLE[state], className
|
|
75
|
+
)}
|
|
76
|
+
style={style}
|
|
77
|
+
>{labels?.[state] ?? state}</span>
|
|
78
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
import { toast } from 'sonner'
|
|
3
|
+
import { isSettled, JobState } from '@owlmeans/queue'
|
|
4
|
+
import type { JobRecord } from '@owlmeans/queue'
|
|
5
|
+
import type { JobToastOptions } from './types.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Announce jobs as they finish, on the `Toaster` the layout already mounts.
|
|
9
|
+
*
|
|
10
|
+
* Hand it whatever the screen is already showing — `useJobs()` from `@owlmeans/client-job` maps
|
|
11
|
+
* straight onto it — and it raises one toast per job the first time that job settles.
|
|
12
|
+
*
|
|
13
|
+
* **The first pass never toasts.** A screen opening onto a store seeded with yesterday's finished
|
|
14
|
+
* jobs would otherwise fire a stack of them at once, so everything already settled when this
|
|
15
|
+
* mounts is recorded as announced and only what settles afterwards is reported.
|
|
16
|
+
*/
|
|
17
|
+
export const useJobToasts = (jobs: JobRecord[], opts?: JobToastOptions): void => {
|
|
18
|
+
const announced = useRef<Set<string>>(new Set())
|
|
19
|
+
const primed = useRef(false)
|
|
20
|
+
// Re-run on what actually decides a toast, not on the array identity a caller rebuilds per render.
|
|
21
|
+
const settlement = jobs.map(job => `${job.id}:${job.state}`).join(',')
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
jobs.forEach(job => {
|
|
25
|
+
if (job.id == null || !isSettled(job.state) || announced.current.has(job.id)) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
announced.current.add(job.id)
|
|
29
|
+
if (!primed.current) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
const message = opts?.message?.(job) ?? job.name
|
|
33
|
+
if (job.state === JobState.Completed) {
|
|
34
|
+
toast.success(message)
|
|
35
|
+
} else {
|
|
36
|
+
toast.error(job.error != null && job.error !== '' ? `${String(message)}: ${job.error}` : message)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
primed.current = true
|
|
40
|
+
}, [settlement])
|
|
41
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import type { JobRecord, JobState } from '@owlmeans/queue'
|
|
3
|
+
import type { StyledProps } from '../components/types.js'
|
|
4
|
+
|
|
5
|
+
export interface JobProps extends StyledProps {
|
|
6
|
+
job: JobRecord
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface JobStatusProps extends JobProps {
|
|
10
|
+
/**
|
|
11
|
+
* What each state is called on screen.
|
|
12
|
+
*
|
|
13
|
+
* There is no packaged wording: the states are broker vocabulary, and the sentence an app wants
|
|
14
|
+
* for them ("Queued", "Rendering", "Ready") is the app's own copy in the app's own namespace.
|
|
15
|
+
* Absent a label the raw state is rendered, which is data rather than an untranslated string.
|
|
16
|
+
*/
|
|
17
|
+
labels?: Partial<Record<JobState, ReactNode>>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface JobToastOptions {
|
|
21
|
+
/** What the toast says. The job's own name when omitted. */
|
|
22
|
+
message?: (job: JobRecord) => ReactNode
|
|
23
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { clsx, type ClassValue } from 'clsx'
|
|
2
|
+
import { twMerge } from 'tailwind-merge'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The class-name merger every component in this package is written against, exported so a
|
|
6
|
+
* consuming application doesn't declare its own copy.
|
|
7
|
+
*
|
|
8
|
+
* This is deliberately NOT a re-export of `@/lib/utils`. That specifier is left verbatim in the
|
|
9
|
+
* build and resolves to the CONSUMER's vendored file, so re-exporting it would hand an app back
|
|
10
|
+
* its own function and fail outright wherever the `@` alias isn't configured. The vendored copy
|
|
11
|
+
* under `src/@/lib/` stays exactly as shadcn emits it, because the package's own components must
|
|
12
|
+
* keep resolving through the `@` contract.
|
|
13
|
+
*/
|
|
14
|
+
export const cn = (...inputs: ClassValue[]): string => twMerge(clsx(inputs))
|