diff --git a/src/components/Dropdown.jsx b/src/components/Dropdown.jsx index 4b5b2d9..e84a8a5 100644 --- a/src/components/Dropdown.jsx +++ b/src/components/Dropdown.jsx @@ -49,19 +49,19 @@ const itemStyles = { fontSize: '$3', fontWeight: '$2', lineHeight: 1, - color: '$hiContrast', + color: '$textDark', borderRadius: 3, display: 'flex', alignItems: 'center', height: 27, padding: '0 5px', position: 'relative', - paddingLeft: '$2', + paddingLeft: 28, userSelect: 'none', '&[data-disabled]': { color: mauve.mauve8, - // pointerEvents: 'none', + pointerEvents: 'none', }, '&[data-state="checked"]': { diff --git a/src/features/cameras/CameraList.jsx b/src/features/cameras/CameraList.jsx index 7805d59..843a011 100644 --- a/src/features/cameras/CameraList.jsx +++ b/src/features/cameras/CameraList.jsx @@ -7,6 +7,7 @@ import { DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, + DropdownMenuItemIconLeft, DropdownMenuArrow, } from '../../components/Dropdown.jsx'; import { @@ -21,7 +22,11 @@ import { registerCamera, setDeleteCameraAlertStatus, } from './wirelessCamerasSlice'; -import { setModalContent, setSelectedCamera } from '../projects/projectsSlice.js'; +import { + selectSelectedProjectId, + setModalContent, + setSelectedCamera, +} from '../projects/projectsSlice.js'; import IconButton from '../../components/IconButton'; import { Cross2Icon, @@ -31,7 +36,7 @@ import { ChevronDownIcon, } from '@radix-ui/react-icons'; import { StandAloneInput as Input } from '../../components/Form'; -import { Camera, MapPin } from 'lucide-react'; +import { Camera, MapPin, IdCard, Trash2, Unlink, Link } from 'lucide-react'; import { indigo } from '@radix-ui/colors'; import { @@ -165,6 +170,7 @@ const ActiveState = ({ active }) => ( ); const CameraList = ({ cameras, handleSaveDepClick, handleDeleteDepClick }) => { + const selectedProjectId = useSelector(selectSelectedProjectId); const userRoles = useSelector(selectUserCurrentRoles); const dispatch = useDispatch(); @@ -186,9 +192,12 @@ const CameraList = ({ cameras, handleSaveDepClick, handleDeleteDepClick }) => { dispatch(setSelectedCamera(cameraId)); }; - const [tooltipOpen, setTooltipOpen] = useState(false); const [dropdownOpen, setDropdownOpen] = useState(null); + const [editSnTooltipOpen, setEditSnTooltipOpen] = useState(false); + const [deleteCamTooltipOpen, setDeleteCamTooltipOpen] = useState(false); + const [releaseCamTooltipOpen, setReleaseCamTooltipOpen] = useState(false); + const [cameraFilter, setCameraFilter] = useState(''); const filteredCameras = cameras.filter( (cam) => @@ -231,20 +240,26 @@ const CameraList = ({ cameras, handleSaveDepClick, handleDeleteDepClick }) => { > {hasRole(userRoles, WRITE_DEPLOYMENTS_ROLES) && ( handleSaveDepClick({ cameraId: cam._id })} + onSelect={() => handleSaveDepClick({ cameraId: cam._id })} > + + + Add Deployment )} {hasRole(userRoles, WRITE_CAMERA_SERIAL_NUMBER_ROLES) && ( - + handleEditSerialNumberClick({ cameraId: cam._id })} - onClick={() => cam.isWireless && setTooltipOpen(true)} - onMouseLeave={() => setTooltipOpen(false)} + onClick={() => cam.isWireless && setEditSnTooltipOpen(true)} + onMouseLeave={() => setEditSnTooltipOpen(false)} disabled={cam.isWireless} > + + + Edit camera serial number @@ -255,22 +270,40 @@ const CameraList = ({ cameras, handleSaveDepClick, handleDeleteDepClick }) => { )} {hasRole(userRoles, WRITE_CAMERA_REGISTRATION_ROLES) && cam.active && ( - { - e.stopPropagation; - handleUnregisterClick({ - cameraId: cam._id, - }); - }} - > - Release camera - + + + { + if (cam.isWireless && selectedProjectId === 'default_project') { + setReleaseCamTooltipOpen(true); + } + }} + onMouseLeave={() => setReleaseCamTooltipOpen(false)} + onSelect={(e) => { + e.stopPropagation; + handleUnregisterClick({ + cameraId: cam._id, + }); + }} + > + + + + Release camera + + + + You cannot release wireless cameras from the Default Project + + + )} {hasRole(userRoles, WRITE_CAMERA_REGISTRATION_ROLES) && cam.isWireless && !cam.active && ( { + onSelect={(e) => { e.stopPropagation; handleReRegisterCameraClick({ cameraId: cam._id, @@ -278,21 +311,41 @@ const CameraList = ({ cameras, handleSaveDepClick, handleDeleteDepClick }) => { }); }} > + + + Re-register camera )} {hasRole(userRoles, WRITE_CAMERA_REGISTRATION_ROLES) && ( - { - e.stopPropagation; - handleDeleteCameraClick({ - cameraId: cam._id, - }); - }} - > - Delete camera - + + + { + if (cam.isWireless && selectedProjectId === 'default_project') { + setDeleteCamTooltipOpen(true); + } + }} + onMouseLeave={() => setDeleteCamTooltipOpen(false)} + onSelect={(e) => { + e.stopPropagation; + handleDeleteCameraClick({ + cameraId: cam._id, + }); + }} + > + + + + Delete camera + + + + You cannot delete wireless cameras from the Default Project + + + )} diff --git a/src/features/cameras/DeleteCameraAlert.jsx b/src/features/cameras/DeleteCameraAlert.jsx index ec487a6..4ebf037 100644 --- a/src/features/cameras/DeleteCameraAlert.jsx +++ b/src/features/cameras/DeleteCameraAlert.jsx @@ -93,7 +93,7 @@ const DeleteCameraAlert = () => {

Are you sure you'd like to delete Camera {selectedCamera}?{' '} {imageCount === 0 && 'This will remove the Camera and the Deployments '} - {imageCount > 0 && ( + {!imageCountLoading && imageCount > 0 && ( <> This will remove the Camera, its Deployments, and{' '} {imageCount > 1 ? 'all' : 'the'}{' '} diff --git a/src/features/filters/FiltersPanelFooterDropdown.jsx b/src/features/filters/FiltersPanelFooterDropdown.jsx index 783e5fa..8dfee0a 100644 --- a/src/features/filters/FiltersPanelFooterDropdown.jsx +++ b/src/features/filters/FiltersPanelFooterDropdown.jsx @@ -7,10 +7,12 @@ import { DropdownMenuContent, DropdownMenuItem, DropdownMenuArrow, + DropdownMenuItemIconLeft, } from '../../components/Dropdown.jsx'; import { selectUserCurrentRoles } from '../auth/authSlice.js'; import { hasRole, DELETE_IMAGES_ROLES, EXPORT_DATA_ROLES } from '../auth/roles.js'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; +import { Download, Trash2 } from 'lucide-react'; import { setDeleteImagesAlertStatus } from '../images/imagesSlice'; const StyledDropdownMenuTrigger = styled(DropdownMenuTrigger, { @@ -39,12 +41,18 @@ const FiltersPanelFooterDropdown = (props) => { {hasRole(userRoles, EXPORT_DATA_ROLES) && ( - props.handleModalToggle('export-modal')}> + props.handleModalToggle('export-modal')}> + + + Export currently filtered data )} {hasRole(userRoles, DELETE_IMAGES_ROLES) && ( - + + + + Delete all currently filtered images )} diff --git a/src/features/loupe/Comment.jsx b/src/features/loupe/Comment.jsx index 53e7b89..8244932 100644 --- a/src/features/loupe/Comment.jsx +++ b/src/features/loupe/Comment.jsx @@ -7,6 +7,7 @@ import { DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, + DropdownMenuItemIconLeft, DropdownMenuArrow, } from '../../components/Dropdown.jsx'; import Button from '../../components/Button.jsx'; @@ -17,6 +18,7 @@ import { selectUserUsername } from '../auth/authSlice.js'; import { DateTime } from 'luxon'; import { editComment } from '../review/reviewSlice.js'; import { indigo } from '@radix-ui/colors'; +import { Trash2, Pencil } from 'lucide-react'; const StyledFieldRow = styled(FieldRow, { display: 'block', @@ -196,8 +198,18 @@ export const Comment = ({ comment, imageId, onChangeOpen, scrollRef }) => { - setIsDeleteConfirm(true)}>Delete - setIsEdit(true)}>Edit + setIsDeleteConfirm(true)}> + + + + Delete + + setIsEdit(true)}> + + + + Edit + diff --git a/src/features/loupe/LoupeDropdown.jsx b/src/features/loupe/LoupeDropdown.jsx index 6180208..8855dd5 100644 --- a/src/features/loupe/LoupeDropdown.jsx +++ b/src/features/loupe/LoupeDropdown.jsx @@ -6,6 +6,7 @@ import { DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, + DropdownMenuItemIconLeft, DropdownMenuArrow, } from '../../components/Dropdown.jsx'; import IconButton from '../../components/IconButton.jsx'; @@ -13,6 +14,7 @@ import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import DeleteImagesAlert from '../images/DeleteImagesAlert.jsx'; import { setDeleteImagesAlertStatus } from '../images/imagesSlice'; import { selectFocusIndex, setSelectedImageIndices } from '../review/reviewSlice.js'; +import { Trash2 } from 'lucide-react'; const StyledDropdownMenuTrigger = styled(DropdownMenuTrigger, { position: 'absolute', @@ -37,7 +39,12 @@ const LoupeDropdown = ({ image }) => { - Delete Image + + + + + Delete Image +