Merge branch 'star-projects' into star-projects2, bringing star-projects onto master

This commit is contained in:
2025-09-27 14:23:35 -06:00
20 changed files with 1146 additions and 68 deletions

View File

@@ -51,6 +51,33 @@
<!-- Secondary Tabs -->
<div class="text-center text-slate-500 border-b border-slate-300">
<ul class="flex flex-wrap justify-center gap-4 -mb-px">
<li v-if="isProjectsActive">
<a
href="#"
:class="computedStarredTabStyleClassNames()"
@click="
projects = [];
userProfiles = [];
isStarredActive = true;
isLocalActive = false;
isMappedActive = false;
isAnywhereActive = false;
isSearchVisible = false;
tempSearchBox = null;
searchStarred();
"
>
Starred
<!-- restore when the links don't jump around for different numbers
<span
class="font-semibold text-sm bg-slate-200 px-1.5 py-0.5 rounded-md"
v-if="isLocalActive"
>
{{ localCount > -1 ? localCount : "?" }}
</span>
-->
</a>
</li>
<li>
<a
href="#"
@@ -58,9 +85,11 @@
@click="
projects = [];
userProfiles = [];
isStarredActive = false;
isLocalActive = true;
isMappedActive = false;
isAnywhereActive = false;
isStarredActive = false;
isSearchVisible = true;
tempSearchBox = null;
searchLocal();
@@ -84,9 +113,11 @@
@click="
projects = [];
userProfiles = [];
isStarredActive = false;
isLocalActive = false;
isMappedActive = true;
isAnywhereActive = false;
isStarredActive = false;
isSearchVisible = false;
searchTerms = '';
tempSearchBox = null;
@@ -103,9 +134,11 @@
@click="
projects = [];
userProfiles = [];
isStarredActive = false;
isLocalActive = false;
isMappedActive = false;
isAnywhereActive = true;
isStarredActive = false;
isSearchVisible = true;
tempSearchBox = null;
searchAll();
@@ -201,6 +234,15 @@
>No {{ isProjectsActive ? "projects" : "people" }} were found with
that search.</span
>
<span v-else-if="isStarredActive">
<p>
You have no starred projects. Star some projects to see them here.
</p>
<p class="mt-4">
When you star projects, you will get a notice on the front page when
they change.
</p>
</span>
</p>
</div>
@@ -383,9 +425,12 @@ export default class DiscoverView extends Vue {
allMyDids: Array<string> = [];
apiServer = "";
isLoading = false;
isLocalActive = false;
isMappedActive = false;
isAnywhereActive = true;
isStarredActive = false;
isProjectsActive = true;
isPeopleActive = false;
isSearchVisible = true;
@@ -474,6 +519,8 @@ export default class DiscoverView extends Vue {
leafletObject: L.Map;
};
this.requestTiles(mapRef.leafletObject); // not ideal because I found this from experimentation, not documentation
} else if (this.isStarredActive) {
await this.searchStarred();
} else {
await this.searchAll();
}
@@ -544,6 +591,60 @@ export default class DiscoverView extends Vue {
}
}
public async searchStarred() {
this.resetCounts();
// Clear any previous results
this.projects = [];
this.userProfiles = [];
try {
this.isLoading = true;
// Get starred project IDs from settings
const settings = await this.$accountSettings();
const starredIds = settings.starredPlanHandleIds || [];
if (starredIds.length === 0) {
// No starred projects
return;
}
// This could be optimized to only pull those not already in the cache (endorserServer.ts)
const planHandleIdsJson = JSON.stringify(starredIds);
const endpoint =
this.apiServer +
"/api/v2/report/plans?planHandleIds=" +
encodeURIComponent(planHandleIdsJson);
const response = await this.axios.get(endpoint, {
headers: await getHeaders(this.activeDid),
});
if (response.status !== 200) {
this.notify.error("Failed to load starred projects", TIMEOUTS.SHORT);
return;
}
const starredPlans: PlanData[] = response.data.data;
if (response.data.hitLimit) {
// someday we'll have to let them incrementally load the rest
this.notify.warning(
"Beware: you have so many starred projects that we cannot load them all.",
TIMEOUTS.SHORT,
);
}
this.projects = starredPlans;
} catch (error: unknown) {
logger.error("Error loading starred projects:", error);
this.notify.error(
"Failed to load starred projects. Please try again.",
TIMEOUTS.LONG,
);
} finally {
this.isLoading = false;
}
}
public async searchLocal(beforeId?: string) {
this.resetCounts();
@@ -637,9 +738,12 @@ export default class DiscoverView extends Vue {
const latestProject = this.projects[this.projects.length - 1];
if (this.isLocalActive || this.isMappedActive) {
this.searchLocal(latestProject.rowId);
} else if (this.isStarredActive) {
this.searchStarred();
} else if (this.isAnywhereActive) {
this.searchAll(latestProject.rowId);
}
// Note: Starred tab doesn't support pagination since we load all starred projects at once
} else if (this.isPeopleActive && this.userProfiles.length > 0) {
const latestProfile = this.userProfiles[this.userProfiles.length - 1];
if (this.isLocalActive || this.isMappedActive) {
@@ -779,6 +883,24 @@ export default class DiscoverView extends Vue {
this.$router.push(route);
}
public computedStarredTabStyleClassNames() {
return {
"inline-block": true,
"py-3": true,
"rounded-t-lg": true,
"border-b-2": true,
active: this.isStarredActive,
"text-black": this.isStarredActive,
"border-black": this.isStarredActive,
"font-semibold": this.isStarredActive,
"text-blue-600": !this.isStarredActive,
"border-transparent": !this.isStarredActive,
"hover:border-slate-400": !this.isStarredActive,
};
}
public computedLocalTabStyleClassNames() {
return {
"inline-block": true,