From 0b6257040a6bae553ad4bf64ac1d5f2fcafd5ef2 Mon Sep 17 00:00:00 2001 From: Jean-Marc Millet Date: Thu, 25 Apr 2024 15:16:44 +0200 Subject: [PATCH 1/2] remove overlayStyle to avoid tooltip being too wide and right alignment --- src/react/next-architecture/ui/metrics/LatestUsedCapacity.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/react/next-architecture/ui/metrics/LatestUsedCapacity.tsx b/src/react/next-architecture/ui/metrics/LatestUsedCapacity.tsx index df88b8c5e..0edeac145 100644 --- a/src/react/next-architecture/ui/metrics/LatestUsedCapacity.tsx +++ b/src/react/next-architecture/ui/metrics/LatestUsedCapacity.tsx @@ -35,7 +35,6 @@ export function UsedCapacity({ value }: { value: LatestUsedCapacity }) { {' '} From c28b10ead653eaec37956881f75330db317ec0be Mon Sep 17 00:00:00 2001 From: Jean-Marc Millet Date: Thu, 25 Apr 2024 15:19:28 +0200 Subject: [PATCH 2/2] change canDeleteLocation function to give explanation about why deletion is impossible in tooltip --- src/react/locations/LocationsList.tsx | 58 ++++++++++++++++++++------- src/react/locations/utils.tsx | 48 ++++++---------------- 2 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/react/locations/LocationsList.tsx b/src/react/locations/LocationsList.tsx index 71c27d735..aeea45c1b 100644 --- a/src/react/locations/LocationsList.tsx +++ b/src/react/locations/LocationsList.tsx @@ -1,5 +1,5 @@ -import { Icon, IconHelp, Stack, Wrap } from '@scality/core-ui'; -import { ComponentType, useMemo, useState } from 'react'; +import { Icon, IconHelp, Stack, Wrap, spacing } from '@scality/core-ui'; +import { useMemo, useState } from 'react'; import { useMutation, useQueryClient } from 'react-query'; import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; @@ -32,7 +32,8 @@ import { Warning } from '../ui-elements/Warning'; import { getLocationType } from '../utils/storageOptions'; import { useWorkflows } from '../workflow/Workflows'; import { PauseAndResume } from './PauseAndResume'; -import { canDeleteLocation } from './utils'; +import { getLocationDeletionBlocker } from './utils'; +import styled from 'styled-components'; const ActionButtons = ({ rowValues, @@ -100,13 +101,42 @@ const ActionButtons = ({ } }, [waiterStatus]); - const isDeletionEnable = canDeleteLocation( - rowValues, - replications, - transitions, - buckets, - accountsLocationsAndEndpoints?.endpoints || [], - ); + const { isBuiltin, hasWorkflow, hasBucket, hasEndpoint } = + getLocationDeletionBlocker( + rowValues, + replications, + transitions, + buckets, + accountsLocationsAndEndpoints?.endpoints || [], + ); + const isDeletionDisabled = + isBuiltin || hasWorkflow || hasBucket || hasEndpoint; + + const List = styled.ul` + margin-left: ${spacing.r8}; + li { + margin-bottom: 0; + } + `; + + const TooltipOverlay = () => { + return isDeletionDisabled ? ( + isBuiltin ? ( + <>You cannot delete a default location + ) : ( +
+ You cannot delete this location because it has: + + {hasWorkflow &&
  • at least one workflow
  • } + {hasBucket &&
  • at least one bucket
  • } + {hasEndpoint &&
  • at least one data service
  • } +
    +
    + ) + ) : ( + <>Delete location + ); + }; return (
    @@ -139,12 +169,10 @@ const ActionButtons = ({ onClick={() => setShowModal(true)} type="button" tooltip={{ - overlay: isDeletionEnable - ? 'Delete Location' - : `You can't delete this location`, - overlayStyle: { width: '8rem' }, + overlay: , + overlayStyle: { textAlign: 'left' }, }} - disabled={!isDeletionEnable} + disabled={isDeletionDisabled} /> diff --git a/src/react/locations/utils.tsx b/src/react/locations/utils.tsx index 2753622a3..60278e6db 100644 --- a/src/react/locations/utils.tsx +++ b/src/react/locations/utils.tsx @@ -88,65 +88,43 @@ function convertToForm(locationProps: LocationInfo): LocationForm { return ret; } -// TODO: add specific tooltip message about why location can not be deleted -function canDeleteLocation( +function getLocationDeletionBlocker( location: NextLocation, replicationStreams: Array, transitions: Array, buckets: BucketList, endpoints: Array, -) { - if (!location) { - return false; - } - +): Record { const isBuiltin = location.isBuiltin; - if (isBuiltin) { - return false; - } - const checkStreamLocations = replicationStreams.every((r) => { //@ts-expect-error fix this when you are working on it if (r.destination.location) { //@ts-expect-error fix this when you are working on it return r.destination.location !== location.name; } - return r.destination.locations.every((destLocation) => { return destLocation.name !== location.name; }); }); + const hasReplicationWorkflow = !checkStreamLocations; - const isTransitionCreatedOnLocation = !!transitions.find( + const hasTransitionWorkflow = !!transitions.find( (t: BucketWorkflowTransitionV2) => t.locationName === location.name, ); - if (isTransitionCreatedOnLocation) { - return false; - } - - if (!checkStreamLocations) { - return false; - } - - const checkBucketLocations = buckets.every( + const hasBucket = !buckets.every( (bucket) => bucket.location !== location.name, ); - if (!checkBucketLocations) { - return false; - } - - const checkEndpointLocations = endpoints.every( - (e) => e.locationName !== location.name, - ); - - if (!checkEndpointLocations) { - return false; - } + const hasEndpoint = !endpoints.every((e) => e.locationName !== location.name); - return true; + return { + isBuiltin, + hasWorkflow: hasTransitionWorkflow || hasReplicationWorkflow, + hasBucket, + hasEndpoint, + }; } function isLocationExists(location: string): boolean { @@ -205,7 +183,7 @@ export { convertToLocation, convertToForm, newLocationDetails, - canDeleteLocation, + getLocationDeletionBlocker, isLocationExists, convertToBucketInfo, renderLocation,