@finema/finework-layer 0.2.50 → 0.2.52

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.
@@ -0,0 +1,646 @@
1
+ # Troubleshooting Guide
2
+
3
+ ## 🔧 Common Issues & Solutions
4
+
5
+ ### Authentication Issues
6
+
7
+ #### Issue: "Token not found" or "Unauthorized"
8
+
9
+ **Symptoms:**
10
+ - Redirected to login page repeatedly
11
+ - API requests return 401 errors
12
+ - `auth.token.value` is undefined
13
+
14
+ **Solutions:**
15
+
16
+ 1. **Check Cookie Configuration**
17
+ ```typescript
18
+ // Verify cookie is being set correctly
19
+ const token = useCookie('token', {
20
+ path: '/',
21
+ maxAge: 60 * 60 * 24 * 365
22
+ })
23
+
24
+ console.log('Token:', token.value)
25
+ ```
26
+
27
+ 2. **Verify API Response**
28
+ - Backend must set the cookie with correct domain
29
+ - Cookie must be HttpOnly and Secure in production
30
+ - Check browser DevTools > Application > Cookies
31
+
32
+ 3. **Check CORS Settings**
33
+ ```typescript
34
+ // Backend must allow credentials
35
+ Access-Control-Allow-Credentials: true
36
+ Access-Control-Allow-Origin: https://your-domain.com
37
+ ```
38
+
39
+ 4. **Clear Browser Cookies**
40
+ ```javascript
41
+ // In browser console
42
+ document.cookie.split(";").forEach(c => {
43
+ document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
44
+ });
45
+ ```
46
+
47
+ ---
48
+
49
+ #### Issue: User data not loading
50
+
51
+ **Symptoms:**
52
+ - `auth.me.value` is null
53
+ - Page shows loading state indefinitely
54
+
55
+ **Solutions:**
56
+
57
+ 1. **Check API Endpoint**
58
+ ```typescript
59
+ const auth = useAuth()
60
+
61
+ // Manually trigger fetch
62
+ await auth.fetchMe.run()
63
+
64
+ // Check status
65
+ console.log('Status:', auth.fetchMe.status.value)
66
+ console.log('Error:', auth.fetchMe.status.value.errorData)
67
+ ```
68
+
69
+ 2. **Verify Middleware Order**
70
+ ```typescript
71
+ // Correct order
72
+ definePageMeta({
73
+ middleware: ['common', 'auth', 'permissions']
74
+ })
75
+ ```
76
+
77
+ 3. **Check Cache Timing**
78
+ ```typescript
79
+ // Force refresh
80
+ auth.me.setTimestamp(null)
81
+ await auth.fetchMe.run()
82
+ ```
83
+
84
+ ---
85
+
86
+ ### Permission Issues
87
+
88
+ #### Issue: "Access Denied" or 403 errors
89
+
90
+ **Symptoms:**
91
+ - User redirected to error page
92
+ - Cannot access certain routes
93
+ - Features hidden unexpectedly
94
+
95
+ **Solutions:**
96
+
97
+ 1. **Verify User Permissions**
98
+ ```typescript
99
+ const auth = useAuth()
100
+
101
+ console.log('Access Level:', auth.me.value?.access_level)
102
+ console.log('Has PMO Admin:', auth.hasPermission(UserModule.PMO, Permission.ADMIN))
103
+ ```
104
+
105
+ 2. **Check Route Configuration**
106
+ ```typescript
107
+ definePageMeta({
108
+ middleware: ['auth', 'permissions'],
109
+ accessGuard: {
110
+ permissions: ['pmo:USER', 'pmo:ADMIN'], // OR logic
111
+ redirectTo: '/unauthorized'
112
+ }
113
+ })
114
+ ```
115
+
116
+ 3. **Debug Permission Check**
117
+ ```typescript
118
+ const canAccess = computed(() => {
119
+ const result = auth.hasPermission(UserModule.PMO, Permission.ADMIN)
120
+ console.log('Can Access:', result)
121
+ console.log('User Module:', auth.me.value?.access_level?.pmo)
122
+ return result
123
+ })
124
+ ```
125
+
126
+ ---
127
+
128
+ ### Data Loading Issues
129
+
130
+ #### Issue: Data not loading or infinite loading
131
+
132
+ **Symptoms:**
133
+ - StatusBox shows loading spinner forever
134
+ - `loader.data.value` is null
135
+ - No error messages
136
+
137
+ **Solutions:**
138
+
139
+ 1. **Check Loader Configuration**
140
+ ```typescript
141
+ const loader = useObjectLoader({
142
+ method: 'GET',
143
+ url: '/api/data',
144
+ getRequestOptions: useRequestOptions().auth // Make sure this is correct
145
+ })
146
+
147
+ // Verify it's being called
148
+ onMounted(() => {
149
+ console.log('Loading data...')
150
+ loader.run()
151
+ })
152
+ ```
153
+
154
+ 2. **Check API Response**
155
+ ```typescript
156
+ // Add error handling
157
+ watch(() => loader.status.value, (status) => {
158
+ console.log('Loading:', status.isLoading)
159
+ console.log('Success:', status.isSuccess)
160
+ console.log('Error:', status.isError)
161
+
162
+ if (status.isError) {
163
+ console.error('Error Data:', status.errorData)
164
+ }
165
+
166
+ if (status.isSuccess) {
167
+ console.log('Data:', loader.data.value)
168
+ }
169
+ })
170
+ ```
171
+
172
+ 3. **Verify API Endpoint**
173
+ ```typescript
174
+ // Check full URL
175
+ const config = useRuntimeConfig()
176
+ console.log('Base URL:', config.public.baseAPI)
177
+ console.log('Full URL:', config.public.baseAPI + '/api/data')
178
+ ```
179
+
180
+ 4. **Check Network Tab**
181
+ - Open DevTools > Network
182
+ - Look for failed requests
183
+ - Check request headers (Authorization)
184
+ - Verify response status and body
185
+
186
+ ---
187
+
188
+ #### Issue: Data loads but StatusBox shows error
189
+
190
+ **Symptoms:**
191
+ - Network request succeeds
192
+ - Data is in response
193
+ - StatusBox shows error state
194
+
195
+ **Solutions:**
196
+
197
+ 1. **Check Data Structure**
198
+ ```typescript
199
+ // StatusBox expects data to be truthy
200
+ // If API returns { data: null }, StatusBox will show error
201
+
202
+ // Solution: Transform response
203
+ const loader = useObjectLoader({
204
+ method: 'GET',
205
+ url: '/api/data',
206
+ getRequestOptions: useRequestOptions().auth
207
+ })
208
+
209
+ const transformedData = computed(() => {
210
+ return loader.data.value?.data || loader.data.value
211
+ })
212
+ ```
213
+
214
+ 2. **Check Status Object**
215
+ ```typescript
216
+ // Ensure status is properly structured
217
+ console.log('Status:', loader.status.value)
218
+ // Should have: isLoading, isSuccess, isError
219
+ ```
220
+
221
+ ---
222
+
223
+ ### Component Issues
224
+
225
+ #### Issue: Component not found
226
+
227
+ **Symptoms:**
228
+ - "Component not found" error
229
+ - Component doesn't render
230
+ - Import errors
231
+
232
+ **Solutions:**
233
+
234
+ 1. **Check Component Location**
235
+ ```
236
+ app/components/
237
+ ├── MyComponent.vue ✅ Auto-imported
238
+ ├── Button/
239
+ │ └── Custom.vue ✅ Auto-imported as ButtonCustom
240
+ └── nested/
241
+ └── Deep.vue ✅ Auto-imported as NestedDeep
242
+ ```
243
+
244
+ 2. **Verify Component Name**
245
+ ```vue
246
+ <!-- Correct -->
247
+ <MyComponent />
248
+ <ButtonCustom />
249
+ <NestedDeep />
250
+
251
+ <!-- Incorrect -->
252
+ <my-component /> ❌
253
+ <Custom /> ❌
254
+ ```
255
+
256
+ 3. **Restart Dev Server**
257
+ ```bash
258
+ # Sometimes auto-import needs refresh
259
+ pnpm dev
260
+ ```
261
+
262
+ 4. **Check nuxt.config.ts**
263
+ ```typescript
264
+ export default defineNuxtConfig({
265
+ components: true // Should be enabled
266
+ })
267
+ ```
268
+
269
+ ---
270
+
271
+ #### Issue: Props not working
272
+
273
+ **Symptoms:**
274
+ - Props are undefined
275
+ - Type errors
276
+ - Default values not applied
277
+
278
+ **Solutions:**
279
+
280
+ 1. **Check Prop Definition**
281
+ ```vue
282
+ <script setup lang="ts">
283
+ // ✅ Correct
284
+ interface Props {
285
+ title: string
286
+ count?: number
287
+ }
288
+
289
+ const props = defineProps<Props>()
290
+
291
+ // ✅ With defaults
292
+ const props = withDefaults(defineProps<Props>(), {
293
+ count: 0
294
+ })
295
+
296
+ // ❌ Incorrect
297
+ const props = defineProps(['title', 'count']) // No types
298
+ </script>
299
+ ```
300
+
301
+ 2. **Check Prop Passing**
302
+ ```vue
303
+ <!-- ✅ Correct -->
304
+ <MyComponent :title="myTitle" :count="42" />
305
+
306
+ <!-- ❌ Incorrect -->
307
+ <MyComponent title="myTitle" count="42" /> <!-- Strings, not reactive -->
308
+ ```
309
+
310
+ ---
311
+
312
+ ### Routing Issues
313
+
314
+ #### Issue: Route not found or 404
315
+
316
+ **Symptoms:**
317
+ - Page shows 404
318
+ - Navigation doesn't work
319
+ - Route constants undefined
320
+
321
+ **Solutions:**
322
+
323
+ 1. **Check File Structure**
324
+ ```
325
+ pages/
326
+ ├── index.vue → /
327
+ ├── about.vue → /about
328
+ ├── projects/
329
+ │ ├── index.vue → /projects
330
+ │ ├── [id].vue → /projects/:id
331
+ │ └── new.vue → /projects/new
332
+ ```
333
+
334
+ 2. **Verify Route Constant**
335
+ ```typescript
336
+ // Check if route exists
337
+ console.log('Routes:', routes)
338
+ console.log('PMO Route:', routes.pmo.project.projects.to)
339
+
340
+ // Use correct path
341
+ navigateTo(routes.pmo.project.projects.to) // ✅
342
+ navigateTo('/pmo/projects') // ✅
343
+ navigateTo(routes.pmo.projects.to) // ❌ Wrong path
344
+ ```
345
+
346
+ 3. **Check Middleware**
347
+ ```typescript
348
+ // Middleware might be blocking
349
+ definePageMeta({
350
+ middleware: ['auth'] // Remove temporarily to test
351
+ })
352
+ ```
353
+
354
+ ---
355
+
356
+ ### Build Issues
357
+
358
+ #### Issue: Build fails with type errors
359
+
360
+ **Symptoms:**
361
+ - `pnpm build` fails
362
+ - TypeScript errors
363
+ - Module not found errors
364
+
365
+ **Solutions:**
366
+
367
+ 1. **Check TypeScript Config**
368
+ ```bash
369
+ # Regenerate types
370
+ pnpm dev:prepare
371
+ ```
372
+
373
+ 2. **Clear Cache**
374
+ ```bash
375
+ # Remove generated files
376
+ rm -rf .nuxt node_modules/.cache
377
+
378
+ # Reinstall
379
+ pnpm install
380
+
381
+ # Rebuild
382
+ pnpm build
383
+ ```
384
+
385
+ 3. **Check Imports**
386
+ ```typescript
387
+ // ✅ Correct - auto-imported
388
+ const auth = useAuth()
389
+
390
+ // ❌ Incorrect - manual import
391
+ import { useAuth } from '~/composables/useAuth'
392
+ ```
393
+
394
+ ---
395
+
396
+ ### Styling Issues
397
+
398
+ #### Issue: Tailwind classes not working
399
+
400
+ **Symptoms:**
401
+ - Classes have no effect
402
+ - Styles not applied
403
+ - Custom colors not working
404
+
405
+ **Solutions:**
406
+
407
+ 1. **Check CSS Import**
408
+ ```typescript
409
+ // nuxt.config.ts
410
+ export default defineNuxtConfig({
411
+ css: ['~/assets/css/main.css']
412
+ })
413
+ ```
414
+
415
+ ```css
416
+ /* assets/css/main.css */
417
+ @import "tailwindcss";
418
+ @import "@nuxt/ui";
419
+ ```
420
+
421
+ 2. **Check Class Names**
422
+ ```vue
423
+ <!-- ✅ Correct -->
424
+ <div class="flex items-center gap-4">
425
+
426
+ <!-- ❌ Incorrect -->
427
+ <div class="flex items-center gap-4px"> <!-- Invalid unit -->
428
+ ```
429
+
430
+ 3. **Purge Configuration**
431
+ ```typescript
432
+ // If using custom Tailwind config
433
+ export default {
434
+ content: [
435
+ './components/**/*.{vue,js,ts}',
436
+ './layouts/**/*.vue',
437
+ './pages/**/*.vue',
438
+ './app.vue'
439
+ ]
440
+ }
441
+ ```
442
+
443
+ ---
444
+
445
+ ### Performance Issues
446
+
447
+ #### Issue: Slow page load or navigation
448
+
449
+ **Symptoms:**
450
+ - Pages take long to load
451
+ - Navigation is sluggish
452
+ - High memory usage
453
+
454
+ **Solutions:**
455
+
456
+ 1. **Check Data Fetching**
457
+ ```typescript
458
+ // ❌ Bad - Multiple sequential requests
459
+ await loader1.run()
460
+ await loader2.run()
461
+ await loader3.run()
462
+
463
+ // ✅ Good - Parallel requests
464
+ await Promise.all([
465
+ loader1.run(),
466
+ loader2.run(),
467
+ loader3.run()
468
+ ])
469
+ ```
470
+
471
+ 2. **Implement Lazy Loading**
472
+ ```typescript
473
+ // Lazy load heavy components
474
+ const HeavyChart = defineAsyncComponent(() =>
475
+ import('~/components/HeavyChart.vue')
476
+ )
477
+ ```
478
+
479
+ 3. **Check Cache Settings**
480
+ ```typescript
481
+ // Increase cache time if appropriate
482
+ const me = defineStore('auth.me', () => {
483
+ const isShouldFetch = () => {
484
+ // Cache for 5 minutes instead of 1
485
+ return Date.now() - timestamp.value > 1000 * 60 * 5
486
+ }
487
+ })
488
+ ```
489
+
490
+ 4. **Use Pagination**
491
+ ```typescript
492
+ // Don't load all data at once
493
+ const loader = useListLoader({
494
+ method: 'GET',
495
+ url: '/api/data',
496
+ getRequestOptions: useRequestOptions().auth
497
+ })
498
+
499
+ loader.run({
500
+ params: {
501
+ page: 1,
502
+ per_page: 20 // Limit results
503
+ }
504
+ })
505
+ ```
506
+
507
+ ---
508
+
509
+ ## 🐛 Debugging Tools
510
+
511
+ ### 1. Vue DevTools
512
+
513
+ ```bash
514
+ # Install browser extension
515
+ # Chrome: https://chrome.google.com/webstore/detail/vuejs-devtools
516
+ # Firefox: https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/
517
+ ```
518
+
519
+ **Features:**
520
+ - Inspect component tree
521
+ - View component props and state
522
+ - Track events
523
+ - Inspect Pinia stores
524
+
525
+ ### 2. Nuxt DevTools
526
+
527
+ ```typescript
528
+ // Enable in nuxt.config.ts
529
+ export default defineNuxtConfig({
530
+ devtools: {
531
+ enabled: true
532
+ }
533
+ })
534
+ ```
535
+
536
+ **Features:**
537
+ - Component inspector
538
+ - Route analyzer
539
+ - Module inspector
540
+ - Performance metrics
541
+
542
+ ### 3. Console Debugging
543
+
544
+ ```typescript
545
+ // Add strategic console logs
546
+ console.log('🔍 Debug:', {
547
+ user: auth.me.value,
548
+ token: auth.token.value,
549
+ permissions: auth.me.value?.access_level
550
+ })
551
+
552
+ // Use console.table for arrays
553
+ console.table(projects.data.value)
554
+
555
+ // Use console.group for organization
556
+ console.group('Data Loading')
557
+ console.log('Status:', loader.status.value)
558
+ console.log('Data:', loader.data.value)
559
+ console.groupEnd()
560
+ ```
561
+
562
+ ### 4. Network Debugging
563
+
564
+ ```typescript
565
+ // Log all requests
566
+ const loader = useObjectLoader({
567
+ method: 'GET',
568
+ url: '/api/data',
569
+ getRequestOptions: () => {
570
+ const options = useRequestOptions().auth()
571
+ console.log('Request:', options)
572
+ return options
573
+ }
574
+ })
575
+ ```
576
+
577
+ ---
578
+
579
+ ## 📞 Getting Help
580
+
581
+ ### Before Asking for Help
582
+
583
+ 1. ✅ Check this troubleshooting guide
584
+ 2. ✅ Review error messages carefully
585
+ 3. ✅ Check browser console for errors
586
+ 4. ✅ Verify network requests in DevTools
587
+ 5. ✅ Try clearing cache and rebuilding
588
+ 6. ✅ Check if issue exists in fresh install
589
+
590
+ ### When Reporting Issues
591
+
592
+ Include:
593
+ - Error message (full stack trace)
594
+ - Code snippet (minimal reproduction)
595
+ - Steps to reproduce
596
+ - Expected vs actual behavior
597
+ - Environment (Node version, OS, browser)
598
+ - Screenshots if applicable
599
+
600
+ ---
601
+
602
+ ## 🔍 Common Error Messages
603
+
604
+ ### "Cannot read property 'value' of undefined"
605
+
606
+ **Cause:** Accessing reactive ref before initialization
607
+
608
+ **Solution:**
609
+ ```typescript
610
+ // ❌ Bad
611
+ const data = loader.data.value.items // loader might be undefined
612
+
613
+ // ✅ Good
614
+ const data = computed(() => loader.data.value?.items || [])
615
+ ```
616
+
617
+ ### "Module not found"
618
+
619
+ **Cause:** Import path incorrect or module not installed
620
+
621
+ **Solution:**
622
+ ```bash
623
+ # Check if module is installed
624
+ pnpm list @finema/finework-layer
625
+
626
+ # Reinstall if needed
627
+ pnpm install
628
+ ```
629
+
630
+ ### "Hydration mismatch"
631
+
632
+ **Cause:** Server and client render different content
633
+
634
+ **Solution:**
635
+ ```vue
636
+ <!-- Use ClientOnly for client-specific content -->
637
+ <ClientOnly>
638
+ <div>{{ new Date().toLocaleString() }}</div>
639
+ </ClientOnly>
640
+ ```
641
+
642
+ ---
643
+
644
+ **Last Updated:** 2025-11-07
645
+ **Need more help? Check the other documentation files!**
646
+
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <Button
3
- icon="icon-park-outline:left"
3
+ icon="ph:caret-left"
4
4
  variant="outline"
5
5
  color="neutral"
6
6
  :to="to"
@@ -230,10 +230,17 @@ const mappedItems = (items: NavigationMenuItem[]): NavigationMenuItem[] => {
230
230
  (p) => normalizePath(route.path) === normalizePath(p),
231
231
  )
232
232
 
233
+ const basePath = item.to ? normalizePath(String(item.to)) : ''
234
+ const currentPath = normalizePath(route.path)
233
235
  const selfIsActive = item.to
234
- ? normalizePath(route.path) === normalizePath(String(item.to))
235
- || (route.path.startsWith(normalizePath(String(item.to)))
236
- && !hasExactMatch)
236
+ ? (
237
+ currentPath === basePath
238
+ || (
239
+ currentPath.startsWith(`${basePath}/`)
240
+ && !currentPath.slice(basePath.length + 1).includes('/')
241
+ && !hasExactMatch
242
+ )
243
+ )
237
244
  : false
238
245
 
239
246
  const itemIsActive = selfIsActive || isAnyChildActive
@@ -173,6 +173,7 @@ const props = withDefaults(
173
173
  sidebarItems: NavigationMenuItem[]
174
174
  isSidebarGroup?: boolean
175
175
  fullScreen?: boolean
176
+ rootAppPath?: string
176
177
  }>(),
177
178
  {
178
179
  fullScreen: true,
@@ -207,18 +208,13 @@ const breadcrumbsItems = computed(() => {
207
208
  const list = app.pageMeta.breadcrumbs || []
208
209
  if (!list.length) return []
209
210
 
210
- const [first, ...rest] = list
211
- const home = {
212
- label: '',
213
- icon: 'ph:house-line',
214
- to: first?.to,
215
- }
216
-
217
- const extra = rest.map((item: any) => ({
218
- ...item,
219
- icon: '',
220
- }))
221
-
222
- return [home, ...extra]
211
+ return [
212
+ {
213
+ label: '',
214
+ icon: 'ph:house-line',
215
+ to: props.rootAppPath || '/',
216
+ },
217
+ ...list,
218
+ ]
223
219
  })
224
220
  </script>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@finema/finework-layer",
3
3
  "type": "module",
4
- "version": "0.2.50",
4
+ "version": "0.2.52",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "dev": "nuxi dev .playground -o",