feat: filter digest tiles by user permissions and add import progress status
Build and Push Multi-Platform Images / build-and-push (push) Successful in 42s
Build and Push Multi-Platform Images / build-and-push (push) Successful in 42s
- Store UserGroups from OIDC in UserSettings entity, sync on each request - Filter daily digest tiles based on user's permission groups - Add in-memory job status tracking to EmailImportService - Poll import job status in MailImportWizard and show progress in Spin tip Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -62,10 +62,19 @@ export const emailImportApi = {
|
||||
return res.data.isDuplicate;
|
||||
},
|
||||
|
||||
executeImport: async (emailDate: string, attachments: AttachmentImportData[]): Promise<{ success: boolean; results: any[] }> => {
|
||||
const res = await api.post('/api/email-import/execute', { emailDate, attachments });
|
||||
executeImport: async (emailDate: string, attachments: AttachmentImportData[], jobId?: string): Promise<{ success: boolean; results: any[] }> => {
|
||||
const res = await api.post('/api/email-import/execute', { emailDate, attachments, jobId }, { timeout: 300_000 });
|
||||
return res.data;
|
||||
},
|
||||
|
||||
getJobStatus: async (jobId: string): Promise<{ message: string; done: boolean } | null> => {
|
||||
try {
|
||||
const res = await api.get(`/api/email-import/jobs/${jobId}/status`);
|
||||
return res.data;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
ensurePreviews: async (emailId: number): Promise<void> => {
|
||||
await api.post(`/api/email-import/emails/${emailId}/ensure-previews`);
|
||||
|
||||
@@ -44,6 +44,7 @@ export default function MailImportWizard({ visible, onClose, onSuccess, email, a
|
||||
|
||||
// Step 3 specific state
|
||||
const [importSuccess, setImportSuccess] = useState(false);
|
||||
const [importStatus, setImportStatus] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (visible && attachments.length > 0) {
|
||||
@@ -315,6 +316,14 @@ export default function MailImportWizard({ visible, onClose, onSuccess, email, a
|
||||
|
||||
const executeImport = async () => {
|
||||
setLoading(true);
|
||||
setImportStatus('Import wird gestartet...');
|
||||
const jobId = crypto.randomUUID ? crypto.randomUUID() : `job-${Date.now()}`;
|
||||
const statusPoll = setInterval(async () => {
|
||||
try {
|
||||
const status = await emailImportApi.getJobStatus(jobId);
|
||||
if (status?.message) setImportStatus(status.message);
|
||||
} catch {}
|
||||
}, 1500);
|
||||
try {
|
||||
const finalData = [];
|
||||
|
||||
@@ -358,12 +367,14 @@ export default function MailImportWizard({ visible, onClose, onSuccess, email, a
|
||||
});
|
||||
}
|
||||
|
||||
await emailImportApi.executeImport(email.Date, finalData);
|
||||
await emailImportApi.executeImport(email.Date, finalData, jobId);
|
||||
setImportSuccess(true);
|
||||
setCurrentStep(2);
|
||||
} catch (e: any) {
|
||||
message.error(`Fehler beim Import: ${e.message}`);
|
||||
} finally {
|
||||
clearInterval(statusPoll);
|
||||
setImportStatus('');
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
@@ -747,7 +758,7 @@ export default function MailImportWizard({ visible, onClose, onSuccess, email, a
|
||||
style={{ marginBottom: 24 }}
|
||||
/>
|
||||
|
||||
<Spin spinning={loading}>
|
||||
<Spin spinning={loading} tip={importStatus || undefined}>
|
||||
<div style={{ minHeight: 300 }}>
|
||||
{currentStep === 0 && renderStep1()}
|
||||
{currentStep === 1 && renderStep2()}
|
||||
|
||||
Reference in New Issue
Block a user