Various cosmetic fixes for 0.4.0 (#4844)

In this PR:
- fix empty list placeholder positionning
- prevent user from erasing custom address field as composite types
removal is not supported yet @ijreilly FYI
- fix show page relation error
- Implement address filter
This commit is contained in:
Charles Bochet
2024-04-05 17:32:14 +02:00
committed by GitHub
parent f8da8f9805
commit f4017119ab
8 changed files with 93 additions and 12 deletions

View File

@ -2,6 +2,7 @@ import { useLazyQuery } from '@apollo/client';
import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly'; import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly';
import { ObjectMetadataItemIdentifier } from '@/object-metadata/types/ObjectMetadataItemIdentifier'; import { ObjectMetadataItemIdentifier } from '@/object-metadata/types/ObjectMetadataItemIdentifier';
import { getRecordFromRecordNode } from '@/object-record/cache/utils/getRecordFromRecordNode';
import { useGenerateFindOneRecordQuery } from '@/object-record/hooks/useGenerateFindOneRecordQuery'; import { useGenerateFindOneRecordQuery } from '@/object-record/hooks/useGenerateFindOneRecordQuery';
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
@ -31,7 +32,8 @@ export const useLazyFindOneRecord = <T extends ObjectRecord = ObjectRecord>({
findOneRecord: ({ objectRecordId, onCompleted }: FindOneRecordParams<T>) => findOneRecord: ({ objectRecordId, onCompleted }: FindOneRecordParams<T>) =>
findOneRecord({ findOneRecord({
variables: { objectRecordId }, variables: { objectRecordId },
onCompleted: (data) => onCompleted?.(data[objectNameSingular]), onCompleted: (data) =>
onCompleted?.(getRecordFromRecordNode(data[objectNameSingular])),
}), }),
called, called,
error, error,

View File

@ -48,9 +48,16 @@ export const MultipleFiltersDropdownContent = ({
<> <>
<ObjectFilterDropdownOperandButton /> <ObjectFilterDropdownOperandButton />
<DropdownMenuSeparator /> <DropdownMenuSeparator />
{['TEXT', 'EMAIL', 'PHONE', 'FULL_NAME', 'LINK'].includes( {[
filterDefinitionUsedInDropdown.type, 'TEXT',
) && <ObjectFilterDropdownTextSearchInput />} 'EMAIL',
'PHONE',
'FULL_NAME',
'LINK',
'ADDRESS',
].includes(filterDefinitionUsedInDropdown.type) && (
<ObjectFilterDropdownTextSearchInput />
)}
{['NUMBER', 'CURRENCY'].includes( {['NUMBER', 'CURRENCY'].includes(
filterDefinitionUsedInDropdown.type, filterDefinitionUsedInDropdown.type,
) && <ObjectFilterDropdownNumberInput />} ) && <ObjectFilterDropdownNumberInput />}

View File

@ -11,6 +11,7 @@ describe('getOperandsForFilterType', () => {
'FULL_NAME', 'FULL_NAME',
[ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain], [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain],
], ],
['ADDRESS', [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain]],
['LINK', [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain]], ['LINK', [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain]],
['CURRENCY', [ViewFilterOperand.GreaterThan, ViewFilterOperand.LessThan]], ['CURRENCY', [ViewFilterOperand.GreaterThan, ViewFilterOperand.LessThan]],
['NUMBER', [ViewFilterOperand.GreaterThan, ViewFilterOperand.LessThan]], ['NUMBER', [ViewFilterOperand.GreaterThan, ViewFilterOperand.LessThan]],

View File

@ -9,6 +9,7 @@ export const getOperandsForFilterType = (
case 'TEXT': case 'TEXT':
case 'EMAIL': case 'EMAIL':
case 'FULL_NAME': case 'FULL_NAME':
case 'ADDRESS':
case 'LINK': case 'LINK':
return [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain]; return [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain];
case 'CURRENCY': case 'CURRENCY':

View File

@ -1,6 +1,7 @@
import { isNonEmptyString } from '@sniptt/guards'; import { isNonEmptyString } from '@sniptt/guards';
import { import {
AddressFilter,
CurrencyFilter, CurrencyFilter,
DateFilter, DateFilter,
FloatFilter, FloatFilter,
@ -254,6 +255,74 @@ export const turnObjectDropdownFilterIntoQueryFilter = (
); );
} }
break; break;
case 'ADDRESS':
switch (rawUIFilter.operand) {
case ViewFilterOperand.Contains:
objectRecordFilters.push({
or: [
{
[correspondingField.name]: {
addressStreet1: {
ilike: `%${rawUIFilter.value}%`,
},
} as AddressFilter,
},
{
[correspondingField.name]: {
addressStreet2: {
ilike: `%${rawUIFilter.value}%`,
},
} as AddressFilter,
},
{
[correspondingField.name]: {
addressCity: {
ilike: `%${rawUIFilter.value}%`,
},
} as AddressFilter,
},
],
});
break;
case ViewFilterOperand.DoesNotContain:
objectRecordFilters.push({
and: [
{
not: {
[correspondingField.name]: {
addressStreet1: {
ilike: `%${rawUIFilter.value}%`,
},
} as AddressFilter,
},
},
{
not: {
[correspondingField.name]: {
addressStreet2: {
ilike: `%${rawUIFilter.value}%`,
},
} as AddressFilter,
},
},
{
not: {
[correspondingField.name]: {
addressCity: {
ilike: `%${rawUIFilter.value}%`,
},
} as AddressFilter,
},
},
],
});
break;
default:
throw new Error(
`Unknown operand ${rawUIFilter.operand} for ${rawUIFilter.definition.type} filter`,
);
}
break;
case 'SELECT': { case 'SELECT': {
const stringifiedSelectValues = rawUIFilter.value; const stringifiedSelectValues = rawUIFilter.value;
let parsedOptionValues: string[] = []; let parsedOptionValues: string[] = [];

View File

@ -33,6 +33,7 @@ const StyledTableWithHeader = styled.div`
flex: 1; flex: 1;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
height: 100%;
`; `;
const StyledTableContainer = styled.div` const StyledTableContainer = styled.div`

View File

@ -6,10 +6,11 @@ import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { FieldMetadataType } from '~/generated-metadata/graphql';
type SettingsObjectFieldInactiveActionDropdownProps = { type SettingsObjectFieldInactiveActionDropdownProps = {
isCustomField?: boolean; isCustomField?: boolean;
isRelationType?: boolean; fieldType?: FieldMetadataType;
onActivate: () => void; onActivate: () => void;
onErase: () => void; onErase: () => void;
scopeKey: string; scopeKey: string;
@ -20,7 +21,7 @@ export const SettingsObjectFieldInactiveActionDropdown = ({
scopeKey, scopeKey,
onErase, onErase,
isCustomField, isCustomField,
isRelationType, fieldType,
}: SettingsObjectFieldInactiveActionDropdownProps) => { }: SettingsObjectFieldInactiveActionDropdownProps) => {
const dropdownId = `${scopeKey}-settings-field-disabled-action-dropdown`; const dropdownId = `${scopeKey}-settings-field-disabled-action-dropdown`;
@ -36,7 +37,10 @@ export const SettingsObjectFieldInactiveActionDropdown = ({
closeDropdown(); closeDropdown();
}; };
const isErasable = isCustomField && !isRelationType; const isErasable =
isCustomField &&
fieldType !== FieldMetadataType.Relation &&
fieldType !== FieldMetadataType.Address;
return ( return (
<Dropdown <Dropdown

View File

@ -32,7 +32,6 @@ import { Table } from '@/ui/layout/table/components/Table';
import { TableHeader } from '@/ui/layout/table/components/TableHeader'; import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { TableSection } from '@/ui/layout/table/components/TableSection'; import { TableSection } from '@/ui/layout/table/components/TableSection';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { FieldMetadataType } from '~/generated-metadata/graphql';
const StyledDiv = styled.div` const StyledDiv = styled.div`
display: flex; display: flex;
@ -192,10 +191,7 @@ export const SettingsObjectDetail = () => {
ActionIcon={ ActionIcon={
<SettingsObjectFieldInactiveActionDropdown <SettingsObjectFieldInactiveActionDropdown
isCustomField={!!disabledMetadataField.isCustom} isCustomField={!!disabledMetadataField.isCustom}
isRelationType={ fieldType={disabledMetadataField.type}
disabledMetadataField.type ===
FieldMetadataType.Relation
}
scopeKey={disabledMetadataField.id} scopeKey={disabledMetadataField.id}
onActivate={() => onActivate={() =>
activateMetadataField(disabledMetadataField) activateMetadataField(disabledMetadataField)