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.pull/142/head
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