viur-ui 0.0.1
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 +79 -0
- package/index.d.ts +351 -0
- package/index.js +46 -0
- package/package.json +84 -0
- package/src/components/Browser/Browser.vue +496 -0
- package/src/components/Browser/TreeNav.vue +408 -0
- package/src/components/Browser/ViurBrowser.d.vue.ts +64 -0
- package/src/components/Browser/ViurBrowser.vue +271 -0
- package/src/components/Browser/dragSession.ts +134 -0
- package/src/components/Browser/index.ts +14 -0
- package/src/components/Browser/types.ts +30 -0
- package/src/components/DataTable/ColumnFilterPanel.vue +225 -0
- package/src/components/DataTable/DataTable.vue +3155 -0
- package/src/components/DataTable/ViurDataTable.d.vue.ts +72 -0
- package/src/components/DataTable/ViurDataTable.vue +331 -0
- package/src/components/DataTable/columns.ts +400 -0
- package/src/components/DataTable/index.ts +60 -0
- package/src/components/DataTable/rows.ts +446 -0
- package/src/components/DataTable/types.ts +267 -0
- package/src/components/DataTable/useColumnLayout.ts +294 -0
- package/src/components/DataTable/useGridNavigation.ts +193 -0
- package/src/components/DataTable/useVirtualRows.ts +126 -0
- package/src/components/DataTable/viurColumns.ts +330 -0
- package/src/forms/ViForm.d.vue.ts +106 -0
- package/src/forms/ViForm.vue +592 -0
- package/src/forms/ViFormCategory.vue +57 -0
- package/src/forms/bones/Bone.vue +1023 -0
- package/src/forms/bones/BoneActions.vue +127 -0
- package/src/forms/bones/BoneLabel.vue +122 -0
- package/src/forms/bones/BoneMultipleList.vue +91 -0
- package/src/forms/bones/BoneMultipleWrapper.vue +105 -0
- package/src/forms/bones/BoneNestedWrapper.vue +155 -0
- package/src/forms/bones/BoneSingleEntry.vue +51 -0
- package/src/forms/bones/FilterBone.vue +694 -0
- package/src/forms/bones/actionbar/defaultBar.vue +98 -0
- package/src/forms/bones/actionbar/fileBar.vue +165 -0
- package/src/forms/bones/actionbar/relationalBar.vue +125 -0
- package/src/forms/bones/actions/ActionDialog.vue +70 -0
- package/src/forms/bones/actions/Debug.vue +106 -0
- package/src/forms/bones/actions/Delete.vue +13 -0
- package/src/forms/bones/actions/DescribeImage.vue +201 -0
- package/src/forms/bones/actions/Download.vue +27 -0
- package/src/forms/bones/actions/Placeholder.vue +14 -0
- package/src/forms/bones/actions/Translation.vue +238 -0
- package/src/forms/bones/actions/index.js +280 -0
- package/src/forms/bones/bone.d.ts +45 -0
- package/src/forms/bones/country_information.json +779 -0
- package/src/forms/bones/index.js +225 -0
- package/src/forms/bones/uploadAdapter.js +46 -0
- package/src/forms/bones/utils.js +284 -0
- package/src/forms/bones/view/base_item.vue +35 -0
- package/src/forms/bones/view/boneLogic.js +202 -0
- package/src/forms/bones/view/index.js +5 -0
- package/src/forms/bones/widgets/booleanBone.vue +83 -0
- package/src/forms/bones/widgets/booleanBoneChoose.vue +57 -0
- package/src/forms/bones/widgets/booleanBoneSelect.vue +58 -0
- package/src/forms/bones/widgets/codeBone.vue +214 -0
- package/src/forms/bones/widgets/colorBone.vue +75 -0
- package/src/forms/bones/widgets/dateBone.vue +114 -0
- package/src/forms/bones/widgets/emailBone.vue +100 -0
- package/src/forms/bones/widgets/fileBone.vue +273 -0
- package/src/forms/bones/widgets/jsonBone.vue +63 -0
- package/src/forms/bones/widgets/keyBone.vue +71 -0
- package/src/forms/bones/widgets/numericBone.vue +125 -0
- package/src/forms/bones/widgets/passwordBone.vue +215 -0
- package/src/forms/bones/widgets/phoneBone.vue +173 -0
- package/src/forms/bones/widgets/rawBone.vue +94 -0
- package/src/forms/bones/widgets/recordBone.vue +64 -0
- package/src/forms/bones/widgets/relationalBone.vue +164 -0
- package/src/forms/bones/widgets/relationalBoneSelect.vue +120 -0
- package/src/forms/bones/widgets/selectBone.vue +122 -0
- package/src/forms/bones/widgets/selectBoneChoose.vue +104 -0
- package/src/forms/bones/widgets/spatialBone.vue +111 -0
- package/src/forms/bones/widgets/stringBone.vue +139 -0
- package/src/forms/bones/widgets/textBone.vue +641 -0
- package/src/forms/install.d.ts +4 -0
- package/src/forms/install.js +43 -0
- package/src/forms/layouts/LayloutList2Columns.vue +57 -0
- package/src/forms/layouts/LayoutCategory.vue +38 -0
- package/src/forms/layouts/LayoutList.vue +31 -0
- package/src/forms/utils.js +601 -0
- package/src/public/assets/icons/fontawesome-manifest.json +8 -0
- package/src/public/assets/icons/regular/file.svg +1 -0
- package/src/public/assets/icons/solid/arrows-left-right.svg +1 -0
- package/src/public/assets/icons/solid/bug.svg +1 -0
- package/src/public/assets/icons/solid/check.svg +1 -0
- package/src/public/assets/icons/solid/circle-info.svg +1 -0
- package/src/public/assets/icons/solid/compress.svg +1 -0
- package/src/public/assets/icons/solid/download.svg +1 -0
- package/src/public/assets/icons/solid/expand.svg +1 -0
- package/src/public/assets/icons/solid/grip-vertical.svg +1 -0
- package/src/public/assets/icons/solid/plus.svg +1 -0
- package/src/public/assets/icons/solid/question.svg +1 -0
- package/src/public/assets/icons/solid/triangle-exclamation.svg +1 -0
- package/src/public/assets/icons/solid/upload.svg +1 -0
- package/src/public/assets/icons/solid/xmark.svg +1 -0
- package/src/request/cache.js +183 -0
- package/src/request/configStore.js +516 -0
- package/src/request/envelope.js +211 -0
- package/src/request/index.js +35 -0
- package/src/request/messageStore.js +201 -0
- package/src/request/request.js +752 -0
- package/src/request/skel.js +90 -0
- package/src/theme/colorStore.js +168 -0
- package/src/translations/de.js +178 -0
- package/src/translations/en.js +177 -0
- package/src/user/LoginScreen.d.vue.ts +54 -0
- package/src/user/LoginScreen.vue +627 -0
- package/src/user/google.js +75 -0
- package/src/user/index.js +3 -0
- package/src/user/store.d.ts +59 -0
- package/src/user/store.js +183 -0
- package/src/webawesomeCompat.css +72 -0
- package/src/webawesomeConfig.js +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# viur-ui
|
|
2
|
+
|
|
3
|
+
Official UI Components for Vue 3.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install viur-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Requires:** Vue 3.3+, Vite with `@vitejs/plugin-vue`
|
|
12
|
+
|
|
13
|
+
## Development
|
|
14
|
+
|
|
15
|
+
### Histoire (Component Stories)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Neue Bones (WebAwesome) — http://localhost:6006
|
|
19
|
+
npm run story:dev
|
|
20
|
+
|
|
21
|
+
# Legacy-Vergleich: Alt (Shoelace) vs. Neu (WebAwesome) — http://localhost:6007
|
|
22
|
+
npm run histoire:legacy
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Tests
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Unit-Tests (Vitest, watch mode)
|
|
29
|
+
npm run test
|
|
30
|
+
|
|
31
|
+
# Unit-Tests einmalig ausführen
|
|
32
|
+
npm run test:run
|
|
33
|
+
|
|
34
|
+
# Contract Tests (Playwright gegen laufenden Histoire-Server auf :6007)
|
|
35
|
+
npm run test:contract
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> Die Contract Tests starten den Legacy-Histoire-Server automatisch, falls er noch nicht läuft.
|
|
39
|
+
|
|
40
|
+
**Ersteinrichtung Playwright:** Nach `npm install` oder nach einem Playwright-Update müssen die Browser einmalig installiert werden:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx playwright install chromium
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Vite Configuration
|
|
47
|
+
|
|
48
|
+
Add to your `vite.config.js` so Vite processes the `.vue` files from this package:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import vue from '@vitejs/plugin-vue'
|
|
52
|
+
|
|
53
|
+
export default {
|
|
54
|
+
plugins: [vue()],
|
|
55
|
+
optimizeDeps: {
|
|
56
|
+
exclude: ['viur-ui']
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
### Named import via index
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
import { HelloWorld } from 'viur-ui'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Direct path import
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
import HelloWorld from 'viur-ui/src/components/HelloWorld.vue'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Components
|
|
76
|
+
|
|
77
|
+
| Component | Description |
|
|
78
|
+
|-----------|-------------|
|
|
79
|
+
| `HelloWorld` | Renders "Hello World" |
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import type { Ref, ComputedRef } from "vue"
|
|
2
|
+
import type { UseFetchReturn } from "@vueuse/core"
|
|
3
|
+
|
|
4
|
+
// ─── List ─────────────────────────────────────────────────────────────────────
|
|
5
|
+
|
|
6
|
+
export interface ListFetchInstance {
|
|
7
|
+
data: Ref<Record<string, any>[]>
|
|
8
|
+
structure: Ref<Record<string, any>>
|
|
9
|
+
orders: Ref<any[]>
|
|
10
|
+
cursor: Ref<string>
|
|
11
|
+
params: Ref<Record<string, any>>
|
|
12
|
+
/** everything loaded (finished and no cursor left) — safe for local sort/filter */
|
|
13
|
+
complete: ComputedRef<boolean>
|
|
14
|
+
isFetching: Ref<boolean>
|
|
15
|
+
isFinished: Ref<boolean>
|
|
16
|
+
error: Ref<any>
|
|
17
|
+
execute: () => Promise<any>
|
|
18
|
+
/** load the next `pages` pages (default 1) */
|
|
19
|
+
next: (pages?: number) => Promise<void>
|
|
20
|
+
/** load every remaining page */
|
|
21
|
+
nextAll: () => Promise<void>
|
|
22
|
+
filter: (params: Record<string, any>) => Promise<any>
|
|
23
|
+
reset: () => void
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ListFetchOptions {
|
|
27
|
+
params?: Record<string, any>
|
|
28
|
+
group?: string | null
|
|
29
|
+
url?: string | null
|
|
30
|
+
renderer?: string
|
|
31
|
+
immediate?: boolean
|
|
32
|
+
cached?: boolean
|
|
33
|
+
ttl?: number
|
|
34
|
+
/** Zusatz-Header der LIST-Requests (nicht der Struktur) — Objekt oder
|
|
35
|
+
* Funktion, pro Request ausgewertet (z.B. X-VIUR-BONELIST). */
|
|
36
|
+
headers?: Record<string, string> | (() => Record<string, string> | null) | null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export declare const useListFetch: (controller: string | string[], options?: ListFetchOptions) => ListFetchInstance
|
|
40
|
+
export declare const useListFetchAll: (controller: string | string[], options?: ListFetchOptions) => ListFetchInstance
|
|
41
|
+
|
|
42
|
+
// ─── Tree (nodes + leaves) ────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
export interface TreeFetchOptions extends Omit<ListFetchOptions, "group" | "url"> {
|
|
45
|
+
/** shortcut for `params.parententry` */
|
|
46
|
+
parententry?: string | null
|
|
47
|
+
/** fetch every page of both lists automatically */
|
|
48
|
+
all?: boolean
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface TreeFetchInstance {
|
|
52
|
+
nodes: ListFetchInstance
|
|
53
|
+
leaves: ListFetchInstance
|
|
54
|
+
/** nodes followed by leaves, each enriched with `skelType: "node" | "leaf"` */
|
|
55
|
+
data: ComputedRef<Record<string, any>[]>
|
|
56
|
+
structure: ComputedRef<{ node: Record<string, any>; leaf: Record<string, any> }>
|
|
57
|
+
isFetching: ComputedRef<boolean>
|
|
58
|
+
isFinished: ComputedRef<boolean>
|
|
59
|
+
error: ComputedRef<any>
|
|
60
|
+
hasMore: ComputedRef<boolean>
|
|
61
|
+
/** both lists fully loaded — safe for local sort/filter */
|
|
62
|
+
complete: ComputedRef<boolean>
|
|
63
|
+
execute: () => Promise<any>
|
|
64
|
+
/** paginates nodes first, then leaves */
|
|
65
|
+
next: () => Promise<any>
|
|
66
|
+
/** loads every remaining page of both lists */
|
|
67
|
+
nextAll: () => Promise<any>
|
|
68
|
+
filter: (params: Record<string, any>) => Promise<any>
|
|
69
|
+
/** switch to another parent node, keeping the other params */
|
|
70
|
+
open: (parententry: string) => Promise<any>
|
|
71
|
+
reset: () => void
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export declare function useTreeFetch(controller: string | string[], options?: TreeFetchOptions): TreeFetchInstance
|
|
75
|
+
|
|
76
|
+
// ─── View / Add / Edit / Delete ───────────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
type ControllerFetchFn = (
|
|
79
|
+
controller: string | string[],
|
|
80
|
+
args?: string,
|
|
81
|
+
data?: Record<string, any>,
|
|
82
|
+
ctx?: Record<string, any>
|
|
83
|
+
) => UseFetchReturn<any>
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Eigene Abfrage gegen einen Endpunkt eines Moduls bauen — die Grundlage der
|
|
87
|
+
* `use*Fetch`-Helfer. `ctx` nimmt u. a. `renderer`, `version`, `query`
|
|
88
|
+
* (zusätzlicher Query-String), `headers`, `immediate`.
|
|
89
|
+
*/
|
|
90
|
+
export declare function createControllerFetch(options?: {
|
|
91
|
+
endpoint?: string
|
|
92
|
+
method?: string
|
|
93
|
+
secure?: boolean
|
|
94
|
+
invalidates?: boolean
|
|
95
|
+
invalidatesAll?: boolean
|
|
96
|
+
}): ControllerFetchFn
|
|
97
|
+
|
|
98
|
+
export declare const useViewFetch: ControllerFetchFn
|
|
99
|
+
export declare const useStructureFetch: ControllerFetchFn
|
|
100
|
+
/** Envelope v2 auspacken (v1-Antworten kommen unveraendert zurueck). */
|
|
101
|
+
export declare function normalizeEnvelope(body: unknown): unknown
|
|
102
|
+
/** Skel-Struktur glaetten — akzeptiert Dict- wie Paar-Listen-Form. */
|
|
103
|
+
export declare function normalizeStructure(structure: unknown): Record<string, Record<string, unknown>>
|
|
104
|
+
export declare const useAddFetch: ControllerFetchFn
|
|
105
|
+
export declare const useEditFetch: ControllerFetchFn
|
|
106
|
+
export declare const useDeleteFetch: ControllerFetchFn
|
|
107
|
+
/** List & Tree: `{ key, ...values }` / `{ skelType, key, parententry, ...values }` */
|
|
108
|
+
export declare const useCloneFetch: ControllerFetchFn
|
|
109
|
+
/** List only */
|
|
110
|
+
export declare const usePreviewFetch: ControllerFetchFn
|
|
111
|
+
/** Tree only: `{ skelType, key, parentNode, sortindex? }` */
|
|
112
|
+
export declare const useMoveFetch: ControllerFetchFn
|
|
113
|
+
/** Tree only: GET, resolves to `Array<{ name: string; key: string }>` */
|
|
114
|
+
export declare const useListRootNodesFetch: ControllerFetchFn
|
|
115
|
+
|
|
116
|
+
// ─── Config store (/vi/config) ────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
export interface ConfigStoreState {
|
|
119
|
+
/** public `conf.admin.*` settings with dotted keys, e.g. "admin.name" */
|
|
120
|
+
configuration: Record<string, any>
|
|
121
|
+
/** admin/root only: `{ [modulePath]: adminInfo }`, null until loaded */
|
|
122
|
+
modules: Record<string, Record<string, any>> | null
|
|
123
|
+
/** admin/root only: core version `[major, minor, patch, extra]` */
|
|
124
|
+
version: (number | string | null)[] | null
|
|
125
|
+
status: "unknown" | "loading" | "public" | "admin" | "error"
|
|
126
|
+
error: Error | null
|
|
127
|
+
renderer: string
|
|
128
|
+
/** access flags gating the module tree (set via fetchConfig({ user }) / setAccess) */
|
|
129
|
+
access: string[]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** A node of the module tree built from `modules` + `admin.module.groups`. */
|
|
133
|
+
export interface ModuleNode {
|
|
134
|
+
type: "group" | "module" | "view"
|
|
135
|
+
/** "shop.order" | "shop.order#1" (view) | "group:shop" */
|
|
136
|
+
key: string
|
|
137
|
+
/** group key for type "group", else null */
|
|
138
|
+
groupKey: string | null
|
|
139
|
+
/** dotted module path; null for groups */
|
|
140
|
+
module: string | null
|
|
141
|
+
/** last path segment: "shop.order" → "order" */
|
|
142
|
+
baseModule: string | null
|
|
143
|
+
name: string
|
|
144
|
+
icon: string | null
|
|
145
|
+
handler: string | null
|
|
146
|
+
handlerType: "list" | "tree" | "hierarchy" | "singleton" | null
|
|
147
|
+
/** `group` of a list.grouped view */
|
|
148
|
+
group?: string | null
|
|
149
|
+
display: "visible" | "hidden" | "group" | string
|
|
150
|
+
sortIndex?: number
|
|
151
|
+
/** user may use the module (add/edit/delete right, root, …) */
|
|
152
|
+
hasAccess: boolean
|
|
153
|
+
/** node should be rendered in a navigation */
|
|
154
|
+
visible: boolean
|
|
155
|
+
/** view index below its module; null otherwise */
|
|
156
|
+
view?: number | null
|
|
157
|
+
/** key of the parent node, null at top level */
|
|
158
|
+
parent: string | null
|
|
159
|
+
/** the (merged) adminInfo; never the server object itself */
|
|
160
|
+
info: Record<string, any>
|
|
161
|
+
children: ModuleNode[]
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export declare function buildModuleTree(input?: {
|
|
165
|
+
modules?: Record<string, Record<string, any>> | null
|
|
166
|
+
groups?: Record<string, Record<string, any>> | null
|
|
167
|
+
access?: string[]
|
|
168
|
+
}): ModuleNode[]
|
|
169
|
+
export declare function flattenModuleTree(tree: ModuleNode[]): Record<string, ModuleNode>
|
|
170
|
+
export declare function findModule(
|
|
171
|
+
lookup: Record<string, ModuleNode>,
|
|
172
|
+
module: string,
|
|
173
|
+
view?: number | string | null
|
|
174
|
+
): ModuleNode | null
|
|
175
|
+
export declare function visibleModuleTree(tree: ModuleNode[]): ModuleNode[]
|
|
176
|
+
export declare function hasModuleAccess(
|
|
177
|
+
access: string[],
|
|
178
|
+
module: string,
|
|
179
|
+
options?: { group?: string | null; showWithViewAccess?: boolean }
|
|
180
|
+
): boolean
|
|
181
|
+
export declare function handlerType(handler: string | null | undefined): ModuleNode["handlerType"]
|
|
182
|
+
|
|
183
|
+
export interface ConfigStore {
|
|
184
|
+
state: ConfigStoreState
|
|
185
|
+
isLoaded: boolean
|
|
186
|
+
isAdminLoaded: boolean
|
|
187
|
+
googleClientId: string | null
|
|
188
|
+
hasGoogleLogin: boolean
|
|
189
|
+
language: string | null
|
|
190
|
+
languages: string[]
|
|
191
|
+
moduleNames: string[]
|
|
192
|
+
/** `configuration["admin.module.groups"]` (viur-core: `conf.admin.module_groups`) */
|
|
193
|
+
groups: Record<string, Record<string, any>>
|
|
194
|
+
/** full tree incl. hidden/inaccessible nodes */
|
|
195
|
+
moduleTree: ModuleNode[]
|
|
196
|
+
/** tree pruned to visible nodes — what a navigation renders */
|
|
197
|
+
navigationTree: ModuleNode[]
|
|
198
|
+
/** `{ [key]: node }`; keys "shop.order", "shop.order#1", "group:shop" */
|
|
199
|
+
moduleLookup: Record<string, ModuleNode>
|
|
200
|
+
/** read a setting by dotted key; the `admin.` prefix is optional */
|
|
201
|
+
get<T = any>(key: string, fallback?: T): T
|
|
202
|
+
/** raw adminInfo of a module as served by /vi/config */
|
|
203
|
+
module(name: string): Record<string, any> | null
|
|
204
|
+
/** resolved tree node of a module or one of its views (index | group | name) */
|
|
205
|
+
moduleNode(name: string, view?: number | string | null): ModuleNode | null
|
|
206
|
+
/** set the access flags used for the tree (usually `user.access`) */
|
|
207
|
+
setAccess(access: string[] | null | undefined): void
|
|
208
|
+
configure(options?: { renderer?: string }): void
|
|
209
|
+
/**
|
|
210
|
+
* Load `/vi/config`. Without `user`: always requests (call before rendering
|
|
211
|
+
* the login screen). With `user`: only requests when the user has admin/root
|
|
212
|
+
* rights (the module part), otherwise it is skipped.
|
|
213
|
+
*/
|
|
214
|
+
fetchConfig(options?: { user?: Record<string, any> | null; force?: boolean }): Promise<ConfigStoreState>
|
|
215
|
+
reset(): void
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export declare function useConfigStore(): ConfigStore
|
|
219
|
+
|
|
220
|
+
// ─── Message store (user feedback) ────────────────────────────────────────────
|
|
221
|
+
|
|
222
|
+
export type MessageType = "success" | "error" | "warning" | "info"
|
|
223
|
+
|
|
224
|
+
export interface Message {
|
|
225
|
+
id: number
|
|
226
|
+
type: MessageType
|
|
227
|
+
/** translation key, e.g. "messages.request.edit.success" */
|
|
228
|
+
code: string | null
|
|
229
|
+
/** generic translation key, e.g. "messages.request.default.success" */
|
|
230
|
+
fallbackCode: string
|
|
231
|
+
/** ready-made text (e.g. a server error message); wins over `code` in UIs */
|
|
232
|
+
text: string | null
|
|
233
|
+
params: Record<string, any>
|
|
234
|
+
/** controller path, dotted ("user", "shop.order") */
|
|
235
|
+
module: string | null
|
|
236
|
+
/** envelope action / endpoint ("edit", "login") */
|
|
237
|
+
action: string | null
|
|
238
|
+
key: string | null
|
|
239
|
+
/** envelope errors of a rejected request */
|
|
240
|
+
errors: any[]
|
|
241
|
+
/** HTTP status of a failed request */
|
|
242
|
+
status: number | null
|
|
243
|
+
/** ms until auto-dismiss, 0 = sticky */
|
|
244
|
+
timeout: number
|
|
245
|
+
timestamp: number
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export type MessageInput = Partial<Omit<Message, "id" | "timestamp">>
|
|
249
|
+
|
|
250
|
+
export interface MessageStore {
|
|
251
|
+
state: { messages: Message[]; timeouts: Record<MessageType, number>; max: number }
|
|
252
|
+
latest: Message | null
|
|
253
|
+
errors: Message[]
|
|
254
|
+
count: number
|
|
255
|
+
configure(options?: { timeouts?: Partial<Record<MessageType, number>>; max?: number }): void
|
|
256
|
+
push(message: MessageInput): Message
|
|
257
|
+
success(codeOrMessage: string | MessageInput, extra?: MessageInput): Message
|
|
258
|
+
error(codeOrMessage: string | MessageInput, extra?: MessageInput): Message
|
|
259
|
+
warning(codeOrMessage: string | MessageInput, extra?: MessageInput): Message
|
|
260
|
+
info(codeOrMessage: string | MessageInput, extra?: MessageInput): Message
|
|
261
|
+
remove(id: number): void
|
|
262
|
+
clear(type?: MessageType | null): void
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export declare function useMessageStore(): MessageStore
|
|
266
|
+
/** The message store if the app installed Pinia, else null. */
|
|
267
|
+
export declare function getMessageStore(): MessageStore | null
|
|
268
|
+
/** Push a message when a store exists; no-op (null) otherwise. */
|
|
269
|
+
export declare function notify(message: MessageInput): Message | null
|
|
270
|
+
export declare function canAccessAdminConfig(user: Record<string, any> | null | undefined): boolean
|
|
271
|
+
|
|
272
|
+
// ─── Color store (brand color from the configuration) ─────────────────────────
|
|
273
|
+
|
|
274
|
+
export interface ColorStore {
|
|
275
|
+
/** Set to override the configuration; null → `admin.color.primary` / `.secondary`. */
|
|
276
|
+
state: { primaryColor: string | null; secondaryColor: string | null }
|
|
277
|
+
/** WebAwesome brand tokens (`--wa-color-brand-95…05`, `--wa-color-brand`, `-on`); empty without a valid color */
|
|
278
|
+
brandColors: Record<string, string>
|
|
279
|
+
/** `hsl(…)` with hue/saturation of the color; `lightness` (%) replaces its lightness, 0 keeps it */
|
|
280
|
+
getPrimaryColor(lightness?: number): string | null
|
|
281
|
+
getSecondaryColor(lightness?: number): string | null
|
|
282
|
+
getAlphaColor(color: "primaryColor" | "secondaryColor", lightness: number, alpha: number): string | null
|
|
283
|
+
/** Writes the brand palette into `doc` (a `<style>` in the head) and keeps it in sync; returns stop() */
|
|
284
|
+
applyBrandColor(doc?: Document): () => void
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export declare function useColorStore(): ColorStore
|
|
288
|
+
/** "#rrggbb" / "#rgb" → [h, s, l] (degrees, %, %); null for anything else */
|
|
289
|
+
export declare function hexToHsl(color: unknown): [number, number, number] | null
|
|
290
|
+
/** Lightness (HSL, %) per WebAwesome brand step, lightest first */
|
|
291
|
+
export declare const BRAND_LIGHTNESS: [string, number][]
|
|
292
|
+
|
|
293
|
+
// ─── File Upload ──────────────────────────────────────────────────────────────
|
|
294
|
+
|
|
295
|
+
export interface UploadFileOptions {
|
|
296
|
+
target?: string
|
|
297
|
+
publicUpload?: boolean
|
|
298
|
+
renderer?: string
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export declare function uploadFile(file: File, options?: UploadFileOptions): Promise<Record<string, any>>
|
|
302
|
+
export declare function resetState(): Promise<void>
|
|
303
|
+
|
|
304
|
+
export declare class HTTPError extends Error {
|
|
305
|
+
statusCode: number
|
|
306
|
+
statusText: string
|
|
307
|
+
response: Response | null
|
|
308
|
+
constructor(statusCode: number, statusText: string, message?: string, response?: Response | null)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// ─── Skel Utilities ───────────────────────────────────────────────────────────
|
|
312
|
+
|
|
313
|
+
export declare function downloadUrlFor(bone: any, thumbnail?: boolean, renderer?: string): string | null
|
|
314
|
+
export declare function serveUrlFor(
|
|
315
|
+
servingurl: string,
|
|
316
|
+
size?: number | null,
|
|
317
|
+
filename?: string | null,
|
|
318
|
+
options?: string,
|
|
319
|
+
download?: boolean
|
|
320
|
+
): string
|
|
321
|
+
|
|
322
|
+
// ─── Skel Utilities ───────────────────────────────────────────────────────────
|
|
323
|
+
|
|
324
|
+
// ─── Low-level fetch helpers ──────────────────────────────────────────────────
|
|
325
|
+
|
|
326
|
+
export declare function get(url: string): Promise<Response>
|
|
327
|
+
export declare function post(
|
|
328
|
+
url: string,
|
|
329
|
+
data?: Record<string, any>,
|
|
330
|
+
headers?: Record<string, string> | null
|
|
331
|
+
): Promise<Response>
|
|
332
|
+
export declare function securePost(
|
|
333
|
+
url: string,
|
|
334
|
+
data?: Record<string, any>,
|
|
335
|
+
headers?: Record<string, string> | null,
|
|
336
|
+
renderer?: string
|
|
337
|
+
): Promise<Response>
|
|
338
|
+
|
|
339
|
+
// ─── Skel Utilities ───────────────────────────────────────────────────────────
|
|
340
|
+
|
|
341
|
+
export declare function skelDataToFormData(
|
|
342
|
+
skel: Record<string, any>,
|
|
343
|
+
structure: Record<string, any>
|
|
344
|
+
): { [field: string]: any }[]
|
|
345
|
+
|
|
346
|
+
// ─── Translations ─────────────────────────────────────────────────────────────
|
|
347
|
+
|
|
348
|
+
/** Message-Bäume der Paket-Komponenten — in die vue-i18n-Messages der App mergen
|
|
349
|
+
* (vue-i18n ist Voraussetzung; die Komponenten übersetzen mit t() ohne Fallbacks). */
|
|
350
|
+
export declare const deTranslations: Record<string, any>
|
|
351
|
+
export declare const enTranslations: Record<string, any>
|
package/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Request
|
|
2
|
+
export {
|
|
3
|
+
useListFetch,
|
|
4
|
+
useListFetchAll,
|
|
5
|
+
useViewFetch,
|
|
6
|
+
useAddFetch,
|
|
7
|
+
useEditFetch,
|
|
8
|
+
useDeleteFetch,
|
|
9
|
+
useCloneFetch,
|
|
10
|
+
usePreviewFetch,
|
|
11
|
+
useMoveFetch,
|
|
12
|
+
useListRootNodesFetch,
|
|
13
|
+
useTreeFetch,
|
|
14
|
+
useStructureFetch,
|
|
15
|
+
uploadFile,
|
|
16
|
+
downloadUrlFor,
|
|
17
|
+
serveUrlFor,
|
|
18
|
+
skelDataToFormData,
|
|
19
|
+
normalizeEnvelope,
|
|
20
|
+
normalizeStructure,
|
|
21
|
+
resetState,
|
|
22
|
+
HTTPError,
|
|
23
|
+
createControllerFetch,
|
|
24
|
+
useConfigStore,
|
|
25
|
+
canAccessAdminConfig,
|
|
26
|
+
buildModuleTree,
|
|
27
|
+
flattenModuleTree,
|
|
28
|
+
findModule,
|
|
29
|
+
visibleModuleTree,
|
|
30
|
+
hasModuleAccess,
|
|
31
|
+
handlerType,
|
|
32
|
+
useMessageStore,
|
|
33
|
+
getMessageStore,
|
|
34
|
+
notify,
|
|
35
|
+
} from "./src/request/index.js"
|
|
36
|
+
|
|
37
|
+
// Theme (brand color from the configuration)
|
|
38
|
+
export { useColorStore, hexToHsl, BRAND_LIGHTNESS } from "./src/theme/colorStore.js"
|
|
39
|
+
|
|
40
|
+
// Translations (Komponenten dieses Pakets; in die vue-i18n-Instanz der App mergen —
|
|
41
|
+
// vue-i18n ist Voraussetzung, die Komponenten übersetzen mit t() ohne Fallbacks)
|
|
42
|
+
export { default as deTranslations } from "./src/translations/de.js"
|
|
43
|
+
export { default as enTranslations } from "./src/translations/en.js"
|
|
44
|
+
|
|
45
|
+
// Anzeige von Bone-Werten (vormals aus dem Legacy-Paket)
|
|
46
|
+
export { default as boneLogic } from "./src/forms/bones/view/boneLogic.js"
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "viur-ui",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/viur-framework/viur-ui"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./index.js",
|
|
10
|
+
"types": "./index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"src",
|
|
13
|
+
"index.js",
|
|
14
|
+
"index.d.ts"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"destr": "^2.0.5",
|
|
18
|
+
"json-editor-vue": "^0.18.1",
|
|
19
|
+
"libphonenumber-js": "^1.12.41",
|
|
20
|
+
"logics-js": "^0.4.1",
|
|
21
|
+
"vue-draggable-plus": "^0.6.1",
|
|
22
|
+
"vue-json-pretty": "^2.6.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@ckeditor/ckeditor5-vue": "^7.3.0",
|
|
26
|
+
"@codemirror/language-data": "^6.5.2",
|
|
27
|
+
"@viur/shoelace": ">=1.0.0-0",
|
|
28
|
+
"@viur/webawesome": ">=0.10.0",
|
|
29
|
+
"@vueuse/core": "^12.4.0",
|
|
30
|
+
"ckeditor5": "^45.2.0",
|
|
31
|
+
"codemirror": "^6.0.1",
|
|
32
|
+
"pinia": "^2.3.0 || ^3.0.0",
|
|
33
|
+
"vue": "^3.3.0",
|
|
34
|
+
"vue-i18n": "^11.0.1",
|
|
35
|
+
"vue-router": "^4.5.0"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"icons": "npx wa-icons . ./src/public/assets/icons",
|
|
39
|
+
"test": "vitest",
|
|
40
|
+
"test:run": "vitest run",
|
|
41
|
+
"story:dev": "histoire dev",
|
|
42
|
+
"story:build": "histoire build",
|
|
43
|
+
"histoire:legacy": "histoire dev --config histoire.legacy.config.js",
|
|
44
|
+
"test:contract": "playwright test --config tests/contract/playwright.config.ts",
|
|
45
|
+
"lint": "eslint .",
|
|
46
|
+
"format:check": "prettier --check .",
|
|
47
|
+
"prepare": "lefthook install"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@histoire/plugin-vue": "^1.0.0-beta.1",
|
|
51
|
+
"@playwright/test": "^1.59.1",
|
|
52
|
+
"@vitejs/plugin-vue": "^6.0.6",
|
|
53
|
+
"@vueuse/core": "^14.2.1",
|
|
54
|
+
"eslint": "^10.2.1",
|
|
55
|
+
"eslint-config-prettier": "^10.1.8",
|
|
56
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
57
|
+
"eslint-plugin-vue": "^10.8.0",
|
|
58
|
+
"fake-indexeddb": "^6.2.5",
|
|
59
|
+
"globals": "^17.5.0",
|
|
60
|
+
"happy-dom": "^20.9.0",
|
|
61
|
+
"histoire": "^1.0.0-beta.1",
|
|
62
|
+
"lefthook": "^2.1.6",
|
|
63
|
+
"prettier": "^3.8.3",
|
|
64
|
+
"vite": "^7.3.0",
|
|
65
|
+
"vitest": "^4.1.4",
|
|
66
|
+
"vue": "^3.5.32",
|
|
67
|
+
"vue-component-meta": "^3.2.7",
|
|
68
|
+
"vue-docgen-api": "^4.79.2"
|
|
69
|
+
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@ckeditor/ckeditor5-vue": {
|
|
72
|
+
"optional": true
|
|
73
|
+
},
|
|
74
|
+
"@codemirror/language-data": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"ckeditor5": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"codemirror": {
|
|
81
|
+
"optional": true
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|