grantthomas-nuxt 1.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.
Files changed (74) hide show
  1. package/README.md +484 -0
  2. package/dist/module.d.mts +23 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +54 -0
  5. package/dist/runtime/components/AlertDisplay.d.vue.ts +2 -0
  6. package/dist/runtime/components/AlertDisplay.vue +55 -0
  7. package/dist/runtime/components/AlertDisplay.vue.d.ts +2 -0
  8. package/dist/runtime/components/CrudAddressSearchField.d.vue.ts +8 -0
  9. package/dist/runtime/components/CrudAddressSearchField.vue +117 -0
  10. package/dist/runtime/components/CrudAddressSearchField.vue.d.ts +8 -0
  11. package/dist/runtime/components/CrudApiSelectorField.d.vue.ts +30 -0
  12. package/dist/runtime/components/CrudApiSelectorField.vue +99 -0
  13. package/dist/runtime/components/CrudApiSelectorField.vue.d.ts +30 -0
  14. package/dist/runtime/components/CrudConfirmDialog.d.vue.ts +18 -0
  15. package/dist/runtime/components/CrudConfirmDialog.vue +83 -0
  16. package/dist/runtime/components/CrudConfirmDialog.vue.d.ts +18 -0
  17. package/dist/runtime/components/CrudErrorDisplay.d.vue.ts +6 -0
  18. package/dist/runtime/components/CrudErrorDisplay.vue +28 -0
  19. package/dist/runtime/components/CrudErrorDisplay.vue.d.ts +6 -0
  20. package/dist/runtime/components/CrudFilter.d.vue.ts +8 -0
  21. package/dist/runtime/components/CrudFilter.vue +348 -0
  22. package/dist/runtime/components/CrudFilter.vue.d.ts +8 -0
  23. package/dist/runtime/components/CrudFilterList.d.vue.ts +5 -0
  24. package/dist/runtime/components/CrudFilterList.vue +20 -0
  25. package/dist/runtime/components/CrudFilterList.vue.d.ts +5 -0
  26. package/dist/runtime/components/CrudFormDialog.d.vue.ts +31 -0
  27. package/dist/runtime/components/CrudFormDialog.vue +180 -0
  28. package/dist/runtime/components/CrudFormDialog.vue.d.ts +31 -0
  29. package/dist/runtime/components/CrudFormLoader.d.vue.ts +41 -0
  30. package/dist/runtime/components/CrudFormLoader.vue +238 -0
  31. package/dist/runtime/components/CrudFormLoader.vue.d.ts +41 -0
  32. package/dist/runtime/components/CrudListLoader.d.vue.ts +37 -0
  33. package/dist/runtime/components/CrudListLoader.vue +130 -0
  34. package/dist/runtime/components/CrudListLoader.vue.d.ts +37 -0
  35. package/dist/runtime/components/CrudPaginatedLoader.d.vue.ts +70 -0
  36. package/dist/runtime/components/CrudPaginatedLoader.vue +415 -0
  37. package/dist/runtime/components/CrudPaginatedLoader.vue.d.ts +70 -0
  38. package/dist/runtime/components/CrudUploadField.d.vue.ts +23 -0
  39. package/dist/runtime/components/CrudUploadField.vue +311 -0
  40. package/dist/runtime/components/CrudUploadField.vue.d.ts +23 -0
  41. package/dist/runtime/components/CrudUploadFieldSelection.d.vue.ts +18 -0
  42. package/dist/runtime/components/CrudUploadFieldSelection.vue +178 -0
  43. package/dist/runtime/components/CrudUploadFieldSelection.vue.d.ts +18 -0
  44. package/dist/runtime/composables/PublicClientApplicationSingleton.d.ts +5 -0
  45. package/dist/runtime/composables/PublicClientApplicationSingleton.js +14 -0
  46. package/dist/runtime/composables/useAlertService.d.ts +14 -0
  47. package/dist/runtime/composables/useAlertService.js +38 -0
  48. package/dist/runtime/composables/useCrudApi.d.ts +35 -0
  49. package/dist/runtime/composables/useCrudApi.js +314 -0
  50. package/dist/runtime/composables/useCrudConverters.d.ts +33 -0
  51. package/dist/runtime/composables/useCrudConverters.js +202 -0
  52. package/dist/runtime/composables/useListenerService.d.ts +7 -0
  53. package/dist/runtime/composables/useListenerService.js +43 -0
  54. package/dist/runtime/composables/useMSAuth.d.ts +13 -0
  55. package/dist/runtime/composables/useMSAuth.js +125 -0
  56. package/dist/runtime/composables/usePreviousRoute.d.ts +1 -0
  57. package/dist/runtime/composables/usePreviousRoute.js +4 -0
  58. package/dist/runtime/constants/crudAuthInterceptor.d.ts +6 -0
  59. package/dist/runtime/constants/crudAuthInterceptor.js +8 -0
  60. package/dist/runtime/plugin.client.d.ts +2 -0
  61. package/dist/runtime/plugin.client.js +11 -0
  62. package/dist/runtime/plugin.luxon.d.ts +2 -0
  63. package/dist/runtime/plugin.luxon.js +5 -0
  64. package/dist/runtime/plugins/track-previous-route.client.d.ts +2 -0
  65. package/dist/runtime/plugins/track-previous-route.client.js +10 -0
  66. package/dist/runtime/server/api/maps/autocomplete.d.ts +5 -0
  67. package/dist/runtime/server/api/maps/autocomplete.js +12 -0
  68. package/dist/runtime/server/api/maps/geocode.d.ts +5 -0
  69. package/dist/runtime/server/api/maps/geocode.js +12 -0
  70. package/dist/runtime/server/api/maps/places.d.ts +5 -0
  71. package/dist/runtime/server/api/maps/places.js +12 -0
  72. package/dist/runtime/server/tsconfig.json +3 -0
  73. package/dist/types.d.mts +9 -0
  74. package/package.json +58 -0
package/README.md ADDED
@@ -0,0 +1,484 @@
1
+ <!--
2
+ Get your module up and running quickly.
3
+
4
+ Find and replace all on all files (CMD+SHIFT+F):
5
+ - Name: Crud Nuxt
6
+ - Package name: crud-nuxt
7
+ - Description: My new Nuxt module
8
+ -->
9
+
10
+ # Crud Nuxt
11
+
12
+ [![npm version][npm-version-src]][npm-version-href]
13
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
14
+ [![License][license-src]][license-href]
15
+ [![Nuxt][nuxt-src]][nuxt-href]
16
+
17
+ ## Features
18
+
19
+ <!-- Highlight some of the features your module provide here -->
20
+ - &nbsp;Crud operations
21
+ - &nbsp;Components for pagination and filtering
22
+ - &nbsp;Baz
23
+
24
+ ## Quick Setup
25
+
26
+ Install the module to your Nuxt application with one command:
27
+
28
+ ```bash
29
+ npx nuxi module add crud-nuxt
30
+ ```
31
+
32
+ That's it! You can now use My Module in your Nuxt app ✨
33
+
34
+
35
+
36
+
37
+ <details>
38
+ <summary>Local development</summary>
39
+
40
+ ```bash
41
+ # Install dependencies
42
+ npm install
43
+
44
+ # Generate type stubs
45
+ npm run dev:prepare
46
+
47
+ # Develop with the playground
48
+ npm run dev
49
+
50
+ # Build the playground
51
+ npm run dev:build
52
+
53
+ # Run ESLint
54
+ npm run lint
55
+
56
+ # Run Vitest
57
+ npm run test
58
+ npm run test:watch
59
+
60
+ # Release new version
61
+ npm run release
62
+ ```
63
+
64
+ </details>
65
+
66
+
67
+ # CRUD API and Pagination Loader
68
+
69
+ This repository provides a composable for managing CRUD operations and a Vue component for rendering a paginated list of items with filtering and actions.
70
+
71
+ ## Table of Contents
72
+
73
+ - [useCrudApi Composable](#usecrudapi-composable)
74
+ - [CrudPaginatedLoader Component](#crudpaginatedloader-component)
75
+
76
+ ---
77
+
78
+ ## useCrudApi Composable
79
+
80
+ The `useCrudApi` composable provides a set of functions and reactive state management for performing CRUD operations against a specified API endpoint. It integrates authentication handling, pagination, filtering, and error management.
81
+
82
+ ### Usage
83
+
84
+ ```javascript
85
+ import { useCrudApi } from 'path/to/useCrudApi';
86
+
87
+ const { getItems, createItem, updateItem, deleteItem, items, currentPage } = useCrudApi('your/api/path');
88
+ ```
89
+
90
+ ### Parameters
91
+
92
+ - **path**: `string` - The API endpoint path.
93
+ - **watchPage**: `boolean` (optional, default: `true`) - Whether to watch the current page for changes.
94
+ - **transformItem**: `Function` (optional) - A function to transform a single item.
95
+ - **transformItems**: `Function` (optional) - A function to transform multiple items.
96
+
97
+ ### Returns
98
+
99
+ - **items**: `Ref<Array>` - The list of items fetched from the API.
100
+ - **currentPage**: `Ref<number>` - The current page number.
101
+ - **totalPages**: `Ref<number>` - The total number of pages available.
102
+ - **totalItems**: `Ref<number>` - The total number of items available.
103
+ - **perPage**: `Ref<number>` - The number of items per page.
104
+ - **filters**: `Ref<Record<string, any>>[]` - The active filters.
105
+ - **item**: `Ref<any>` - The currently selected item.
106
+ - **count**: `Ref<number>` - The count of items.
107
+ - **listErrors**: `Ref<Record<string, any>>` - Errors encountered during list fetches.
108
+ - **formErrors**: `Ref<Record<string, any>>` - Errors encountered during form submissions.
109
+ - **itemErrors**: `Ref<Record<string, any>>` - Errors encountered when fetching or updating a single item.
110
+ - **countErrors**: `Ref<Record<string, any>>` - Errors encountered when fetching counts.
111
+ - **exportErrors**: `Ref<Record<string, any>>` - Errors encountered during export operations.
112
+ - **hasFormErrors**: `Ref<boolean>` - Indicates if there are form errors.
113
+ - **hasItemErrors**: `Ref<boolean>` - Indicates if there are item errors.
114
+ - **hasCountErrors**: `Ref<boolean>` - Indicates if there are count errors.
115
+ - **hasExportErrors**: `Ref<boolean>` - Indicates if there are export errors.
116
+ - **listPending**: `Ref<boolean>` - Indicates if a list fetch is pending.
117
+ - **formPending**: `Ref<boolean>` - Indicates if a form operation is pending.
118
+ - **itemPending**: `Ref<boolean>` - Indicates if fetching or updating an item is pending.
119
+ - **countPending**: `Ref<boolean>` - Indicates if a count fetch is pending.
120
+ - **exportPending**: `Ref<boolean>` - Indicates if an export operation is pending.
121
+ - **getItems**: `Function` - Fetches the items from the API.
122
+ - **createItem**: `Function` - Creates a new item in the API.
123
+ - **updateItem**: `Function` - Updates an existing item in the API.
124
+ - **deleteItem**: `Function` - Deletes an item from the API.
125
+
126
+ ---
127
+
128
+ ## CrudPaginatedLoader Component
129
+
130
+ The `CrudPaginatedLoader` component provides a UI for displaying a paginated list of items, along with options for filtering, creating, updating, and deleting items.
131
+
132
+ ### Usage
133
+
134
+ ```vue
135
+
136
+ <script setup>
137
+
138
+ </script>
139
+ <template>
140
+ <crud-paginated-loader
141
+ path="your/api/path"
142
+ :custom-filters="{}"
143
+ create-title="Create Item"
144
+ update-title="Update Item"
145
+ delete-title="Delete Item"
146
+ :per-page="10"
147
+ :listeners="['onItemCreated']" <!-- List of events to listen for from useListenerService and reload results when the happen -->
148
+ :await="false" <!-- Set to true to wait for the fetchItems function to resolve before rendering -->
149
+ >
150
+ <!-- Your custom slots here -->
151
+ <template #before="{
152
+ items,
153
+ listPending,
154
+ createForm,
155
+ updateForm,
156
+ deleteForm,
157
+ formPending,
158
+ exportAction,
159
+ exportPending,
160
+ exportErrors
161
+ }">
162
+ <!-- Your custom content here -->
163
+ <v-btn @click="createForm">Open create form</v-btn>
164
+ <v-btn :loading="exportPending" @click="exportItems">Export filtered items</v-btn>
165
+ </template>
166
+
167
+ <template #default="{
168
+ items, // The list of items in current page
169
+ pending, // If the list is loading
170
+ updateForm, // Action to show the update form
171
+ deleteForm, // Action to show the delete form
172
+ formPending // If the form is loading
173
+ }">
174
+ <!-- Your item list here -->
175
+ <v-simple-table>
176
+ <template #default="{ items }">
177
+ <tr v-for="item in items" :key="item.id">
178
+ <td>{{ item.name }}</td>
179
+ <td>{{ item.email }}</td>
180
+ <td>
181
+ <v-btn @click="updateForm(item.id)">Edit</v-btn>
182
+ <v-btn @click="deleteForm(item.id)">Delete</v-btn>
183
+ </td>
184
+ </tr>
185
+ </template>
186
+ </v-simple-table>
187
+ </template>
188
+
189
+ <template #form="{
190
+ action, // The action to perform (create, update, delete)
191
+ item, // The item object to update prior to form submission
192
+ errors // The errors with any form submission
193
+ }">
194
+ <!-- Your form layout here typically in it's own component for neatness and reusability -->
195
+ <v-text-field
196
+ v-model="item.name"
197
+ label="Name"
198
+ :error="errors.name"
199
+ :error-messages="errors.name"
200
+ />
201
+ <v-text-field
202
+ v-model="item.email"
203
+ label="Email"
204
+ :error="errors.email"
205
+ :error-messages="errors.email"
206
+ />
207
+ </template>
208
+
209
+ </crud-paginated-loader>
210
+ </template>
211
+
212
+ ```
213
+
214
+ ### Props
215
+
216
+ - **fetchItems**: `Function` - A function to fetch the items.
217
+
218
+ ---
219
+
220
+
221
+
222
+
223
+ # useListenerService
224
+
225
+ The `useListenerService` is a utility service for managing event listeners in a JavaScript application. It allows you to add, remove, and notify listeners based on specific events.
226
+
227
+ ## Overview
228
+
229
+ This service is useful for applications that need to respond to various events without tightly coupling components. It provides a way to manage listeners dynamically, ensuring that they can be added or removed as needed.
230
+
231
+ ## Types
232
+
233
+ ### Listener
234
+
235
+ ```typescript
236
+ type Listener = {
237
+ id: string; // Unique identifier for the listener
238
+ event: string; // Name of the event to listen for
239
+ callback: Function; // Function to call when the event occurs
240
+ };
241
+ ```
242
+
243
+ ## Functions
244
+
245
+ ### `useListenerService`
246
+
247
+ This function initializes and returns the listener service, providing methods to manage listeners.
248
+
249
+ #### Returns
250
+
251
+ An object containing the following methods:
252
+
253
+ - **removeLocalListeners**:
254
+ - Removes all listeners that were added during the current session.
255
+
256
+ - **removeLocalListenersWithEvent(event: string)**:
257
+ - Removes all local listeners associated with a specific event.
258
+ - **Parameters**:
259
+ - `event`: The name of the event whose listeners should be removed.
260
+
261
+ - **addListener(event: string, callback: Function)**:
262
+ - Adds a new listener for the specified event.
263
+ - **Parameters**:
264
+ - `event`: The name of the event to listen for.
265
+ - `callback`: The function to call when the event is triggered.
266
+ - **Returns**: The unique identifier (ID) of the added listener.
267
+
268
+ - **removeListener(id: string)**:
269
+ - Removes a listener by its unique identifier.
270
+ - **Parameters**:
271
+ - `id`: The unique identifier of the listener to be removed.
272
+
273
+ - **notify(key: string, data: any)**:
274
+ - Triggers all callbacks for listeners associated with the specified event.
275
+ - **Parameters**:
276
+ - `key`: The name of the event to notify.
277
+ - `data`: The data to pass to the callback functions.
278
+
279
+ ## Example Usage
280
+
281
+ ```javascript
282
+ const listenerService = useListenerService();
283
+
284
+ // Adding a listener
285
+ const listenerId = listenerService.addListener('myEvent', (data) => {
286
+ console.log('Event received:', data);
287
+ });
288
+
289
+ // Notifying listeners
290
+ listenerService.notify('myEvent', { key: 'value' });
291
+
292
+ // Removing a specific listener
293
+ listenerService.removeListener(listenerId);
294
+
295
+ // Removing all local listeners
296
+ listenerService.removeLocalListeners();
297
+ ```
298
+
299
+ # `useCrudConverters`
300
+
301
+ This composable provides a variety of utility functions for handling CRUD operations, formatting dates, converting files, and manipulating query strings in a Nuxt application.
302
+
303
+ ## Usage
304
+
305
+ Import `useCrudConverters` where needed in your Nuxt components or composables.
306
+
307
+ ```typescript
308
+ import { useCrudConverters } from '~/path/to/composables';
309
+ ```
310
+
311
+ ### Available Methods
312
+
313
+ #### **`localDateForDb(date: Date): string`**
314
+ Converts a local `Date` object to a UTC ISO string formatted for database storage.
315
+
316
+ ---
317
+
318
+ #### **`cloneDeep(obj: any): any`**
319
+ Performs a deep clone of the provided object.
320
+
321
+ ---
322
+
323
+ #### **`flattenQuery(obj: Record<string, any>, prefix = ''): Record<string, any>`**
324
+ Flattens nested objects into a single-level query string-compatible format.
325
+
326
+ ---
327
+
328
+ #### **`parseQuery(query: string): Record<string, any>`**
329
+ Parses a query string into a JavaScript object.
330
+
331
+ ---
332
+
333
+ #### **`stringifyQuery(params: Record<string, any>, prefix: string = '', options: StringifyOptions): string`**
334
+ Converts an object to a query string with configurable formatting options.
335
+
336
+ - `params`: The object to stringify.
337
+ - `prefix`: Prefix for the query string.
338
+ - `options`: Optional settings such as `arrayFormat` and `skipNull`.
339
+
340
+ ---
341
+
342
+ #### **`getFileType(file): number | null`**
343
+ Determines the file type based on its MIME type.
344
+
345
+ ---
346
+
347
+ #### **`mimeTypeToMdiIcon(mimeType: string): string`**
348
+ Maps MIME types to Material Design Icons.
349
+
350
+ ---
351
+
352
+ #### **`toBase64(file): Promise<string>`**
353
+ Converts a file to a Base64-encoded string.
354
+
355
+ ---
356
+
357
+ #### **`convertAddress(item: Record<string, any>, separator = ', '): string`**
358
+ Concatenates address components into a formatted string.
359
+
360
+ ---
361
+
362
+ #### **`formatRange(min: string, max: string, separator = ' - '): string`**
363
+ Formats a date range string for display, adjusting based on current date context.
364
+
365
+ ---
366
+
367
+ #### **`formatDate(date: Date, format: Intl.DateTimeFormatOptions): string`**
368
+ Formats a `Date` object according to provided formatting options.
369
+
370
+ ---
371
+
372
+ #### **`formatStringDate(dateString: string, format: Intl.DateTimeFormatOptions): string`**
373
+ Formats a date string according to specified options.
374
+
375
+ ---
376
+
377
+ #### **`parseDate(dateStr: string): Date`**
378
+ Parses a date string into a `Date` object.
379
+
380
+ ---
381
+
382
+ #### **`filtersToBase64String(filters: any): string`**
383
+ Encodes filter values into a Base64-encoded JSON string.
384
+
385
+ ---
386
+
387
+ #### **`base64StringToObj(base64String: string): any | null`**
388
+ Decodes a Base64 string back into a JavaScript object.
389
+
390
+ ---
391
+
392
+ #### **`extractFilterValues(filters: { key: string; value: any }[]): Record<string, any>`**
393
+ Extracts key-value pairs from an array of filter objects.
394
+
395
+ ---
396
+
397
+ #### **`uploadFilenameToUrl(fileLocation: string, size: string): string`**
398
+ Constructs a URL for an uploaded file with specified size prefix (`thumbnail`, `medium`, `large`).
399
+
400
+ ---
401
+
402
+ #### **`uploadToUrl(upload: { fileLocation: string }, size: string): string`**
403
+ Similar to `uploadFilenameToUrl` but takes an object with a `fileLocation` property.
404
+
405
+ ---
406
+
407
+ #### **`outputDateFromDb(dateStr: string, formatOut = 'dd/MM/yyyy'): string`**
408
+ Formats a UTC ISO date string from the database to the local timezone format.
409
+
410
+ ---
411
+
412
+ #### **`inputDateForDb(dateStr: string, formatIn = 'dd/MM/yyyy'): string`**
413
+ Parses a date string in the local timezone and converts it to a UTC ISO date string for storage.
414
+
415
+ ---
416
+
417
+ ### Example Usages
418
+
419
+ 1. **Flattening Query Parameters**
420
+
421
+ ```typescript
422
+ const params = {
423
+ user: { id: 1, name: "Alice" },
424
+ filters: { age: { min: 18, max: 30 }, isActive: true }
425
+ };
426
+ const flatParams = flattenQuery(params);
427
+ console.log(flatParams);
428
+ // Output: { "user[id]": 1, "user[name]": "Alice", "filters[age][min]": 18, "filters[age][max]": 30, "filters[isActive]": true }
429
+ ```
430
+
431
+ 2. **Encoding and Decoding Filters**
432
+
433
+ ```typescript
434
+ const filters = { status: "active", roles: ["admin", "user"] };
435
+ const encodedFilters = filtersToBase64String(filters);
436
+ const decodedFilters = base64StringToObj(encodedFilters);
437
+ console.log(decodedFilters);
438
+ // Output: { status: "active", roles: ["admin", "user"] }
439
+ ```
440
+
441
+ 3. **Stringifying Query with Custom Options**
442
+
443
+ ```typescript
444
+ const query = { name: "John", roles: ["admin", "user"], isActive: true };
445
+ const queryString = stringifyQuery(query, '', { arrayFormat: 'bracket' });
446
+ console.log(queryString);
447
+ // Output: "name=John&roles[]=admin&roles[]=user&isActive=true"
448
+ ```
449
+
450
+ 4. **Formatting Dates for Display and Storage**
451
+
452
+ ```typescript
453
+ const dbDate = outputDateFromDb("2024-10-26T12:00:00Z", "dd MMM yyyy");
454
+ console.log(dbDate);
455
+ // Output (localized): "26 Oct 2024"
456
+
457
+ const isoDate = inputDateForDb("26/10/2024", "dd/MM/yyyy");
458
+ console.log(isoDate);
459
+ // Output: "2024-10-26T00:00:00.000Z" (UTC format)
460
+ ```
461
+
462
+ 5. **Converting a File to Base64**
463
+
464
+ ```typescript
465
+ const fileInput = document.querySelector("input[type='file']");
466
+ fileInput.addEventListener('change', async (event) => {
467
+ const file = event.target.files[0];
468
+ const base64String = await toBase64(file);
469
+ console.log(base64String);
470
+ });
471
+ ```
472
+
473
+ <!-- Badges -->
474
+ [npm-version-src]: https://img.shields.io/npm/v/crud-nuxt/latest.svg?style=flat&colorA=020420&colorB=00DC82
475
+ [npm-version-href]: https://npmjs.com/package/crud-nuxt
476
+
477
+ [npm-downloads-src]: https://img.shields.io/npm/dm/crud-nuxt.svg?style=flat&colorA=020420&colorB=00DC82
478
+ [npm-downloads-href]: https://npmjs.com/package/crud-nuxt
479
+
480
+ [license-src]: https://img.shields.io/npm/l/crud-nuxt.svg?style=flat&colorA=020420&colorB=00DC82
481
+ [license-href]: https://npmjs.com/package/crud-nuxt
482
+
483
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
484
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1,23 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface azureAdB2COptions {
4
+ clientId: string;
5
+ authority: string;
6
+ knownAuthorities?: Array<string>;
7
+ redirectUri: string;
8
+ postLogoutRedirectUri?: string;
9
+ navigateToLoginRequestUrl: boolean;
10
+ scopes?: string[];
11
+ }
12
+ interface CrudModuleOptions {
13
+ apiBaseUrl?: string;
14
+ storageBaseUrl?: string;
15
+ additionalHeaders?: Record<string, string>;
16
+ azureAdB2C?: azureAdB2COptions;
17
+ googleMapsApiKey?: string;
18
+ debug?: boolean;
19
+ }
20
+ declare const _default: _nuxt_schema.NuxtModule<CrudModuleOptions, CrudModuleOptions, false>;
21
+
22
+ export { _default as default };
23
+ export type { CrudModuleOptions, azureAdB2COptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@grantthomas/nuxt",
3
+ "configKey": "grantThomasNuxt",
4
+ "version": "1.0.1",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "3.6.1"
8
+ }
9
+ }
@@ -0,0 +1,54 @@
1
+ import { defineNuxtModule, createResolver, addServerHandler, addPlugin, addComponentsDir, addImportsDir, installModule } from '@nuxt/kit';
2
+
3
+ const module = defineNuxtModule({
4
+ meta: {
5
+ name: "@grantthomas/nuxt",
6
+ configKey: "grantThomasNuxt"
7
+ },
8
+ defaults: {
9
+ debug: true,
10
+ additionalHeaders: {
11
+ "Content-Type": "application/json",
12
+ "Accept": "application/json"
13
+ }
14
+ },
15
+ async setup(options, nuxt) {
16
+ const resolver = createResolver(import.meta.url);
17
+ nuxt.options.runtimeConfig.public.crudNuxt = options;
18
+ nuxt.options.build.transpile.push("qs");
19
+ addServerHandler({
20
+ route: "/api/maps/autocomplete",
21
+ handler: resolver.resolve("runtime/server/api/maps/autocomplete")
22
+ });
23
+ addServerHandler({
24
+ route: "/api/maps/places",
25
+ handler: resolver.resolve("runtime/server/api/maps/places")
26
+ });
27
+ addServerHandler({
28
+ route: "/api/maps/geocode",
29
+ handler: resolver.resolve("runtime/server/api/maps/geocode")
30
+ });
31
+ addPlugin({
32
+ src: resolver.resolve("runtime/plugins/track-previous-route.client"),
33
+ mode: "client"
34
+ });
35
+ await addComponentsDir({
36
+ path: resolver.resolve("runtime/components")
37
+ });
38
+ addImportsDir(resolver.resolve("runtime/composables"));
39
+ addImportsDir(resolver.resolve("runtime/constants"));
40
+ addImportsDir(resolver.resolve("runtime/utils"));
41
+ await installModule("@nuxt/image");
42
+ await installModule("vuetify-nuxt-module");
43
+ await installModule("@vueuse/nuxt");
44
+ await installModule("@nuxt/scripts");
45
+ addPlugin({
46
+ src: resolver.resolve("runtime/plugin.luxon"),
47
+ mode: "all"
48
+ // Available both client and server-side
49
+ });
50
+ addPlugin(resolver.resolve("./runtime/plugin.client"));
51
+ }
52
+ });
53
+
54
+ export { module as default };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ export default _default;
@@ -0,0 +1,55 @@
1
+ <script setup>
2
+ import { useAlertService } from "../composables/useAlertService";
3
+ import { computed } from "vue";
4
+ const { alertMessage, alertActive } = useAlertService();
5
+ const message = computed(() => {
6
+ if (!alertMessage.value || !alertActive.value) {
7
+ return null;
8
+ }
9
+ return typeof alertMessage.value === "string" ? alertMessage.value : alertMessage.value.message;
10
+ });
11
+ const color = computed(() => {
12
+ if (!alertMessage.value || !alertActive.value) {
13
+ return null;
14
+ }
15
+ return typeof alertMessage.value === "string" ? "success" : alertMessage.value.color || "success";
16
+ });
17
+ const location = computed(() => {
18
+ if (!alertMessage.value || !alertActive.value) {
19
+ return "";
20
+ }
21
+ return typeof alertMessage.value === "string" ? "" : alertMessage.value.location || "";
22
+ });
23
+ const icon = computed(() => {
24
+ if (!alertMessage.value || !alertActive.value) {
25
+ return null;
26
+ }
27
+ return typeof alertMessage.value === "string" ? null : alertMessage.value.icon || null;
28
+ });
29
+ const clickable = computed(() => {
30
+ if (!alertMessage.value || !alertActive.value || typeof alertMessage.value === "string" || !alertMessage.value.onClick) {
31
+ return false;
32
+ }
33
+ return true;
34
+ });
35
+ const onClick = () => {
36
+ if (!clickable.value) {
37
+ return;
38
+ }
39
+ alertMessage.value.onClick();
40
+ };
41
+ </script>
42
+
43
+ <template>
44
+ <v-snackbar v-model="alertActive" :color="color" timeout="3000" :top="true" :location="location">
45
+ <div class="d-flex align-center justify-between">
46
+ <v-icon v-if="icon" :icon="icon" class="mr-2"></v-icon>
47
+ <div class="flex-fill">
48
+ {{ message }}
49
+ </div>
50
+ <v-btn size="small" class="ml-2" v-if="clickable" @click="onClick" :icon="true">
51
+ <v-icon icon="mdi-chevron-right"/>
52
+ </v-btn>
53
+ </div>
54
+ </v-snackbar>
55
+ </template>
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ export default _default;
@@ -0,0 +1,8 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {
2
+ hint: string;
3
+ label: string;
4
+ placeholder: string;
5
+ countries: unknown[];
6
+ $props: any;
7
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
8
+ export default _default;