Unset companies and owners (#1185)

* unselect users and companies

* Icon now works with theme

---------

Co-authored-by: vboxuser <vboxuser@Ubu.myguest.virtualbox.org>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
josoriomarin 2023-08-25 15:28:17 -04:00 committed by GitHub
parent 0e5dcd7037
commit 36cbafe4cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 6 deletions

View File

@ -77,7 +77,13 @@ export function CompanyPickerCell({
}); });
setIsCreating(false); setIsCreating(false);
} }
const noUser: EntityForSelect = {
entityType: Entity.Company,
id: '',
name: 'No Company',
avatarType: 'rounded',
avatarUrl: '',
};
return isCreating ? ( return isCreating ? (
<DoubleTextCellEdit <DoubleTextCellEdit
firstValue={searchFilter} firstValue={searchFilter}
@ -97,6 +103,7 @@ export function CompanyPickerCell({
selectedEntity: companies.selectedEntities[0], selectedEntity: companies.selectedEntities[0],
loading: companies.loading, loading: companies.loading,
}} }}
noUser={noUser}
/> />
); );
} }

View File

@ -27,6 +27,7 @@ export function SingleEntitySelect<
onCancel, onCancel,
width, width,
disableBackgroundBlur = false, disableBackgroundBlur = false,
noUser,
}: { }: {
onCancel?: () => void; onCancel?: () => void;
onCreate?: () => void; onCreate?: () => void;
@ -34,6 +35,7 @@ export function SingleEntitySelect<
onEntitySelected: (entity: CustomEntityForSelect | null | undefined) => void; onEntitySelected: (entity: CustomEntityForSelect | null | undefined) => void;
disableBackgroundBlur?: boolean; disableBackgroundBlur?: boolean;
width?: number; width?: number;
noUser?: CustomEntityForSelect;
}) { }) {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
@ -53,7 +55,6 @@ export function SingleEntitySelect<
onCancel?.(); onCancel?.();
}, },
}); });
return ( return (
<StyledDropdownMenu <StyledDropdownMenu
disableBlur={disableBackgroundBlur} disableBlur={disableBackgroundBlur}
@ -70,6 +71,7 @@ export function SingleEntitySelect<
entities={entities} entities={entities}
onEntitySelected={onEntitySelected} onEntitySelected={onEntitySelected}
onCancel={onCancel} onCancel={onCancel}
noUser={noUser}
/> />
{showCreateButton && ( {showCreateButton && (
<> <>

View File

@ -1,8 +1,10 @@
import { useRef } from 'react'; import { useRef } from 'react';
import { useTheme } from '@emotion/react';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
import { DropdownMenuItem } from '@/ui/dropdown/components/DropdownMenuItem'; import { DropdownMenuItem } from '@/ui/dropdown/components/DropdownMenuItem';
import { DropdownMenuSelectableItem } from '@/ui/dropdown/components/DropdownMenuSelectableItem'; import { DropdownMenuSelectableItem } from '@/ui/dropdown/components/DropdownMenuSelectableItem';
import { IconBuildingSkyscraper, IconUserCircle } from '@/ui/icon';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer'; import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { OverflowingTextWithTooltip } from '@/ui/tooltip/OverflowingTextWithTooltip'; import { OverflowingTextWithTooltip } from '@/ui/tooltip/OverflowingTextWithTooltip';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
@ -12,6 +14,7 @@ import { isNonEmptyString } from '~/utils/isNonEmptyString';
import { useEntitySelectScroll } from '../hooks/useEntitySelectScroll'; import { useEntitySelectScroll } from '../hooks/useEntitySelectScroll';
import { EntityForSelect } from '../types/EntityForSelect'; import { EntityForSelect } from '../types/EntityForSelect';
import { Entity } from '../types/EntityTypeForSelect';
import { RelationPickerHotkeyScope } from '../types/RelationPickerHotkeyScope'; import { RelationPickerHotkeyScope } from '../types/RelationPickerHotkeyScope';
import { DropdownMenuSkeletonItem } from './skeletons/DropdownMenuSkeletonItem'; import { DropdownMenuSkeletonItem } from './skeletons/DropdownMenuSkeletonItem';
@ -30,10 +33,12 @@ export function SingleEntitySelectBase<
entities, entities,
onEntitySelected, onEntitySelected,
onCancel, onCancel,
noUser,
}: { }: {
entities: EntitiesForSingleEntitySelect<CustomEntityForSelect>; entities: EntitiesForSingleEntitySelect<CustomEntityForSelect>;
onEntitySelected: (entity: CustomEntityForSelect | null | undefined) => void; onEntitySelected: (entity: CustomEntityForSelect | null | undefined) => void;
onCancel?: () => void; onCancel?: () => void;
noUser?: CustomEntityForSelect;
}) { }) {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
let entitiesInDropdown = isDefined(entities.selectedEntity) let entitiesInDropdown = isDefined(entities.selectedEntity)
@ -71,9 +76,22 @@ export function SingleEntitySelectBase<
entitiesInDropdown = entitiesInDropdown.filter((entity) => entitiesInDropdown = entitiesInDropdown.filter((entity) =>
isNonEmptyString(entity.name.trim()), isNonEmptyString(entity.name.trim()),
); );
const theme = useTheme();
return ( return (
<StyledDropdownMenuItemsContainer ref={containerRef} hasMaxHeight> <StyledDropdownMenuItemsContainer ref={containerRef} hasMaxHeight>
{noUser && (
<DropdownMenuItem onClick={() => onEntitySelected(noUser)}>
{noUser.entityType === Entity.User ? (
<IconUserCircle size={theme.icon.size.md} />
) : (
<IconBuildingSkyscraper
size={theme.icon.size.md}
></IconBuildingSkyscraper>
)}
{noUser.name}
</DropdownMenuItem>
)}
{entities.loading ? ( {entities.loading ? (
<DropdownMenuSkeletonItem /> <DropdownMenuSkeletonItem />
) : entitiesInDropdown.length === 0 ? ( ) : entitiesInDropdown.length === 0 ? (

View File

@ -91,8 +91,7 @@ export function useUpdateEntityField() {
const newSelectedEntity = newFieldValueUnknown; const newSelectedEntity = newFieldValueUnknown;
const fieldName = viewField.metadata.fieldName; const fieldName = viewField.metadata.fieldName;
if (!newSelectedEntity || newSelectedEntity.id === '') {
if (!newSelectedEntity) {
updateEntity({ updateEntity({
variables: { variables: {
where: { id: currentEntityId }, where: { id: currentEntityId },

View File

@ -47,7 +47,13 @@ export function UserPicker({
) { ) {
onSubmit(selectedUser ?? null); onSubmit(selectedUser ?? null);
} }
const noUser: UserForSelect = {
entityType: Entity.User,
id: '',
name: 'No Owner',
avatarType: 'rounded',
avatarUrl: '',
};
return ( return (
<SingleEntitySelect <SingleEntitySelect
width={width} width={width}
@ -58,6 +64,7 @@ export function UserPicker({
entitiesToSelect: users.entitiesToSelect, entitiesToSelect: users.entitiesToSelect,
selectedEntity: users.selectedEntities[0], selectedEntity: users.selectedEntities[0],
}} }}
noUser={noUser}
/> />
); );
} }

View File

@ -74,6 +74,10 @@ const simpleAbilityCheck: OperationAbilityChecker = async (
// Extract entity name from model name // Extract entity name from model name
const entity = camelCase(modelName); const entity = camelCase(modelName);
//TODO: Fix boolean data types so that disconnects are possible
if (typeof data === 'boolean') {
return true;
}
// Handle all operations cases // Handle all operations cases
const operations = !Array.isArray(data) ? [data] : data; const operations = !Array.isArray(data) ? [data] : data;
// Handle where case // Handle where case
@ -139,7 +143,6 @@ export async function relationAbilityChecker(
// Extract operation name and value // Extract operation name and value
const operationType = Object.keys(operation)[0] as OperationType; const operationType = Object.keys(operation)[0] as OperationType;
const operationValue = operation[operationType]; const operationValue = operation[operationType];
// Get operation checker for the operation type // Get operation checker for the operation type
const operationChecker = operationAbilityCheckers[operationType]; const operationChecker = operationAbilityCheckers[operationType];