@sfxcode/nuxt-ui-mongocamp 1.1.0
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/LICENSE +21 -0
- package/README.md +308 -0
- package/dist/module.d.mts +8 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +35 -0
- package/dist/runtime/components/MongocampAccount.d.vue.ts +3 -0
- package/dist/runtime/components/MongocampAccount.vue +197 -0
- package/dist/runtime/components/MongocampAccount.vue.d.ts +3 -0
- package/dist/runtime/components/MongocampCollectionData.d.vue.ts +6 -0
- package/dist/runtime/components/MongocampCollectionData.vue +511 -0
- package/dist/runtime/components/MongocampCollectionData.vue.d.ts +6 -0
- package/dist/runtime/components/MongocampCollectionInfos.d.vue.ts +9 -0
- package/dist/runtime/components/MongocampCollectionInfos.vue +393 -0
- package/dist/runtime/components/MongocampCollectionInfos.vue.d.ts +9 -0
- package/dist/runtime/components/MongocampCollections.d.vue.ts +7 -0
- package/dist/runtime/components/MongocampCollections.vue +231 -0
- package/dist/runtime/components/MongocampCollections.vue.d.ts +7 -0
- package/dist/runtime/components/MongocampDatabases.d.vue.ts +3 -0
- package/dist/runtime/components/MongocampDatabases.vue +112 -0
- package/dist/runtime/components/MongocampDatabases.vue.d.ts +3 -0
- package/dist/runtime/components/MongocampJobs.d.vue.ts +3 -0
- package/dist/runtime/components/MongocampJobs.vue +354 -0
- package/dist/runtime/components/MongocampJobs.vue.d.ts +3 -0
- package/dist/runtime/components/MongocampLogin.d.vue.ts +3 -0
- package/dist/runtime/components/MongocampLogin.vue +63 -0
- package/dist/runtime/components/MongocampLogin.vue.d.ts +3 -0
- package/dist/runtime/components/MongocampRoleGrants.d.vue.ts +6 -0
- package/dist/runtime/components/MongocampRoleGrants.vue +276 -0
- package/dist/runtime/components/MongocampRoleGrants.vue.d.ts +6 -0
- package/dist/runtime/components/MongocampRoles.d.vue.ts +6 -0
- package/dist/runtime/components/MongocampRoles.vue +272 -0
- package/dist/runtime/components/MongocampRoles.vue.d.ts +6 -0
- package/dist/runtime/components/MongocampUsers.d.vue.ts +3 -0
- package/dist/runtime/components/MongocampUsers.vue +320 -0
- package/dist/runtime/components/MongocampUsers.vue.d.ts +3 -0
- package/dist/runtime/components/MongocampVersion.d.vue.ts +3 -0
- package/dist/runtime/components/MongocampVersion.vue +25 -0
- package/dist/runtime/components/MongocampVersion.vue.d.ts +3 -0
- package/dist/runtime/composables/useMongocampAccount.d.ts +7 -0
- package/dist/runtime/composables/useMongocampAccount.js +28 -0
- package/dist/runtime/composables/useMongocampAdmin.d.ts +14 -0
- package/dist/runtime/composables/useMongocampAdmin.js +48 -0
- package/dist/runtime/composables/useMongocampBucket.d.ts +15 -0
- package/dist/runtime/composables/useMongocampBucket.js +109 -0
- package/dist/runtime/composables/useMongocampCollection.d.ts +17 -0
- package/dist/runtime/composables/useMongocampCollection.js +12 -0
- package/dist/runtime/composables/useMongocampDocument.d.ts +13 -0
- package/dist/runtime/composables/useMongocampDocument.js +18 -0
- package/dist/runtime/composables/useMongocampDynamicForm.d.ts +14 -0
- package/dist/runtime/composables/useMongocampDynamicForm.js +231 -0
- package/dist/runtime/composables/useMongocampIndex.d.ts +9 -0
- package/dist/runtime/composables/useMongocampIndex.js +23 -0
- package/dist/runtime/composables/useMongocampJobs.d.ts +9 -0
- package/dist/runtime/composables/useMongocampJobs.js +25 -0
- package/dist/runtime/composables/useMongocampQuery.d.ts +99 -0
- package/dist/runtime/composables/useMongocampQuery.js +108 -0
- package/dist/runtime/composables/useMongocampQueryBuilder.d.ts +30 -0
- package/dist/runtime/composables/useMongocampQueryBuilder.js +112 -0
- package/dist/runtime/composables/useMongocampSchema.d.ts +14 -0
- package/dist/runtime/composables/useMongocampSchema.js +142 -0
- package/dist/runtime/composables/useMongocampSystem.d.ts +12 -0
- package/dist/runtime/composables/useMongocampSystem.js +21 -0
- package/dist/runtime/plugin.d.ts +6 -0
- package/dist/runtime/plugin.js +23 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/types.d.mts +3 -0
- package/package.json +99 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 sfxcode
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# nuxt-ui-mongocamp
|
|
2
|
+
|
|
3
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![License][license-src]][license-href]
|
|
6
|
+
[![Nuxt][nuxt-src]][nuxt-href]
|
|
7
|
+
[![Docs][docs-src]][docs-href]
|
|
8
|
+
|
|
9
|
+
A Nuxt module that wraps [`@sfxcode/nuxt-mongocamp-server`](https://www.npmjs.com/package/@sfxcode/nuxt-mongocamp-server) with ready-made UI components, composables, and a runtime plugin. Add the module to your Nuxt app and get MongoCamp authentication, user/role management, and collection access out of the box — built on [Nuxt UI](https://ui.nuxt.com) and [FormKit](https://formkit.com).
|
|
10
|
+
|
|
11
|
+
- [✨ Release Notes](/CHANGELOG.md)
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Auth middleware** — global route guard that protects `/secured/**` (login required) and `/admin/**` (admin role required)
|
|
16
|
+
- **Ready-made components** — login form, user/role management tables, collection browser with stats and paginated data table, server version badge
|
|
17
|
+
- **FormKit-powered forms** — schema-driven forms via `@sfxcode/nuxt-ui-formkit` with `nuxtUIInput`, `nuxtUISwitch`, `nuxtUIListbox`, and `nuxtUISelectMenu` inputs
|
|
18
|
+
- **Composables** — `useMongocampAdmin`, `useMongocampCollection`, `useMongocampDocument`, `useMongocampSchema` auto-imported into your app
|
|
19
|
+
- **Zero extra config** — peer modules (`@nuxt/ui`, `@formkit/nuxt`, `unocss-nuxt-ui`) are declared as `moduleDependencies` and configured automatically
|
|
20
|
+
|
|
21
|
+
## Module Dependencies
|
|
22
|
+
|
|
23
|
+
These modules are declared as `moduleDependencies` and are automatically set up — you do not need to add them manually to your `nuxt.config.ts`:
|
|
24
|
+
|
|
25
|
+
| Module | Purpose |
|
|
26
|
+
|---|---|
|
|
27
|
+
| [`@nuxt/ui`](https://ui.nuxt.com) | Component library (UTable, UModal, UBadge, UPageCard, …) |
|
|
28
|
+
| [`unocss-nuxt-ui`](https://www.npmjs.com/package/unocss-nuxt-ui) | UnoCSS preset that matches Nuxt UI's design tokens |
|
|
29
|
+
| [`@formkit/nuxt`](https://formkit.com/getting-started/installation#with-nuxt) | FormKit core integration for Nuxt |
|
|
30
|
+
| [`@sfxcode/nuxt-ui-formkit`](https://www.npmjs.com/package/@sfxcode/nuxt-ui-formkit) | Nuxt UI input types for FormKit (`nuxtUIInput`, `nuxtUISwitch`, `nuxtUIListbox`, `nuxtUISelectMenu`) |
|
|
31
|
+
| [`@sfxcode/nuxt-mongocamp-server`](https://www.npmjs.com/package/@sfxcode/nuxt-mongocamp-server) | MongoCamp REST API client, auth state, and `useMongocampApi()` / `useMongocampAuth()` composables |
|
|
32
|
+
|
|
33
|
+
## Quick Setup
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install nuxt-ui-mongocamp
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Add the module to `nuxt.config.ts`:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
export default defineNuxtConfig({
|
|
43
|
+
modules: ['nuxt-ui-mongocamp'],
|
|
44
|
+
|
|
45
|
+
mongocamp: {
|
|
46
|
+
url: process.env.MONGOCAMP_URL,
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The `mongocamp` key is forwarded to `@sfxcode/nuxt-mongocamp-server`. Set `MONGOCAMP_URL` (and optionally `MONGOCAMP_ADMIN_USER` / `MONGOCAMP_ADMIN_PASSWORD`) in your `.env` file.
|
|
52
|
+
|
|
53
|
+
## Components
|
|
54
|
+
|
|
55
|
+
All components are auto-imported.
|
|
56
|
+
|
|
57
|
+
### `<MongocampLogin />`
|
|
58
|
+
|
|
59
|
+
FormKit schema-driven login form. Persists the last user ID in a cookie (`mongocamp_login`) and redirects to `/secured` on success.
|
|
60
|
+
|
|
61
|
+
```vue
|
|
62
|
+
<template>
|
|
63
|
+
<MongocampLogin />
|
|
64
|
+
</template>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `<MongocampUsers />`
|
|
68
|
+
|
|
69
|
+
Full CRUD table for managing users — create, edit (roles via transfer listbox, password change), and delete, all via modal dialogs. Includes a server-side debounced search input and sortable column headers.
|
|
70
|
+
|
|
71
|
+
```vue
|
|
72
|
+
<template>
|
|
73
|
+
<MongocampUsers />
|
|
74
|
+
</template>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### `<MongocampRoles />`
|
|
78
|
+
|
|
79
|
+
Full CRUD table for managing roles — create, edit (admin flag, collection grants), and delete. Includes a server-side debounced search input and sortable column headers.
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<template>
|
|
83
|
+
<MongocampRoles />
|
|
84
|
+
</template>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### `<MongocampRoleGrants />`
|
|
88
|
+
|
|
89
|
+
Per-role collection grant management — lists grants for a named role, with add/edit/delete. Filters the collection picker to exclude already-granted collections.
|
|
90
|
+
|
|
91
|
+
```vue
|
|
92
|
+
<template>
|
|
93
|
+
<MongocampRoleGrants role-name="myRole" />
|
|
94
|
+
</template>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### `<MongocampCollections />`
|
|
98
|
+
|
|
99
|
+
Table of all collections with document count, storage size, and index count. Each row links to the collection info and data pages. Includes a client-side filter input and sortable column headers.
|
|
100
|
+
|
|
101
|
+
| Prop | Type | Default | Description |
|
|
102
|
+
|---|---|---|---|
|
|
103
|
+
| `infoPath` | `string` | `/secured/admin/collections` | Base path for the info page link |
|
|
104
|
+
| `dataPath` | `string` | `/secured/admin/collections` | Base path for the data page link (`<dataPath>/<name>/data`) |
|
|
105
|
+
|
|
106
|
+
```vue
|
|
107
|
+
<template>
|
|
108
|
+
<MongocampCollections />
|
|
109
|
+
</template>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### `<MongocampCollectionInfos />`
|
|
113
|
+
|
|
114
|
+
Stat-card grid for a single collection — document count, data size, storage size, avg doc size, index count, total index size, and a per-index size table.
|
|
115
|
+
|
|
116
|
+
```vue
|
|
117
|
+
<template>
|
|
118
|
+
<MongocampCollectionInfos collection-name="myCollection" />
|
|
119
|
+
</template>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### `<MongocampCollectionData />`
|
|
123
|
+
|
|
124
|
+
Schema-driven paginated data table for a collection.
|
|
125
|
+
|
|
126
|
+
- **Columns** derived from the collection's JSON schema; falls back to first-row key derivation when no schema properties exist. Column order: `_id` first, `metaData` last, all others sorted A–Z.
|
|
127
|
+
- **Sorting** — clickable column headers trigger server-side sort via the MongoCamp API (`field` / `-field`).
|
|
128
|
+
- **Filtering** — debounced search input sends a Lucene query (`col1: *term* OR col2: *term*`) across all string-typed columns to the API; disabled until the schema is loaded.
|
|
129
|
+
- **Cell rendering**:
|
|
130
|
+
- `date-time` columns and MongoDB `$date` extended JSON → locale-formatted date string
|
|
131
|
+
- MongoDB `$oid` → monospaced ID string
|
|
132
|
+
- `metaData` objects (with `created`/`updated` fields) → structured `created / updated / by` rows
|
|
133
|
+
- All other objects and arrays → icon button (`{}` / list); click opens a modal with pretty-printed JSON in a `<pre>` tag
|
|
134
|
+
- Includes a reload button and paginated footer.
|
|
135
|
+
|
|
136
|
+
```vue
|
|
137
|
+
<template>
|
|
138
|
+
<MongocampCollectionData collection-name="myCollection" />
|
|
139
|
+
</template>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `<MongocampVersion />`
|
|
143
|
+
|
|
144
|
+
Displays the connected MongoCamp server name and version as a `UBadge`. Shows a neutral "unavailable" badge when the server cannot be reached.
|
|
145
|
+
|
|
146
|
+
```vue
|
|
147
|
+
<template>
|
|
148
|
+
<MongocampVersion />
|
|
149
|
+
</template>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Composables
|
|
153
|
+
|
|
154
|
+
All composables are auto-imported.
|
|
155
|
+
|
|
156
|
+
### `useMongocampAdmin()`
|
|
157
|
+
|
|
158
|
+
Wraps the `adminApi` and `collectionApi` for user and role management.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
const {
|
|
162
|
+
listUsers, // (filter?: string) => Promise<UserProfile[]>
|
|
163
|
+
addUser, // (userId, password, apiKey?, roles?) => Promise<UserProfile>
|
|
164
|
+
deleteUser, // (userId) => Promise<void>
|
|
165
|
+
updateUserRoles, // (userId, roles) => Promise<UserProfile>
|
|
166
|
+
updateUserPassword, // (userId, password) => Promise<void>
|
|
167
|
+
listRoles, // (filter?: string) => Promise<Role[]>
|
|
168
|
+
addRole, // (name, isAdmin?, collectionGrants?) => Promise<Role>
|
|
169
|
+
updateRole, // (roleName, isAdmin, collectionGrants?) => Promise<Role>
|
|
170
|
+
deleteRole, // (roleName) => Promise<void>
|
|
171
|
+
listCollections, // () => Promise<string[]>
|
|
172
|
+
} = useMongocampAdmin()
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### `useMongocampCollection()`
|
|
176
|
+
|
|
177
|
+
Reactive state for paginated collection queries.
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
const {
|
|
181
|
+
filter, // Ref<string | undefined> — MongoDB filter expression
|
|
182
|
+
sort, // Ref<string[] | undefined> — sort fields
|
|
183
|
+
projection, // Ref<string[] | undefined> — field projection
|
|
184
|
+
pagination, // Ref<{ pageIndex: number, pageSize: number }>
|
|
185
|
+
total, // Ref<number> — total document count
|
|
186
|
+
} = useMongocampCollection()
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### `useMongocampDocument()`
|
|
190
|
+
|
|
191
|
+
Helpers for document-level operations.
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
const {
|
|
195
|
+
ensureMetaData, // <T>(data: T) => T — stamps createdBy/updatedBy/timestamps from logged-in user
|
|
196
|
+
updateFromPartial, // <T>(obj: T, updates: Partial<T>) => T
|
|
197
|
+
} = useMongocampDocument()
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `useMongocampSchema()`
|
|
201
|
+
|
|
202
|
+
Converts a `JsonSchemaDefinition` to typed table column definitions. Used internally by `MongocampCollectionData`.
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const { schemaToColumnDefinition } = useMongocampSchema()
|
|
206
|
+
|
|
207
|
+
// schemaToColumnDefinition(definition, fields) => ColumnDefinition[]
|
|
208
|
+
// ColumnDefinition: { columnName, columnKey, columnType }
|
|
209
|
+
// columnType: 'string' | 'number' | 'date-time'
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Fields are sorted with `_id` first, `metaData` last, and all other fields alphabetically.
|
|
213
|
+
|
|
214
|
+
## Route Protection
|
|
215
|
+
|
|
216
|
+
The module registers a global route middleware at startup:
|
|
217
|
+
|
|
218
|
+
| Path pattern | Requirement |
|
|
219
|
+
|---|---|
|
|
220
|
+
| `/secured/**` | User must be logged in; redirects to `/` otherwise |
|
|
221
|
+
| `/admin/**` or `/secured/admin/**` | User must be logged in **and** have the admin role; redirects to `/secured` otherwise |
|
|
222
|
+
| `/logout` | Calls `logout()` and redirects to `/` |
|
|
223
|
+
|
|
224
|
+
## Runtime Plugin
|
|
225
|
+
|
|
226
|
+
The plugin provides `$mongocampVersion` (a `Ref` to the server's version info) via `useNuxtApp()`:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
const { $mongocampVersion } = useNuxtApp()
|
|
230
|
+
// $mongocampVersion.value?.name
|
|
231
|
+
// $mongocampVersion.value?.version
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Configuration
|
|
235
|
+
|
|
236
|
+
The module's own config key is `nuxtUiMongocamp` (currently no options). The MongoCamp server is configured under the `mongocamp` key (provided by `@sfxcode/nuxt-mongocamp-server`):
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
mongocamp: {
|
|
240
|
+
url: 'https://your-mongocamp-server',
|
|
241
|
+
paginationSize: 500, // default: 500
|
|
242
|
+
refreshToken: true, // default: true
|
|
243
|
+
tokenRefreshIntervall: 5000, // ms, default: 5000
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Contribution
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Install dependencies
|
|
251
|
+
pnpm install
|
|
252
|
+
|
|
253
|
+
# Build stubs + prepare the playground (run once after clone)
|
|
254
|
+
pnpm run dev:prepare
|
|
255
|
+
|
|
256
|
+
# Start playground dev server
|
|
257
|
+
pnpm run dev
|
|
258
|
+
|
|
259
|
+
# Lint
|
|
260
|
+
pnpm run lint
|
|
261
|
+
|
|
262
|
+
# Run tests (Vitest + @nuxt/test-utils e2e)
|
|
263
|
+
pnpm run test
|
|
264
|
+
pnpm run test:watch
|
|
265
|
+
|
|
266
|
+
# Type-check
|
|
267
|
+
pnpm run test:types
|
|
268
|
+
|
|
269
|
+
# Build for publishing
|
|
270
|
+
pnpm run prepack
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The playground reads `playground/.env` for `MONGOCAMP_URL`, `MONGOCAMP_ADMIN_USER`, and `MONGOCAMP_ADMIN_PASSWORD`.
|
|
274
|
+
|
|
275
|
+
## Documentation
|
|
276
|
+
|
|
277
|
+
Full documentation (guides, components, composables) lives in `docs/` and is built with [VitePress](https://vitepress.dev):
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# Start the docs dev server
|
|
281
|
+
pnpm run docs:dev
|
|
282
|
+
|
|
283
|
+
# Build the static site
|
|
284
|
+
pnpm run docs:build
|
|
285
|
+
|
|
286
|
+
# Preview the built site
|
|
287
|
+
pnpm run docs:preview
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## License
|
|
291
|
+
|
|
292
|
+
[MIT](./LICENSE)
|
|
293
|
+
|
|
294
|
+
<!-- Badges -->
|
|
295
|
+
[npm-version-src]: https://img.shields.io/npm/v/nuxt-ui-mongocamp/latest.svg?style=flat&colorA=020420&colorB=00DC82
|
|
296
|
+
[npm-version-href]: https://npmjs.com/package/nuxt-ui-mongocamp
|
|
297
|
+
|
|
298
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-ui-mongocamp.svg?style=flat&colorA=020420&colorB=00DC82
|
|
299
|
+
[npm-downloads-href]: https://npm.chart.dev/nuxt-ui-mongocamp
|
|
300
|
+
|
|
301
|
+
[license-src]: https://img.shields.io/npm/l/nuxt-ui-mongocamp.svg?style=flat&colorA=020420&colorB=00DC82
|
|
302
|
+
[license-href]: https://npmjs.com/package/nuxt-ui-mongocamp
|
|
303
|
+
|
|
304
|
+
[nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt
|
|
305
|
+
[nuxt-href]: https://nuxt.com
|
|
306
|
+
|
|
307
|
+
[docs-src]: https://img.shields.io/badge/docs-vitepress-020420.svg?style=flat&colorA=020420&colorB=00DC82
|
|
308
|
+
[docs-href]: https://sfxcode.github.io/nuxt-ui-mongocamp/
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, addPlugin, addComponentsDir, addImportsDir } from '@nuxt/kit';
|
|
2
|
+
|
|
3
|
+
const module$1 = defineNuxtModule({
|
|
4
|
+
meta: {
|
|
5
|
+
name: "nuxt-ui-mongocamp",
|
|
6
|
+
configKey: "nuxtUiMongocamp",
|
|
7
|
+
compatibility: {
|
|
8
|
+
nuxt: ">=3.16.0"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
// Default configuration options of the Nuxt module
|
|
12
|
+
defaults: {},
|
|
13
|
+
moduleDependencies: {
|
|
14
|
+
"@nuxt/ui": {},
|
|
15
|
+
"unocss-nuxt-ui": {},
|
|
16
|
+
"@formkit/nuxt": {},
|
|
17
|
+
"@sfxcode/nuxt-ui-formkit": {},
|
|
18
|
+
"@sfxcode/nuxt-mongocamp-server": {
|
|
19
|
+
defaults: {
|
|
20
|
+
paginationSize: 500,
|
|
21
|
+
refreshToken: true,
|
|
22
|
+
tokenRefreshIntervall: 5e3
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
setup(_options, _nuxt) {
|
|
27
|
+
const { resolve } = createResolver(import.meta.url);
|
|
28
|
+
const runtimeDir = resolve("./runtime");
|
|
29
|
+
addPlugin(resolve(runtimeDir, "plugin"));
|
|
30
|
+
addComponentsDir({ path: resolve(runtimeDir, "components") });
|
|
31
|
+
addImportsDir(resolve(runtimeDir, "composables"));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export { module$1 as default };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { reactive, ref, resolveComponent } from "vue";
|
|
3
|
+
import { useMongocampAccount, useToast } from "#imports";
|
|
4
|
+
const { fetchProfile, changePassword, regenerateApiKey } = useMongocampAccount();
|
|
5
|
+
const toast = useToast();
|
|
6
|
+
const UBadge = resolveComponent("UBadge");
|
|
7
|
+
const profile = ref(null);
|
|
8
|
+
const loading = ref(false);
|
|
9
|
+
async function loadProfile() {
|
|
10
|
+
loading.value = true;
|
|
11
|
+
try {
|
|
12
|
+
profile.value = await fetchProfile();
|
|
13
|
+
} finally {
|
|
14
|
+
loading.value = false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const passwordData = ref({ password: "" });
|
|
18
|
+
const passwordSchema = reactive([
|
|
19
|
+
{
|
|
20
|
+
$formkit: "nuxtUIInput",
|
|
21
|
+
name: "password",
|
|
22
|
+
label: "New Password",
|
|
23
|
+
inputType: "password",
|
|
24
|
+
validation: "required|length:3"
|
|
25
|
+
}
|
|
26
|
+
]);
|
|
27
|
+
async function handleChangePassword() {
|
|
28
|
+
const success = await changePassword(passwordData.value.password);
|
|
29
|
+
if (success) {
|
|
30
|
+
passwordData.value = { password: "" };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const isRegenerateModalOpen = ref(false);
|
|
34
|
+
const newApiKey = ref(null);
|
|
35
|
+
function openRegenerateModal() {
|
|
36
|
+
isRegenerateModalOpen.value = true;
|
|
37
|
+
}
|
|
38
|
+
function closeRegenerateModal() {
|
|
39
|
+
isRegenerateModalOpen.value = false;
|
|
40
|
+
}
|
|
41
|
+
async function handleRegenerateApiKey() {
|
|
42
|
+
newApiKey.value = await regenerateApiKey();
|
|
43
|
+
isRegenerateModalOpen.value = false;
|
|
44
|
+
}
|
|
45
|
+
async function copyApiKey() {
|
|
46
|
+
if (!newApiKey.value) return;
|
|
47
|
+
await navigator.clipboard.writeText(newApiKey.value);
|
|
48
|
+
toast.add({ title: "Copied to clipboard", description: "API key copied.", color: "success" });
|
|
49
|
+
}
|
|
50
|
+
function dismissApiKey() {
|
|
51
|
+
newApiKey.value = null;
|
|
52
|
+
}
|
|
53
|
+
loadProfile();
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<template>
|
|
57
|
+
<div class="flex flex-col gap-4">
|
|
58
|
+
<USkeleton
|
|
59
|
+
v-if="loading"
|
|
60
|
+
class="h-32 w-full"
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
<UCard v-else-if="profile">
|
|
64
|
+
<template #header>
|
|
65
|
+
<span class="font-semibold">Account</span>
|
|
66
|
+
</template>
|
|
67
|
+
<div class="flex flex-col gap-3">
|
|
68
|
+
<div>
|
|
69
|
+
<div class="text-sm text-gray-500 dark:text-gray-400">
|
|
70
|
+
User
|
|
71
|
+
</div>
|
|
72
|
+
<div class="text-lg font-medium">
|
|
73
|
+
{{ profile.user }}
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
<div>
|
|
77
|
+
<div class="text-sm text-gray-500 dark:text-gray-400 mb-1">
|
|
78
|
+
Role
|
|
79
|
+
</div>
|
|
80
|
+
<UBadge
|
|
81
|
+
:label="profile.isAdmin ? 'Admin' : 'Standard'"
|
|
82
|
+
:color="profile.isAdmin ? 'error' : 'neutral'"
|
|
83
|
+
variant="subtle"
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
<div>
|
|
87
|
+
<div class="text-sm text-gray-500 dark:text-gray-400 mb-1">
|
|
88
|
+
Roles
|
|
89
|
+
</div>
|
|
90
|
+
<div
|
|
91
|
+
v-if="profile.roles?.length"
|
|
92
|
+
class="flex flex-wrap gap-1"
|
|
93
|
+
>
|
|
94
|
+
<UBadge
|
|
95
|
+
v-for="role in profile.roles"
|
|
96
|
+
:key="role"
|
|
97
|
+
:label="role"
|
|
98
|
+
color="primary"
|
|
99
|
+
variant="subtle"
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
<span
|
|
103
|
+
v-else
|
|
104
|
+
class="text-dimmed"
|
|
105
|
+
>—</span>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</UCard>
|
|
109
|
+
|
|
110
|
+
<UCard>
|
|
111
|
+
<template #header>
|
|
112
|
+
<span class="font-semibold">Change Password</span>
|
|
113
|
+
</template>
|
|
114
|
+
<FUDataEdit
|
|
115
|
+
:data="passwordData"
|
|
116
|
+
:schema="passwordSchema"
|
|
117
|
+
submit-label="Change Password"
|
|
118
|
+
submit-icon="i-lucide-save"
|
|
119
|
+
@data-saved="handleChangePassword"
|
|
120
|
+
/>
|
|
121
|
+
</UCard>
|
|
122
|
+
|
|
123
|
+
<UCard>
|
|
124
|
+
<template #header>
|
|
125
|
+
<span class="font-semibold">API Key</span>
|
|
126
|
+
</template>
|
|
127
|
+
<div
|
|
128
|
+
v-if="newApiKey"
|
|
129
|
+
class="flex flex-col gap-2"
|
|
130
|
+
>
|
|
131
|
+
<p class="text-sm text-warning-500">
|
|
132
|
+
This key is shown only once. Copy it now — it cannot be retrieved again.
|
|
133
|
+
</p>
|
|
134
|
+
<div class="flex items-center gap-2">
|
|
135
|
+
<UInput
|
|
136
|
+
:model-value="newApiKey"
|
|
137
|
+
readonly
|
|
138
|
+
class="flex-1 font-mono text-xs"
|
|
139
|
+
/>
|
|
140
|
+
<UButton
|
|
141
|
+
icon="i-lucide-copy"
|
|
142
|
+
label="Copy"
|
|
143
|
+
color="neutral"
|
|
144
|
+
variant="subtle"
|
|
145
|
+
@click="copyApiKey"
|
|
146
|
+
/>
|
|
147
|
+
</div>
|
|
148
|
+
<UButton
|
|
149
|
+
label="Dismiss"
|
|
150
|
+
color="neutral"
|
|
151
|
+
variant="ghost"
|
|
152
|
+
class="self-start"
|
|
153
|
+
@click="dismissApiKey"
|
|
154
|
+
/>
|
|
155
|
+
</div>
|
|
156
|
+
<div
|
|
157
|
+
v-else
|
|
158
|
+
class="flex items-center justify-between gap-4"
|
|
159
|
+
>
|
|
160
|
+
<p class="text-sm text-gray-500 dark:text-gray-400">
|
|
161
|
+
Regenerating your API key immediately invalidates the current one.
|
|
162
|
+
</p>
|
|
163
|
+
<UButton
|
|
164
|
+
label="Regenerate API Key"
|
|
165
|
+
color="error"
|
|
166
|
+
variant="subtle"
|
|
167
|
+
icon="i-lucide-key-round"
|
|
168
|
+
@click="openRegenerateModal"
|
|
169
|
+
/>
|
|
170
|
+
</div>
|
|
171
|
+
</UCard>
|
|
172
|
+
|
|
173
|
+
<UModal
|
|
174
|
+
v-model:open="isRegenerateModalOpen"
|
|
175
|
+
title="Regenerate API Key"
|
|
176
|
+
:ui="{ footer: 'justify-end' }"
|
|
177
|
+
>
|
|
178
|
+
<template #body>
|
|
179
|
+
<p>Are you sure you want to regenerate your API key? Your current key will stop working immediately.</p>
|
|
180
|
+
</template>
|
|
181
|
+
<template #footer>
|
|
182
|
+
<UButton
|
|
183
|
+
label="Cancel"
|
|
184
|
+
color="neutral"
|
|
185
|
+
variant="ghost"
|
|
186
|
+
@click="closeRegenerateModal"
|
|
187
|
+
/>
|
|
188
|
+
<UButton
|
|
189
|
+
label="Regenerate"
|
|
190
|
+
color="error"
|
|
191
|
+
icon="i-lucide-key-round"
|
|
192
|
+
@click="handleRegenerateApiKey"
|
|
193
|
+
/>
|
|
194
|
+
</template>
|
|
195
|
+
</UModal>
|
|
196
|
+
</div>
|
|
197
|
+
</template>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
collectionName: string;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
declare const _default: typeof __VLS_export;
|
|
6
|
+
export default _default;
|