Add documents page to the compliance portal
Build the Trust Center documents page: a unified list of published documents, uploaded files, and audit reports, grouped into category sections. An All/Public/Private tab bar filters the list by trust center visibility. Expose that filter over the trust v1 API by adding a TrustCenterVisibility enum and a shared TrustCenterVisibilityFilter input, wiring it through the documents, audits, and trustCenterFiles connections down to the existing coredata SQL filters. "All" keeps the default public+private slice; the other tabs pin a single visibility. Access controls are display-only for now (auth is handled separately): authorized or public entries open their exported PDF via the export mutations, requested entries show a pending state, and everything else shows an inert Get Access affordance. Add the v2 Tabs and Toaster kit components (Base UI headless) needed by the page and mount a toast provider at the app root for mutation feedback. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -16,6 +16,7 @@ type TrustCenter implements Node {
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
filter: TrustCenterVisibilityFilter
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
audits(
|
||||
@@ -23,6 +24,7 @@ type TrustCenter implements Node {
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
filter: TrustCenterVisibilityFilter
|
||||
): AuditConnection! @goField(forceResolver: true)
|
||||
|
||||
subprocessors(
|
||||
@@ -50,6 +52,7 @@ type TrustCenter implements Node {
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
filter: TrustCenterVisibilityFilter
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
|
||||
complianceFrameworks(
|
||||
@@ -95,6 +98,18 @@ enum DocumentType
|
||||
)
|
||||
}
|
||||
|
||||
enum TrustCenterVisibility
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.TrustCenterVisibility") {
|
||||
PRIVATE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.TrustCenterVisibilityPrivate")
|
||||
PUBLIC
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.TrustCenterVisibilityPublic")
|
||||
}
|
||||
|
||||
input TrustCenterVisibilityFilter {
|
||||
visibility: TrustCenterVisibility
|
||||
}
|
||||
|
||||
type Document implements Node @nda {
|
||||
id: ID!
|
||||
title: String!
|
||||
|
||||
@@ -758,7 +758,7 @@ func (r *trustCenterResolver) Organization(ctx context.Context, obj *types.Trust
|
||||
}
|
||||
|
||||
// Documents is the resolver for the documents field.
|
||||
func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentConnection, error) {
|
||||
func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, filter *types.TrustCenterVisibilityFilter) (*types.DocumentConnection, error) {
|
||||
compliancePage := compliancepage.CompliancePageFromContext(ctx)
|
||||
scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID)
|
||||
trustService := r.trust
|
||||
@@ -768,7 +768,12 @@ func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCen
|
||||
}
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
documentPage, err := trustService.Documents.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor)
|
||||
documentFilter := coredata.NewDocumentTrustCenterFilter()
|
||||
if filter != nil && filter.Visibility != nil {
|
||||
documentFilter = documentFilter.WithTrustCenterVisibilities(*filter.Visibility)
|
||||
}
|
||||
|
||||
documentPage, err := trustService.Documents.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, documentFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list public documents", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
@@ -778,7 +783,7 @@ func (r *trustCenterResolver) Documents(ctx context.Context, obj *types.TrustCen
|
||||
}
|
||||
|
||||
// Audits is the resolver for the audits field.
|
||||
func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.AuditConnection, error) {
|
||||
func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, filter *types.TrustCenterVisibilityFilter) (*types.AuditConnection, error) {
|
||||
compliancePage := compliancepage.CompliancePageFromContext(ctx)
|
||||
scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID)
|
||||
trustService := r.trust
|
||||
@@ -788,7 +793,12 @@ func (r *trustCenterResolver) Audits(ctx context.Context, obj *types.TrustCenter
|
||||
}
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
auditPage, err := trustService.Audits.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor)
|
||||
auditFilter := coredata.NewAuditTrustCenterFilter()
|
||||
if filter != nil && filter.Visibility != nil {
|
||||
auditFilter = auditFilter.WithTrustCenterVisibilities(*filter.Visibility)
|
||||
}
|
||||
|
||||
auditPage, err := trustService.Audits.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, auditFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list public audits", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
@@ -888,7 +898,7 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe
|
||||
}
|
||||
|
||||
// TrustCenterFiles is the resolver for the trustCenterFiles field.
|
||||
func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterFileConnection, error) {
|
||||
func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, filter *types.TrustCenterVisibilityFilter) (*types.TrustCenterFileConnection, error) {
|
||||
compliancePage := compliancepage.CompliancePageFromContext(ctx)
|
||||
scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID)
|
||||
trustService := r.trust
|
||||
@@ -898,14 +908,19 @@ func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.T
|
||||
}
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
filter := coredata.NewTrustCenterFileFilter(
|
||||
coredata.WithTrustCenterFileVisibilities(
|
||||
coredata.TrustCenterVisibilityPublic,
|
||||
coredata.TrustCenterVisibilityPrivate,
|
||||
),
|
||||
visibilities := []coredata.TrustCenterVisibility{
|
||||
coredata.TrustCenterVisibilityPublic,
|
||||
coredata.TrustCenterVisibilityPrivate,
|
||||
}
|
||||
if filter != nil && filter.Visibility != nil {
|
||||
visibilities = []coredata.TrustCenterVisibility{*filter.Visibility}
|
||||
}
|
||||
|
||||
fileFilter := coredata.NewTrustCenterFileFilter(
|
||||
coredata.WithTrustCenterFileVisibilities(visibilities...),
|
||||
)
|
||||
|
||||
trustCenterFilePage, err := trustService.TrustCenterFiles.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, filter)
|
||||
trustCenterFilePage, err := trustService.TrustCenterFiles.ListForOrganizationId(ctx, scope, obj.Organization.ID, cursor, fileFilter)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list public trust center files", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
|
||||
Reference in New Issue
Block a user