Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions src/components/CreateSnapshotDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@ interface CreateSnapshotDialogProps {
onClose: () => void;
}

export const CreateSnapshotDialog: React.FC<CreateSnapshotDialogProps> = ({
open,
onClose,
}) => {
export const CreateSnapshotDialog: React.FC<CreateSnapshotDialogProps> = ({ open, onClose }) => {
const [title, setTitle] = useState('');
const [comment, setComment] = useState('');
const [description, setDescription] = useState('');
const { startSnapshot } = useSnapshot();

const handleCreate = () => {
Expand All @@ -30,17 +27,17 @@ export const CreateSnapshotDialog: React.FC<CreateSnapshotDialogProps> = ({
}

// Fire and forget - starts the snapshot in the background
startSnapshot(title.trim(), comment.trim() || undefined);
startSnapshot(title.trim(), description.trim() || undefined);

// Reset form and close dialog immediately
setTitle('');
setComment('');
setDescription('');
onClose();
};

const handleClose = () => {
setTitle('');
setComment('');
setDescription('');
onClose();
};

Expand All @@ -64,9 +61,9 @@ export const CreateSnapshotDialog: React.FC<CreateSnapshotDialogProps> = ({
/>

<TextField
label="Comment (optional)"
value={comment}
onChange={(e) => setComment(e.target.value)}
label="Description (optional)"
value={description}
onChange={(e) => setDescription(e.target.value)}
fullWidth
size="small"
multiline
Expand All @@ -76,14 +73,8 @@ export const CreateSnapshotDialog: React.FC<CreateSnapshotDialogProps> = ({
</Stack>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>
Cancel
</Button>
<Button
onClick={handleCreate}
variant="contained"
disabled={!title.trim()}
>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleCreate} variant="contained" disabled={!title.trim()}>
Start Snapshot
</Button>
</DialogActions>
Expand Down
2 changes: 1 addition & 1 deletion src/components/SnapshotHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const SnapshotHeader: React.FC<SnapshotHeaderProps> = ({ snapshot, onBack
<Typography variant="h6" color="text.secondary" fontWeight="bold">
|
</Typography>
<Typography variant="body1" fontWeight={600} color="primary">
<Typography variant="body1" fontWeight={600} color="text.primary">
{snapshot?.title || 'Loading...'}
</Typography>
<Typography variant="h6" color="text.secondary" fontWeight="bold">
Expand Down
30 changes: 16 additions & 14 deletions src/components/VirtualTable/pvColumns.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createColumnHelper, ColumnDef } from '@tanstack/react-table';
import { Checkbox } from '@mui/material';
import { Box, Checkbox } from '@mui/material';
import { EpicsData, Severity } from '../../types';
import { SeverityIcon, EpicsValueCell, LiveValueCell, PVNameCell, DeviceCell } from './ValueCells';

Expand Down Expand Up @@ -47,26 +47,28 @@ export function createPVColumns(options?: {
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onChange={row.getToggleSelectedHandler()}
size="small"
/>
<Box sx={{ overflow: 'visible' }}>
<Checkbox
checked={row.getIsSelected()}
onChange={row.getToggleSelectedHandler()}
size="small"
/>
</Box>
),
size: 50,
}) as ColumnDef<PVRow, unknown>
);
}

// Severity column
columns.push(
columnHelper.accessor('severity', {
header: '',
cell: ({ getValue }) => <SeverityIcon severity={getValue()} />,
size: 50,
enableSorting: false,
}) as ColumnDef<PVRow, unknown>
);
// columns.push(
// columnHelper.accessor('severity', {
// header: '',
// cell: ({ getValue }) => <SeverityIcon severity={getValue()} />,
// size: 50,
// enableSorting: false,
// }) as ColumnDef<PVRow, unknown>
// );

// Device column
columns.push(
Expand Down
164 changes: 85 additions & 79 deletions src/contexts/SnapshotContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface SnapshotProgress {

interface SnapshotContextType {
snapshotProgress: SnapshotProgress;
startSnapshot: (title: string, comment?: string) => void;
startSnapshot: (title: string, description?: string) => void;
clearSnapshot: () => void;
}

Expand Down Expand Up @@ -40,99 +40,105 @@ export const SnapshotProvider: React.FC<{ children: React.ReactNode }> = ({ chil
}
}, []);

const pollJobStatus = useCallback((jobId: string, title: string) => {
const poll = async () => {
try {
const job = await jobService.getJobStatus(jobId);
console.log('Job status:', job);

if (job.status === 'completed') {
stopPolling();
setSnapshotProgress({
isCreating: false,
title,
progress: 100,
error: null,
snapshotId: job.resultId || null,
message: job.message || 'Snapshot created successfully',
});
} else if (job.status === 'failed') {
const pollJobStatus = useCallback(
(jobId: string, title: string) => {
const poll = async () => {
try {
const job = await jobService.getJobStatus(jobId);
console.log('Job status:', job);

if (job.status === 'completed') {
stopPolling();
setSnapshotProgress({
isCreating: false,
title,
progress: 100,
error: null,
snapshotId: job.resultId || null,
message: job.message || 'Snapshot created successfully',
});
} else if (job.status === 'failed') {
stopPolling();
setSnapshotProgress({
isCreating: false,
title,
progress: null,
error: job.error || 'Snapshot creation failed',
snapshotId: null,
message: null,
});
} else {
// Still running or pending
setSnapshotProgress({
isCreating: true,
title,
progress: job.progress,
error: null,
snapshotId: null,
message: job.message || 'Creating snapshot...',
});
}
} catch (err) {
console.error('Failed to poll job status:', err);
stopPolling();
setSnapshotProgress({
isCreating: false,
title,
progress: null,
error: job.error || 'Snapshot creation failed',
error: err instanceof Error ? err.message : 'Failed to check job status',
snapshotId: null,
message: null,
});
} else {
// Still running or pending
setSnapshotProgress({
isCreating: true,
title,
progress: job.progress,
error: null,
snapshotId: null,
message: job.message || 'Creating snapshot...',
});
}
} catch (err) {
console.error('Failed to poll job status:', err);
stopPolling();
setSnapshotProgress({
isCreating: false,
title,
progress: null,
error: err instanceof Error ? err.message : 'Failed to check job status',
snapshotId: null,
message: null,
});
}
};
};

// Start polling
poll(); // Initial poll
pollIntervalRef.current = window.setInterval(poll, POLL_INTERVAL_MS);
}, [stopPolling]);
// Start polling
poll(); // Initial poll
pollIntervalRef.current = window.setInterval(poll, POLL_INTERVAL_MS);
},
[stopPolling]
);

const startSnapshot = useCallback((title: string, comment?: string) => {
// Stop any existing polling
stopPolling();
const startSnapshot = useCallback(
(title: string, description?: string) => {
// Stop any existing polling
stopPolling();

// Set initial state - creating, no progress yet
setSnapshotProgress({
isCreating: true,
title,
progress: null,
error: null,
snapshotId: null,
message: 'Starting snapshot...',
});

// Fire off the async request
snapshotService
.createSnapshotAsync({
// Set initial state - creating, no progress yet
setSnapshotProgress({
isCreating: true,
title,
comment: comment || undefined,
})
.then((result) => {
console.log('Snapshot job started:', result);
// Start polling for job status
pollJobStatus(result.jobId, title);
})
.catch((err) => {
console.error('Failed to start snapshot:', err);
setSnapshotProgress({
isCreating: false,
progress: null,
error: null,
snapshotId: null,
message: 'Starting snapshot...',
});

// Fire off the async request
snapshotService
.createSnapshotAsync({
title,
progress: null,
error: err instanceof Error ? err.message : 'Failed to start snapshot',
snapshotId: null,
message: null,
description: description || undefined,
})
.then((result) => {
console.log('Snapshot job started:', result);
// Start polling for job status
pollJobStatus(result.jobId, title);
})
.catch((err) => {
console.error('Failed to start snapshot:', err);
setSnapshotProgress({
isCreating: false,
title,
progress: null,
error: err instanceof Error ? err.message : 'Failed to start snapshot',
snapshotId: null,
message: null,
});
});
});
}, [pollJobStatus, stopPolling]);
},
[pollJobStatus, stopPolling]
);

const clearSnapshot = useCallback(() => {
stopPolling();
Expand Down
Loading
Loading