459 lines
No EOL
20 KiB
TypeScript
Executable file
459 lines
No EOL
20 KiB
TypeScript
Executable file
const compareRemediationRouteActionReadiness = useMemo<RunboardCompareRouteActionReadiness | null>(() => {
|
|
if (!compareRemediationRoutePlan.active || !compareRemediationRoutePlan.actionHints) return null
|
|
|
|
const actionHints = compareRemediationRoutePlan.actionHints
|
|
const queryAttachedCount = queryIntegrityIssueCount && Number.isFinite(Number(queryIntegrityIssueCount))
|
|
? Math.trunc(Number(queryIntegrityIssueCount))
|
|
: null
|
|
const queryIntegrityKey = queryIntegrityIssueKey || null
|
|
const summaryRecord = (integritySummary as unknown as Record<string, unknown> | null) || null
|
|
const issuesRecord = (integrityIssues as unknown as Record<string, unknown> | null) || null
|
|
const mappedIssuePayload = queryIntegrityKey ? issuesRecord?.[queryIntegrityKey] : null
|
|
const liveIntegrityCount = queryIntegrityKey
|
|
? (
|
|
coerceUnknownCount(summaryRecord?.[queryIntegrityKey])
|
|
?? coerceUnknownCount(issuesRecord?.[queryIntegrityKey])
|
|
)
|
|
: null
|
|
const liveIntegrityCountSource =
|
|
queryIntegrityKey && coerceUnknownCount(summaryRecord?.[queryIntegrityKey]) !== null
|
|
? 'summary'
|
|
: (queryIntegrityKey && coerceUnknownCount(issuesRecord?.[queryIntegrityKey]) !== null ? 'issues' : 'none')
|
|
|
|
const severityLabel =
|
|
actionHints.integritySeverity === 'high' ? 'High' :
|
|
actionHints.integritySeverity === 'moderate' ? 'Moderate' :
|
|
actionHints.integritySeverity === 'low' ? 'Low' :
|
|
actionHints.integritySeverity === 'none' ? 'None' :
|
|
'Unknown'
|
|
const severityToneClass =
|
|
actionHints.integritySeverity === 'high' ? 'text-red-300' :
|
|
actionHints.integritySeverity === 'moderate' ? 'text-amber-300' :
|
|
actionHints.integritySeverity === 'low' ? 'text-indigo-300' :
|
|
actionHints.integritySeverity === 'none' ? 'text-emerald-300' :
|
|
'text-gray-300'
|
|
const graphDiffContext = compareRemediationRoutePlan.graphDiffContext
|
|
const graphDiffSeverityLabel = compareRouteGraphDiffSeverityLabel(graphDiffContext?.severity || null)
|
|
const graphDiffSeverityToneClass = compareRouteGraphDiffSeverityToneClass(graphDiffContext?.severity || null)
|
|
const graphDiffSeverityScore = (typeof graphDiffContext?.severityScore === 'number' && Number.isFinite(graphDiffContext.severityScore))
|
|
? Math.trunc(graphDiffContext.severityScore)
|
|
: null
|
|
const graphDiffTriagePriorityLabel = compareRouteGraphDiffTriagePriorityLabel(graphDiffContext?.triagePriority || null)
|
|
const graphDiffTriagePriorityToneClass = compareRouteGraphDiffTriagePriorityToneClass(graphDiffContext?.triagePriority || null)
|
|
|
|
let runReason: string | null = null
|
|
let artifactReason: string | null = null
|
|
const runBlockerCodes: string[] = []
|
|
const artifactBlockerCodes: string[] = []
|
|
let integrityMappingStateLabel = 'mapping unknown'
|
|
let integrityMappingStateToneClass = 'text-gray-300'
|
|
|
|
if (queryAttachedCount !== null && liveIntegrityCount !== null) {
|
|
if (liveIntegrityCount === queryAttachedCount) {
|
|
integrityMappingStateLabel = 'mapping aligned'
|
|
integrityMappingStateToneClass = 'text-emerald-300'
|
|
} else if (queryAttachedCount > 0 && liveIntegrityCount === 0) {
|
|
integrityMappingStateLabel = 'mapping cleared'
|
|
integrityMappingStateToneClass = 'text-indigo-300'
|
|
} else {
|
|
integrityMappingStateLabel = 'mapping drifted'
|
|
integrityMappingStateToneClass = 'text-amber-300'
|
|
}
|
|
} else if (queryAttachedCount !== null && liveIntegrityCount === null) {
|
|
integrityMappingStateLabel = isLoadingIntegrity ? 'mapping refreshing' : 'mapping unavailable'
|
|
integrityMappingStateToneClass = isLoadingIntegrity ? 'text-indigo-300' : 'text-gray-300'
|
|
} else if (queryAttachedCount === null && liveIntegrityCount !== null) {
|
|
integrityMappingStateLabel = 'live-only mapping'
|
|
integrityMappingStateToneClass = 'text-indigo-300'
|
|
}
|
|
|
|
let hasMappingDrift = false
|
|
|
|
if (isApplyingAction) {
|
|
runReason = 'Run action is already applying.'
|
|
artifactReason = 'Run action is already applying.'
|
|
runBlockerCodes.push('run_action_in_progress')
|
|
artifactBlockerCodes.push('run_action_in_progress')
|
|
} else if (actionHints.requiresLiveIntegrityRefresh && !integritySummary) {
|
|
const runIntegrityPendingReason = isLoadingIntegrity
|
|
? 'Integrity report is loading for route run verification.'
|
|
: 'Refresh integrity report to verify mapped issue state before route run action execution.'
|
|
const artifactIntegrityPendingReason = isLoadingIntegrity
|
|
? 'Integrity report is loading for route artifact verification.'
|
|
: 'Refresh integrity report to verify mapped issue state before route artifact action execution.'
|
|
const integrityPendingCode = isLoadingIntegrity ? 'integrity_refresh_loading' : 'integrity_refresh_required'
|
|
runReason = runIntegrityPendingReason
|
|
artifactReason = artifactIntegrityPendingReason
|
|
runBlockerCodes.push(integrityPendingCode)
|
|
artifactBlockerCodes.push(integrityPendingCode)
|
|
} else if (isLoadingRuns) {
|
|
const runRefreshReason = 'Run list refresh already in progress.'
|
|
runReason = runRefreshReason
|
|
artifactReason = runRefreshReason
|
|
runBlockerCodes.push('run_refresh_in_progress')
|
|
artifactBlockerCodes.push('run_refresh_in_progress')
|
|
} else if (!compareRemediationSuggestedRunId) {
|
|
const noRunReason = 'No route-matching run is available under the current route filters.'
|
|
runReason = noRunReason
|
|
artifactReason = noRunReason
|
|
runBlockerCodes.push('no_route_run')
|
|
artifactBlockerCodes.push('no_route_run')
|
|
} else if (selectedRunId && !selectedRun) {
|
|
runReason = 'Selected route run is unavailable in current run list.'
|
|
artifactReason = 'Selected route run is unavailable in current run list.'
|
|
runBlockerCodes.push('selected_run_unavailable')
|
|
artifactBlockerCodes.push('selected_run_unavailable')
|
|
} else if (selectedRunId !== compareRemediationSuggestedRunId) {
|
|
runReason = 'Apply route focus (or select the route run) before executing the suggested run action.'
|
|
artifactReason = 'Apply route focus (or select the route run) before executing the suggested artifact action.'
|
|
runBlockerCodes.push('route_run_not_selected')
|
|
artifactBlockerCodes.push('route_run_not_selected')
|
|
} else if (isLoadingDetails) {
|
|
runReason = 'Run details are loading.'
|
|
artifactReason = actionHints.artifactActionRequiresUri
|
|
? 'Artifact inventory is loading for the selected route run.'
|
|
: 'Run details are loading.'
|
|
runBlockerCodes.push('run_details_loading')
|
|
artifactBlockerCodes.push(actionHints.artifactActionRequiresUri ? 'artifact_inventory_loading' : 'run_details_loading')
|
|
} else {
|
|
hasMappingDrift =
|
|
(integrityMappingStateLabel === 'mapping drifted' || integrityMappingStateLabel === 'mapping cleared')
|
|
const runStatusNotRetryable =
|
|
selectedRun !== null
|
|
&& !isCompareRouteRunRetryableStatus(actionHints.runAction, selectedRun.status)
|
|
|
|
if (runStatusNotRetryable) {
|
|
runReason = 'Suggested run action requires a failed or canceled run.'
|
|
runBlockerCodes.push('run_status_not_retryable')
|
|
} else if (actionHints.runAction === 'queue_retry' && hasMappingDrift) {
|
|
runReason = 'Mapped integrity count changed since compare handoff. Review live mapped integrity payload before retrying.'
|
|
runBlockerCodes.push('integrity_mapping_drift')
|
|
}
|
|
|
|
if (runStatusNotRetryable) {
|
|
artifactReason = 'Select a failed/canceled route run before continuing route artifact action.'
|
|
artifactBlockerCodes.push('run_status_not_retryable')
|
|
} else if (!compareRemediationSuggestedArtifactId) {
|
|
artifactReason = 'No route-matching artifact is available for the selected route run.'
|
|
artifactBlockerCodes.push('no_route_artifact')
|
|
} else if (actionHints.artifactActionRequiresUri && !compareRemediationSuggestedArtifact?.uri) {
|
|
artifactReason = 'Suggested artifact action requires an artifact URI, but the route artifact has none.'
|
|
artifactBlockerCodes.push('artifact_uri_missing')
|
|
} else if (hasMappingDrift && actionHints.artifactActionRequiresUri && !artifactReason) {
|
|
artifactReason = actionHints.artifactAction === 'copy_artifact_uri'
|
|
? 'Mapped integrity count changed since compare handoff. Refresh integrity and verify the route artifact before copying URI.'
|
|
: 'Mapped integrity count changed since compare handoff. Inspect route artifact in-panel before opening URI.'
|
|
artifactBlockerCodes.push('integrity_mapping_drift')
|
|
}
|
|
}
|
|
|
|
const liveIntegrityStateLabel = isLoadingIntegrity
|
|
? 'refreshing'
|
|
: (liveIntegrityCount === null ? 'unavailable' : `attached via ${liveIntegrityCountSource}`)
|
|
const mappedIssuePreviewLabel = queryIntegrityKey
|
|
? formatMappedIntegrityIssuePreview(mappedIssuePayload)
|
|
: 'no mapped integrity key'
|
|
const mappedIssuePayloadCopy = queryIntegrityKey
|
|
? serializeMappedIntegrityIssuePayload(mappedIssuePayload)
|
|
: null
|
|
const mappedIssuePayloadEntryCount = queryIntegrityKey
|
|
? deriveMappedIntegrityIssueEntryCount(mappedIssuePayload)
|
|
: null
|
|
const mappedIssueDocumentProjection = queryIntegrityKey
|
|
? deriveMappedIntegrityIssueDocumentIds(mappedIssuePayload)
|
|
: { ids: [] as string[], total: 0 }
|
|
const mappedIssueDocumentIds = mappedIssueDocumentProjection.ids
|
|
const mappedIssueDocumentTotalCount = mappedIssueDocumentProjection.total
|
|
const mappedIssueDocumentIdsTruncated = mappedIssueDocumentTotalCount > mappedIssueDocumentIds.length
|
|
const mappedIssueDocumentOmittedCount = Math.max(0, mappedIssueDocumentTotalCount - mappedIssueDocumentIds.length)
|
|
const routeContextDocumentProjection = deriveCompareRouteContextDocumentIds(
|
|
queryPrimaryDocId,
|
|
querySecondaryDocId,
|
|
mappedIssueDocumentIds,
|
|
mappedIssuePayload
|
|
)
|
|
const routeContextDocumentIds = routeContextDocumentProjection.ids
|
|
const routeContextDocumentTotalCount = routeContextDocumentProjection.total
|
|
const routeContextDocumentIdsTruncated = routeContextDocumentTotalCount > routeContextDocumentIds.length
|
|
const routeContextDocumentOmittedCount = Math.max(0, routeContextDocumentTotalCount - routeContextDocumentIds.length)
|
|
const routeContextReplayMetadata = buildCompareRouteContextReplayMetadata({
|
|
remediationSource: queryCompareRemediationSource,
|
|
remediationRoute: queryCompareRemediationRoute,
|
|
compareIssueKind: queryCompareIssueKindNormalized,
|
|
compareIssueCount: queryCompareIssueCountNormalized,
|
|
compareIssueFilterMode: queryCompareIssueFilterModeNormalized,
|
|
compareIssueFirstLine: queryCompareIssueFirstLineNormalized,
|
|
compareIssueLastLine: queryCompareIssueLastLineNormalized,
|
|
integrityIssueKey: queryIntegrityIssueKey,
|
|
compareAttachedCount: queryAttachedCount,
|
|
primaryDocId: queryPrimaryDocId,
|
|
secondaryDocId: querySecondaryDocId,
|
|
secondaryDocName: querySecondaryDocName,
|
|
graphDiffBaselineSnapshotId: queryGraphDiffBaselineSnapshotId,
|
|
graphDiffTargetSnapshotId: queryGraphDiffTargetSnapshotId,
|
|
graphDiffBaselineSnapshotName: queryGraphDiffBaselineSnapshotName,
|
|
graphDiffTargetSnapshotName: queryGraphDiffTargetSnapshotName,
|
|
graphDiffNodeDelta: queryGraphDiffNodeDelta,
|
|
graphDiffEdgeDelta: queryGraphDiffEdgeDelta,
|
|
graphDiffAddedNodes: queryGraphDiffAddedNodes,
|
|
graphDiffRemovedNodes: queryGraphDiffRemovedNodes,
|
|
graphDiffAddedEdges: queryGraphDiffAddedEdges,
|
|
graphDiffRemovedEdges: queryGraphDiffRemovedEdges,
|
|
statusFilter,
|
|
kindFilter,
|
|
projectFilter,
|
|
selectedRunId,
|
|
selectedArtifactId,
|
|
})
|
|
const routeContextDocumentCopy = serializeCompareRouteDocumentContext({
|
|
remediationSource: queryCompareRemediationSource,
|
|
remediationRoute: queryCompareRemediationRoute,
|
|
compareIssueKind: queryCompareIssueKindNormalized,
|
|
compareIssueCount: queryCompareIssueCountNormalized,
|
|
compareIssueFilterMode: queryCompareIssueFilterModeNormalized,
|
|
compareIssueFirstLine: queryCompareIssueFirstLineNormalized,
|
|
compareIssueLastLine: queryCompareIssueLastLineNormalized,
|
|
primaryDocId: queryPrimaryDocId,
|
|
secondaryDocId: querySecondaryDocId,
|
|
secondaryDocName: querySecondaryDocName,
|
|
graphDiffBaselineSnapshotId: queryGraphDiffBaselineSnapshotId,
|
|
graphDiffTargetSnapshotId: queryGraphDiffTargetSnapshotId,
|
|
graphDiffBaselineSnapshotName: queryGraphDiffBaselineSnapshotName,
|
|
graphDiffTargetSnapshotName: queryGraphDiffTargetSnapshotName,
|
|
graphDiffNodeDelta: queryGraphDiffNodeDelta,
|
|
graphDiffEdgeDelta: queryGraphDiffEdgeDelta,
|
|
graphDiffAddedNodes: queryGraphDiffAddedNodes,
|
|
graphDiffRemovedNodes: queryGraphDiffRemovedNodes,
|
|
graphDiffAddedEdges: queryGraphDiffAddedEdges,
|
|
graphDiffRemovedEdges: queryGraphDiffRemovedEdges,
|
|
graphDiffSeverity: String(graphDiffContext?.severity || '').trim() || null,
|
|
graphDiffSeverityScore,
|
|
graphDiffTriagePriority: String(graphDiffContext?.triagePriority || '').trim() || null,
|
|
integrityIssueKey: queryIntegrityIssueKey,
|
|
compareAttachedCount: queryAttachedCount,
|
|
liveIntegrityCount,
|
|
mappedIssuePayloadEntryCount,
|
|
mappedIssueDocumentTotalCount,
|
|
mappedIssueDocumentIdsTruncated,
|
|
mappedIssueDocumentOmittedCount,
|
|
routeContextDocumentTotalCount,
|
|
routeContextDocumentIdsTruncated,
|
|
routeContextDocumentOmittedCount,
|
|
mappedIssueDocumentIds,
|
|
routeContextDocumentIds,
|
|
statusFilter,
|
|
kindFilter,
|
|
projectFilter,
|
|
selectedRunId,
|
|
selectedArtifactId,
|
|
})
|
|
const runPreconditions = [
|
|
{
|
|
id: 'integrity_report',
|
|
passed: !actionHints.requiresLiveIntegrityRefresh || Boolean(integritySummary),
|
|
},
|
|
{
|
|
id: 'route_run_available',
|
|
passed: Boolean(compareRemediationSuggestedRunId),
|
|
},
|
|
{
|
|
id: 'suggested_run_available',
|
|
passed: !compareRemediationSuggestedRunId || Boolean(compareRemediationSuggestedRun),
|
|
},
|
|
{
|
|
id: 'run_list_ready',
|
|
passed: !isLoadingRuns,
|
|
},
|
|
{
|
|
id: 'route_run_selected',
|
|
passed: Boolean(compareRemediationSuggestedRunId) && selectedRunId === compareRemediationSuggestedRunId,
|
|
},
|
|
{
|
|
id: 'selected_run_available',
|
|
passed: !selectedRunId || Boolean(selectedRun),
|
|
},
|
|
{
|
|
id: 'run_details_ready',
|
|
passed: !isLoadingDetails,
|
|
},
|
|
{
|
|
id: 'run_retryable_status',
|
|
passed: isCompareRouteRunRetryableStatus(actionHints.runAction, selectedRun?.status),
|
|
},
|
|
{
|
|
id: 'run_action_idle',
|
|
passed: !isApplyingAction,
|
|
},
|
|
{
|
|
id: 'integrity_mapping_stable_for_retry',
|
|
passed: actionHints.runAction !== 'queue_retry' || !hasMappingDrift,
|
|
},
|
|
]
|
|
const runPreconditionSummary = runPreconditions
|
|
.map((item) => `${item.id}:${item.passed ? 'ready' : 'blocked'}`)
|
|
.join(' · ')
|
|
const artifactPreconditions = [
|
|
{
|
|
id: 'integrity_report',
|
|
passed: !actionHints.requiresLiveIntegrityRefresh || Boolean(integritySummary),
|
|
},
|
|
{
|
|
id: 'route_run_available',
|
|
passed: Boolean(compareRemediationSuggestedRunId),
|
|
},
|
|
{
|
|
id: 'suggested_run_available',
|
|
passed: !compareRemediationSuggestedRunId || Boolean(compareRemediationSuggestedRun),
|
|
},
|
|
{
|
|
id: 'route_run_selected',
|
|
passed: Boolean(compareRemediationSuggestedRunId) && selectedRunId === compareRemediationSuggestedRunId,
|
|
},
|
|
{
|
|
id: 'selected_run_available',
|
|
passed: !selectedRunId || Boolean(selectedRun),
|
|
},
|
|
{
|
|
id: 'run_list_ready',
|
|
passed: !isLoadingRuns,
|
|
},
|
|
{
|
|
id: 'run_action_idle',
|
|
passed: !isApplyingAction,
|
|
},
|
|
{
|
|
id: 'run_retryable_status',
|
|
passed: isCompareRouteRunRetryableStatus(actionHints.runAction, selectedRun?.status),
|
|
},
|
|
{
|
|
id: 'artifact_inventory_ready',
|
|
passed: !isLoadingDetails,
|
|
},
|
|
{
|
|
id: 'route_artifact_available',
|
|
passed: Boolean(compareRemediationSuggestedArtifactId),
|
|
},
|
|
{
|
|
id: 'suggested_artifact_available',
|
|
passed: !compareRemediationSuggestedArtifactId || Boolean(compareRemediationSuggestedArtifact),
|
|
},
|
|
{
|
|
id: 'artifact_uri_available',
|
|
passed: !actionHints.artifactActionRequiresUri || Boolean(compareRemediationSuggestedArtifact?.uri),
|
|
},
|
|
{
|
|
id: 'integrity_mapping_stable',
|
|
passed: !(hasMappingDrift && actionHints.artifactActionRequiresUri),
|
|
},
|
|
]
|
|
const artifactPreconditionSummary = artifactPreconditions
|
|
.map((item) => `${item.id}:${item.passed ? 'ready' : 'blocked'}`)
|
|
.join(' · ')
|
|
const routeFilterContext = {
|
|
filtersAreBroad: statusFilter === 'all' && kindFilter === 'all',
|
|
projectFilterEmpty: projectFilter.trim().length === 0,
|
|
projectFilterValue: projectFilter.trim(),
|
|
statusFilterNarrowed: statusFilter !== 'all',
|
|
kindFilterNarrowed: kindFilter !== 'all',
|
|
statusFilterValue: statusFilter,
|
|
kindFilterValue: kindFilter,
|
|
}
|
|
const runNextStep = describeCompareRouteActionNextStep(runBlockerCodes, 'run', routeFilterContext)
|
|
const artifactNextStep = describeCompareRouteActionNextStep(artifactBlockerCodes, 'artifact', routeFilterContext)
|
|
const runActionTooltip = compareRouteActionButtonTitle(
|
|
!runReason,
|
|
compareRemediationRoutePlan.actionHints.runActionLabel,
|
|
runReason,
|
|
runNextStep
|
|
)
|
|
const artifactActionTooltip = compareRouteActionButtonTitle(
|
|
!artifactReason,
|
|
compareRemediationRoutePlan.actionHints.artifactActionLabel,
|
|
artifactReason,
|
|
artifactNextStep
|
|
)
|
|
|
|
return {
|
|
runReady: !runReason,
|
|
artifactReady: !artifactReason,
|
|
runReason,
|
|
artifactReason,
|
|
runNextStep,
|
|
artifactNextStep,
|
|
runActionTooltip,
|
|
artifactActionTooltip,
|
|
runBlockerCodes,
|
|
artifactBlockerCodes,
|
|
integrityMappingStateLabel,
|
|
integrityMappingStateToneClass,
|
|
integrityFocusLabel: actionHints.integrityFocusLabel,
|
|
integrityMappingBasisLabel: actionHints.integrityMappingBasisLabel,
|
|
integritySeverityLabel: severityLabel,
|
|
integritySeverityToneClass: severityToneClass,
|
|
graphDiffSeverityLabel,
|
|
graphDiffSeverityToneClass,
|
|
graphDiffSeverityScore,
|
|
graphDiffTriagePriorityLabel,
|
|
graphDiffTriagePriorityToneClass,
|
|
compareAttachedCount: queryAttachedCount,
|
|
liveIntegrityCount,
|
|
liveIntegrityStateLabel,
|
|
mappedIssuePreviewLabel,
|
|
mappedIssuePayloadCopy,
|
|
mappedIssuePayloadEntryCount,
|
|
mappedIssueDocumentIds,
|
|
mappedIssueDocumentTotalCount,
|
|
mappedIssueDocumentIdsTruncated,
|
|
mappedIssueDocumentOmittedCount,
|
|
routeContextDocumentIds,
|
|
routeContextDocumentTotalCount,
|
|
routeContextDocumentIdsTruncated,
|
|
routeContextDocumentOmittedCount,
|
|
routeContextDocumentCopy,
|
|
routeContextQueryString: routeContextReplayMetadata.routeContextQueryString,
|
|
routeContextHref: routeContextReplayMetadata.routeContextHref,
|
|
routeReplayQueryString: routeContextReplayMetadata.routeReplayQueryString,
|
|
routeReplayHref: routeContextReplayMetadata.routeReplayHref,
|
|
runPreconditionSummary,
|
|
artifactPreconditionSummary,
|
|
}
|
|
}, [
|
|
compareRemediationRoutePlan,
|
|
compareRemediationSuggestedRunId,
|
|
compareRemediationSuggestedRun,
|
|
compareRemediationSuggestedArtifactId,
|
|
compareRemediationSuggestedArtifact,
|
|
queryIntegrityIssueCount,
|
|
queryIntegrityIssueKey,
|
|
queryCompareRemediationSource,
|
|
queryCompareRemediationRoute,
|
|
queryCompareIssueKindNormalized,
|
|
queryCompareIssueCountNormalized,
|
|
queryCompareIssueFilterModeNormalized,
|
|
queryCompareIssueFirstLineNormalized,
|
|
queryCompareIssueLastLineNormalized,
|
|
queryGraphDiffAddedEdges,
|
|
queryGraphDiffAddedNodes,
|
|
queryGraphDiffBaselineSnapshotId,
|
|
queryGraphDiffBaselineSnapshotName,
|
|
queryGraphDiffEdgeDelta,
|
|
queryGraphDiffNodeDelta,
|
|
queryGraphDiffRemovedEdges,
|
|
queryGraphDiffRemovedNodes,
|
|
queryGraphDiffTargetSnapshotId,
|
|
queryGraphDiffTargetSnapshotName,
|
|
queryPrimaryDocId,
|
|
querySecondaryDocId,
|
|
querySecondaryDocName,
|
|
integritySummary,
|
|
integrityIssues,
|
|
isLoadingIntegrity,
|
|
selectedRunId,
|
|
selectedArtifactId,
|
|
selectedRun,
|
|
isLoadingDetails,
|
|
isApplyingAction,
|
|
statusFilter,
|
|
kindFilter,
|
|
projectFilter,
|
|
]) |