Fix signature count mismatch with signatures tab on documents
The badge on a document version showed signatures filtered by
activeContract: true, while the signatures tab fetched signatures with
no filter and listed people filtered by contractEnded: false and
state: ACTIVE. The two views disagreed both when a signer's contract had
ended and when a signer was deactivated while still under contract.
Add a state: ProfileState field to DocumentVersionSignatureFilter
alongside the existing activeContract filter, so the signature query
can mirror the same predicates as the people query. Pass
{ activeContract: true, state: ACTIVE } from the badge, the document
list item, and the signatures tab fragment. The same filter is now
evaluated on both the count and the list.
Threaded through the console and MCP resolvers, the MCP spec, and the
n8n getAllSignatures operation.
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -40,10 +40,10 @@ export const documentLayoutQuery = graphql`
|
||||
...DocumentTitleFormFragment
|
||||
...DocumentActionsDropdown_versionFragment
|
||||
...DocumentDetailsCard_versionFragment
|
||||
signatures(first: 0 filter: { activeContract: true }) {
|
||||
signatures(first: 0 filter: { activeContract: true, state: ACTIVE }) {
|
||||
totalCount
|
||||
}
|
||||
signedSignatures: signatures(first: 0 filter: { states: [SIGNED], activeContract: true }) {
|
||||
signedSignatures: signatures(first: 0 filter: { states: [SIGNED], activeContract: true, state: ACTIVE }) {
|
||||
totalCount
|
||||
}
|
||||
approvalQuorums(first: 1, orderBy: { field: CREATED_AT, direction: DESC }) {
|
||||
@@ -85,10 +85,10 @@ export const documentLayoutQuery = graphql`
|
||||
...DocumentTitleFormFragment
|
||||
...DocumentActionsDropdown_versionFragment
|
||||
...DocumentDetailsCard_versionFragment
|
||||
signatures(first: 0 filter: { activeContract: true }) {
|
||||
signatures(first: 0 filter: { activeContract: true, state: ACTIVE }) {
|
||||
totalCount
|
||||
}
|
||||
signedSignatures: signatures(first: 0 filter: { states: [SIGNED], activeContract: true }) {
|
||||
signedSignatures: signatures(first: 0 filter: { states: [SIGNED], activeContract: true, state: ACTIVE }) {
|
||||
totalCount
|
||||
}
|
||||
approvalQuorums(first: 1, orderBy: { field: CREATED_AT, direction: DESC }) {
|
||||
|
||||
@@ -54,10 +54,10 @@ const fragment = graphql`
|
||||
}
|
||||
}
|
||||
}
|
||||
signatures(first: 0 filter: { activeContract: true }) {
|
||||
signatures(first: 0 filter: { activeContract: true, state: ACTIVE }) {
|
||||
totalCount
|
||||
}
|
||||
signedSignatures: signatures(first: 0 filter: { states: [SIGNED], activeContract: true }) {
|
||||
signedSignatures: signatures(first: 0 filter: { states: [SIGNED], activeContract: true, state: ACTIVE }) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const versionFragment = graphql`
|
||||
@argumentDefinitions(
|
||||
count: { type: "Int", defaultValue: 1000 }
|
||||
cursor: { type: "CursorKey" }
|
||||
signatureFilter: { type: "DocumentVersionSignatureFilter" }
|
||||
signatureFilter: { type: "DocumentVersionSignatureFilter", defaultValue: { activeContract: true, state: ACTIVE } }
|
||||
) {
|
||||
...DocumentSignaturePlaceholder_versionFragment
|
||||
signatures(first: $count, after: $cursor, filter: $signatureFilter)
|
||||
@@ -102,8 +102,11 @@ export function DocumentSignatureList(props: {
|
||||
return;
|
||||
}
|
||||
|
||||
const filter
|
||||
= selectedStates.length > 0 ? { states: selectedStates } : null;
|
||||
const filter = {
|
||||
activeContract: true,
|
||||
state: "ACTIVE" as const,
|
||||
...(selectedStates.length > 0 ? { states: selectedStates } : {}),
|
||||
};
|
||||
|
||||
refetch({ signatureFilter: filter });
|
||||
}, [selectedStates, refetch]);
|
||||
|
||||
@@ -91,6 +91,18 @@ export const description: INodeProperties[] = [
|
||||
default: false,
|
||||
description: 'Whether to filter by active contract status',
|
||||
},
|
||||
{
|
||||
displayName: 'Profile State',
|
||||
name: 'state',
|
||||
type: 'options',
|
||||
default: '',
|
||||
description: 'Filter by signatory profile state',
|
||||
options: [
|
||||
{ name: 'Any', value: '' },
|
||||
{ name: 'Active', value: 'ACTIVE' },
|
||||
{ name: 'Inactive', value: 'INACTIVE' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -107,6 +119,7 @@ export async function execute(
|
||||
const filter: IDataObject = {};
|
||||
if ((filters.states as string[])?.length) filter.states = filters.states;
|
||||
if (filters.activeContract !== undefined) filter.activeContract = filters.activeContract;
|
||||
if (filters.state) filter.state = filters.state;
|
||||
|
||||
const hasFilter = Object.keys(filter).length > 0;
|
||||
|
||||
|
||||
@@ -22,13 +22,15 @@ type (
|
||||
DocumentVersionSignatureFilter struct {
|
||||
states DocumentVersionSignatureStates
|
||||
activeContract *bool
|
||||
state *ProfileState
|
||||
}
|
||||
)
|
||||
|
||||
func NewDocumentVersionSignatureFilter(states []DocumentVersionSignatureState, activeContract *bool) *DocumentVersionSignatureFilter {
|
||||
func NewDocumentVersionSignatureFilter(states []DocumentVersionSignatureState, activeContract *bool, state *ProfileState) *DocumentVersionSignatureFilter {
|
||||
return &DocumentVersionSignatureFilter{
|
||||
states: DocumentVersionSignatureStates(states),
|
||||
activeContract: activeContract,
|
||||
state: state,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +38,7 @@ func (f *DocumentVersionSignatureFilter) SQLArguments() pgx.StrictNamedArgs {
|
||||
return pgx.StrictNamedArgs{
|
||||
"states": f.states,
|
||||
"active_contract": f.activeContract,
|
||||
"profile_state": f.state,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,5 +73,16 @@ func (f *DocumentVersionSignatureFilter) SQLFragment() string {
|
||||
)
|
||||
)
|
||||
END
|
||||
AND
|
||||
CASE
|
||||
WHEN @profile_state::text IS NULL
|
||||
THEN TRUE
|
||||
ELSE EXISTS (
|
||||
SELECT 1
|
||||
FROM iam_membership_profiles p
|
||||
WHERE p.id = signed_by_profile_id
|
||||
AND p.state = @profile_state::membership_state
|
||||
)
|
||||
END
|
||||
)`
|
||||
}
|
||||
|
||||
@@ -279,6 +279,7 @@ func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.Doc
|
||||
var (
|
||||
signatureStates []coredata.DocumentVersionSignatureState
|
||||
activeContract *bool
|
||||
profileState *coredata.ProfileState
|
||||
)
|
||||
|
||||
if filter != nil {
|
||||
@@ -289,9 +290,13 @@ func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.Doc
|
||||
if filter.ActiveContract != nil {
|
||||
activeContract = filter.ActiveContract
|
||||
}
|
||||
|
||||
if filter.State != nil {
|
||||
profileState = filter.State
|
||||
}
|
||||
}
|
||||
|
||||
signatureFilter := coredata.NewDocumentVersionSignatureFilter(signatureStates, activeContract)
|
||||
signatureFilter := coredata.NewDocumentVersionSignatureFilter(signatureStates, activeContract, profileState)
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
|
||||
@@ -247,6 +247,7 @@ input DocumentVersionSignatureOrder {
|
||||
input DocumentVersionSignatureFilter {
|
||||
states: [DocumentVersionSignatureState!]
|
||||
activeContract: Boolean
|
||||
state: ProfileState
|
||||
}
|
||||
|
||||
input DocumentVersionApprovalQuorumOrder {
|
||||
|
||||
@@ -2188,6 +2188,7 @@ func (r *Resolver) ListDocumentVersionSignaturesTool(ctx context.Context, req *m
|
||||
var (
|
||||
signatureStates []coredata.DocumentVersionSignatureState
|
||||
activeContract *bool
|
||||
profileState *coredata.ProfileState
|
||||
)
|
||||
|
||||
if input.Filter != nil {
|
||||
@@ -2198,9 +2199,13 @@ func (r *Resolver) ListDocumentVersionSignaturesTool(ctx context.Context, req *m
|
||||
if input.Filter.ActiveContract != nil {
|
||||
activeContract = input.Filter.ActiveContract
|
||||
}
|
||||
|
||||
if input.Filter.State != nil {
|
||||
profileState = input.Filter.State
|
||||
}
|
||||
}
|
||||
|
||||
signatureFilter := coredata.NewDocumentVersionSignatureFilter(signatureStates, activeContract)
|
||||
signatureFilter := coredata.NewDocumentVersionSignatureFilter(signatureStates, activeContract, profileState)
|
||||
|
||||
page, err := prb.Documents.ListSignatures(ctx, scope, input.DocumentVersionID, cursor, signatureFilter)
|
||||
if err != nil {
|
||||
|
||||
@@ -6322,6 +6322,9 @@ components:
|
||||
active_contract:
|
||||
type: boolean
|
||||
description: Signatory contract status
|
||||
state:
|
||||
$ref: "#/components/schemas/ProfileState"
|
||||
description: Signatory profile state
|
||||
|
||||
ListDocumentVersionSignaturesOutput:
|
||||
type: object
|
||||
|
||||
Reference in New Issue
Block a user