diff --git a/worklenz-frontend/public/locales/en/project-view-finance.json b/worklenz-frontend/public/locales/en/project-view-finance.json index 2c2d0325..642422b2 100644 --- a/worklenz-frontend/public/locales/en/project-view-finance.json +++ b/worklenz-frontend/public/locales/en/project-view-finance.json @@ -35,7 +35,8 @@ "ratecardsPluralText": "Rate Card Templates", "deleteConfirm": "Are you sure ?", "yes": "Yes", - "no": "No" + "no": "No", + "alreadyImportedRateCardMessage": "A rate card has already been imported. Clear all imported rate cards to add a new one." } \ No newline at end of file diff --git a/worklenz-frontend/src/components/project-ratecard/ratecard-assignee-selector.tsx b/worklenz-frontend/src/components/project-ratecard/ratecard-assignee-selector.tsx index 175ad48e..dc2521d4 100644 --- a/worklenz-frontend/src/components/project-ratecard/ratecard-assignee-selector.tsx +++ b/worklenz-frontend/src/components/project-ratecard/ratecard-assignee-selector.tsx @@ -23,7 +23,8 @@ const RateCardAssigneeSelector = ({ onChange, selectedMemberIds = [], memberlist = [], -}: RateCardAssigneeSelectorProps) => { + assignedMembers = [], // New prop: List of all assigned member IDs across all job titles +}: RateCardAssigneeSelectorProps & { assignedMembers: string[] }) => { const membersInputRef = useRef(null); const [searchQuery, setSearchQuery] = useState(''); const [members, setMembers] = useState(memberlist); @@ -46,33 +47,39 @@ const RateCardAssigneeSelector = ({ /> {filteredMembers.length ? ( - filteredMembers.map((member) => ( - - onChange?.(member.id || '')} - /> - - {member.name} - - )) + filteredMembers.map((member) => { + const isAssignedToAnotherJobTitle = + assignedMembers.includes(member.id || '') && + !selectedMemberIds.includes(member.id || ''); // Check if the member is assigned elsewhere + + return ( + + onChange?.(member.id || '')} + /> + + {member.name} + + ); + }) ) : ( )} diff --git a/worklenz-frontend/src/features/finance/ratecard-drawer/import-ratecards-drawer.tsx b/worklenz-frontend/src/features/finance/ratecard-drawer/import-ratecards-drawer.tsx index ff44f9f0..3e9e4d10 100644 --- a/worklenz-frontend/src/features/finance/ratecard-drawer/import-ratecards-drawer.tsx +++ b/worklenz-frontend/src/features/finance/ratecard-drawer/import-ratecards-drawer.tsx @@ -1,4 +1,4 @@ -import { Drawer, Typography, Button, Table, Menu, Flex, Spin } from 'antd'; +import { Drawer, Typography, Button, Table, Menu, Flex, Spin, Alert } from 'antd'; import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useAppSelector } from '../../../hooks/useAppSelector'; @@ -85,32 +85,45 @@ const ImportRatecardsDrawer: React.FC = () => { } footer={
- + {/* Alert message */} + {rolesRedux.length !== 0 ? ( +
+ +
+ ) : ( +
+ +
+ )}
} open={isDrawerOpen} diff --git a/worklenz-frontend/src/features/finance/ratecard-drawer/ratecard-drawer.tsx b/worklenz-frontend/src/features/finance/ratecard-drawer/ratecard-drawer.tsx index f3645752..b968f3e3 100644 --- a/worklenz-frontend/src/features/finance/ratecard-drawer/ratecard-drawer.tsx +++ b/worklenz-frontend/src/features/finance/ratecard-drawer/ratecard-drawer.tsx @@ -307,16 +307,21 @@ const RatecardDrawer = ({ }, ]; - const handleDrawerClose = () => { - if (!name || name.trim() === '' || name === 'Untitled Rate Card') { + const handleDrawerClose = async() => { + if (!name || name.trim() === '') { messageApi.open({ - type: 'warning', - content: t('ratecardNameRequired') || 'Rate card name is required.', - }); - return; - } else if (hasChanges) { + type: 'warning', + content: t('ratecardNameRequired') || 'Rate card name is required.', + }); + return; + } else if (hasChanges) { setShowUnsavedAlert(true); - } else { + } + else if (name === 'Untitled Rate Card' && roles.length === 0){ + await dispatch(deleteRateCard(ratecardId)); + dispatch(toggleRatecardDrawer()); + } + else { dispatch(toggleRatecardDrawer()); } }; @@ -339,95 +344,95 @@ const RatecardDrawer = ({ return ( <> - {contextHolder} - - - { - setName(e.target.value); - }} - /> - - - {t('currency')} - { + setName(e.target.value); + }} + /> + + + {t('currency')} +