Skip to content

Commit

Permalink
Show projects you are a member of on profile
Browse files Browse the repository at this point in the history
Closes #1380
  • Loading branch information
kennytv committed Jul 30, 2024
1 parent a7de374 commit 9b94a02
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.papermc.hangar.controller.extras.pagination.filters.projects.ProjectCategoryFilter;
import io.papermc.hangar.controller.extras.pagination.filters.projects.ProjectLicenseFilter;
import io.papermc.hangar.controller.extras.pagination.filters.projects.ProjectMCVersionFilter;
import io.papermc.hangar.controller.extras.pagination.filters.projects.ProjectMemberFilter;
import io.papermc.hangar.controller.extras.pagination.filters.projects.ProjectPlatformFilter;
import io.papermc.hangar.controller.extras.pagination.filters.projects.ProjectQueryFilter;
import io.papermc.hangar.controller.extras.pagination.filters.projects.ProjectTagFilter;
Expand Down Expand Up @@ -58,7 +59,7 @@ public ResponseEntity<PaginatedResult<ProjectMember>> getProjectMembers(final St
}

@Override
@ApplicableFilters({ProjectCategoryFilter.class, ProjectPlatformFilter.class, ProjectAuthorFilter.class, ProjectQueryFilter.class, ProjectLicenseFilter.class, ProjectMCVersionFilter.class, ProjectTagFilter.class})
@ApplicableFilters({ProjectCategoryFilter.class, ProjectPlatformFilter.class, ProjectAuthorFilter.class, ProjectQueryFilter.class, ProjectLicenseFilter.class, ProjectMCVersionFilter.class, ProjectTagFilter.class, ProjectMemberFilter.class})
@ApplicableSorters({SorterRegistry.VIEWS, SorterRegistry.DOWNLOADS, SorterRegistry.NEWEST, SorterRegistry.STARS, SorterRegistry.UPDATED, SorterRegistry.RECENT_DOWNLOADS, SorterRegistry.RECENT_VIEWS, SorterRegistry.SLUG})
public ResponseEntity<PaginatedResult<Project>> getProjects(final boolean prioritizeExactMatch, final @NotNull RequestPagination pagination) {
final boolean seeHidden = this.getGlobalPermissions().has(Permission.SeeHidden);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.papermc.hangar.controller.extras.pagination.filters.projects;

import io.papermc.hangar.controller.extras.pagination.Filter;
import java.util.Locale;
import java.util.Set;
import org.jdbi.v3.core.statement.SqlStatement;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.NativeWebRequest;

@Component
public class ProjectMemberFilter implements Filter<ProjectMemberFilter.ProjectMemberFilterInstance, String> {

@Override
public Set<String> getQueryParamNames() {
return Set.of("member");
}

@Override
public String getDescription() {
return "The member of the project";
}

@Override
public String getValue(final NativeWebRequest webRequest) {
return webRequest.getParameter(this.getSingleQueryParam());
}

@Override
public @NotNull ProjectMemberFilterInstance create(final NativeWebRequest webRequest) {
return new ProjectMemberFilterInstance(this.getValue(webRequest));
}

static class ProjectMemberFilterInstance implements Filter.FilterInstance {

private final String memberName;

ProjectMemberFilterInstance(final String memberName) {
this.memberName = memberName;
}

@Override
public void createSql(final StringBuilder sb, final SqlStatement<?> q) {
sb.append(" AND :memberName = ANY(hp.project_member_names)");
q.bind("memberName", this.memberName.toLowerCase(Locale.ROOT));
}

@Override
public String toString() {
return "ProjectMemberFilterInstance{" +
"memberName='" + this.memberName + '\'' +
'}';
}
}
}
2 changes: 2 additions & 0 deletions backend/src/main/resources/db/migration/R__02_home_view.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ DROP MATERIALIZED VIEW IF EXISTS home_projects CASCADE;
CREATE MATERIALIZED VIEW home_projects AS
SELECT p.id,
array_agg(DISTINCT pm.user_id) AS project_members,
array_agg(DISTINCT lower(u.name)) AS project_member_names,
coalesce(pva.views::bigint, 0::bigint) AS views,
coalesce(pda.downloads::bigint, 0::bigint) AS downloads,
coalesce(pvr.recent_views::bigint, 0::bigint) AS recent_views,
Expand All @@ -47,6 +48,7 @@ CREATE MATERIALIZED VIEW home_projects AS
FROM projects p
LEFT JOIN project_versions lv ON p.id = lv.project_id
JOIN project_members_all pm ON p.id = pm.id
JOIN users u ON pm.user_id = u.id
LEFT JOIN (SELECT p_1.id,
count(ps_1.user_id) AS stars
FROM projects p_1
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/composables/useApiHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export async function useUserData(
useApi<PaginatedResultProjectCompact>(`users/${user}/starred`),
useApi<PaginatedResultProjectCompact>(`users/${user}/watching`),
useApi<PaginatedResultProject>(`projects`, "get", {
owner: user,
member: user,
...projectsParams,
}),
useInternalApi<{ [key: string]: OrganizationRoleTable }>(`organizations/${user}/userOrganizations`),
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/[user]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ watchDebounced(
// set the request params
await router.replace({ query: { page: page.value, ...paramsWithoutLimit } });
// do the update
projects.value = await useApi<PaginatedResultProject>("projects", "get", { owner: props.user?.name, ...requestParams.value });
projects.value = await useApi<PaginatedResultProject>("projects", "get", { member: props.user?.name, ...requestParams.value });
},
{ deep: true, debounce: 250 }
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/notifications.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function updateSelectedNotifications() {
</div>
</template>
</Pagination>
<Button v-if="notifications?.result && selectedTab === 'unread' && notifications.result.length !== 0" size="small" class="mt-2" @click="markAllAsRead">
<Button v-if="notifications?.result?.length && selectedTab === 'unread'" size="small" class="mt-2" @click="markAllAsRead">
{{ i18n.t("notifications.readAll") }}
</Button>
</Card>
Expand Down

0 comments on commit 9b94a02

Please sign in to comment.