Browse Source
- Add configurable entity display logic via function props to EntityGrid - Implement comprehensive test suite for EntityGrid function props in TestView - Apply consistent code formatting across 15 components and views - Fix linting issues with trailing commas and line breaks - Add new EntityGridFunctionPropTest.vue for component testing - Update endorserServer with improved error handling and logging - Streamline PlatformServiceMixin with better cache management - Enhance component documentation and type safety Changes span 15 files with 159 additions and 69 deletions, focusing on component flexibility, code quality, and testing infrastructure.web-serve-fix
16 changed files with 383 additions and 69 deletions
@ -0,0 +1,224 @@ |
|||
<template> |
|||
<div> |
|||
<h2>EntityGrid Function Prop Test</h2> |
|||
|
|||
<div class="mb-4"> |
|||
<button @click="toggleCustomFunction"> |
|||
{{ useCustomFunction ? "Use Default" : "Use Custom Function" }} |
|||
</button> |
|||
<span class="ml-2" |
|||
>Current: {{ useCustomFunction ? "Custom" : "Default" }}</span |
|||
> |
|||
</div> |
|||
|
|||
<div class="mb-4"> |
|||
<h3> |
|||
People Grid ({{ people.length }} total, |
|||
{{ displayedPeopleCount }} shown) |
|||
</h3> |
|||
<EntityGrid |
|||
entity-type="people" |
|||
:entities="people" |
|||
:max-items="5" |
|||
:active-did="activeDid" |
|||
:all-my-dids="allMyDids" |
|||
:all-contacts="people" |
|||
:conflict-checker="conflictChecker" |
|||
:display-entities-function=" |
|||
useCustomFunction ? customPeopleFunction : undefined |
|||
" |
|||
@entity-selected="handleEntitySelected" |
|||
/> |
|||
</div> |
|||
|
|||
<div class="mb-4"> |
|||
<h3> |
|||
Projects Grid ({{ projects.length }} total, |
|||
{{ displayedProjectsCount }} shown) |
|||
</h3> |
|||
<EntityGrid |
|||
entity-type="projects" |
|||
:entities="projects" |
|||
:max-items="3" |
|||
:active-did="activeDid" |
|||
:all-my-dids="allMyDids" |
|||
:all-contacts="people" |
|||
:conflict-checker="conflictChecker" |
|||
:display-entities-function=" |
|||
useCustomFunction ? customProjectsFunction : undefined |
|||
" |
|||
@entity-selected="handleEntitySelected" |
|||
/> |
|||
</div> |
|||
|
|||
<div class="mt-4"> |
|||
<h3>Selected Entity:</h3> |
|||
<pre>{{ selectedEntity }}</pre> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { Component, Vue } from "vue-facing-decorator"; |
|||
import EntityGrid from "../components/EntityGrid.vue"; |
|||
import { Contact } from "../db/tables/contacts"; |
|||
import { PlanData } from "../interfaces/records"; |
|||
|
|||
/** |
|||
* Test component to demonstrate EntityGrid's new displayEntitiesFunction prop |
|||
* |
|||
* Shows how parent components can control which entities are displayed |
|||
* through function props instead of relying on computed properties. |
|||
*/ |
|||
@Component({ |
|||
components: { |
|||
EntityGrid, |
|||
}, |
|||
}) |
|||
export default class EntityGridFunctionPropTest extends Vue { |
|||
useCustomFunction = false; |
|||
selectedEntity: { |
|||
type: "person" | "project" | "special"; |
|||
entityType?: string; |
|||
data: Contact | PlanData | { did?: string; name: string }; |
|||
} | null = null; |
|||
|
|||
// Test data |
|||
activeDid = "did:example:123"; |
|||
allMyDids = ["did:example:123"]; |
|||
|
|||
people: Contact[] = [ |
|||
{ |
|||
did: "did:example:1", |
|||
name: "Alice", |
|||
profileImageUrl: "https://example.com/alice.jpg", |
|||
}, |
|||
{ did: "did:example:2", name: "Bob", profileImageUrl: "" }, |
|||
{ |
|||
did: "did:example:3", |
|||
name: "Charlie", |
|||
profileImageUrl: "https://example.com/charlie.jpg", |
|||
}, |
|||
{ did: "did:example:4", name: "Diana", profileImageUrl: "" }, |
|||
{ |
|||
did: "did:example:5", |
|||
name: "Eve", |
|||
profileImageUrl: "https://example.com/eve.jpg", |
|||
}, |
|||
{ |
|||
did: "did:example:6", |
|||
name: "Frank", |
|||
profileImageUrl: "https://example.com/frank.jpg", |
|||
}, |
|||
{ did: "did:example:7", name: "Grace", profileImageUrl: "" }, |
|||
]; |
|||
|
|||
projects: PlanData[] = [ |
|||
{ |
|||
handleId: "proj1", |
|||
name: "Zebra Project", |
|||
description: "A project about zebras", |
|||
issuerDid: "did:example:1", |
|||
}, |
|||
{ |
|||
handleId: "proj2", |
|||
name: "Alpha Project", |
|||
description: "The first project", |
|||
issuerDid: "did:example:2", |
|||
}, |
|||
{ |
|||
handleId: "proj3", |
|||
name: "Beta Project", |
|||
description: "The second project", |
|||
issuerDid: "did:example:3", |
|||
}, |
|||
{ |
|||
handleId: "proj4", |
|||
name: "Gamma Project", |
|||
description: "The third project", |
|||
issuerDid: "did:example:4", |
|||
}, |
|||
{ |
|||
handleId: "proj5", |
|||
name: "Delta Project", |
|||
description: "The fourth project", |
|||
issuerDid: "did:example:5", |
|||
}, |
|||
]; |
|||
|
|||
/** |
|||
* Custom function for people: only show those with profile images |
|||
*/ |
|||
customPeopleFunction = ( |
|||
entities: Contact[], |
|||
_entityType: string, |
|||
maxItems: number, |
|||
): Contact[] => { |
|||
return entities |
|||
.filter((person) => person.profileImageUrl) |
|||
.slice(0, maxItems); |
|||
}; |
|||
|
|||
/** |
|||
* Custom function for projects: sort by name and limit to 3 |
|||
*/ |
|||
customProjectsFunction = ( |
|||
entities: PlanData[], |
|||
_entityType: string, |
|||
_maxItems: number, |
|||
): PlanData[] => { |
|||
return entities.sort((a, b) => a.name.localeCompare(b.name)).slice(0, 3); |
|||
}; |
|||
|
|||
/** |
|||
* Simple conflict checker for testing |
|||
*/ |
|||
conflictChecker = (did: string): boolean => { |
|||
return did === this.activeDid; |
|||
}; |
|||
|
|||
/** |
|||
* Toggle between custom and default display functions |
|||
*/ |
|||
toggleCustomFunction(): void { |
|||
this.useCustomFunction = !this.useCustomFunction; |
|||
} |
|||
|
|||
/** |
|||
* Handle entity selection |
|||
*/ |
|||
handleEntitySelected(event: { |
|||
type: "person" | "project" | "special"; |
|||
entityType?: string; |
|||
data: Contact | PlanData | { did?: string; name: string }; |
|||
}): void { |
|||
this.selectedEntity = event; |
|||
} |
|||
|
|||
/** |
|||
* Computed properties to show display counts |
|||
*/ |
|||
get displayedPeopleCount(): number { |
|||
if (this.useCustomFunction) { |
|||
return this.customPeopleFunction(this.people, "people", 5).length; |
|||
} |
|||
return Math.min(5, this.people.length); |
|||
} |
|||
|
|||
get displayedProjectsCount(): number { |
|||
if (this.useCustomFunction) { |
|||
return this.customProjectsFunction(this.projects, "projects", 3).length; |
|||
} |
|||
return Math.min(7, this.projects.length); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
pre { |
|||
background: #f5f5f5; |
|||
padding: 10px; |
|||
border-radius: 4px; |
|||
font-size: 12px; |
|||
} |
|||
</style> |
Loading…
Reference in new issue