[GroupBy] Add views filters to groupBy query 2/2: handle anyFieldFilter (#14791)
Following https://github.com/twentyhq/twenty/pull/14762 In this PR - moved logic around any field filter formatting to twenty-shared - added any field filter to the filters applied to groupBy when viewId is defined - added integration test
This commit is contained in:
@@ -2,13 +2,15 @@ import { type ContextStoreTargetedRecordsRule } from '@/context-store/states/con
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter';
|
||||
import { makeAndFilterVariables } from '@/object-record/utils/makeAndFilterVariables';
|
||||
import {
|
||||
type RecordFilterValueDependencies,
|
||||
type RecordGqlOperationFilter,
|
||||
} from 'twenty-shared/types';
|
||||
import { computeRecordGqlOperationFilter } from 'twenty-shared/utils';
|
||||
import {
|
||||
computeRecordGqlOperationFilter,
|
||||
turnAnyFieldFilterIntoRecordGqlFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
type ComputeContextStoreFiltersProps = {
|
||||
contextStoreTargetedRecordsRule: ContextStoreTargetedRecordsRule;
|
||||
@@ -32,7 +34,7 @@ export const computeContextStoreFilters = ({
|
||||
const { recordGqlOperationFilter: recordGqlFilterForAnyFieldFilter } =
|
||||
turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue: contextStoreAnyFieldFilterValue,
|
||||
objectMetadataItem,
|
||||
fields: objectMetadataItem.fields,
|
||||
});
|
||||
|
||||
if (contextStoreTargetedRecordsRule.mode === 'exclusion') {
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import { type FieldMetadataItemRelation } from '@/object-metadata/types/FieldMetadataItemRelation';
|
||||
import { type FieldDateMetadataSettings } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
|
||||
import { type PartialFieldMetadataItemOption } from 'twenty-shared/types';
|
||||
import { type ThemeColor } from 'twenty-ui/theme';
|
||||
import { type Field } from '~/generated-metadata/graphql';
|
||||
|
||||
export type FieldMetadataItemOption = {
|
||||
export type FieldMetadataItemOption = PartialFieldMetadataItemOption & {
|
||||
color: ThemeColor;
|
||||
id: string;
|
||||
label: string;
|
||||
position: number;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type FieldMetadataItem = Omit<
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
import { gql } from '@apollo/client';
|
||||
import { isUndefined } from '@sniptt/guards';
|
||||
import { isNonEmptyArray, isUndefined } from '@sniptt/guards';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
@@ -11,7 +11,6 @@ import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions
|
||||
import { getCombinedFindManyRecordsQueryFilteringPart } from '@/object-record/multiple-objects/utils/getCombinedFindManyRecordsQueryFilteringPart';
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
||||
|
||||
export const useGenerateCombinedFindManyRecordsQuery = ({
|
||||
operationSignatures,
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
import { type RecordGqlOperationSignature } from '@/object-record/graphql/types/RecordGqlOperationSignature';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { capitalize, isDefined, isNonEmptyArray } from 'twenty-shared/utils';
|
||||
|
||||
export const generateCombinedFindManyRecordsQueryVariables = ({
|
||||
operationSignatures,
|
||||
|
||||
+1
-1
@@ -3,11 +3,11 @@ import { FormNestedFieldInputContainer } from '@/object-record/record-field/ui/f
|
||||
import { FormNumberFieldInput } from '@/object-record/record-field/ui/form-types/components/FormNumberFieldInput';
|
||||
import { FormSelectFieldInput } from '@/object-record/record-field/ui/form-types/components/FormSelectFieldInput';
|
||||
import { type VariablePickerComponent } from '@/object-record/record-field/ui/form-types/types/VariablePickerComponent';
|
||||
import { type CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { type FormFieldCurrencyValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { useMemo } from 'react';
|
||||
import { type CurrencyCode } from 'twenty-shared/constants';
|
||||
import { IconCircleOff } from 'twenty-ui/display';
|
||||
|
||||
type FormCurrencyFieldInputProps = {
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { type FieldCurrencyValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { type Meta, type StoryObj } from '@storybook/react';
|
||||
import { expect, within } from '@storybook/test';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { WorkflowStepDecorator } from '~/testing/decorators/WorkflowStepDecorator';
|
||||
import { MOCKED_STEP_ID } from '~/testing/mock-data/workflow';
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { type FieldCurrencyValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { CurrencyInput } from '@/ui/field/input/components/CurrencyInput';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
|
||||
import { useCurrencyField } from '../../hooks/useCurrencyField';
|
||||
|
||||
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
export enum CurrencyCode {
|
||||
AED = 'AED',
|
||||
AFN = 'AFN',
|
||||
ALL = 'ALL',
|
||||
AMD = 'AMD',
|
||||
ANG = 'ANG',
|
||||
AOA = 'AOA',
|
||||
ARS = 'ARS',
|
||||
AUD = 'AUD',
|
||||
AWG = 'AWG',
|
||||
AZN = 'AZN',
|
||||
BAM = 'BAM',
|
||||
BBD = 'BBD',
|
||||
BDT = 'BDT',
|
||||
BGN = 'BGN',
|
||||
BHD = 'BHD',
|
||||
BIF = 'BIF',
|
||||
BMD = 'BMD',
|
||||
BND = 'BND',
|
||||
BOB = 'BOB',
|
||||
BRL = 'BRL',
|
||||
BSD = 'BSD',
|
||||
BTN = 'BTN',
|
||||
BWP = 'BWP',
|
||||
BYN = 'BYN',
|
||||
BZD = 'BZD',
|
||||
CAD = 'CAD',
|
||||
CDF = 'CDF',
|
||||
CHF = 'CHF',
|
||||
CLP = 'CLP',
|
||||
CNY = 'CNY',
|
||||
COP = 'COP',
|
||||
CRC = 'CRC',
|
||||
CUP = 'CUP',
|
||||
CVE = 'CVE',
|
||||
CZK = 'CZK',
|
||||
DJF = 'DJF',
|
||||
DKK = 'DKK',
|
||||
DOP = 'DOP',
|
||||
DZD = 'DZD',
|
||||
EGP = 'EGP',
|
||||
ERN = 'ERN',
|
||||
ETB = 'ETB',
|
||||
EUR = 'EUR',
|
||||
FJD = 'FJD',
|
||||
FKP = 'FKP',
|
||||
GBP = 'GBP',
|
||||
GEL = 'GEL',
|
||||
GHS = 'GHS',
|
||||
GIP = 'GIP',
|
||||
GMD = 'GMD',
|
||||
GNF = 'GNF',
|
||||
GTQ = 'GTQ',
|
||||
GYD = 'GYD',
|
||||
HKD = 'HKD',
|
||||
HNL = 'HNL',
|
||||
HTG = 'HTG',
|
||||
HUF = 'HUF',
|
||||
IDR = 'IDR',
|
||||
ILS = 'ILS',
|
||||
INR = 'INR',
|
||||
IQD = 'IQD',
|
||||
IRR = 'IRR',
|
||||
ISK = 'ISK',
|
||||
JMD = 'JMD',
|
||||
JOD = 'JOD',
|
||||
JPY = 'JPY',
|
||||
KES = 'KES',
|
||||
KGS = 'KGS',
|
||||
KHR = 'KHR',
|
||||
KMF = 'KMF',
|
||||
KPW = 'KPW',
|
||||
KRW = 'KRW',
|
||||
KWD = 'KWD',
|
||||
KYD = 'KYD',
|
||||
KZT = 'KZT',
|
||||
LAK = 'LAK',
|
||||
LBP = 'LBP',
|
||||
LKR = 'LKR',
|
||||
LRD = 'LRD',
|
||||
LSL = 'LSL',
|
||||
LYD = 'LYD',
|
||||
MAD = 'MAD',
|
||||
MDL = 'MDL',
|
||||
MGA = 'MGA',
|
||||
MKD = 'MKD',
|
||||
MMK = 'MMK',
|
||||
MNT = 'MNT',
|
||||
MOP = 'MOP',
|
||||
MRU = 'MRU',
|
||||
MUR = 'MUR',
|
||||
MVR = 'MVR',
|
||||
MWK = 'MWK',
|
||||
MXN = 'MXN',
|
||||
MYR = 'MYR',
|
||||
MZN = 'MZN',
|
||||
NAD = 'NAD',
|
||||
NGN = 'NGN',
|
||||
NIO = 'NIO',
|
||||
NOK = 'NOK',
|
||||
NPR = 'NPR',
|
||||
NZD = 'NZD',
|
||||
OMR = 'OMR',
|
||||
PAB = 'PAB',
|
||||
PEN = 'PEN',
|
||||
PGK = 'PGK',
|
||||
PHP = 'PHP',
|
||||
PKR = 'PKR',
|
||||
PLN = 'PLN',
|
||||
PYG = 'PYG',
|
||||
QAR = 'QAR',
|
||||
RON = 'RON',
|
||||
RSD = 'RSD',
|
||||
RUB = 'RUB',
|
||||
RWF = 'RWF',
|
||||
SAR = 'SAR',
|
||||
SBD = 'SBD',
|
||||
SCR = 'SCR',
|
||||
SDG = 'SDG',
|
||||
SEK = 'SEK',
|
||||
SGD = 'SGD',
|
||||
SHP = 'SHP',
|
||||
SLE = 'SLE',
|
||||
SOS = 'SOS',
|
||||
SRD = 'SRD',
|
||||
SSP = 'SSP',
|
||||
STN = 'STN',
|
||||
SVC = 'SVC',
|
||||
SYP = 'SYP',
|
||||
SZL = 'SZL',
|
||||
THB = 'THB',
|
||||
TJS = 'TJS',
|
||||
TMT = 'TMT',
|
||||
TND = 'TND',
|
||||
TOP = 'TOP',
|
||||
TRY = 'TRY',
|
||||
TTD = 'TTD',
|
||||
TWD = 'TWD',
|
||||
TZS = 'TZS',
|
||||
UAH = 'UAH',
|
||||
UGX = 'UGX',
|
||||
USD = 'USD',
|
||||
UYU = 'UYU',
|
||||
UZS = 'UZS',
|
||||
VES = 'VES',
|
||||
VND = 'VND',
|
||||
VUV = 'VUV',
|
||||
WST = 'WST',
|
||||
XCD = 'XCD',
|
||||
XOF = 'XOF',
|
||||
YER = 'YER',
|
||||
ZAR = 'ZAR',
|
||||
ZMW = 'ZMW',
|
||||
ZWG = 'ZWG',
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,3 @@
|
||||
import { type CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import {
|
||||
type FieldActorValue,
|
||||
type FieldAddressValue,
|
||||
@@ -19,6 +18,7 @@ import {
|
||||
type FieldUUidValue,
|
||||
type PhoneRecord,
|
||||
} from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { type CurrencyCode } from 'twenty-shared/constants';
|
||||
import { type FieldRatingValue } from 'twenty-shared/types';
|
||||
|
||||
export type FieldTextDraftValue = string;
|
||||
|
||||
+1
-1
@@ -1,6 +1,7 @@
|
||||
import { type FieldMetadataItemRelation } from '@/object-metadata/types/FieldMetadataItemRelation';
|
||||
import { type ZodHelperLiteral } from '@/object-record/record-field/ui/types/ZodHelperLiteral';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { type CurrencyCode } from 'twenty-shared/constants';
|
||||
import {
|
||||
ConnectedAccountProvider,
|
||||
type AllowedAddressSubField,
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
import { type ThemeColor } from 'twenty-ui/theme';
|
||||
import { z } from 'zod';
|
||||
import { type RelationType } from '~/generated-metadata/graphql';
|
||||
import { type CurrencyCode } from './CurrencyCode';
|
||||
|
||||
type BaseFieldMetadata = {
|
||||
fieldName: string;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { CurrencyCode } from '../CurrencyCode';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
import { type FieldCurrencyValue } from '../FieldMetadata';
|
||||
|
||||
const currencySchema = z.object({
|
||||
|
||||
+1
-1
@@ -1,4 +1,3 @@
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { type FieldDefinition } from '@/object-record/record-field/ui/types/FieldDefinition';
|
||||
import { type FieldInputDraftValue } from '@/object-record/record-field/ui/types/FieldInputDraftValue';
|
||||
import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
@@ -13,6 +12,7 @@ import { isFieldPhones } from '@/object-record/record-field/ui/types/guards/isFi
|
||||
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
|
||||
import { isFieldText } from '@/object-record/record-field/ui/types/guards/isFieldText';
|
||||
import { isFieldUuid } from '@/object-record/record-field/ui/types/guards/isFieldUuid';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
import { CustomError } from 'twenty-shared/utils';
|
||||
|
||||
type computeDraftValueFromStringParams = {
|
||||
|
||||
+1
-1
@@ -1,4 +1,3 @@
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { type FieldDefinition } from '@/object-record/record-field/ui/types/FieldDefinition';
|
||||
import { type FieldInputDraftValue } from '@/object-record/record-field/ui/types/FieldInputDraftValue';
|
||||
import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
@@ -12,6 +11,7 @@ import { isFieldRawJson } from '@/object-record/record-field/ui/types/guards/isF
|
||||
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
|
||||
import { isFieldText } from '@/object-record/record-field/ui/types/guards/isFieldText';
|
||||
import { isFieldUuid } from '@/object-record/record-field/ui/types/guards/isFieldUuid';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
import { CustomError } from 'twenty-shared/utils';
|
||||
|
||||
type computeEmptyDraftValueParams = {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
|
||||
export const currencyCodeSchema = z.enum(CurrencyCode);
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { type CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { currencyCodeSchema } from '@/object-record/record-field/ui/validation-schemas/currencyCodeSchema';
|
||||
import { type CurrencyCode } from 'twenty-shared/constants';
|
||||
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
|
||||
import { simpleQuotesStringSchema } from '~/utils/validation-schemas/simpleQuotesStringSchema';
|
||||
|
||||
|
||||
-606
@@ -1,606 +0,0 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { filterSelectOptionsOfFieldMetadataItem } from '@/object-record/record-filter/utils/filterSelectOptionsOfFieldMetadataItem';
|
||||
import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
const baseFieldMetadataItem: FieldMetadataItem = {
|
||||
id: 'base-field-metadata-item-id',
|
||||
createdAt: new Date().toISOString(),
|
||||
label: 'Test',
|
||||
name: 'test',
|
||||
type: FieldMetadataType.TEXT,
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const textFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'text-field-id',
|
||||
name: 'textField',
|
||||
};
|
||||
|
||||
const addressFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'address-field-id',
|
||||
type: FieldMetadataType.ADDRESS,
|
||||
name: 'addressField',
|
||||
};
|
||||
|
||||
const linksFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'links-field-id',
|
||||
type: FieldMetadataType.LINKS,
|
||||
name: 'linksField',
|
||||
};
|
||||
|
||||
const fullNameFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'full-name-field-id',
|
||||
type: FieldMetadataType.FULL_NAME,
|
||||
name: 'fullNameField',
|
||||
};
|
||||
|
||||
const arrayFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'array-field-id',
|
||||
type: FieldMetadataType.ARRAY,
|
||||
name: 'arrayField',
|
||||
};
|
||||
|
||||
const emailsFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'emails-field-id',
|
||||
type: FieldMetadataType.EMAILS,
|
||||
name: 'emailsField',
|
||||
};
|
||||
|
||||
const phonesFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'phones-field-id',
|
||||
type: FieldMetadataType.PHONES,
|
||||
name: 'phonesField',
|
||||
};
|
||||
|
||||
const numberFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'number-field-id',
|
||||
type: FieldMetadataType.NUMBER,
|
||||
name: 'numberField',
|
||||
};
|
||||
|
||||
const currencyFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'currency-field-id',
|
||||
type: FieldMetadataType.CURRENCY,
|
||||
name: 'currencyField',
|
||||
};
|
||||
|
||||
const selectFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'select-field-id',
|
||||
type: FieldMetadataType.SELECT,
|
||||
name: 'selectField',
|
||||
options: [
|
||||
{
|
||||
color: 'blue',
|
||||
id: '1',
|
||||
label: 'blue',
|
||||
position: 1,
|
||||
value: 'BLUE',
|
||||
},
|
||||
{
|
||||
color: 'red',
|
||||
id: '2',
|
||||
label: 'red',
|
||||
position: 2,
|
||||
value: 'RED',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const multiSelectFieldMetadataItem: FieldMetadataItem = {
|
||||
...baseFieldMetadataItem,
|
||||
id: 'multi-select-field-id',
|
||||
type: FieldMetadataType.MULTI_SELECT,
|
||||
name: 'multiSelect',
|
||||
options: [
|
||||
{
|
||||
color: 'blue',
|
||||
id: '1',
|
||||
label: 'blue',
|
||||
position: 1,
|
||||
value: 'BLUE',
|
||||
},
|
||||
{
|
||||
color: 'red',
|
||||
id: '2',
|
||||
label: 'red',
|
||||
position: 2,
|
||||
value: 'RED',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const mockObjectMetadataItem: ObjectMetadataItem = {
|
||||
id: 'mock-object-metadata-item',
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
indexMetadatas: [],
|
||||
isActive: true,
|
||||
isCustom: true,
|
||||
isLabelSyncedWithName: true,
|
||||
isRemote: false,
|
||||
isSearchable: true,
|
||||
isSystem: false,
|
||||
isUIReadOnly: false,
|
||||
labelIdentifierFieldMetadataId: 'mock-id',
|
||||
labelPlural: 'Tests',
|
||||
labelSingular: 'Test',
|
||||
nameSingular: 'test',
|
||||
namePlural: 'tests',
|
||||
fields: [],
|
||||
readableFields: [],
|
||||
updatableFields: [],
|
||||
};
|
||||
|
||||
const mockObjectMetadataItemWithAllFields: ObjectMetadataItem = {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [
|
||||
textFieldMetadataItem,
|
||||
addressFieldMetadataItem,
|
||||
linksFieldMetadataItem,
|
||||
fullNameFieldMetadataItem,
|
||||
arrayFieldMetadataItem,
|
||||
emailsFieldMetadataItem,
|
||||
phonesFieldMetadataItem,
|
||||
numberFieldMetadataItem,
|
||||
currencyFieldMetadataItem,
|
||||
selectFieldMetadataItem,
|
||||
multiSelectFieldMetadataItem,
|
||||
],
|
||||
};
|
||||
|
||||
describe('turnAnyFieldFilterIntoRecordGqlFilter', () => {
|
||||
describe('TEXT field type', () => {
|
||||
it('should generate correct filter for text field', () => {
|
||||
const filterValue = 'test';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [textFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
[textFieldMetadataItem.name]: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ADDRESS field type', () => {
|
||||
it('should generate correct filter for address field', () => {
|
||||
const filterValue = 'New York';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [addressFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
or: [
|
||||
{
|
||||
[addressFieldMetadataItem.name]: {
|
||||
addressStreet1: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[addressFieldMetadataItem.name]: {
|
||||
addressStreet2: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[addressFieldMetadataItem.name]: {
|
||||
addressCity: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[addressFieldMetadataItem.name]: {
|
||||
addressState: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[addressFieldMetadataItem.name]: {
|
||||
addressCountry: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[addressFieldMetadataItem.name]: {
|
||||
addressPostcode: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('LINKS field type', () => {
|
||||
it('should generate correct filter for links field', () => {
|
||||
const filterValue = 'test';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [linksFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
or: [
|
||||
{
|
||||
[linksFieldMetadataItem.name]: {
|
||||
primaryLinkUrl: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[linksFieldMetadataItem.name]: {
|
||||
primaryLinkLabel: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[linksFieldMetadataItem.name]: {
|
||||
secondaryLinks: {
|
||||
like: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('FULL_NAME field type', () => {
|
||||
it('should generate correct filter for full name field', () => {
|
||||
const filterValue = 'test';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [fullNameFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
or: [
|
||||
{
|
||||
[fullNameFieldMetadataItem.name]: {
|
||||
firstName: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[fullNameFieldMetadataItem.name]: {
|
||||
lastName: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ARRAY field type', () => {
|
||||
it('should generate correct filter for array field', () => {
|
||||
const filterValue = 'test';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [arrayFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
[arrayFieldMetadataItem.name]: {
|
||||
containsIlike: `%${filterValue}%`,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('EMAILS field type', () => {
|
||||
it('should generate correct filter for emails field', () => {
|
||||
const filterValue = 'test';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [emailsFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
or: [
|
||||
{
|
||||
[emailsFieldMetadataItem.name]: {
|
||||
primaryEmail: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[emailsFieldMetadataItem.name]: {
|
||||
additionalEmails: {
|
||||
like: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PHONES field type', () => {
|
||||
it('should generate correct filter for phones field', () => {
|
||||
const filterValue = '123';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [phonesFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
or: [
|
||||
{
|
||||
[phonesFieldMetadataItem.name]: {
|
||||
primaryPhoneNumber: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[phonesFieldMetadataItem.name]: {
|
||||
primaryPhoneCallingCode: {
|
||||
ilike: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
[phonesFieldMetadataItem.name]: {
|
||||
additionalPhones: {
|
||||
like: `%${filterValue}%`,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('NUMBER field type', () => {
|
||||
it('should generate correct filter for number field with numeric value', () => {
|
||||
const filterValue = '123.1';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [numberFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
[numberFieldMetadataItem.name]: {
|
||||
eq: 123.1,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not generate filter for number field with non-numeric value', () => {
|
||||
const filterValue = 'not a number';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [numberFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('CURRENCY field type', () => {
|
||||
it('should generate correct filter for currency field with numeric value', () => {
|
||||
const filterValue = '123';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [currencyFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
[currencyFieldMetadataItem.name]: {
|
||||
amountMicros: {
|
||||
eq: 123000000,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate correct filter for currency field with currency code', () => {
|
||||
const filterValue = 'USD';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [currencyFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
(result.recordGqlOperationFilter.or as any)?.[0][
|
||||
currencyFieldMetadataItem.name
|
||||
].currencyCode.in.includes(filterValue),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SELECT field type', () => {
|
||||
it('should generate correct filter for select field with matching option', () => {
|
||||
const filterValue = 'r';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [selectFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
const { foundCorrespondingSelectOptions: expectedOptions } =
|
||||
filterSelectOptionsOfFieldMetadataItem({
|
||||
fieldMetadataItem: selectFieldMetadataItem,
|
||||
filterValue,
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
[selectFieldMetadataItem.name]: {
|
||||
in: expectedOptions?.map((option) => option.value),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not generate filter for select field with non-matching value', () => {
|
||||
const filterValue = 'not-found';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [selectFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('MULTI_SELECT field type', () => {
|
||||
it('should generate correct filter for multi-select field with matching option', () => {
|
||||
const filterValue = 'r';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [multiSelectFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
const { foundCorrespondingSelectOptions: expectedOptions } =
|
||||
filterSelectOptionsOfFieldMetadataItem({
|
||||
fieldMetadataItem: multiSelectFieldMetadataItem,
|
||||
filterValue,
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter.or).toContainEqual({
|
||||
[multiSelectFieldMetadataItem.name]: {
|
||||
containsAny: expectedOptions?.map((option) => option.value),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not generate filter for multi-select field with non-matching value', () => {
|
||||
const filterValue = 'not-found';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [multiSelectFieldMetadataItem],
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('combined field filters', () => {
|
||||
it('should generate OR filter combining all matching field types', () => {
|
||||
const filterValue = 'a';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: mockObjectMetadataItemWithAllFields,
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter).toHaveProperty('or');
|
||||
expect(Array.isArray(result.recordGqlOperationFilter.or)).toBe(true);
|
||||
expect(
|
||||
(result.recordGqlOperationFilter.or as any[])?.length,
|
||||
).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should handle empty filter value', () => {
|
||||
const filterValue = '';
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue,
|
||||
objectMetadataItem: mockObjectMetadataItemWithAllFields,
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter).toEqual({});
|
||||
});
|
||||
|
||||
it('should handle object with no fields', () => {
|
||||
const emptyObjectMetadata = {
|
||||
...mockObjectMetadataItem,
|
||||
fields: [],
|
||||
};
|
||||
|
||||
const result = turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
filterValue: 'test',
|
||||
objectMetadataItem: emptyObjectMetadata,
|
||||
});
|
||||
|
||||
expect(result.recordGqlOperationFilter).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
export const createAnyFieldRecordFilterBaseProperties = ({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}: {
|
||||
filterValue: string;
|
||||
fieldMetadataItem: FieldMetadataItem;
|
||||
}): Pick<
|
||||
RecordFilter,
|
||||
'id' | 'value' | 'displayValue' | 'label' | 'fieldMetadataId'
|
||||
> => {
|
||||
return {
|
||||
id: v4(),
|
||||
value: filterValue,
|
||||
displayValue: '',
|
||||
label: '',
|
||||
fieldMetadataId: fieldMetadataItem.id,
|
||||
};
|
||||
};
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
|
||||
export const filterSelectOptionsOfFieldMetadataItem = ({
|
||||
fieldMetadataItem,
|
||||
filterValue,
|
||||
}: {
|
||||
fieldMetadataItem: FieldMetadataItem;
|
||||
filterValue: string;
|
||||
}) => {
|
||||
const selectOptions = fieldMetadataItem.options;
|
||||
|
||||
const foundCorrespondingSelectOptions = selectOptions?.filter(
|
||||
(selectOption) =>
|
||||
selectOption.value
|
||||
.toLocaleLowerCase()
|
||||
.includes(filterValue.toLocaleLowerCase()) ||
|
||||
selectOption.label
|
||||
.toLocaleLowerCase()
|
||||
.includes(filterValue.toLocaleLowerCase()),
|
||||
);
|
||||
|
||||
return {
|
||||
foundCorrespondingSelectOptions,
|
||||
};
|
||||
};
|
||||
-238
@@ -1,238 +0,0 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
|
||||
import { createAnyFieldRecordFilterBaseProperties } from '@/object-record/record-filter/utils/createAnyFieldRecordFilterBaseProperties';
|
||||
import { filterSelectOptionsOfFieldMetadataItem } from '@/object-record/record-filter/utils/filterSelectOptionsOfFieldMetadataItem';
|
||||
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { type RecordGqlOperationFilter } from 'twenty-shared/types';
|
||||
import {
|
||||
isDefined,
|
||||
turnRecordFilterIntoRecordGqlOperationFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
import { z } from 'zod';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
||||
|
||||
export const turnAnyFieldFilterIntoRecordGqlFilter = ({
|
||||
filterValue,
|
||||
objectMetadataItem,
|
||||
}: {
|
||||
filterValue: string;
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
}) => {
|
||||
const fieldMetadataItems = objectMetadataItem.fields;
|
||||
|
||||
const anyFieldRecordFilters: RecordFilter[] = [];
|
||||
|
||||
const isFilterValueANumber = z.coerce.number().safeParse(filterValue).success;
|
||||
|
||||
for (const fieldMetadataItem of fieldMetadataItems) {
|
||||
switch (fieldMetadataItem.type) {
|
||||
case FieldMetadataType.TEXT: {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'TEXT',
|
||||
} satisfies RecordFilter);
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.ADDRESS: {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'ADDRESS',
|
||||
} satisfies RecordFilter);
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.LINKS: {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'LINKS',
|
||||
} satisfies RecordFilter);
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.FULL_NAME: {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'FULL_NAME',
|
||||
} satisfies RecordFilter);
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.ARRAY: {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'ARRAY',
|
||||
} satisfies RecordFilter);
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.EMAILS: {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'EMAILS',
|
||||
} satisfies RecordFilter);
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.PHONES: {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'PHONES',
|
||||
} satisfies RecordFilter);
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.NUMBER: {
|
||||
if (isFilterValueANumber) {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.IS,
|
||||
type: 'NUMBER',
|
||||
} satisfies RecordFilter);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.CURRENCY: {
|
||||
if (isFilterValueANumber) {
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.IS,
|
||||
type: 'CURRENCY',
|
||||
subFieldName: 'amountMicros',
|
||||
} satisfies RecordFilter);
|
||||
}
|
||||
|
||||
if (isNonEmptyString(filterValue)) {
|
||||
const foundCorrespondingCurrencies = CURRENCIES.filter(
|
||||
(currency) =>
|
||||
currency.label.includes(filterValue) ||
|
||||
currency.value.includes(filterValue),
|
||||
);
|
||||
|
||||
if (isNonEmptyArray(foundCorrespondingCurrencies)) {
|
||||
const arrayOfCurrenciesStringified = JSON.stringify(
|
||||
foundCorrespondingCurrencies.map((currency) => currency.value),
|
||||
);
|
||||
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
filterValue: arrayOfCurrenciesStringified,
|
||||
fieldMetadataItem,
|
||||
}),
|
||||
operand: RecordFilterOperand.IS,
|
||||
type: 'CURRENCY',
|
||||
subFieldName: 'currencyCode',
|
||||
} satisfies RecordFilter);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.SELECT: {
|
||||
if (isNonEmptyString(filterValue)) {
|
||||
const { foundCorrespondingSelectOptions } =
|
||||
filterSelectOptionsOfFieldMetadataItem({
|
||||
fieldMetadataItem,
|
||||
filterValue,
|
||||
});
|
||||
|
||||
if (isNonEmptyArray(foundCorrespondingSelectOptions)) {
|
||||
const arrayOfSelectValues = JSON.stringify(
|
||||
foundCorrespondingSelectOptions.map(
|
||||
(selectOption) => selectOption.value,
|
||||
),
|
||||
);
|
||||
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
fieldMetadataItem,
|
||||
filterValue: arrayOfSelectValues,
|
||||
}),
|
||||
operand: RecordFilterOperand.IS,
|
||||
type: 'SELECT',
|
||||
} satisfies RecordFilter);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FieldMetadataType.MULTI_SELECT: {
|
||||
if (isNonEmptyString(filterValue)) {
|
||||
const { foundCorrespondingSelectOptions } =
|
||||
filterSelectOptionsOfFieldMetadataItem({
|
||||
fieldMetadataItem,
|
||||
filterValue,
|
||||
});
|
||||
|
||||
if (isNonEmptyArray(foundCorrespondingSelectOptions)) {
|
||||
const arrayOfSelectValues = JSON.stringify(
|
||||
foundCorrespondingSelectOptions.map(
|
||||
(selectOption) => selectOption.value,
|
||||
),
|
||||
);
|
||||
|
||||
anyFieldRecordFilters.push({
|
||||
...createAnyFieldRecordFilterBaseProperties({
|
||||
fieldMetadataItem,
|
||||
filterValue: arrayOfSelectValues,
|
||||
}),
|
||||
operand: RecordFilterOperand.CONTAINS,
|
||||
type: 'MULTI_SELECT',
|
||||
} satisfies RecordFilter);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const baseRecordGqlOperationFilters = anyFieldRecordFilters
|
||||
.map((recordFilter) =>
|
||||
turnRecordFilterIntoRecordGqlOperationFilter({
|
||||
filterValueDependencies: {},
|
||||
fieldMetadataItems: objectMetadataItem.fields,
|
||||
recordFilter,
|
||||
}),
|
||||
)
|
||||
.filter(isDefined);
|
||||
|
||||
const recordGqlOperationFilter: RecordGqlOperationFilter = {
|
||||
or: baseRecordGqlOperationFilters,
|
||||
};
|
||||
|
||||
if (baseRecordGqlOperationFilters.length === 0) {
|
||||
return { recordGqlOperationFilter: {} };
|
||||
}
|
||||
|
||||
return {
|
||||
recordGqlOperationFilter,
|
||||
};
|
||||
};
|
||||
+2
-2
@@ -4,7 +4,6 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record-
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter';
|
||||
import { useCurrentRecordGroupDefinition } from '@/object-record/record-group/hooks/useCurrentRecordGroupDefinition';
|
||||
import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter';
|
||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||
@@ -12,6 +11,7 @@ import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/ho
|
||||
import {
|
||||
combineFilters,
|
||||
computeRecordGqlOperationFilter,
|
||||
turnAnyFieldFilterIntoRecordGqlFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
export const useFindManyRecordIndexTableParams = (
|
||||
objectNameSingular: string,
|
||||
@@ -53,7 +53,7 @@ export const useFindManyRecordIndexTableParams = (
|
||||
|
||||
const { recordGqlOperationFilter: anyFieldFilter } =
|
||||
turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
objectMetadataItem,
|
||||
fields: objectMetadataItem?.fields ?? [],
|
||||
filterValue: anyFieldFilterValue,
|
||||
});
|
||||
|
||||
|
||||
+2
-2
@@ -15,13 +15,13 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte
|
||||
import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState';
|
||||
|
||||
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
|
||||
import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter';
|
||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import {
|
||||
combineFilters,
|
||||
computeRecordGqlOperationFilter,
|
||||
isDefined,
|
||||
turnAnyFieldFilterIntoRecordGqlFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
type UseLoadRecordIndexBoardProps = {
|
||||
@@ -74,7 +74,7 @@ export const useLoadRecordIndexBoardColumn = ({
|
||||
|
||||
const { recordGqlOperationFilter: anyFieldFilter } =
|
||||
turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
objectMetadataItem,
|
||||
fields: objectMetadataItem.fields,
|
||||
filterValue: anyFieldFilterValue,
|
||||
});
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,6 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record-
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter';
|
||||
import { recordIndexKanbanAggregateOperationState } from '@/object-record/record-index/states/recordIndexKanbanAggregateOperationState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { UserContext } from '@/users/contexts/UserContext';
|
||||
@@ -15,6 +14,7 @@ import { useRecoilValue } from 'recoil';
|
||||
import {
|
||||
computeRecordGqlOperationFilter,
|
||||
isDefined,
|
||||
turnAnyFieldFilterIntoRecordGqlFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
|
||||
@@ -64,7 +64,7 @@ export const useAggregateRecordsForHeader = ({
|
||||
|
||||
const { recordGqlOperationFilter: anyFieldFilter } =
|
||||
turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
objectMetadataItem,
|
||||
fields: objectMetadataItem.fields,
|
||||
filterValue: anyFieldFilterValue,
|
||||
});
|
||||
|
||||
|
||||
+2
-2
@@ -4,7 +4,6 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record-
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter';
|
||||
import { useRecordGroupFilter } from '@/object-record/record-group/hooks/useRecordGroupFilter';
|
||||
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
|
||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||
@@ -20,6 +19,7 @@ import {
|
||||
computeRecordGqlOperationFilter,
|
||||
isDefined,
|
||||
isFieldMetadataDateKind,
|
||||
turnAnyFieldFilterIntoRecordGqlFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
|
||||
@@ -96,7 +96,7 @@ export const useAggregateRecordsForRecordTableColumnFooter = (
|
||||
|
||||
const { recordGqlOperationFilter: anyFieldFilter } =
|
||||
turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
objectMetadataItem,
|
||||
fields: objectMetadataItem.fields,
|
||||
filterValue: anyFieldFilterValue,
|
||||
});
|
||||
|
||||
|
||||
+1
-2
@@ -8,8 +8,7 @@ import { RecordTableCellStyleWrapper } from '@/object-record/record-table/record
|
||||
import { RecordTableCellWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellWrapper';
|
||||
import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
||||
import { isDefined, isNonEmptyArray } from 'twenty-shared/utils';
|
||||
|
||||
export const RecordTableCellsVisible = () => {
|
||||
const { isSelected, rowIndex } = useRecordTableRowContextOrThrow();
|
||||
|
||||
+4
-2
@@ -1,4 +1,3 @@
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import {
|
||||
type FieldActorValue,
|
||||
type FieldAddressValue,
|
||||
@@ -12,7 +11,10 @@ import {
|
||||
import { COMPOSITE_FIELD_SUB_FIELD_LABELS } from '@/settings/data-model/constants/CompositeFieldSubFieldLabel';
|
||||
import { type SettingsFieldTypeConfig } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs';
|
||||
import { type CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType';
|
||||
import { COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES } from 'twenty-shared/constants';
|
||||
import {
|
||||
COMPOSITE_FIELD_TYPE_SUB_FIELDS_NAMES,
|
||||
CurrencyCode,
|
||||
} from 'twenty-shared/constants';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import {
|
||||
IllustrationIconCurrency,
|
||||
|
||||
+181
-155
@@ -1,4 +1,7 @@
|
||||
import { type CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import {
|
||||
CURRENCY_CODE_LABELS,
|
||||
type CurrencyCode,
|
||||
} from 'twenty-shared/constants';
|
||||
import {
|
||||
IconCoins,
|
||||
IconCurrencyAfghani,
|
||||
@@ -53,162 +56,185 @@ import {
|
||||
IconCurrencyZloty,
|
||||
type IconComponent,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
export const SETTINGS_FIELD_CURRENCY_CODES: Record<
|
||||
CurrencyCode,
|
||||
{ label: string; Icon: IconComponent }
|
||||
> = {
|
||||
AED: { label: 'UAE dirham', Icon: IconCurrencyDirham },
|
||||
AFN: { label: 'Afghan afghani', Icon: IconCurrencyAfghani },
|
||||
ALL: { label: 'Albanian lek', Icon: IconCurrencyLeu },
|
||||
AMD: { label: 'Armenian dram', Icon: IconCurrencyDram },
|
||||
ANG: { label: 'Netherlands Antillean guilder', Icon: IconCurrencyFlorin },
|
||||
AOA: { label: 'Angolan kwanza', Icon: IconCoins },
|
||||
ARS: { label: 'Argentine peso', Icon: IconCoins },
|
||||
AUD: { label: 'Australian dollar', Icon: IconCurrencyDollarAustralian },
|
||||
AWG: { label: 'Aruban florin', Icon: IconCurrencyFlorin },
|
||||
AZN: { label: 'Azerbaijani manat', Icon: IconCurrencyManat },
|
||||
BAM: { label: 'Bosnia and Herzegovina mark', Icon: IconCoins },
|
||||
BBD: { label: 'Barbados dollar', Icon: IconCurrencyDollar },
|
||||
BDT: { label: 'Bangladeshi taka', Icon: IconCurrencyTaka },
|
||||
BGN: { label: 'Bulgarian lev', Icon: IconCoins },
|
||||
BHD: { label: 'Bahraini dinar', Icon: IconCurrencyBahraini },
|
||||
BIF: { label: 'Burundian franc', Icon: IconCoins },
|
||||
BMD: { label: 'Bermudian dollar', Icon: IconCurrencyDollar },
|
||||
BND: { label: 'Brunei dollar', Icon: IconCurrencyDollarBrunei },
|
||||
BOB: { label: 'Boliviano', Icon: IconCoins },
|
||||
BRL: { label: 'Brazilian real', Icon: IconCurrencyReal },
|
||||
BSD: { label: 'Bahamian dollar', Icon: IconCurrencyDollar },
|
||||
BTN: { label: 'Bhutanese ngultrum', Icon: IconCurrencyDollar },
|
||||
BWP: { label: 'Botswana pula', Icon: IconCoins },
|
||||
BYN: { label: 'Belarusian ruble', Icon: IconCoins },
|
||||
BZD: { label: 'Belize dollar', Icon: IconCurrencyDollar },
|
||||
CAD: { label: 'Canadian dollar', Icon: IconCurrencyDollarCanadian },
|
||||
CDF: { label: 'Congolese franc', Icon: IconCoins },
|
||||
CHF: { label: 'Swiss franc', Icon: IconCurrencyFrank },
|
||||
CLP: { label: 'Chilean peso', Icon: IconCoins },
|
||||
CNY: { label: 'Chinese yuan', Icon: IconCurrencyYuan },
|
||||
COP: { label: 'Colombian peso', Icon: IconCoins },
|
||||
CRC: { label: 'Costa Rican colon', Icon: IconCoins },
|
||||
CUP: { label: 'Cuban peso', Icon: IconCoins },
|
||||
CVE: { label: 'Cape Verdean escudo', Icon: IconCoins },
|
||||
CZK: { label: 'Czech koruna', Icon: IconCurrencyKroneCzech },
|
||||
DJF: { label: 'Djiboutian franc', Icon: IconCoins },
|
||||
DKK: { label: 'Danish krone', Icon: IconCurrencyKroneDanish },
|
||||
DOP: { label: 'Dominican peso', Icon: IconCoins },
|
||||
DZD: { label: 'Algerian Dinar', Icon: IconCoins },
|
||||
EGP: { label: 'Egyptian pound', Icon: IconCoins },
|
||||
ERN: { label: 'Eritrean nakfa', Icon: IconCoins },
|
||||
ETB: { label: 'Ethiopian birr', Icon: IconCoins },
|
||||
EUR: { label: 'Euro', Icon: IconCurrencyEuro },
|
||||
FJD: { label: 'Fiji dollar', Icon: IconCurrencyDollar },
|
||||
FKP: { label: 'Falkland Islands pound', Icon: IconCoins },
|
||||
GBP: { label: 'British pound', Icon: IconCurrencyPound },
|
||||
GEL: { label: 'Georgian lari', Icon: IconCurrencyLari },
|
||||
GHS: { label: 'Ghanaian cedi', Icon: IconCoins },
|
||||
GIP: { label: 'Gibraltar pound', Icon: IconCoins },
|
||||
GMD: { label: 'Gambian dalasi', Icon: IconCoins },
|
||||
GNF: { label: 'Guinean franc', Icon: IconCoins },
|
||||
GTQ: { label: 'Guatemalan quetzal', Icon: IconCurrencyQuetzal },
|
||||
GYD: { label: 'Guyanese dollar', Icon: IconCurrencyDollarGuyanese },
|
||||
HKD: { label: 'Hong Kong dollar', Icon: IconCurrencyRenminbi },
|
||||
HNL: { label: 'Honduran lempira', Icon: IconCurrencyLeu },
|
||||
HTG: { label: 'Haitian gourde', Icon: IconCoins },
|
||||
HUF: { label: 'Hungarian forint', Icon: IconCurrencyForint },
|
||||
IDR: { label: 'Indonesian rupiah', Icon: IconCoins },
|
||||
ILS: { label: 'Israeli shekel', Icon: IconCurrencyShekel },
|
||||
INR: { label: 'Indian rupee', Icon: IconCurrencyRupee },
|
||||
IQD: { label: 'Iraqi dinar', Icon: IconCoins },
|
||||
IRR: { label: 'Iranian rial', Icon: IconCurrencyIranianRial },
|
||||
ISK: { label: 'Icelandic króna', Icon: IconCoins },
|
||||
JMD: { label: 'Jamaican dollar', Icon: IconCurrencyDollar },
|
||||
JOD: { label: 'Jordanian dinar', Icon: IconCoins },
|
||||
JPY: { label: 'Japanese yen', Icon: IconCurrencyYen },
|
||||
KES: { label: 'Kenyan shilling', Icon: IconCoins },
|
||||
KGS: { label: 'Kyrgyzstani som', Icon: IconCurrencySom },
|
||||
KHR: { label: 'Cambodian riel', Icon: IconCoins },
|
||||
KMF: { label: 'Comoro franc', Icon: IconCoins },
|
||||
KPW: { label: 'North Korean won', Icon: IconCurrencyWon },
|
||||
KRW: { label: 'South Korean won', Icon: IconCurrencyWon },
|
||||
KWD: { label: 'Kuwaiti dinar', Icon: IconCurrencyDinar },
|
||||
KYD: { label: 'Cayman Islands dollar', Icon: IconCurrencyDollar },
|
||||
KZT: { label: 'Kazakhstani tenge', Icon: IconCurrencyTenge },
|
||||
LAK: { label: 'Lao kip', Icon: IconCurrencyKip },
|
||||
LBP: { label: 'Lebanese pound', Icon: IconCoins },
|
||||
LKR: { label: 'Sri Lankan rupee', Icon: IconCoins },
|
||||
LRD: { label: 'Liberian dollar', Icon: IconCurrencyDollar },
|
||||
LSL: { label: 'Lesotho loti', Icon: IconCurrencyLeu },
|
||||
LYD: { label: 'Libyan dinar', Icon: IconCurrencyLyd },
|
||||
MAD: { label: 'Moroccan dirham', Icon: IconCurrencyDirham },
|
||||
MDL: { label: 'Moldovan leu', Icon: IconCurrencyLeu },
|
||||
MGA: { label: 'Malagasy ariary', Icon: IconCoins },
|
||||
MKD: { label: 'Macedonian denar', Icon: IconCoins },
|
||||
MMK: { label: 'Myanmar kyat', Icon: IconCoins },
|
||||
MNT: { label: 'Mongolian tögrög', Icon: IconCurrencyTugrik },
|
||||
MOP: { label: 'Macanese pataca', Icon: IconCurrencyRenminbi },
|
||||
MRU: { label: 'Mauritanian ouguiya', Icon: IconCoins },
|
||||
MUR: { label: 'Mauritian rupee', Icon: IconCoins },
|
||||
MVR: { label: 'Maldivian rufiyaa', Icon: IconCurrencyRufiyaa },
|
||||
MWK: { label: 'Malawian kwacha', Icon: IconCoins },
|
||||
MXN: { label: 'Mexican peso', Icon: IconCoins },
|
||||
MYR: { label: 'Malaysian ringgit', Icon: IconCoins },
|
||||
MZN: { label: 'Mozambican metical', Icon: IconCoins },
|
||||
NAD: { label: 'Namibian dollar', Icon: IconCurrencyDollar },
|
||||
NGN: { label: 'Nigerian naira', Icon: IconCurrencyNaira },
|
||||
NIO: { label: 'Nicaraguan córdoba', Icon: IconCoins },
|
||||
NOK: { label: 'Norwegian krone', Icon: IconCurrencyKroneSwedish },
|
||||
NPR: { label: 'Nepalese rupee', Icon: IconCurrencyRupeeNepalese },
|
||||
NZD: { label: 'New Zealand dollar', Icon: IconCurrencyDollar },
|
||||
OMR: { label: 'Omani rial', Icon: IconCoins },
|
||||
PAB: { label: 'Panamanian balboa', Icon: IconCoins },
|
||||
PEN: { label: 'Peruvian sol', Icon: IconCoins },
|
||||
PGK: { label: 'Papua New Guinean kina', Icon: IconCoins },
|
||||
PHP: { label: 'Philippine peso', Icon: IconCurrencyPeso },
|
||||
PKR: { label: 'Pakistani rupee', Icon: IconCoins },
|
||||
PLN: { label: 'Polish złoty', Icon: IconCurrencyZloty },
|
||||
PYG: { label: 'Paraguayan guaraní', Icon: IconCurrencyGuarani },
|
||||
QAR: { label: 'Qatari riyal', Icon: IconCurrencyRiyal },
|
||||
RON: { label: 'Romanian leu', Icon: IconCurrencyLeu },
|
||||
RSD: { label: 'Serbian dinar', Icon: IconCoins },
|
||||
RUB: { label: 'Russian ruble', Icon: IconCurrencyRubel },
|
||||
RWF: { label: 'Rwandan franc', Icon: IconCoins },
|
||||
SAR: { label: 'Saudi riyal', Icon: IconCoins },
|
||||
SBD: { label: 'Solomon Islands dollar', Icon: IconCurrencyDollar },
|
||||
SCR: { label: 'Seychelles rupee', Icon: IconCoins },
|
||||
SDG: { label: 'Sudanese pound', Icon: IconCoins },
|
||||
SEK: { label: 'Swedish krona', Icon: IconCurrencyKroneSwedish },
|
||||
SGD: { label: 'Singapore dollar', Icon: IconCurrencyDollarSingapore },
|
||||
SHP: { label: 'Saint Helena pound', Icon: IconCoins },
|
||||
SLE: { label: 'Sierra Leonean leone', Icon: IconCoins },
|
||||
SOS: { label: 'Somalian shilling', Icon: IconCoins },
|
||||
SRD: { label: 'Surinamese dollar', Icon: IconCurrencyDollar },
|
||||
SSP: { label: 'South Sudanese pound', Icon: IconCoins },
|
||||
STN: { label: 'São Tomé and Príncipe dobra', Icon: IconCoins },
|
||||
SVC: { label: 'Salvadoran colón', Icon: IconCoins },
|
||||
SYP: { label: 'Syrian pound', Icon: IconCoins },
|
||||
SZL: { label: 'Swazi lilangeni', Icon: IconCurrencyLeu },
|
||||
THB: { label: 'Thai Baht', Icon: IconCurrencyBaht },
|
||||
TJS: { label: 'Tajikistani somoni', Icon: IconCoins },
|
||||
TMT: { label: 'Turkmenistan manat', Icon: IconCurrencyManat },
|
||||
TND: { label: 'Tunisian dinar', Icon: IconCoins },
|
||||
TOP: { label: 'Tongan paʻanga', Icon: IconCurrencyPaanga },
|
||||
TRY: { label: 'Turkish lira', Icon: IconCurrencyLira },
|
||||
TTD: { label: 'Trinidad and Tobago dollar', Icon: IconCurrencyDollar },
|
||||
TWD: { label: 'Taiwanese dollar', Icon: IconCurrencyRenminbi },
|
||||
TZS: { label: 'Tanzanian shilling', Icon: IconCoins },
|
||||
UAH: { label: 'Ukrainian hryvnia', Icon: IconCurrencyHryvnia },
|
||||
UGX: { label: 'Ugandan shilling', Icon: IconCoins },
|
||||
USD: { label: 'United States dollar', Icon: IconCurrencyDollar },
|
||||
UYU: { label: 'Uruguayan peso', Icon: IconCoins },
|
||||
UZS: { label: 'Uzbekistani sum', Icon: IconCoins },
|
||||
VES: { label: 'Venezuelan bolívar', Icon: IconCoins },
|
||||
VND: { label: 'Vietnamese đồng', Icon: IconCurrencyDong },
|
||||
VUV: { label: 'Vanuatu vatu', Icon: IconCoins },
|
||||
WST: { label: 'Samoan tala', Icon: IconCoins },
|
||||
XOF: { label: 'West African CFA franc', Icon: IconCoins },
|
||||
XCD: { label: 'East Caribbean dollar', Icon: IconCurrencyDollar },
|
||||
YER: { label: 'Yemeni rial', Icon: IconCoins },
|
||||
ZAR: { label: 'South African rand', Icon: IconCoins },
|
||||
ZMW: { label: 'Zambian kwacha', Icon: IconCoins },
|
||||
ZWG: { label: 'Zimbabwe Gold', Icon: IconCoins },
|
||||
AED: { label: CURRENCY_CODE_LABELS.AED.label, Icon: IconCurrencyDirham },
|
||||
AFN: { label: CURRENCY_CODE_LABELS.AFN.label, Icon: IconCurrencyAfghani },
|
||||
ALL: { label: CURRENCY_CODE_LABELS.ALL.label, Icon: IconCurrencyLeu },
|
||||
AMD: { label: CURRENCY_CODE_LABELS.AMD.label, Icon: IconCurrencyDram },
|
||||
ANG: { label: CURRENCY_CODE_LABELS.ANG.label, Icon: IconCurrencyFlorin },
|
||||
AOA: { label: CURRENCY_CODE_LABELS.AOA.label, Icon: IconCoins },
|
||||
ARS: { label: CURRENCY_CODE_LABELS.ARS.label, Icon: IconCoins },
|
||||
AUD: {
|
||||
label: CURRENCY_CODE_LABELS.AUD.label,
|
||||
Icon: IconCurrencyDollarAustralian,
|
||||
},
|
||||
AWG: { label: CURRENCY_CODE_LABELS.AWG.label, Icon: IconCurrencyFlorin },
|
||||
AZN: { label: CURRENCY_CODE_LABELS.AZN.label, Icon: IconCurrencyManat },
|
||||
BAM: { label: CURRENCY_CODE_LABELS.BAM.label, Icon: IconCoins },
|
||||
BBD: { label: CURRENCY_CODE_LABELS.BBD.label, Icon: IconCurrencyDollar },
|
||||
BDT: { label: CURRENCY_CODE_LABELS.BDT.label, Icon: IconCurrencyTaka },
|
||||
BGN: { label: CURRENCY_CODE_LABELS.BGN.label, Icon: IconCoins },
|
||||
BHD: { label: CURRENCY_CODE_LABELS.BHD.label, Icon: IconCurrencyBahraini },
|
||||
BIF: { label: CURRENCY_CODE_LABELS.BIF.label, Icon: IconCoins },
|
||||
BMD: { label: CURRENCY_CODE_LABELS.BMD.label, Icon: IconCurrencyDollar },
|
||||
BND: {
|
||||
label: CURRENCY_CODE_LABELS.BND.label,
|
||||
Icon: IconCurrencyDollarBrunei,
|
||||
},
|
||||
BOB: { label: CURRENCY_CODE_LABELS.BOB.label, Icon: IconCoins },
|
||||
BRL: { label: CURRENCY_CODE_LABELS.BRL.label, Icon: IconCurrencyReal },
|
||||
BSD: { label: CURRENCY_CODE_LABELS.BSD.label, Icon: IconCurrencyDollar },
|
||||
BTN: { label: CURRENCY_CODE_LABELS.BTN.label, Icon: IconCurrencyDollar },
|
||||
BWP: { label: CURRENCY_CODE_LABELS.BWP.label, Icon: IconCoins },
|
||||
BYN: { label: CURRENCY_CODE_LABELS.BYN.label, Icon: IconCoins },
|
||||
BZD: { label: CURRENCY_CODE_LABELS.BZD.label, Icon: IconCurrencyDollar },
|
||||
CAD: {
|
||||
label: CURRENCY_CODE_LABELS.CAD.label,
|
||||
Icon: IconCurrencyDollarCanadian,
|
||||
},
|
||||
CDF: { label: CURRENCY_CODE_LABELS.CDF.label, Icon: IconCoins },
|
||||
CHF: { label: CURRENCY_CODE_LABELS.CHF.label, Icon: IconCurrencyFrank },
|
||||
CLP: { label: CURRENCY_CODE_LABELS.CLP.label, Icon: IconCoins },
|
||||
CNY: { label: CURRENCY_CODE_LABELS.CNY.label, Icon: IconCurrencyYuan },
|
||||
COP: { label: CURRENCY_CODE_LABELS.COP.label, Icon: IconCoins },
|
||||
CRC: { label: CURRENCY_CODE_LABELS.CRC.label, Icon: IconCoins },
|
||||
CUP: { label: CURRENCY_CODE_LABELS.CUP.label, Icon: IconCoins },
|
||||
CVE: { label: CURRENCY_CODE_LABELS.CVE.label, Icon: IconCoins },
|
||||
CZK: { label: CURRENCY_CODE_LABELS.CZK.label, Icon: IconCurrencyKroneCzech },
|
||||
DJF: { label: CURRENCY_CODE_LABELS.DJF.label, Icon: IconCoins },
|
||||
DKK: { label: CURRENCY_CODE_LABELS.DKK.label, Icon: IconCurrencyKroneDanish },
|
||||
DOP: { label: CURRENCY_CODE_LABELS.DOP.label, Icon: IconCoins },
|
||||
DZD: { label: CURRENCY_CODE_LABELS.DZD.label, Icon: IconCoins },
|
||||
EGP: { label: CURRENCY_CODE_LABELS.EGP.label, Icon: IconCoins },
|
||||
ERN: { label: CURRENCY_CODE_LABELS.ERN.label, Icon: IconCoins },
|
||||
ETB: { label: CURRENCY_CODE_LABELS.ETB.label, Icon: IconCoins },
|
||||
EUR: { label: CURRENCY_CODE_LABELS.EUR.label, Icon: IconCurrencyEuro },
|
||||
FJD: { label: CURRENCY_CODE_LABELS.FJD.label, Icon: IconCurrencyDollar },
|
||||
FKP: { label: CURRENCY_CODE_LABELS.FKP.label, Icon: IconCoins },
|
||||
GBP: { label: CURRENCY_CODE_LABELS.GBP.label, Icon: IconCurrencyPound },
|
||||
GEL: { label: CURRENCY_CODE_LABELS.GEL.label, Icon: IconCurrencyLari },
|
||||
GHS: { label: CURRENCY_CODE_LABELS.GHS.label, Icon: IconCoins },
|
||||
GIP: { label: CURRENCY_CODE_LABELS.GIP.label, Icon: IconCoins },
|
||||
GMD: { label: CURRENCY_CODE_LABELS.GMD.label, Icon: IconCoins },
|
||||
GNF: { label: CURRENCY_CODE_LABELS.GNF.label, Icon: IconCoins },
|
||||
GTQ: { label: CURRENCY_CODE_LABELS.GTQ.label, Icon: IconCurrencyQuetzal },
|
||||
GYD: {
|
||||
label: CURRENCY_CODE_LABELS.GYD.label,
|
||||
Icon: IconCurrencyDollarGuyanese,
|
||||
},
|
||||
HKD: { label: CURRENCY_CODE_LABELS.HKD.label, Icon: IconCurrencyRenminbi },
|
||||
HNL: { label: CURRENCY_CODE_LABELS.HNL.label, Icon: IconCurrencyLeu },
|
||||
HTG: { label: CURRENCY_CODE_LABELS.HTG.label, Icon: IconCoins },
|
||||
HUF: { label: CURRENCY_CODE_LABELS.HUF.label, Icon: IconCurrencyForint },
|
||||
IDR: { label: CURRENCY_CODE_LABELS.IDR.label, Icon: IconCoins },
|
||||
ILS: { label: CURRENCY_CODE_LABELS.ILS.label, Icon: IconCurrencyShekel },
|
||||
INR: { label: CURRENCY_CODE_LABELS.INR.label, Icon: IconCurrencyRupee },
|
||||
IQD: { label: CURRENCY_CODE_LABELS.IQD.label, Icon: IconCoins },
|
||||
IRR: { label: CURRENCY_CODE_LABELS.IRR.label, Icon: IconCurrencyIranianRial },
|
||||
ISK: { label: CURRENCY_CODE_LABELS.ISK.label, Icon: IconCoins },
|
||||
JMD: { label: CURRENCY_CODE_LABELS.JMD.label, Icon: IconCurrencyDollar },
|
||||
JOD: { label: CURRENCY_CODE_LABELS.JOD.label, Icon: IconCoins },
|
||||
JPY: { label: CURRENCY_CODE_LABELS.JPY.label, Icon: IconCurrencyYen },
|
||||
KES: { label: CURRENCY_CODE_LABELS.KES.label, Icon: IconCoins },
|
||||
KGS: { label: CURRENCY_CODE_LABELS.KGS.label, Icon: IconCurrencySom },
|
||||
KHR: { label: CURRENCY_CODE_LABELS.KHR.label, Icon: IconCoins },
|
||||
KMF: { label: CURRENCY_CODE_LABELS.KMF.label, Icon: IconCoins },
|
||||
KPW: { label: CURRENCY_CODE_LABELS.KPW.label, Icon: IconCurrencyWon },
|
||||
KRW: { label: CURRENCY_CODE_LABELS.KRW.label, Icon: IconCurrencyWon },
|
||||
KWD: { label: CURRENCY_CODE_LABELS.KWD.label, Icon: IconCurrencyDinar },
|
||||
KYD: { label: CURRENCY_CODE_LABELS.KYD.label, Icon: IconCurrencyDollar },
|
||||
KZT: { label: CURRENCY_CODE_LABELS.KZT.label, Icon: IconCurrencyTenge },
|
||||
LAK: { label: CURRENCY_CODE_LABELS.LAK.label, Icon: IconCurrencyKip },
|
||||
LBP: { label: CURRENCY_CODE_LABELS.LBP.label, Icon: IconCoins },
|
||||
LKR: { label: CURRENCY_CODE_LABELS.LKR.label, Icon: IconCoins },
|
||||
LRD: { label: CURRENCY_CODE_LABELS.LRD.label, Icon: IconCurrencyDollar },
|
||||
LSL: { label: CURRENCY_CODE_LABELS.LSL.label, Icon: IconCurrencyLeu },
|
||||
LYD: { label: CURRENCY_CODE_LABELS.LYD.label, Icon: IconCurrencyLyd },
|
||||
MAD: { label: CURRENCY_CODE_LABELS.MAD.label, Icon: IconCurrencyDirham },
|
||||
MDL: { label: CURRENCY_CODE_LABELS.MDL.label, Icon: IconCurrencyLeu },
|
||||
MGA: { label: CURRENCY_CODE_LABELS.MGA.label, Icon: IconCoins },
|
||||
MKD: { label: CURRENCY_CODE_LABELS.MKD.label, Icon: IconCoins },
|
||||
MMK: { label: CURRENCY_CODE_LABELS.MMK.label, Icon: IconCoins },
|
||||
MNT: { label: CURRENCY_CODE_LABELS.MNT.label, Icon: IconCurrencyTugrik },
|
||||
MOP: { label: CURRENCY_CODE_LABELS.MOP.label, Icon: IconCurrencyRenminbi },
|
||||
MRU: { label: CURRENCY_CODE_LABELS.MRU.label, Icon: IconCoins },
|
||||
MUR: { label: CURRENCY_CODE_LABELS.MUR.label, Icon: IconCoins },
|
||||
MVR: { label: CURRENCY_CODE_LABELS.MVR.label, Icon: IconCurrencyRufiyaa },
|
||||
MWK: { label: CURRENCY_CODE_LABELS.MWK.label, Icon: IconCoins },
|
||||
MXN: { label: CURRENCY_CODE_LABELS.MXN.label, Icon: IconCoins },
|
||||
MYR: { label: CURRENCY_CODE_LABELS.MYR.label, Icon: IconCoins },
|
||||
MZN: { label: CURRENCY_CODE_LABELS.MZN.label, Icon: IconCoins },
|
||||
NAD: { label: CURRENCY_CODE_LABELS.NAD.label, Icon: IconCurrencyDollar },
|
||||
NGN: { label: CURRENCY_CODE_LABELS.NGN.label, Icon: IconCurrencyNaira },
|
||||
NIO: { label: CURRENCY_CODE_LABELS.NIO.label, Icon: IconCoins },
|
||||
NOK: {
|
||||
label: CURRENCY_CODE_LABELS.NOK.label,
|
||||
Icon: IconCurrencyKroneSwedish,
|
||||
},
|
||||
NPR: {
|
||||
label: CURRENCY_CODE_LABELS.NPR.label,
|
||||
Icon: IconCurrencyRupeeNepalese,
|
||||
},
|
||||
NZD: { label: CURRENCY_CODE_LABELS.NZD.label, Icon: IconCurrencyDollar },
|
||||
OMR: { label: CURRENCY_CODE_LABELS.OMR.label, Icon: IconCoins },
|
||||
PAB: { label: CURRENCY_CODE_LABELS.PAB.label, Icon: IconCoins },
|
||||
PEN: { label: CURRENCY_CODE_LABELS.PEN.label, Icon: IconCoins },
|
||||
PGK: { label: CURRENCY_CODE_LABELS.PGK.label, Icon: IconCoins },
|
||||
PHP: { label: CURRENCY_CODE_LABELS.PHP.label, Icon: IconCurrencyPeso },
|
||||
PKR: { label: CURRENCY_CODE_LABELS.PKR.label, Icon: IconCoins },
|
||||
PLN: { label: CURRENCY_CODE_LABELS.PLN.label, Icon: IconCurrencyZloty },
|
||||
PYG: { label: CURRENCY_CODE_LABELS.PYG.label, Icon: IconCurrencyGuarani },
|
||||
QAR: { label: CURRENCY_CODE_LABELS.QAR.label, Icon: IconCurrencyRiyal },
|
||||
RON: { label: CURRENCY_CODE_LABELS.RON.label, Icon: IconCurrencyLeu },
|
||||
RSD: { label: CURRENCY_CODE_LABELS.RSD.label, Icon: IconCoins },
|
||||
RUB: { label: CURRENCY_CODE_LABELS.RUB.label, Icon: IconCurrencyRubel },
|
||||
RWF: { label: CURRENCY_CODE_LABELS.RWF.label, Icon: IconCoins },
|
||||
SAR: { label: CURRENCY_CODE_LABELS.SAR.label, Icon: IconCoins },
|
||||
SBD: { label: CURRENCY_CODE_LABELS.SBD.label, Icon: IconCurrencyDollar },
|
||||
SCR: { label: CURRENCY_CODE_LABELS.SCR.label, Icon: IconCoins },
|
||||
SDG: { label: CURRENCY_CODE_LABELS.SDG.label, Icon: IconCoins },
|
||||
SEK: {
|
||||
label: CURRENCY_CODE_LABELS.SEK.label,
|
||||
Icon: IconCurrencyKroneSwedish,
|
||||
},
|
||||
SGD: {
|
||||
label: CURRENCY_CODE_LABELS.SGD.label,
|
||||
Icon: IconCurrencyDollarSingapore,
|
||||
},
|
||||
SHP: { label: CURRENCY_CODE_LABELS.SHP.label, Icon: IconCoins },
|
||||
SLE: { label: CURRENCY_CODE_LABELS.SLE.label, Icon: IconCoins },
|
||||
SOS: { label: CURRENCY_CODE_LABELS.SOS.label, Icon: IconCoins },
|
||||
SRD: { label: CURRENCY_CODE_LABELS.SRD.label, Icon: IconCurrencyDollar },
|
||||
SSP: { label: CURRENCY_CODE_LABELS.SSP.label, Icon: IconCoins },
|
||||
STN: { label: CURRENCY_CODE_LABELS.STN.label, Icon: IconCoins },
|
||||
SVC: { label: CURRENCY_CODE_LABELS.SVC.label, Icon: IconCoins },
|
||||
SYP: { label: CURRENCY_CODE_LABELS.SYP.label, Icon: IconCoins },
|
||||
SZL: { label: CURRENCY_CODE_LABELS.SZL.label, Icon: IconCurrencyLeu },
|
||||
THB: { label: CURRENCY_CODE_LABELS.THB.label, Icon: IconCurrencyBaht },
|
||||
TJS: { label: CURRENCY_CODE_LABELS.TJS.label, Icon: IconCoins },
|
||||
TMT: { label: CURRENCY_CODE_LABELS.TMT.label, Icon: IconCurrencyManat },
|
||||
TND: { label: CURRENCY_CODE_LABELS.TND.label, Icon: IconCoins },
|
||||
TOP: { label: CURRENCY_CODE_LABELS.TOP.label, Icon: IconCurrencyPaanga },
|
||||
TRY: { label: CURRENCY_CODE_LABELS.TRY.label, Icon: IconCurrencyLira },
|
||||
TTD: { label: CURRENCY_CODE_LABELS.TTD.label, Icon: IconCurrencyDollar },
|
||||
TWD: { label: CURRENCY_CODE_LABELS.TWD.label, Icon: IconCurrencyRenminbi },
|
||||
TZS: { label: CURRENCY_CODE_LABELS.TZS.label, Icon: IconCoins },
|
||||
UAH: { label: CURRENCY_CODE_LABELS.UAH.label, Icon: IconCurrencyHryvnia },
|
||||
UGX: { label: CURRENCY_CODE_LABELS.UGX.label, Icon: IconCoins },
|
||||
USD: { label: CURRENCY_CODE_LABELS.USD.label, Icon: IconCurrencyDollar },
|
||||
UYU: { label: CURRENCY_CODE_LABELS.UYU.label, Icon: IconCoins },
|
||||
UZS: { label: CURRENCY_CODE_LABELS.UZS.label, Icon: IconCoins },
|
||||
VES: { label: CURRENCY_CODE_LABELS.VES.label, Icon: IconCoins },
|
||||
VND: { label: CURRENCY_CODE_LABELS.VND.label, Icon: IconCurrencyDong },
|
||||
VUV: { label: CURRENCY_CODE_LABELS.VUV.label, Icon: IconCoins },
|
||||
WST: { label: CURRENCY_CODE_LABELS.WST.label, Icon: IconCoins },
|
||||
XOF: { label: CURRENCY_CODE_LABELS.XOF.label, Icon: IconCoins },
|
||||
XCD: { label: CURRENCY_CODE_LABELS.XCD.label, Icon: IconCurrencyDollar },
|
||||
YER: { label: CURRENCY_CODE_LABELS.YER.label, Icon: IconCoins },
|
||||
ZAR: { label: CURRENCY_CODE_LABELS.ZAR.label, Icon: IconCoins },
|
||||
ZMW: { label: CURRENCY_CODE_LABELS.ZMW.label, Icon: IconCoins },
|
||||
ZWG: { label: CURRENCY_CODE_LABELS.ZWG.label, Icon: IconCoins },
|
||||
};
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetadataItemById';
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { type SettingsDataModelFieldCurrencyFormValues } from '@/settings/data-model/fields/forms/currency/components/SettingsDataModelFieldCurrencyForm';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
||||
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
|
||||
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
|
||||
import { getCurrencyFieldPreviewValue } from '../getCurrencyFieldPreviewValue';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
|
||||
const mockedCompanyObjectMetadataItem = generatedMockObjectMetadataItems.find(
|
||||
(item) => item.nameSingular === 'company',
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { type FieldCurrencyValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { currencyFieldDefaultValueSchema } from '@/object-record/record-field/ui/validation-schemas/currencyFieldDefaultValueSchema';
|
||||
import { getSettingsFieldTypeConfig } from '@/settings/data-model/utils/getSettingsFieldTypeConfig';
|
||||
import { type CurrencyCode } from 'twenty-shared/constants';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
|
||||
|
||||
|
||||
+1
-1
@@ -17,10 +17,10 @@ import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isNonEmptyArray } from 'twenty-shared/utils';
|
||||
import { H2Title, IconSearch } from 'twenty-ui/display';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { sortByProperty } from '~/utils/array/sortByProperty';
|
||||
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
||||
import { turnOrderByIntoSort } from '~/utils/turnOrderByIntoSort';
|
||||
|
||||
export const SETTINGS_ROLE_PERMISSION_OBJECT_LEVEL_FIELD_PERMISSION_TABLE_ID =
|
||||
|
||||
@@ -9,7 +9,7 @@ import { settingsPersistedRoleFamilyState } from '@/settings/roles/states/settin
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { isDefined, isNonEmptyArray } from 'twenty-shared/utils';
|
||||
import {
|
||||
useCreateOneRoleMutation,
|
||||
useUpdateOneRoleMutation,
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
import { type Role } from '~/generated/graphql';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { getDirtyFields } from '~/utils/getDirtyFields';
|
||||
import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
|
||||
|
||||
const ROLE_BASIC_KEYS: Array<keyof Role> = [
|
||||
'label',
|
||||
@@ -105,7 +104,7 @@ export const useSaveDraftRoleToDB = ({
|
||||
if (
|
||||
isNonEmptyArray(
|
||||
fieldPermissionsThatShouldntBeCreatedBecauseTheyAreUseless,
|
||||
)
|
||||
) === true
|
||||
) {
|
||||
for (const fieldPermissionToRemoveInDraftRole of fieldPermissionsThatShouldntBeCreatedBecauseTheyAreUseless) {
|
||||
removeFieldPermissionInDraftRole(
|
||||
@@ -183,7 +182,7 @@ export const useSaveDraftRoleToDB = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (isNonEmptyArray(fieldPermissionsToUpsert)) {
|
||||
if (isNonEmptyArray(fieldPermissionsToUpsert) === true) {
|
||||
await upsertFieldPermissions({
|
||||
variables: {
|
||||
upsertFieldPermissionsInput: {
|
||||
@@ -306,7 +305,7 @@ export const useSaveDraftRoleToDB = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (isNonEmptyArray(fieldPermissionsToUpsert)) {
|
||||
if (isNonEmptyArray(fieldPermissionsToUpsert) === true) {
|
||||
await upsertFieldPermissions({
|
||||
variables: {
|
||||
upsertFieldPermissionsInput: {
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { CurrencyCode } from '@/object-record/record-field/ui/types/CurrencyCode';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { CurrencyCode } from 'twenty-shared/constants';
|
||||
|
||||
import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
|
||||
import { type Currency } from '@/ui/input/components/internal/types/Currency';
|
||||
|
||||
+5
-3
@@ -4,11 +4,13 @@ import { currentRecordFilterGroupsComponentState } from '@/object-record/record-
|
||||
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
|
||||
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { turnAnyFieldFilterIntoRecordGqlFilter } from '@/object-record/record-filter/utils/turnAnyFieldFilterIntoRecordGqlFilter';
|
||||
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useGetViewGroupsFilters } from '@/views/hooks/useGetViewGroupsFilters';
|
||||
import { computeRecordGqlOperationFilter } from 'twenty-shared/utils';
|
||||
import {
|
||||
computeRecordGqlOperationFilter,
|
||||
turnAnyFieldFilterIntoRecordGqlFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
|
||||
export const useGetRecordIndexTotalCount = () => {
|
||||
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
|
||||
@@ -38,7 +40,7 @@ export const useGetRecordIndexTotalCount = () => {
|
||||
|
||||
const { recordGqlOperationFilter: anyFieldFilter } =
|
||||
turnAnyFieldFilterIntoRecordGqlFilter({
|
||||
objectMetadataItem,
|
||||
fields: objectMetadataItem.fields,
|
||||
filterValue: anyFieldFilterValue,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user