Fix duplicate export declarations and migrate ContactsView with sub-components

- Remove duplicate NOTIFY_INVITE_MISSING and NOTIFY_INVITE_PROCESSING_ERROR exports
- Update InviteOneAcceptView.vue to use correct NOTIFY_INVITE_TRUNCATED_DATA constant
- Migrate ContactsView to PlatformServiceMixin and extract into modular sub-components
- Resolves TypeScript compilation errors preventing web build
This commit is contained in:
Matthew Raymer
2025-07-16 08:03:26 +00:00
parent 81a6c92068
commit 8dd73950f5
45 changed files with 3216 additions and 1752 deletions

View File

@@ -6,33 +6,30 @@
<!-- Main content with lazy-loaded components -->
<div class="content">
<h1>Lazy Loading Example</h1>
<!-- Lazy-loaded heavy component -->
<LazyHeavyComponent
<LazyHeavyComponent
v-if="showHeavyComponent"
:data="heavyComponentData"
@data-processed="handleDataProcessed"
/>
<!-- Conditionally loaded components -->
<LazyQRScanner
v-if="showQRScanner"
@qr-detected="handleQRDetected"
/>
<LazyThreeJSViewer
<LazyQRScanner v-if="showQRScanner" @qr-detected="handleQRDetected" />
<LazyThreeJSViewer
v-if="showThreeJS"
:model-url="threeJSModelUrl"
@model-loaded="handleModelLoaded"
/>
<!-- Route-based lazy loading -->
<router-view v-slot="{ Component }">
<component :is="Component" />
</router-view>
</div>
</template>
<!-- Loading fallback -->
<template #fallback>
<div class="loading-fallback">
@@ -41,98 +38,101 @@
</div>
</template>
</Suspense>
<!-- Control buttons -->
<div class="controls">
<button @click="toggleHeavyComponent">
{{ showHeavyComponent ? 'Hide' : 'Show' }} Heavy Component
{{ showHeavyComponent ? "Hide" : "Show" }} Heavy Component
</button>
<button @click="toggleQRScanner">
{{ showQRScanner ? 'Hide' : 'Show' }} QR Scanner
{{ showQRScanner ? "Hide" : "Show" }} QR Scanner
</button>
<button @click="toggleThreeJS">
{{ showThreeJS ? 'Hide' : 'Show' }} 3D Viewer
{{ showThreeJS ? "Hide" : "Show" }} 3D Viewer
</button>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-facing-decorator';
import { defineAsyncComponent } from 'vue';
import { Component, Vue, Prop, Watch } from "vue-facing-decorator";
import { defineAsyncComponent } from "vue";
/**
* Lazy Loading Example Component
*
*
* Demonstrates various lazy loading patterns with vue-facing-decorator:
* - defineAsyncComponent for heavy components
* - Conditional loading based on user interaction
* - Suspense for loading states
* - Route-based lazy loading
*
*
* @author Matthew Raymer
* @version 1.0.0
*/
@Component({
name: 'LazyLoadingExample',
name: "LazyLoadingExample",
components: {
// Lazy-loaded components with loading and error states
LazyHeavyComponent: defineAsyncComponent({
loader: () => import('./sub-components/HeavyComponent.vue'),
loader: () => import("./sub-components/HeavyComponent.vue"),
loadingComponent: {
template: '<div class="loading">Loading heavy component...</div>'
template: '<div class="loading">Loading heavy component...</div>',
},
errorComponent: {
template: '<div class="error">Failed to load heavy component</div>'
template: '<div class="error">Failed to load heavy component</div>',
},
delay: 200, // Show loading component after 200ms
timeout: 10000 // Timeout after 10 seconds
timeout: 10000, // Timeout after 10 seconds
}),
LazyQRScanner: defineAsyncComponent({
loader: () => import('./sub-components/QRScannerComponent.vue'),
loader: () => import("./sub-components/QRScannerComponent.vue"),
loadingComponent: {
template: '<div class="loading">Initializing QR scanner...</div>'
template: '<div class="loading">Initializing QR scanner...</div>',
},
errorComponent: {
template: '<div class="error">QR scanner not available</div>'
}
template: '<div class="error">QR scanner not available</div>',
},
}),
LazyThreeJSViewer: defineAsyncComponent({
loader: () => import('./sub-components/ThreeJSViewer.vue'),
loader: () => import("./sub-components/ThreeJSViewer.vue"),
loadingComponent: {
template: '<div class="loading">Loading 3D viewer...</div>'
template: '<div class="loading">Loading 3D viewer...</div>',
},
errorComponent: {
template: '<div class="error">3D viewer failed to load</div>'
}
})
}
template: '<div class="error">3D viewer failed to load</div>',
},
}),
},
})
export default class LazyLoadingExample extends Vue {
// Component state
@Prop({ default: false }) readonly initialLoadHeavy!: boolean;
// Reactive properties
showHeavyComponent = false;
showQRScanner = false;
showThreeJS = false;
// Component data
heavyComponentData = {
items: Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Item ${i}` })),
filters: { category: 'all', status: 'active' },
sortBy: 'name'
items: Array.from({ length: 1000 }, (_, i) => ({
id: i,
name: `Item ${i}`,
})),
filters: { category: "all", status: "active" },
sortBy: "name",
};
threeJSModelUrl = '/models/lupine_plant/scene.gltf';
threeJSModelUrl = "/models/lupine_plant/scene.gltf";
// Computed properties
get isLoadingAnyComponent(): boolean {
return this.showHeavyComponent || this.showQRScanner || this.showThreeJS;
}
get componentCount(): number {
let count = 0;
if (this.showHeavyComponent) count++;
@@ -140,83 +140,91 @@ export default class LazyLoadingExample extends Vue {
if (this.showThreeJS) count++;
return count;
}
// Lifecycle hooks
mounted(): void {
console.log('[LazyLoadingExample] Component mounted');
console.log("[LazyLoadingExample] Component mounted");
// Initialize based on props
if (this.initialLoadHeavy) {
this.showHeavyComponent = true;
}
// Preload critical components
this.preloadCriticalComponents();
}
// Methods
toggleHeavyComponent(): void {
this.showHeavyComponent = !this.showHeavyComponent;
console.log('[LazyLoadingExample] Heavy component toggled:', this.showHeavyComponent);
console.log(
"[LazyLoadingExample] Heavy component toggled:",
this.showHeavyComponent,
);
}
toggleQRScanner(): void {
this.showQRScanner = !this.showQRScanner;
console.log('[LazyLoadingExample] QR scanner toggled:', this.showQRScanner);
console.log("[LazyLoadingExample] QR scanner toggled:", this.showQRScanner);
}
toggleThreeJS(): void {
this.showThreeJS = !this.showThreeJS;
console.log('[LazyLoadingExample] ThreeJS viewer toggled:', this.showThreeJS);
console.log(
"[LazyLoadingExample] ThreeJS viewer toggled:",
this.showThreeJS,
);
}
handleDataProcessed(data: any): void {
console.log('[LazyLoadingExample] Data processed:', data);
console.log("[LazyLoadingExample] Data processed:", data);
// Handle processed data from heavy component
}
handleQRDetected(qrData: string): void {
console.log('[LazyLoadingExample] QR code detected:', qrData);
console.log("[LazyLoadingExample] QR code detected:", qrData);
// Handle QR code data
}
handleModelLoaded(modelInfo: any): void {
console.log('[LazyLoadingExample] 3D model loaded:', modelInfo);
console.log("[LazyLoadingExample] 3D model loaded:", modelInfo);
// Handle 3D model loaded event
}
/**
* Preload critical components for better UX
*/
private preloadCriticalComponents(): void {
// Preload components that are likely to be used
if (process.env.NODE_ENV === 'production') {
if (process.env.NODE_ENV === "production") {
// In production, preload based on user behavior patterns
this.preloadComponent(() => import('./sub-components/HeavyComponent.vue'));
this.preloadComponent(
() => import("./sub-components/HeavyComponent.vue"),
);
}
}
/**
* Preload a component without rendering it
*/
private preloadComponent(componentLoader: () => Promise<any>): void {
componentLoader().catch(error => {
console.warn('[LazyLoadingExample] Preload failed:', error);
componentLoader().catch((error) => {
console.warn("[LazyLoadingExample] Preload failed:", error);
});
}
// Watchers
@Watch('showHeavyComponent')
@Watch("showHeavyComponent")
onHeavyComponentToggle(newValue: boolean): void {
if (newValue) {
// Component is being shown - could trigger analytics
console.log('[LazyLoadingExample] Heavy component shown');
console.log("[LazyLoadingExample] Heavy component shown");
}
}
@Watch('componentCount')
@Watch("componentCount")
onComponentCountChange(newCount: number): void {
console.log('[LazyLoadingExample] Active component count:', newCount);
console.log("[LazyLoadingExample] Active component count:", newCount);
}
}
</script>
@@ -272,8 +280,12 @@ export default class LazyLoadingExample extends Vue {
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.loading {
@@ -290,4 +302,4 @@ export default class LazyLoadingExample extends Vue {
border: 1px solid #f5c6cb;
border-radius: 4px;
}
</style>
</style>