wfm file push indicator re-added in workflow step
This commit is contained in:
parent
a4662c99f3
commit
8940a8981e
@ -658,6 +658,7 @@ function CustomRequestDetailInner({ requestId: propRequestId, onBack, dynamicReq
|
|||||||
pausedByUserId={request?.pauseInfo?.pausedBy?.userId}
|
pausedByUserId={request?.pauseInfo?.pausedBy?.userId}
|
||||||
currentUserId={(user as any)?.userId}
|
currentUserId={(user as any)?.userId}
|
||||||
apiRequest={apiRequest}
|
apiRequest={apiRequest}
|
||||||
|
hideApproveReject={isDealer}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
|
|||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Progress } from '@/components/ui/progress';
|
import { Progress } from '@/components/ui/progress';
|
||||||
import { TrendingUp, Clock, CheckCircle, CircleCheckBig, Upload, Mail, Download, Receipt, Activity, AlertTriangle, AlertOctagon, XCircle, History, ChevronDown, ChevronUp, RefreshCw, RotateCw, Eye, FileSpreadsheet, X, Loader2 } from 'lucide-react';
|
import { TrendingUp, Clock, CheckCircle, CheckCircle2, CircleCheckBig, Upload, Mail, Download, Receipt, Activity, AlertTriangle, AlertOctagon, XCircle, History, ChevronDown, ChevronUp, RefreshCw, RotateCw, Eye, FileSpreadsheet, X, Loader2 } from 'lucide-react';
|
||||||
import { formatDateTime, formatDateDDMMYYYY } from '@/utils/dateFormatter';
|
import { formatDateTime, formatDateDDMMYYYY } from '@/utils/dateFormatter';
|
||||||
import { formatHoursMinutes } from '@/utils/slaTracker';
|
import { formatHoursMinutes } from '@/utils/slaTracker';
|
||||||
import {
|
import {
|
||||||
@ -26,7 +26,7 @@ import {
|
|||||||
// InitiatorActionModal - Removed, using direct buttons instead
|
// InitiatorActionModal - Removed, using direct buttons instead
|
||||||
} from './modals';
|
} from './modals';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { submitProposal, updateIODetails, submitCompletion, updateEInvoice, sendCreditNoteToDealer } from '@/services/dealerClaimApi';
|
import { submitProposal, updateIODetails, submitCompletion, updateEInvoice, sendCreditNoteToDealer, retriggerWFMPush } from '@/services/dealerClaimApi';
|
||||||
import { getWorkflowDetails, approveLevel, rejectLevel, handleInitiatorAction, getWorkflowHistory } from '@/services/workflowApi';
|
import { getWorkflowDetails, approveLevel, rejectLevel, handleInitiatorAction, getWorkflowHistory } from '@/services/workflowApi';
|
||||||
import { uploadDocument } from '@/services/documentApi';
|
import { uploadDocument } from '@/services/documentApi';
|
||||||
import { TokenManager } from '@/utils/tokenManager';
|
import { TokenManager } from '@/utils/tokenManager';
|
||||||
@ -1510,6 +1510,25 @@ export function DealerClaimWorkflowTab({
|
|||||||
loadCompletionDocuments();
|
loadCompletionDocuments();
|
||||||
}, [request]);
|
}, [request]);
|
||||||
|
|
||||||
|
const handleRetrigger = async () => {
|
||||||
|
try {
|
||||||
|
toast.loading('Retriggering WFM push...', { id: 'wfm-retrigger' });
|
||||||
|
await retriggerWFMPush(request.id);
|
||||||
|
toast.success('WFM push re-triggered successfully', { id: 'wfm-retrigger' });
|
||||||
|
|
||||||
|
// Refresh the request data if onRefresh is provided
|
||||||
|
if (onRefresh) {
|
||||||
|
onRefresh();
|
||||||
|
} else {
|
||||||
|
// Fallback or full page refresh
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Error retriggering WFM push:', error);
|
||||||
|
toast.error(error.message || 'Failed to re-trigger WFM push', { id: 'wfm-retrigger' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleDownloadCSV = async () => {
|
const handleDownloadCSV = async () => {
|
||||||
try {
|
try {
|
||||||
const requestId = request.id || request.requestId;
|
const requestId = request.id || request.requestId;
|
||||||
@ -1764,23 +1783,63 @@ export function DealerClaimWorkflowTab({
|
|||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
})()}
|
})()}
|
||||||
{/* CSV Export Button (Requestor Claim Approval) */}
|
{/* CSV Export & WFM Push Status (Requestor Claim Approval) */}
|
||||||
{(() => {
|
{(() => {
|
||||||
const isRequestorClaimStep = (step.levelName || step.title || '').toLowerCase().includes('requestor claim') ||
|
const isRequestorClaimStep = (step.levelName || step.title || '').toLowerCase().includes('requestor claim') ||
|
||||||
(step.levelName || step.title || '').toLowerCase().includes('requestor - claim');
|
(step.levelName || step.title || '').toLowerCase().includes('requestor - claim');
|
||||||
const hasInvoice = request?.invoice || (request?.irn && step.status === 'approved');
|
const hasInvoice = request?.invoice || (request?.irn && step.status === 'approved');
|
||||||
return isRequestorClaimStep && hasInvoice && (
|
const wfmStatus = request?.invoice?.wfmPushStatus || (request?.invoice as any)?.wfmPushStatus;
|
||||||
<Button
|
const wfmError = request?.invoice?.wfmPushError || (request?.invoice as any)?.wfmPushError;
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
return isRequestorClaimStep && hasInvoice && (
|
||||||
className="h-6 w-6 p-0 hover:bg-emerald-100 ml-1"
|
<div className="flex items-center gap-1 ml-1">
|
||||||
title="Export CSV"
|
<Button
|
||||||
onClick={handleDownloadCSV}
|
variant="ghost"
|
||||||
>
|
size="sm"
|
||||||
<FileSpreadsheet className="w-3.5 h-3.5 text-emerald-600" />
|
className="h-6 w-6 p-0 hover:bg-emerald-100"
|
||||||
</Button>
|
title="Export CSV"
|
||||||
);
|
onClick={handleDownloadCSV}
|
||||||
})()}
|
>
|
||||||
|
<FileSpreadsheet className="w-3.5 h-3.5 text-emerald-600" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
{/* WFM Push Status Indication */}
|
||||||
|
{wfmStatus === 'SUCCESS' ? (
|
||||||
|
<div title="Pushed to WFM successfully">
|
||||||
|
<CheckCircle2 className="w-3.5 h-3.5 text-green-500" />
|
||||||
|
</div>
|
||||||
|
) : wfmStatus === 'FAILED' ? (
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<div title={`WFM Push Failed: ${wfmError || 'Unknown error'}`}>
|
||||||
|
<XCircle className="w-3.5 h-3.5 text-red-500" />
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="h-5 px-1.5 text-[10px] text-red-600 hover:text-red-700 hover:bg-red-50 border border-red-200 h-auto py-0"
|
||||||
|
onClick={handleRetrigger}
|
||||||
|
>
|
||||||
|
Retry Push
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<div title="WFM Push Pending">
|
||||||
|
<Clock className="w-3.5 h-3.5 text-amber-500" />
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="h-5 px-1.5 text-[10px] text-amber-600 hover:text-amber-700 hover:bg-amber-50 border border-amber-200 h-auto py-0"
|
||||||
|
onClick={handleRetrigger}
|
||||||
|
>
|
||||||
|
Push Now
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-600">{step.approver}</p>
|
<p className="text-sm text-gray-600">{step.approver}</p>
|
||||||
<p className="text-sm text-gray-500 mt-2 italic">{step.description}</p>
|
<p className="text-sm text-gray-500 mt-2 italic">{step.description}</p>
|
||||||
|
|||||||
@ -230,13 +230,6 @@ export function DealerDashboard({ onNavigate, onNewRequest: _onNewRequest }: Das
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-4 mt-8">
|
<div className="flex flex-wrap gap-4 mt-8">
|
||||||
<Button
|
|
||||||
onClick={() => onNavigate?.('/new-request')}
|
|
||||||
className="bg-blue-600 hover:bg-blue-700 text-white border-0 shadow-lg hover:shadow-xl transition-all duration-200"
|
|
||||||
>
|
|
||||||
<FileText className="w-5 h-5 mr-2" />
|
|
||||||
Create New Claim
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
@ -266,13 +259,6 @@ export function DealerDashboard({ onNavigate, onNewRequest: _onNewRequest }: Das
|
|||||||
You don't have any claims data yet. Once you create and submit claim requests, your analytics will appear here.
|
You don't have any claims data yet. Once you create and submit claim requests, your analytics will appear here.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col sm:flex-row gap-4">
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
<Button
|
|
||||||
onClick={() => onNavigate?.('/new-request')}
|
|
||||||
className="bg-blue-600 hover:bg-blue-700 text-white"
|
|
||||||
>
|
|
||||||
<FileText className="w-5 h-5 mr-2" />
|
|
||||||
Create Your First Claim
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
|
|||||||
@ -690,6 +690,7 @@ function DealerClaimRequestDetailInner({ requestId: propRequestId, onBack, dynam
|
|||||||
pausedByUserId={request?.pauseInfo?.pausedBy?.userId}
|
pausedByUserId={request?.pauseInfo?.pausedBy?.userId}
|
||||||
currentUserId={currentUserId}
|
currentUserId={currentUserId}
|
||||||
apiRequest={apiRequest}
|
apiRequest={apiRequest}
|
||||||
|
hideApproveReject={isDealer}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -331,7 +331,7 @@ export function useRequestDetails(
|
|||||||
internalOrders: internalOrders || [],
|
internalOrders: internalOrders || [],
|
||||||
// New normalized tables (also available via claimDetails for backward compatibility)
|
// New normalized tables (also available via claimDetails for backward compatibility)
|
||||||
budgetTracking: (claimDetails as any)?.budgetTracking || null,
|
budgetTracking: (claimDetails as any)?.budgetTracking || null,
|
||||||
invoice: (claimDetails as any)?.invoice || null,
|
invoice: claimDetails?.invoice || (claimDetails as any)?.invoice || null,
|
||||||
creditNote: (claimDetails as any)?.creditNote || null,
|
creditNote: (claimDetails as any)?.creditNote || null,
|
||||||
completionExpenses: (claimDetails as any)?.completionExpenses || null,
|
completionExpenses: (claimDetails as any)?.completionExpenses || null,
|
||||||
templateType: wf.templateType || wf.template_type,
|
templateType: wf.templateType || wf.template_type,
|
||||||
|
|||||||
@ -32,6 +32,7 @@ interface QuickActionsSidebarProps {
|
|||||||
currentUserId?: string; // Current user's ID (kept for backwards compatibility)
|
currentUserId?: string; // Current user's ID (kept for backwards compatibility)
|
||||||
apiRequest?: any;
|
apiRequest?: any;
|
||||||
onEditClaimAmount?: () => void;
|
onEditClaimAmount?: () => void;
|
||||||
|
hideApproveReject?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function QuickActionsSidebar({
|
export function QuickActionsSidebar({
|
||||||
@ -52,6 +53,7 @@ export function QuickActionsSidebar({
|
|||||||
currentUserId: currentUserIdProp,
|
currentUserId: currentUserIdProp,
|
||||||
apiRequest,
|
apiRequest,
|
||||||
onEditClaimAmount,
|
onEditClaimAmount,
|
||||||
|
hideApproveReject = false,
|
||||||
}: QuickActionsSidebarProps) {
|
}: QuickActionsSidebarProps) {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [sharedRecipients, setSharedRecipients] = useState<SharedRecipient[]>([]);
|
const [sharedRecipients, setSharedRecipients] = useState<SharedRecipient[]>([]);
|
||||||
@ -210,7 +212,7 @@ export function QuickActionsSidebar({
|
|||||||
|
|
||||||
{/* Approve/Reject Buttons */}
|
{/* Approve/Reject Buttons */}
|
||||||
<div className="pt-3 sm:pt-4 space-y-2">
|
<div className="pt-3 sm:pt-4 space-y-2">
|
||||||
{currentApprovalLevel && !isPaused && (
|
{currentApprovalLevel && !isPaused && !hideApproveReject && (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
className="w-full bg-green-600 hover:bg-green-700 text-white h-9 sm:h-10 text-xs sm:text-sm"
|
className="w-full bg-green-600 hover:bg-green-700 text-white h-9 sm:h-10 text-xs sm:text-sm"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user