Expand scoped demo analysis access
This commit is contained in:
@@ -67,17 +67,15 @@ export function useDemoWorkflow({
|
||||
setSegmentationReferenceDatasetId(result.reference_dataset_id)
|
||||
setDemoWorkflowMessage(result.message)
|
||||
await loadProjects(result.project_id)
|
||||
const operatorOnlyLoads = restrictedMode
|
||||
? Promise.resolve()
|
||||
: Promise.all([
|
||||
loadDetectionRuns(result.project_id),
|
||||
loadSegmentationRuns(result.project_id),
|
||||
loadExports(result.project_id),
|
||||
]).then(() => undefined)
|
||||
const analysisLoads = Promise.all([
|
||||
loadDetectionRuns(result.project_id),
|
||||
loadSegmentationRuns(result.project_id),
|
||||
loadExports(result.project_id),
|
||||
]).then(() => undefined)
|
||||
const [projectData] = await Promise.all([
|
||||
loadProjectData(result.project_id),
|
||||
loadQualityChecks(result.project_id),
|
||||
operatorOnlyLoads,
|
||||
analysisLoads,
|
||||
])
|
||||
const candidateDataset = projectData?.datasets.find((dataset) => dataset.id === result.candidate_dataset_id)
|
||||
const rasterDataset = projectData?.datasets.find((dataset) => dataset.id === result.raster_dataset_id)
|
||||
|
||||
@@ -207,6 +207,7 @@ export function useDetectionWorkflow({
|
||||
setDetectionRunError(null)
|
||||
try {
|
||||
const params = {
|
||||
project_id: selectedProjectId ?? '',
|
||||
class_name: detectionClassFilter || null,
|
||||
min_confidence: detectionMinConfidenceFilter > 0 ? detectionMinConfidenceFilter : null,
|
||||
}
|
||||
@@ -415,7 +416,7 @@ export function useDetectionWorkflow({
|
||||
setDetectionQaResult(null)
|
||||
setRunningDetectionQa(true)
|
||||
try {
|
||||
const result = await detectionApi.compareWithReference(analysisRunId, {
|
||||
const result = await detectionApi.compareWithReference(analysisRunId, selectedProjectId!, {
|
||||
reference_dataset_id: referenceDatasetId,
|
||||
iou_threshold: iouThresholdOverride ?? qaIouThreshold,
|
||||
class_name: useCurrentFilters ? detectionClassFilter || null : null,
|
||||
@@ -486,7 +487,7 @@ export function useDetectionWorkflow({
|
||||
parameters_json: { calibration: true, calibration_thresholds: thresholds },
|
||||
})
|
||||
setSelectedDetectionRunId(result.analysis_run_id)
|
||||
const qa = await detectionApi.compareWithReference(result.analysis_run_id, {
|
||||
const qa = await detectionApi.compareWithReference(result.analysis_run_id, selectedProjectId, {
|
||||
reference_dataset_id: detectionReferenceDatasetId,
|
||||
iou_threshold: qaIouThreshold,
|
||||
class_name: detectionClassFilter || null,
|
||||
|
||||
@@ -59,7 +59,7 @@ export function useExportWorkflow({
|
||||
setExporting(true)
|
||||
setExportError(null)
|
||||
try {
|
||||
const response = await exportsApi.exportGeojson({
|
||||
const response = await exportsApi.exportGeojson(selectedDataset.project_id, {
|
||||
dataset_id: selectedDataset.id,
|
||||
export_kind: 'dataset',
|
||||
name: selectedDataset.name.replace(/\.(geo)?json$/i, ''),
|
||||
@@ -74,14 +74,14 @@ export function useExportWorkflow({
|
||||
}
|
||||
|
||||
const exportSelectedDetectionRunGeoJson = async () => {
|
||||
if (!selectedDetectionRunId) {
|
||||
if (!selectedDetectionRunId || !selectedProjectId) {
|
||||
setExportError('Select a detection run before exporting GeoJSON.')
|
||||
return
|
||||
}
|
||||
setExporting(true)
|
||||
setExportError(null)
|
||||
try {
|
||||
const response = await exportsApi.exportGeojson({
|
||||
const response = await exportsApi.exportGeojson(selectedProjectId, {
|
||||
analysis_run_id: selectedDetectionRunId,
|
||||
export_kind: 'detection_run',
|
||||
})
|
||||
@@ -95,14 +95,14 @@ export function useExportWorkflow({
|
||||
}
|
||||
|
||||
const exportSelectedSegmentationRunGeoJson = async () => {
|
||||
if (!selectedSegmentationRunId) {
|
||||
if (!selectedSegmentationRunId || !selectedProjectId) {
|
||||
setExportError('Select a segmentation run before exporting GeoJSON.')
|
||||
return
|
||||
}
|
||||
setExporting(true)
|
||||
setExportError(null)
|
||||
try {
|
||||
const response = await exportsApi.exportGeojson({
|
||||
const response = await exportsApi.exportGeojson(selectedProjectId, {
|
||||
analysis_run_id: selectedSegmentationRunId,
|
||||
export_kind: 'segmentation_run',
|
||||
})
|
||||
@@ -123,7 +123,7 @@ export function useExportWorkflow({
|
||||
setSelectionExporting(true)
|
||||
setSelectionExportError(null)
|
||||
try {
|
||||
const response = await exportsApi.exportGeojson({
|
||||
const response = await exportsApi.exportGeojson(selectedDataset.project_id, {
|
||||
dataset_id: selectedDataset.id,
|
||||
area_id: areaId,
|
||||
export_kind: 'vector_selection',
|
||||
@@ -199,7 +199,8 @@ export function useExportWorkflow({
|
||||
const previewExportContent = async (exportId: string) => {
|
||||
setExportError(null)
|
||||
try {
|
||||
const response = await exportsApi.getContent(exportId)
|
||||
if (!selectedProjectId) return
|
||||
const response = await exportsApi.getContent(selectedProjectId, exportId)
|
||||
setExportPreview(response.content)
|
||||
} catch (error) {
|
||||
setExportError(formatError(error, 'Failed to load export content'))
|
||||
@@ -207,7 +208,8 @@ export function useExportWorkflow({
|
||||
}
|
||||
|
||||
const downloadExportArtifact = (exportId: string) => {
|
||||
window.open(exportsApi.downloadUrl(exportId), '_blank', 'noopener,noreferrer')
|
||||
if (!selectedProjectId) return
|
||||
window.open(exportsApi.downloadUrl(selectedProjectId, exportId), '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
|
||||
const resetExportsForProject = () => {
|
||||
|
||||
@@ -51,7 +51,7 @@ export function useMapSelectionQa({
|
||||
iou_threshold: 0.5,
|
||||
area_id: candidateDataset.area_id ?? null,
|
||||
}
|
||||
const job: JobRead = await qaApi.runQa(request)
|
||||
const job: JobRead = await qaApi.runQa(selectedProjectId, request)
|
||||
if (job.status === 'failed') {
|
||||
setMapSelectionQaError(job.error_message || 'Map selection QA/QC failed')
|
||||
return null
|
||||
|
||||
@@ -92,7 +92,7 @@ export function useQualityWorkflow({ selectedProjectId, loadProjectData }: Quali
|
||||
iou_threshold: qaIouThreshold,
|
||||
area_id: qaAreaId || null,
|
||||
}
|
||||
const job: JobRead = await qaApi.runQa(request)
|
||||
const job: JobRead = await qaApi.runQa(selectedProjectId, request)
|
||||
if (job.status === 'failed') {
|
||||
setQaError(job.error_message || 'QA comparison failed')
|
||||
return
|
||||
|
||||
@@ -104,6 +104,7 @@ export function useSegmentationWorkflow({
|
||||
setSegmentationRunError(null)
|
||||
try {
|
||||
const params = {
|
||||
project_id: selectedProjectId ?? '',
|
||||
class_name: segmentationClassFilter || null,
|
||||
min_confidence: segmentationMinConfidenceFilter > 0 ? segmentationMinConfidenceFilter : null,
|
||||
}
|
||||
@@ -175,7 +176,7 @@ export function useSegmentationWorkflow({
|
||||
setSegmentationQaResult(null)
|
||||
setRunningSegmentationQa(true)
|
||||
try {
|
||||
const result = await segmentationApi.compareWithReference(selectedSegmentationRunId, {
|
||||
const result = await segmentationApi.compareWithReference(selectedSegmentationRunId, selectedProjectId!, {
|
||||
reference_dataset_id: segmentationReferenceDatasetId,
|
||||
iou_threshold: qaIouThreshold,
|
||||
class_name: segmentationClassFilter || null,
|
||||
|
||||
@@ -65,19 +65,19 @@ describe('useWorkbenchBootstrap', () => {
|
||||
expect(state.loadExports).toHaveBeenCalledWith('project-1')
|
||||
})
|
||||
|
||||
it('keeps the guest bootstrap inside the read-only demo surface', async () => {
|
||||
it('loads the same analysis catalog and project results for a guest', async () => {
|
||||
const state = { ...options('project-1'), restrictedMode: true }
|
||||
renderHook(() => useWorkbenchBootstrap(state))
|
||||
|
||||
await waitFor(() => expect(state.loadProjectData).toHaveBeenCalledWith('project-1'))
|
||||
expect(state.loadCapabilities).toHaveBeenCalledOnce()
|
||||
expect(state.loadQualityChecks).toHaveBeenCalledWith('project-1')
|
||||
expect(state.loadDetectionModels).not.toHaveBeenCalled()
|
||||
expect(state.loadSegmentationModels).not.toHaveBeenCalled()
|
||||
expect(state.loadDetectionRuns).not.toHaveBeenCalled()
|
||||
expect(state.loadSegmentationRuns).not.toHaveBeenCalled()
|
||||
expect(state.loadExports).not.toHaveBeenCalled()
|
||||
expect(state.loadDetectionResults).not.toHaveBeenCalled()
|
||||
expect(state.loadSegmentationResults).not.toHaveBeenCalled()
|
||||
expect(state.loadDetectionModels).toHaveBeenCalledOnce()
|
||||
expect(state.loadSegmentationModels).toHaveBeenCalledOnce()
|
||||
expect(state.loadDetectionRuns).toHaveBeenCalledWith('project-1')
|
||||
expect(state.loadSegmentationRuns).toHaveBeenCalledWith('project-1')
|
||||
expect(state.loadExports).toHaveBeenCalledWith('project-1')
|
||||
expect(state.loadDetectionResults).toHaveBeenCalledOnce()
|
||||
expect(state.loadSegmentationResults).toHaveBeenCalledOnce()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -59,10 +59,8 @@ export function useWorkbenchBootstrap({
|
||||
useEffect(() => {
|
||||
loadProjects().catch(() => null)
|
||||
loadCapabilities().catch(() => null)
|
||||
if (!restrictedMode) {
|
||||
loadDetectionModels().catch(() => null)
|
||||
loadSegmentationModels().catch(() => null)
|
||||
}
|
||||
loadDetectionModels().catch(() => null)
|
||||
loadSegmentationModels().catch(() => null)
|
||||
}, [restrictedMode])
|
||||
|
||||
useEffect(() => {
|
||||
@@ -81,20 +79,16 @@ export function useWorkbenchBootstrap({
|
||||
resetExportsForProject()
|
||||
loadProjectData(selectedProjectId).catch(() => null)
|
||||
loadQualityChecks(selectedProjectId).catch(() => null)
|
||||
if (!restrictedMode) {
|
||||
loadDetectionRuns(selectedProjectId).catch(() => null)
|
||||
loadSegmentationRuns(selectedProjectId).catch(() => null)
|
||||
loadExports(selectedProjectId).catch(() => null)
|
||||
}
|
||||
loadDetectionRuns(selectedProjectId).catch(() => null)
|
||||
loadSegmentationRuns(selectedProjectId).catch(() => null)
|
||||
loadExports(selectedProjectId).catch(() => null)
|
||||
}, [restrictedMode, selectedProjectId])
|
||||
|
||||
useEffect(() => {
|
||||
if (restrictedMode) return
|
||||
loadDetectionResults().catch(() => null)
|
||||
}, [restrictedMode, selectedDetectionRunId, detectionClassFilter, detectionMinConfidenceFilter])
|
||||
|
||||
useEffect(() => {
|
||||
if (restrictedMode) return
|
||||
loadSegmentationResults().catch(() => null)
|
||||
}, [restrictedMode, selectedSegmentationRunId, segmentationClassFilter, segmentationMinConfidenceFilter])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user