forked from trent_larson/crowd-funder-for-time-pwa
fix missing starred projects in gift selection, and highlight filter on home view if set
This commit is contained in:
@@ -139,17 +139,17 @@ projects, and special entities with selection. * * @author Matthew Raymer */
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else-if="entityType === 'projects'">
|
<template v-else-if="entityType === 'projects'">
|
||||||
<!-- When showing projects without search: split into recently bookmarked and rest -->
|
<!-- When showing projects without search: split into recently starred and rest -->
|
||||||
<template v-if="!searchTerm.trim()">
|
<template v-if="!searchTerm.trim()">
|
||||||
<!-- Recently Bookmarked Section -->
|
<!-- Recently Starred Section -->
|
||||||
<template v-if="recentBookmarkedProjects.length > 0">
|
<template v-if="recentStarredProjectsToShow.length > 0">
|
||||||
<li
|
<li
|
||||||
class="text-xs font-semibold text-slate-500 uppercase pt-5 pb-1.5 px-2 border-b border-slate-300"
|
class="text-xs font-semibold text-slate-500 uppercase pt-5 pb-1.5 px-2 border-b border-slate-300"
|
||||||
>
|
>
|
||||||
Recently Bookmarked
|
Recently Starred
|
||||||
</li>
|
</li>
|
||||||
<ProjectCard
|
<ProjectCard
|
||||||
v-for="project in recentBookmarkedProjects"
|
v-for="project in recentStarredProjectsToShow"
|
||||||
:key="project.handleId"
|
:key="project.handleId"
|
||||||
:project="project"
|
:project="project"
|
||||||
:active-did="activeDid"
|
:active-did="activeDid"
|
||||||
@@ -164,7 +164,7 @@ projects, and special entities with selection. * * @author Matthew Raymer */
|
|||||||
|
|
||||||
<!-- Rest of Projects Section -->
|
<!-- Rest of Projects Section -->
|
||||||
<li
|
<li
|
||||||
v-if="recentBookmarkedProjects.length > 0"
|
v-if="remainingProjects.length > 0"
|
||||||
class="text-xs font-semibold text-slate-500 uppercase pt-5 pb-1.5 px-2 border-b border-slate-300"
|
class="text-xs font-semibold text-slate-500 uppercase pt-5 pb-1.5 px-2 border-b border-slate-300"
|
||||||
>
|
>
|
||||||
All Projects
|
All Projects
|
||||||
@@ -223,7 +223,7 @@ import { TIMEOUTS } from "@/utils/notify";
|
|||||||
const INITIAL_BATCH_SIZE = 20;
|
const INITIAL_BATCH_SIZE = 20;
|
||||||
const INCREMENT_SIZE = 20;
|
const INCREMENT_SIZE = 20;
|
||||||
const RECENT_CONTACTS_COUNT = 3;
|
const RECENT_CONTACTS_COUNT = 3;
|
||||||
const RECENT_BOOKMARKED_PROJECTS_COUNT = 10;
|
const RECENT_STARRED_PROJECTS_COUNT = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EntityGrid - Unified grid layout for displaying people or projects
|
* EntityGrid - Unified grid layout for displaying people or projects
|
||||||
@@ -272,8 +272,9 @@ export default class EntityGrid extends Vue {
|
|||||||
infiniteScrollReset?: () => void;
|
infiniteScrollReset?: () => void;
|
||||||
scrollContainer?: HTMLElement;
|
scrollContainer?: HTMLElement;
|
||||||
|
|
||||||
// Starred projects state (for showing recently bookmarked projects)
|
// Starred projects state (for showing recently starred projects)
|
||||||
starredPlanHandleIds: string[] = [];
|
starredPlanHandleIds: string[] = [];
|
||||||
|
recentStarredProjects: PlanData[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of entities to display
|
* Array of entities to display
|
||||||
@@ -425,40 +426,19 @@ export default class EntityGrid extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the 3 most recently bookmarked projects (when showing projects and not searching)
|
* Get the 3 most recently starred projects (when showing projects and not searching)
|
||||||
* The starredPlanHandleIds array order represents bookmark order (newest at the end)
|
* Returns the cached member field
|
||||||
*/
|
*/
|
||||||
get recentBookmarkedProjects(): PlanData[] {
|
get recentStarredProjectsToShow(): PlanData[] {
|
||||||
if (
|
if (this.entityType !== "projects" || this.searchTerm.trim()) {
|
||||||
this.entityType !== "projects" ||
|
|
||||||
this.searchTerm.trim() ||
|
|
||||||
this.starredPlanHandleIds.length === 0
|
|
||||||
) {
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
return this.recentStarredProjects;
|
||||||
const projects = this.entitiesToUse as PlanData[];
|
|
||||||
if (projects.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the last 3 starred IDs (most recently bookmarked)
|
|
||||||
const recentStarredIds = this.starredPlanHandleIds.slice(
|
|
||||||
-RECENT_BOOKMARKED_PROJECTS_COUNT,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Find projects matching those IDs, sorting with newest first
|
|
||||||
const recentProjects = recentStarredIds
|
|
||||||
.map((id) => projects.find((p) => p.handleId === id))
|
|
||||||
.filter((p): p is PlanData => p !== undefined)
|
|
||||||
.reverse();
|
|
||||||
|
|
||||||
return recentProjects;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all projects (when showing projects and not searching)
|
* Get all projects (when showing projects and not searching)
|
||||||
* Includes projects shown in "Recently Bookmarked" section as well
|
* Includes projects shown in "Recently Starred" section as well
|
||||||
* Uses infinite scroll to control how many are displayed
|
* Uses infinite scroll to control how many are displayed
|
||||||
*/
|
*/
|
||||||
get remainingProjects(): PlanData[] {
|
get remainingProjects(): PlanData[] {
|
||||||
@@ -520,6 +500,124 @@ export default class EntityGrid extends Vue {
|
|||||||
return UNNAMED_ENTITY_NAME;
|
return UNNAMED_ENTITY_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize infinite scroll on mount
|
||||||
|
*/
|
||||||
|
async mounted(): Promise<void> {
|
||||||
|
if (this.entityType === "projects") {
|
||||||
|
const settings = await this.$accountSettings();
|
||||||
|
this.apiServer = settings.apiServer || "";
|
||||||
|
|
||||||
|
// Load starred project IDs for showing recently starred projects
|
||||||
|
this.starredPlanHandleIds = settings.starredPlanHandleIds || [];
|
||||||
|
|
||||||
|
// Load projects on mount if entities prop not provided
|
||||||
|
this.isLoadingProjects = true;
|
||||||
|
if (!this.entities) {
|
||||||
|
await this.loadProjects();
|
||||||
|
}
|
||||||
|
await this.loadRecentStarredProjects();
|
||||||
|
this.isLoadingProjects = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate entities prop for people
|
||||||
|
if (this.entityType === "people" && !this.entities) {
|
||||||
|
logger.error(
|
||||||
|
"EntityGrid: entities prop is required when entityType is 'people'",
|
||||||
|
);
|
||||||
|
if (this.notify) {
|
||||||
|
this.notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "danger",
|
||||||
|
title: "Error",
|
||||||
|
text: "Contacts data is required but not provided.",
|
||||||
|
},
|
||||||
|
TIMEOUTS.SHORT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const container = this.$refs.scrollContainer as HTMLElement;
|
||||||
|
|
||||||
|
if (container) {
|
||||||
|
const { reset } = useInfiniteScroll(
|
||||||
|
container,
|
||||||
|
async () => {
|
||||||
|
// Search mode: handle search pagination
|
||||||
|
if (this.searchTerm.trim()) {
|
||||||
|
if (this.entityType === "projects") {
|
||||||
|
// Projects: load more search results if available
|
||||||
|
if (
|
||||||
|
this.displayedCount >= this.filteredEntities.length &&
|
||||||
|
this.searchBeforeId &&
|
||||||
|
!this.isLoadingSearchMore
|
||||||
|
) {
|
||||||
|
this.isLoadingSearchMore = true;
|
||||||
|
try {
|
||||||
|
const searchLower = this.searchTerm.toLowerCase().trim();
|
||||||
|
await this.loadProjects(this.searchBeforeId, searchLower);
|
||||||
|
// After loading more, reset scroll state to allow further loading
|
||||||
|
this.infiniteScrollReset?.();
|
||||||
|
} catch (error) {
|
||||||
|
logger.error("Error loading more search results:", error);
|
||||||
|
// Error already handled in loadProjects
|
||||||
|
} finally {
|
||||||
|
this.isLoadingSearchMore = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Show more from already-loaded search results
|
||||||
|
this.displayedCount += INCREMENT_SIZE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Contacts: show more from already-filtered results
|
||||||
|
this.displayedCount += INCREMENT_SIZE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Non-search mode
|
||||||
|
if (this.entityType === "projects") {
|
||||||
|
const projectsToCheck = this.entities || this.allProjects;
|
||||||
|
const beforeId = this.entities ? undefined : this.loadBeforeId;
|
||||||
|
|
||||||
|
// If using internal state and need to load more from server
|
||||||
|
if (
|
||||||
|
!this.entities &&
|
||||||
|
this.displayedCount >= projectsToCheck.length &&
|
||||||
|
beforeId &&
|
||||||
|
!this.isLoadingProjects
|
||||||
|
) {
|
||||||
|
this.isLoadingProjects = true;
|
||||||
|
try {
|
||||||
|
await this.loadProjects(beforeId);
|
||||||
|
// After loading more, reset scroll state to allow further loading
|
||||||
|
this.infiniteScrollReset?.();
|
||||||
|
} catch (error) {
|
||||||
|
logger.error("Error loading more projects:", error);
|
||||||
|
// Error already handled in loadProjects
|
||||||
|
} finally {
|
||||||
|
this.isLoadingProjects = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Normal case: increment displayedCount to show more from memory
|
||||||
|
this.displayedCount += INCREMENT_SIZE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// People: increment displayedCount to show more from memory
|
||||||
|
this.displayedCount += INCREMENT_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
distance: 50, // pixels from bottom
|
||||||
|
canLoadMore: () => this.canLoadMore(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.infiniteScrollReset = reset;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a person DID is conflicted
|
* Check if a person DID is conflicted
|
||||||
*/
|
*/
|
||||||
@@ -604,7 +702,7 @@ export default class EntityGrid extends Vue {
|
|||||||
if (this.entityType === "projects") {
|
if (this.entityType === "projects") {
|
||||||
// Server-side search for projects (initial load, no beforeId)
|
// Server-side search for projects (initial load, no beforeId)
|
||||||
const searchLower = this.searchTerm.toLowerCase().trim();
|
const searchLower = this.searchTerm.toLowerCase().trim();
|
||||||
await this.fetchProjects(undefined, searchLower);
|
await this.loadProjects(undefined, searchLower);
|
||||||
} else {
|
} else {
|
||||||
// Client-side filtering for contacts (complete list)
|
// Client-side filtering for contacts (complete list)
|
||||||
await this.performContactSearch();
|
await this.performContactSearch();
|
||||||
@@ -618,6 +716,57 @@ export default class EntityGrid extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the most recently starred projects
|
||||||
|
* The starredPlanHandleIds array order represents starred order (newest at the end)
|
||||||
|
*/
|
||||||
|
async loadRecentStarredProjects(): Promise<void> {
|
||||||
|
if (
|
||||||
|
this.entityType !== "projects" ||
|
||||||
|
this.searchTerm.trim() ||
|
||||||
|
this.starredPlanHandleIds.length === 0
|
||||||
|
) {
|
||||||
|
this.recentStarredProjects = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the last 3 starred IDs (most recently starred)
|
||||||
|
const recentStarredIds = this.starredPlanHandleIds.slice(
|
||||||
|
-RECENT_STARRED_PROJECTS_COUNT,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find projects matching those IDs, sorting with newest first
|
||||||
|
const projects = this.entitiesToUse as PlanData[];
|
||||||
|
const recentProjects = recentStarredIds
|
||||||
|
.map((id) => projects.find((p) => p.handleId === id))
|
||||||
|
.filter((p): p is PlanData => p !== undefined)
|
||||||
|
.reverse();
|
||||||
|
|
||||||
|
// If any projects are not found, fetch them from the API server
|
||||||
|
if (recentProjects.length < recentStarredIds.length) {
|
||||||
|
const missingIds = recentStarredIds.filter(
|
||||||
|
(id) => !recentProjects.some((p) => p.handleId === id),
|
||||||
|
);
|
||||||
|
const missingProjects = await this.fetchProjectsByIds(missingIds);
|
||||||
|
recentProjects.push(...missingProjects);
|
||||||
|
}
|
||||||
|
this.recentStarredProjects = recentProjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchProjectsByIds(ids: string[]): Promise<PlanData[]> {
|
||||||
|
const idsString = encodeURIComponent(JSON.stringify(ids));
|
||||||
|
const url = `${this.apiServer}/api/v2/report/plans?planHandleIds=${idsString}`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: await getHeaders(this.activeDid),
|
||||||
|
});
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error("Failed to fetch projects");
|
||||||
|
}
|
||||||
|
const results = await response.json();
|
||||||
|
return results.data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch projects from API server
|
* Fetch projects from API server
|
||||||
* Unified method for both loading all projects and searching projects.
|
* Unified method for both loading all projects and searching projects.
|
||||||
@@ -627,10 +776,7 @@ export default class EntityGrid extends Vue {
|
|||||||
* @param beforeId - Optional rowId for pagination (loads projects before this ID)
|
* @param beforeId - Optional rowId for pagination (loads projects before this ID)
|
||||||
* @param claimContents - Optional search term (if provided, performs search; if not, loads all)
|
* @param claimContents - Optional search term (if provided, performs search; if not, loads all)
|
||||||
*/
|
*/
|
||||||
async fetchProjects(
|
async loadProjects(beforeId?: string, claimContents?: string): Promise<void> {
|
||||||
beforeId?: string,
|
|
||||||
claimContents?: string,
|
|
||||||
): Promise<void> {
|
|
||||||
if (!this.apiServer) {
|
if (!this.apiServer) {
|
||||||
if (claimContents) {
|
if (claimContents) {
|
||||||
this.filteredEntities = [];
|
this.filteredEntities = [];
|
||||||
@@ -874,129 +1020,6 @@ export default class EntityGrid extends Vue {
|
|||||||
return this.displayedCount < this.entities.length;
|
return this.displayedCount < this.entities.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize infinite scroll on mount
|
|
||||||
*/
|
|
||||||
async mounted(): Promise<void> {
|
|
||||||
// Load apiServer for project searches/loads
|
|
||||||
if (this.entityType === "projects") {
|
|
||||||
const settings = await this.$accountSettings();
|
|
||||||
this.apiServer = settings.apiServer || "";
|
|
||||||
|
|
||||||
// Load starred project IDs for showing recently bookmarked projects
|
|
||||||
this.starredPlanHandleIds = settings.starredPlanHandleIds || [];
|
|
||||||
|
|
||||||
// Load projects on mount if entities prop not provided
|
|
||||||
if (!this.entities && this.apiServer) {
|
|
||||||
this.isLoadingProjects = true;
|
|
||||||
try {
|
|
||||||
await this.fetchProjects();
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("Error loading projects on mount:", error);
|
|
||||||
} finally {
|
|
||||||
this.isLoadingProjects = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate entities prop for people
|
|
||||||
if (this.entityType === "people" && !this.entities) {
|
|
||||||
logger.error(
|
|
||||||
"EntityGrid: entities prop is required when entityType is 'people'",
|
|
||||||
);
|
|
||||||
if (this.notify) {
|
|
||||||
this.notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "Contacts data is required but not provided.",
|
|
||||||
},
|
|
||||||
TIMEOUTS.SHORT,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
const container = this.$refs.scrollContainer as HTMLElement;
|
|
||||||
|
|
||||||
if (container) {
|
|
||||||
const { reset } = useInfiniteScroll(
|
|
||||||
container,
|
|
||||||
async () => {
|
|
||||||
// Search mode: handle search pagination
|
|
||||||
if (this.searchTerm.trim()) {
|
|
||||||
if (this.entityType === "projects") {
|
|
||||||
// Projects: load more search results if available
|
|
||||||
if (
|
|
||||||
this.displayedCount >= this.filteredEntities.length &&
|
|
||||||
this.searchBeforeId &&
|
|
||||||
!this.isLoadingSearchMore
|
|
||||||
) {
|
|
||||||
this.isLoadingSearchMore = true;
|
|
||||||
try {
|
|
||||||
const searchLower = this.searchTerm.toLowerCase().trim();
|
|
||||||
await this.fetchProjects(this.searchBeforeId, searchLower);
|
|
||||||
// After loading more, reset scroll state to allow further loading
|
|
||||||
this.infiniteScrollReset?.();
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("Error loading more search results:", error);
|
|
||||||
// Error already handled in fetchProjects
|
|
||||||
} finally {
|
|
||||||
this.isLoadingSearchMore = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Show more from already-loaded search results
|
|
||||||
this.displayedCount += INCREMENT_SIZE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Contacts: show more from already-filtered results
|
|
||||||
this.displayedCount += INCREMENT_SIZE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Non-search mode
|
|
||||||
if (this.entityType === "projects") {
|
|
||||||
const projectsToCheck = this.entities || this.allProjects;
|
|
||||||
const beforeId = this.entities ? undefined : this.loadBeforeId;
|
|
||||||
|
|
||||||
// If using internal state and need to load more from server
|
|
||||||
if (
|
|
||||||
!this.entities &&
|
|
||||||
this.displayedCount >= projectsToCheck.length &&
|
|
||||||
beforeId &&
|
|
||||||
!this.isLoadingProjects
|
|
||||||
) {
|
|
||||||
this.isLoadingProjects = true;
|
|
||||||
try {
|
|
||||||
await this.fetchProjects(beforeId);
|
|
||||||
// After loading more, reset scroll state to allow further loading
|
|
||||||
this.infiniteScrollReset?.();
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("Error loading more projects:", error);
|
|
||||||
// Error already handled in fetchProjects
|
|
||||||
} finally {
|
|
||||||
this.isLoadingProjects = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Normal case: increment displayedCount to show more from memory
|
|
||||||
this.displayedCount += INCREMENT_SIZE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// People: increment displayedCount to show more from memory
|
|
||||||
this.displayedCount += INCREMENT_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
distance: 50, // pixels from bottom
|
|
||||||
canLoadMore: () => this.canLoadMore(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
this.infiniteScrollReset = reset;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit methods using @Emit decorator
|
// Emit methods using @Emit decorator
|
||||||
|
|
||||||
@Emit("entity-selected")
|
@Emit("entity-selected")
|
||||||
@@ -1024,28 +1047,17 @@ export default class EntityGrid extends Vue {
|
|||||||
|
|
||||||
// When switching to projects, load them if not provided via entities prop
|
// When switching to projects, load them if not provided via entities prop
|
||||||
if (newType === "projects" && !this.entities) {
|
if (newType === "projects" && !this.entities) {
|
||||||
// Ensure apiServer is loaded
|
|
||||||
if (!this.apiServer) {
|
|
||||||
const settings = await this.$accountSettings();
|
const settings = await this.$accountSettings();
|
||||||
this.apiServer = settings.apiServer || "";
|
this.apiServer = settings.apiServer || "";
|
||||||
this.starredPlanHandleIds = settings.starredPlanHandleIds || [];
|
this.starredPlanHandleIds = settings.starredPlanHandleIds || [];
|
||||||
}
|
|
||||||
|
|
||||||
// Load projects if we have an API server
|
if (this.allProjects.length === 0) {
|
||||||
if (this.apiServer && this.allProjects.length === 0) {
|
|
||||||
this.isLoadingProjects = true;
|
this.isLoadingProjects = true;
|
||||||
try {
|
await this.loadProjects();
|
||||||
await this.fetchProjects();
|
await this.loadRecentStarredProjects();
|
||||||
} catch (error) {
|
|
||||||
logger.error(
|
|
||||||
"Error loading projects when switching to projects:",
|
|
||||||
error,
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
this.isLoadingProjects = false;
|
this.isLoadingProjects = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Clear project state when switching away from projects
|
// Clear project state when switching away from projects
|
||||||
if (newType === "people") {
|
if (newType === "people") {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ properties * * @author Matthew Raymer */
|
|||||||
|
|
||||||
<EntityGrid
|
<EntityGrid
|
||||||
:entity-type="shouldShowProjects ? 'projects' : 'people'"
|
:entity-type="shouldShowProjects ? 'projects' : 'people'"
|
||||||
:entities="shouldShowProjects ? projects || undefined : allContacts"
|
:entities="shouldShowProjects ? undefined : allContacts"
|
||||||
:active-did="activeDid"
|
:active-did="activeDid"
|
||||||
:all-my-dids="allMyDids"
|
:all-my-dids="allMyDids"
|
||||||
:all-contacts="allContacts"
|
:all-contacts="allContacts"
|
||||||
@@ -87,10 +87,6 @@ export default class EntitySelectionStep extends Vue {
|
|||||||
@Prop({ required: true })
|
@Prop({ required: true })
|
||||||
stepType!: "giver" | "recipient";
|
stepType!: "giver" | "recipient";
|
||||||
|
|
||||||
/** Array of available projects (optional - EntityGrid loads internally if not provided) */
|
|
||||||
@Prop({ required: false })
|
|
||||||
projects?: PlanData[];
|
|
||||||
|
|
||||||
/** Array of available contacts */
|
/** Array of available contacts */
|
||||||
@Prop({ required: true })
|
@Prop({ required: true })
|
||||||
allContacts!: Contact[];
|
allContacts!: Contact[];
|
||||||
|
|||||||
@@ -11,10 +11,6 @@
|
|||||||
:step-type="stepType"
|
:step-type="stepType"
|
||||||
:giver-entity-type="currentGiverEntityType"
|
:giver-entity-type="currentGiverEntityType"
|
||||||
:recipient-entity-type="currentRecipientEntityType"
|
:recipient-entity-type="currentRecipientEntityType"
|
||||||
:show-projects="
|
|
||||||
currentGiverEntityType === 'project' ||
|
|
||||||
currentRecipientEntityType === 'project'
|
|
||||||
"
|
|
||||||
:all-contacts="allContacts"
|
:all-contacts="allContacts"
|
||||||
:active-did="activeDid"
|
:active-did="activeDid"
|
||||||
:all-my-dids="allMyDids"
|
:all-my-dids="allMyDids"
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ export interface DatabaseExport {
|
|||||||
const _memoryLogs: string[] = [];
|
const _memoryLogs: string[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enhanced mixin that provides cached platform service access and utility methods
|
* Enhanced mixin that provides platform utility methods
|
||||||
* with smart caching layer for ultimate performance optimization
|
|
||||||
*/
|
*/
|
||||||
export const PlatformServiceMixin = {
|
export const PlatformServiceMixin = {
|
||||||
data() {
|
data() {
|
||||||
@@ -1011,7 +1010,7 @@ export const PlatformServiceMixin = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load settings with optional defaults WITHOUT caching - $settings()
|
* Load settings with optional defaults - $settings()
|
||||||
* Settings are loaded fresh every time for immediate consistency
|
* Settings are loaded fresh every time for immediate consistency
|
||||||
* @param defaults Optional default values
|
* @param defaults Optional default values
|
||||||
* @returns Fresh settings object from database
|
* @returns Fresh settings object from database
|
||||||
@@ -1034,11 +1033,11 @@ export const PlatformServiceMixin = {
|
|||||||
settings.apiServer = DEFAULT_ENDORSER_API_SERVER;
|
settings.apiServer = DEFAULT_ENDORSER_API_SERVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return settings; // Return fresh data without caching
|
return settings;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load account-specific settings WITHOUT caching - $accountSettings()
|
* Load account-specific settings - $accountSettings()
|
||||||
* Settings are loaded fresh every time for immediate consistency
|
* Settings are loaded fresh every time for immediate consistency
|
||||||
* @param did DID identifier (optional, uses current active DID)
|
* @param did DID identifier (optional, uses current active DID)
|
||||||
* @param defaults Optional default values
|
* @param defaults Optional default values
|
||||||
@@ -2242,7 +2241,7 @@ export const PlatformServiceMixin = {
|
|||||||
// =================================================
|
// =================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enhanced interface with caching utility methods
|
* Enhanced interface
|
||||||
*/
|
*/
|
||||||
export interface IPlatformServiceMixin {
|
export interface IPlatformServiceMixin {
|
||||||
platformService: PlatformService;
|
platformService: PlatformService;
|
||||||
|
|||||||
@@ -167,18 +167,12 @@ Raymer * @version 1.0.0 */
|
|||||||
<div class="flex gap-2 items-center mb-3">
|
<div class="flex gap-2 items-center mb-3">
|
||||||
<h2 class="font-bold">Latest Activity</h2>
|
<h2 class="font-bold">Latest Activity</h2>
|
||||||
<button
|
<button
|
||||||
v-if="resultsAreFiltered()"
|
class="block ms-auto text-sm text-center text-white p-1.5 rounded-full shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)]"
|
||||||
class="block ms-auto text-sm text-center text-white bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-1.5 rounded-full"
|
:class="
|
||||||
@click="openFeedFilters()"
|
isAnyFeedFilterOn
|
||||||
>
|
? 'bg-gradient-to-b from-blue-400 to-blue-700'
|
||||||
<font-awesome
|
: 'bg-gradient-to-b from-slate-400 to-slate-700'
|
||||||
icon="filter"
|
"
|
||||||
class="block text-center w-[1em] translate-y-[0.05em]"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
v-else
|
|
||||||
class="block ms-auto text-sm text-center text-white bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-1.5 rounded-full"
|
|
||||||
@click="openFeedFilters()"
|
@click="openFeedFilters()"
|
||||||
>
|
>
|
||||||
<font-awesome
|
<font-awesome
|
||||||
@@ -971,17 +965,6 @@ export default class HomeView extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if feed results are being filtered
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
* Used in template for filter button display
|
|
||||||
* @returns true if visible or nearby filters are active
|
|
||||||
*/
|
|
||||||
resultsAreFiltered() {
|
|
||||||
return this.isFeedFilteredByVisible || this.isFeedFilteredByNearby;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if browser notifications are supported
|
* Checks if browser notifications are supported
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user