Skip to content

Commit

Permalink
Fix filter transform with logic operators (twentyhq#5269)
Browse files Browse the repository at this point in the history
Various fixes

- Remote objects are read-only for now, we already hide and block most
of the write actions but the button that allows you to add a new record
in an empty collection was still visible.
- CreatedAt is not mandatory on remote objects (at least for now) so it
was breaking the show page, it now checks if createdAt exists and is not
null before trying to display the human readable format `Added x days
ago`
- The filters are overwritten in query-runner-args.factory.ts to handle
NUMBER field type, this was only working with filters like
```
      {
        "id": {
          "in": [
            1
          ]
        }
```
but not with more depth such as 
```
    "and": [
      {},
      {
        "id": {
          "in": [
            1
          ]
        }
      }
    ]
 ```
- Fixes CREATE FOREIGN TABLE raw query which was missing ",".
  • Loading branch information
Weiko committed May 3, 2024
1 parent 30ffe01 commit 5042186
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export const RecordTableWithWrappers = ({

const objectLabel = foundObjectMetadataItem?.labelSingular;

const isRemote = foundObjectMetadataItem?.isRemote ?? false;

return (
<EntityDeleteContext.Provider value={deleteOneRecord}>
<ScrollWrapper>
Expand Down Expand Up @@ -113,25 +115,27 @@ export const RecordTableWithWrappers = ({
recordTableId={recordTableId}
tableBodyRef={tableBodyRef}
/>
{!isRecordTableInitialLoading && numberOfTableRows === 0 && (
<AnimatedPlaceholderEmptyContainer>
<AnimatedPlaceholder type="noRecord" />
<AnimatedPlaceholderEmptyTextContainer>
<AnimatedPlaceholderEmptyTitle>
Add your first {objectLabel}
</AnimatedPlaceholderEmptyTitle>
<AnimatedPlaceholderEmptySubTitle>
Use our API or add your first {objectLabel} manually
</AnimatedPlaceholderEmptySubTitle>
</AnimatedPlaceholderEmptyTextContainer>
<Button
Icon={IconPlus}
title={`Add a ${objectLabel}`}
variant={'secondary'}
onClick={createRecord}
/>
</AnimatedPlaceholderEmptyContainer>
)}
{!isRecordTableInitialLoading &&
numberOfTableRows === 0 &&
!isRemote && (
<AnimatedPlaceholderEmptyContainer>
<AnimatedPlaceholder type="noRecord" />
<AnimatedPlaceholderEmptyTextContainer>
<AnimatedPlaceholderEmptyTitle>
Add your first {objectLabel}
</AnimatedPlaceholderEmptyTitle>
<AnimatedPlaceholderEmptySubTitle>
Use our API or add your first {objectLabel} manually
</AnimatedPlaceholderEmptySubTitle>
</AnimatedPlaceholderEmptyTextContainer>
<Button
Icon={IconPlus}
title={`Add a ${objectLabel}`}
variant={'secondary'}
onClick={createRecord}
/>
</AnimatedPlaceholderEmptyContainer>
)}
</StyledTableContainer>
</StyledTableWithHeader>
</RecordUpdateContext.Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ export const ShowPageSummaryCard = ({
</StyledAvatarWrapper>
<StyledInfoContainer>
<StyledTitle>{title}</StyledTitle>
<StyledDate id={dateElementId}>Added {beautifiedCreatedAt}</StyledDate>
{beautifiedCreatedAt && (
<StyledDate id={dateElementId}>
Added {beautifiedCreatedAt}
</StyledDate>
)}
<StyledTooltip
anchorSelect={`#${dateElementId}`}
content={exactCreatedAt}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,30 +131,46 @@ export class QueryRunnerArgsFactory {
return;
}

const createArgPromiseByArgKey = Object.entries(filter).map(
([key, value]) => {
const fieldMetadata = fieldMetadataMap.get(key);

if (!fieldMetadata) {
return [key, value];
const overrideFilter = (filterObject: RecordFilter) => {
return Object.entries(filterObject).reduce((acc, [key, value]) => {
if (key === 'and' || key === 'or') {
acc[key] = value.map((nestedFilter: RecordFilter) =>
overrideFilter(nestedFilter),
);
} else if (key === 'not') {
acc[key] = overrideFilter(value);
} else {
acc[key] = this.transformValueByType(key, value, fieldMetadataMap);
}

const createFilterByKey = Object.entries(value).map(
([filterKey, filterValue]) => {
switch (fieldMetadata.type) {
case FieldMetadataType.NUMBER:
return [filterKey, Number(filterValue)];
default:
return [filterKey, filterValue];
}
},
);
return acc;
}, {});
};

return [key, Object.fromEntries(createFilterByKey)];
},
);
return overrideFilter(filter);
}

return Object.fromEntries(createArgPromiseByArgKey);
private transformValueByType(
key: string,
value: any,
fieldMetadataMap: Map<string, FieldMetadataInterface>,
) {
const fieldMetadata = fieldMetadataMap.get(key);

if (!fieldMetadata) {
return value;
}
switch (fieldMetadata.type) {
case 'NUMBER':
return Object.fromEntries(
Object.entries(value).map(([filterKey, filterValue]) => [
filterKey,
Number(filterValue),
]),
);
default:
return value;
}
}

private async overrideValueByFieldMetadata(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,9 @@ export class WorkspaceMigrationRunnerService {
)
.join(', ');

let serverOptions = '';

Object.entries(foreignTable.referencedTable).forEach(([key, value]) => {
serverOptions += ` ${key} '${value}'`;
});
const serverOptions = Object.entries(foreignTable.referencedTable)
.map(([key, value]) => `${key} '${value}'`)
.join(', ');

await queryRunner.query(
`CREATE FOREIGN TABLE ${schemaName}."${name}" (${foreignTableColumns}) SERVER "${foreignTable.foreignDataWrapperId}" OPTIONS (${serverOptions})`,
Expand Down

0 comments on commit 5042186

Please sign in to comment.