polish(frontend): technical review QA (#5097)

* feat: filtering + sorting alignment

* polish: malicious summary modal changes

* feat: better filter row using floating panel

* fix: re-enable request

* fix: lint

* polish: jump back to files tab qol

* feat: scroll to top of next card when done

* fix: show lock icon on preview msg

* feat: download no _blank

* feat: show also marked in notif

* feat: auto expand if only one class in the file

* feat: proper page titles

* fix: text-contrast typo

* fix: lint

* feat: QA changes

* feat: individual report page + more qa

* fix: back btn

* fix: broken import

* feat: quick reply msgs

* fix: in other queue filter

* fix: caching threads wrongly

* fix: flag filter

* feat: toggle enabled by default

* fix: dont make btns opacity 50

---------

Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
Calum H.
2026-01-20 19:56:24 +00:00
committed by GitHub
parent 2af6a1b36f
commit a869086ce9
20 changed files with 1046 additions and 83 deletions

View File

@@ -1,4 +1,5 @@
import { AbstractModule } from '../../../core/abstract-module'
import { ModrinthApiError } from '../../../core/errors'
import type { Labrinth } from '../types'
export class LabrinthProjectsV3Module extends AbstractModule {
@@ -67,4 +68,39 @@ export class LabrinthProjectsV3Module extends AbstractModule {
body: data,
})
}
/**
* Get the organization that owns a project
*
* @param id - Project ID or slug
* @returns Promise resolving to the organization data, or null if the project is not owned by an organization
*/
public async getOrganization(id: string): Promise<Labrinth.Projects.v3.Organization | null> {
try {
return await this.client.request<Labrinth.Projects.v3.Organization>(
`/project/${id}/organization`,
{ api: 'labrinth', version: 3, method: 'GET' },
)
} catch (error) {
// 404 means the project is not owned by an organization
if (error instanceof ModrinthApiError && error.statusCode === 404) {
return null
}
throw error
}
}
/**
* Get the team members of a project
*
* @param id - Project ID or slug
* @returns Promise resolving to an array of team members
*/
public async getMembers(id: string): Promise<Labrinth.Projects.v3.TeamMember[]> {
return this.client.request<Labrinth.Projects.v3.TeamMember[]>(`/project/${id}/members`, {
api: 'labrinth',
version: 3,
method: 'GET',
})
}
}

View File

@@ -121,4 +121,23 @@ export class LabrinthTechReviewInternalModule extends AbstractModule {
body: data,
})
}
/**
* Get the project report and thread for a specific project.
*
* @param projectId - The project ID
* @returns The project report (may be null if no reports exist) and the moderation thread
*/
public async getProjectReport(
projectId: string,
): Promise<Labrinth.TechReview.Internal.ProjectReportResponse> {
return this.client.request<Labrinth.TechReview.Internal.ProjectReportResponse>(
`/moderation/tech-review/project/${projectId}`,
{
api: 'labrinth',
version: 'internal',
method: 'GET',
},
)
}
}

View File

@@ -363,6 +363,40 @@ export namespace Labrinth {
environment?: Environment
[key: string]: unknown
}
export type Organization = {
id: string
slug: string
name: string
team_id: string
description: string
icon_url: string | null
color: number
members: OrganizationMember[]
}
export type OrganizationMember = {
team_id: string
user: Users.v3.User
role: string
is_owner: boolean
permissions: number
organization_permissions: number
accepted: boolean
payouts_split: number
ordering: number
}
export type TeamMember = {
team_id: string
user: Users.v3.User
role: string
permissions: number
accepted: boolean
payouts_split: number
ordering: number
is_owner: boolean
}
}
}
@@ -749,6 +783,9 @@ export namespace Labrinth {
export type SearchProjectsFilter = {
project_type?: string[]
replied_to?: 'replied' | 'unreplied'
project_status?: string[]
issue_type?: string[]
}
export type SearchProjectsSort =
@@ -912,6 +949,11 @@ export namespace Labrinth {
export type DelphiSeverity = 'low' | 'medium' | 'high' | 'severe'
export type DelphiReportIssueStatus = 'pending' | 'safe' | 'unsafe'
export type ProjectReportResponse = {
project_report: ProjectReport | null
thread: Thread
}
}
}
}