mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 08:02:15 +03:00
console: support computed fields in remote schema join
https://github.com/hasura/graphql-engine-mono/pull/2188 GitOrigin-RevId: 2d6fae62dbdcbdc7515a7b4982299dc9610a2230
This commit is contained in:
parent
7a1446cec2
commit
3f4dda2520
@ -10,9 +10,10 @@
|
||||
- server: fix broken `untrack_function` for non-default source
|
||||
- server: Adding support for TLS allowlist by domain and service id (port)
|
||||
- server: add support for `graphql-ws` clients
|
||||
- console: fix error due too rendering inconsistent object's message
|
||||
- console: fix error due to rendering inconsistent object's message
|
||||
- console: support insecure TLS allowlist
|
||||
- cli: fix delay starting console using `hasura console` (#7255)
|
||||
- console: support computed fields in remote schema join
|
||||
- cli: fix delay starting console using `hasura console` (#7255
|
||||
|
||||
## v2.0.7
|
||||
|
||||
|
@ -310,6 +310,7 @@ const Relationships = ({
|
||||
manualRelAdd,
|
||||
currentSchema,
|
||||
migrationMode,
|
||||
allFunctions,
|
||||
schemaList,
|
||||
readOnlyMode,
|
||||
currentSource,
|
||||
@ -494,6 +495,7 @@ const Relationships = ({
|
||||
relationships={existingRemoteRelationships}
|
||||
reduxDispatch={dispatch}
|
||||
table={tableSchema}
|
||||
allFunctions={allFunctions}
|
||||
remoteSchemas={remoteSchemas}
|
||||
/>
|
||||
</div>
|
||||
@ -518,24 +520,32 @@ Relationships.propTypes = {
|
||||
ongoingRequest: PropTypes.bool.isRequired,
|
||||
lastError: PropTypes.object,
|
||||
lastFormError: PropTypes.object,
|
||||
allFunctions: PropTypes.array.isRequired,
|
||||
lastSuccess: PropTypes.bool,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
remoteSchemas: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
tableName: ownProps.params.table,
|
||||
allSchemas: state.tables.allSchemas,
|
||||
currentSchema: state.tables.currentSchema,
|
||||
migrationMode: state.main.migrationMode,
|
||||
readOnlyMode: state.main.readOnlyMode,
|
||||
serverVersion: state.main.serverVersion,
|
||||
schemaList: state.tables.schemaList,
|
||||
remoteSchemas: getRemoteSchemasSelector(state).map(schema => schema.name),
|
||||
adminHeaders: state.tables.dataHeaders,
|
||||
currentSource: state.tables.currentDataSource,
|
||||
...state.tables.modify,
|
||||
});
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const {
|
||||
nonTrackablePostgresFunctions: nonTrackableFns,
|
||||
postgresFunctions: trackedFns,
|
||||
} = state.tables;
|
||||
return {
|
||||
tableName: ownProps.params.table,
|
||||
allSchemas: state.tables.allSchemas,
|
||||
currentSchema: state.tables.currentSchema,
|
||||
migrationMode: state.main.migrationMode,
|
||||
readOnlyMode: state.main.readOnlyMode,
|
||||
serverVersion: state.main.serverVersion,
|
||||
schemaList: state.tables.schemaList,
|
||||
allFunctions: nonTrackableFns?.concat(trackedFns ?? []) ?? [],
|
||||
remoteSchemas: getRemoteSchemasSelector(state).map(schema => schema.name),
|
||||
adminHeaders: state.tables.dataHeaders,
|
||||
currentSource: state.tables.currentDataSource,
|
||||
...state.tables.modify,
|
||||
};
|
||||
};
|
||||
|
||||
const relationshipsConnector = connect =>
|
||||
connect(mapStateToProps)(Relationships);
|
||||
|
@ -33,6 +33,7 @@ class RelationshipsView extends Component {
|
||||
lastFormError,
|
||||
lastSuccess,
|
||||
dispatch,
|
||||
allFunctions,
|
||||
manualRelAdd,
|
||||
currentSchema,
|
||||
migrationMode,
|
||||
@ -137,6 +138,7 @@ class RelationshipsView extends Component {
|
||||
relationships={tableSchema.remote_relationships}
|
||||
reduxDispatch={dispatch}
|
||||
table={tableSchema}
|
||||
allFunctions={allFunctions}
|
||||
remoteSchemas={remoteSchemas}
|
||||
/>
|
||||
</div>
|
||||
@ -200,22 +202,30 @@ RelationshipsView.propTypes = {
|
||||
lastSuccess: PropTypes.bool,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
serverVersion: PropTypes.string,
|
||||
allFunctions: PropTypes.array.isRequired,
|
||||
remoteSchemas: PropTypes.array.isRequired,
|
||||
featuresCompatibility: PropTypes.object,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
tableName: ownProps.params.table,
|
||||
allSchemas: state.tables.allSchemas,
|
||||
currentSchema: state.tables.currentSchema,
|
||||
migrationMode: state.main.migrationMode,
|
||||
readOnlyMode: state.main.readOnlyMode,
|
||||
serverVersion: state.main.serverVersion,
|
||||
schemaList: state.tables.schemaList,
|
||||
remoteSchemas: getRemoteSchemasSelector(state).map(schema => schema.name),
|
||||
currentSource: state.tables.currentDataSource,
|
||||
...state.tables.modify,
|
||||
});
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const {
|
||||
nonTrackablePostgresFunctions: nonTrackableFns,
|
||||
postgresFunctions: trackedFns,
|
||||
} = state.tables;
|
||||
return {
|
||||
tableName: ownProps.params.table,
|
||||
allSchemas: state.tables.allSchemas,
|
||||
currentSchema: state.tables.currentSchema,
|
||||
migrationMode: state.main.migrationMode,
|
||||
readOnlyMode: state.main.readOnlyMode,
|
||||
serverVersion: state.main.serverVersion,
|
||||
allFunctions: nonTrackableFns?.concat(trackedFns ?? []) ?? [],
|
||||
schemaList: state.tables.schemaList,
|
||||
remoteSchemas: getRemoteSchemasSelector(state).map(schema => schema.name),
|
||||
currentSource: state.tables.currentDataSource,
|
||||
...state.tables.modify,
|
||||
};
|
||||
};
|
||||
|
||||
const relationshipsViewConnector = connect =>
|
||||
connect(mapStateToProps)(RelationshipsView);
|
||||
|
@ -6,11 +6,13 @@ import ToolTip from '../../../../Common/Tooltip/Tooltip';
|
||||
import KnowMoreLink from '../../../../Common/KnowMoreLink/KnowMoreLink';
|
||||
import { Dispatch } from '../../../../../types';
|
||||
import { Table } from '../../../../../dataSources/types';
|
||||
import { PGFunction } from '../../../../../dataSources/services/postgresql/types';
|
||||
|
||||
type Props = {
|
||||
relationships: RemoteRelationshipServer[];
|
||||
reduxDispatch: Dispatch;
|
||||
table: Table;
|
||||
allFunctions: PGFunction[];
|
||||
remoteSchemas: string[];
|
||||
};
|
||||
|
||||
@ -18,6 +20,7 @@ const RemoteRelationships: React.FC<Props> = ({
|
||||
relationships,
|
||||
reduxDispatch,
|
||||
table,
|
||||
allFunctions,
|
||||
remoteSchemas,
|
||||
}) => {
|
||||
return (
|
||||
@ -32,6 +35,7 @@ const RemoteRelationships: React.FC<Props> = ({
|
||||
<RemoteRelationshipList
|
||||
relationships={relationships}
|
||||
table={table}
|
||||
allFunctions={allFunctions}
|
||||
remoteSchemas={remoteSchemas}
|
||||
reduxDispatch={reduxDispatch}
|
||||
/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import "../../../../Common/Common.scss";
|
||||
@import '../../../../Common/Common.scss';
|
||||
|
||||
.schemaExplorerContainer {
|
||||
background-color: #f7f7f7;
|
||||
@ -7,7 +7,7 @@
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.height200Px {
|
||||
.height200Px {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
@ -29,16 +29,15 @@
|
||||
}
|
||||
|
||||
.scalarColumnSelect {
|
||||
margin-left: 5px;
|
||||
margin-left: 5px;
|
||||
border-radius: 4px;
|
||||
background-color: white;
|
||||
background-color: white;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.argValue {
|
||||
background-color: white;
|
||||
height: 30px;
|
||||
padding: 5px;
|
||||
padding-right: 2.5rem;
|
||||
color: #555555;
|
||||
font-style: normal;
|
||||
}
|
||||
@ -54,6 +53,6 @@
|
||||
}
|
||||
|
||||
.argElement {
|
||||
color: #8B2BB9;
|
||||
color: #8b2bb9;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,14 @@ import React from 'react';
|
||||
import { TreeArgElement, ArgValueKind } from '../utils';
|
||||
import styles from '../SchemaExplorer.scss';
|
||||
import ArgValueElement from './ArgValue';
|
||||
import { HasuraColumn } from './Explorer';
|
||||
|
||||
type Props = {
|
||||
arg: TreeArgElement;
|
||||
handleToggle: (a: TreeArgElement) => void;
|
||||
handleArgValueKindChange: (a: TreeArgElement, type: ArgValueKind) => void;
|
||||
handleArgValueChange: (a: TreeArgElement, value: string) => void;
|
||||
columns: string[];
|
||||
columns: HasuraColumn;
|
||||
};
|
||||
|
||||
const ArgElement: React.FC<Props> = ({
|
||||
|
@ -1,12 +1,13 @@
|
||||
import React from 'react';
|
||||
import { ArgValue } from '../utils';
|
||||
import styles from '../SchemaExplorer.scss';
|
||||
import { HasuraColumn } from './Explorer';
|
||||
|
||||
type Props = {
|
||||
value: ArgValue;
|
||||
handleArgValueKindChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||
handleArgValueChange: (e: React.BaseSyntheticEvent) => void;
|
||||
columns: string[];
|
||||
columns: HasuraColumn;
|
||||
};
|
||||
|
||||
const ArgValueElement: React.FC<Props> = ({
|
||||
@ -41,13 +42,26 @@ const ArgValueElement: React.FC<Props> = ({
|
||||
-- column-name --
|
||||
</option>
|
||||
)}
|
||||
{columns.map(o => {
|
||||
return (
|
||||
<option key={o} value={o}>
|
||||
{o}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
<optgroup label="Columns">
|
||||
{columns.columns.map(o => {
|
||||
return (
|
||||
<option key={o} value={o}>
|
||||
{o}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</optgroup>
|
||||
{columns.computedFields.length ? (
|
||||
<optgroup label="Computed Fields">
|
||||
{columns.computedFields.map(o => {
|
||||
return (
|
||||
<option key={o} value={o}>
|
||||
{o}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</optgroup>
|
||||
) : null}
|
||||
</select>
|
||||
) : (
|
||||
<input
|
||||
|
@ -22,10 +22,15 @@ type Props = {
|
||||
handleArgValueKindChange: (a: TreeArgElement, type: ArgValueKind) => void;
|
||||
handleArgValueChange: (a: TreeArgElement, value: string) => void;
|
||||
remoteSchemaName: string;
|
||||
columns: string[];
|
||||
columns: HasuraColumn;
|
||||
reduxDispatch: ThunkAction<void, ReduxState, unknown, ReduxAction>;
|
||||
};
|
||||
|
||||
export type HasuraColumn = {
|
||||
columns: string[];
|
||||
computedFields: string[];
|
||||
};
|
||||
|
||||
const Explorer: React.FC<Props> = ({
|
||||
relationship,
|
||||
toggleArg,
|
||||
@ -85,7 +90,13 @@ const Explorer: React.FC<Props> = ({
|
||||
}
|
||||
case 'field': {
|
||||
const el: TreeFieldElement = element;
|
||||
return <FieldElement field={el} handleToggle={toggleField} />;
|
||||
return (
|
||||
<FieldElement
|
||||
field={el}
|
||||
handleToggle={toggleField}
|
||||
key={`field-element-${el.name}-${el.depth}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
|
@ -25,6 +25,11 @@ import {
|
||||
import Explorer from './Explorer';
|
||||
import { ReduxState, ReduxAction } from '../../../../../../types';
|
||||
import { Table } from '../../../../../../dataSources/types';
|
||||
import { PGFunction } from '../../../../../../dataSources/services/postgresql/types';
|
||||
import {
|
||||
getComputedFieldFunction,
|
||||
getGroupedTableComputedFields,
|
||||
} from '../../../../../../dataSources/services/postgresql';
|
||||
|
||||
type Props = {
|
||||
table: Table;
|
||||
@ -32,6 +37,7 @@ type Props = {
|
||||
isLast: boolean;
|
||||
state: RemoteRelationship;
|
||||
dispatch: React.Dispatch<RemoteRelAction>;
|
||||
allFunctions: PGFunction[];
|
||||
reduxDispatch: ThunkAction<void, ReduxState, unknown, ReduxAction>;
|
||||
};
|
||||
|
||||
@ -40,6 +46,7 @@ const RemoteRelEditor: React.FC<Props> = ({
|
||||
isLast,
|
||||
remoteSchemas,
|
||||
state,
|
||||
allFunctions,
|
||||
dispatch,
|
||||
reduxDispatch,
|
||||
}) => {
|
||||
@ -77,6 +84,18 @@ const RemoteRelEditor: React.FC<Props> = ({
|
||||
}
|
||||
);
|
||||
|
||||
const computedFields = getGroupedTableComputedFields(table, allFunctions);
|
||||
const scalarComputedFields = computedFields.scalar.filter(sc => {
|
||||
const cFn = getComputedFieldFunction(sc, allFunctions)?.input_arg_types;
|
||||
// Only the computed fields that do not require extra arguments other than the table row
|
||||
// are currenlty supported by the server https://github.com/hasura/graphql-engine/issues/7336
|
||||
return cFn?.length === 1 && cFn[0].name === table.table_name;
|
||||
});
|
||||
|
||||
const computedFieldsNames = scalarComputedFields.map(
|
||||
f => f.computed_field_name
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div>
|
||||
@ -152,7 +171,10 @@ const RemoteRelEditor: React.FC<Props> = ({
|
||||
handleArgValueKindChange={handleArgValueKindChange}
|
||||
handleArgValueChange={handleArgValueChange}
|
||||
remoteSchemaName={state.remoteSchema}
|
||||
columns={tableColumns}
|
||||
columns={{
|
||||
columns: tableColumns,
|
||||
computedFields: computedFieldsNames,
|
||||
}}
|
||||
reduxDispatch={reduxDispatch}
|
||||
/>
|
||||
</div>
|
||||
|
@ -7,6 +7,7 @@ import { useRemoteRelationship } from '../state';
|
||||
import { saveRemoteRelationship, dropRemoteRelationship } from '../../Actions';
|
||||
import { Dispatch } from '../../../../../../types';
|
||||
import { Table } from '../../../../../../dataSources/types';
|
||||
import { PGFunction } from '../../../../../../dataSources/services/postgresql/types';
|
||||
|
||||
type Props = {
|
||||
relationship?: RemoteRelationshipServer;
|
||||
@ -14,6 +15,7 @@ type Props = {
|
||||
isLast: boolean;
|
||||
remoteSchemas: string[];
|
||||
reduxDispatch: Dispatch;
|
||||
allFunctions: PGFunction[];
|
||||
};
|
||||
|
||||
const EditorWrapper: React.FC<Props> = ({
|
||||
@ -22,6 +24,7 @@ const EditorWrapper: React.FC<Props> = ({
|
||||
isLast,
|
||||
remoteSchemas,
|
||||
reduxDispatch,
|
||||
allFunctions,
|
||||
}) => {
|
||||
const { state, dispatch, reset } = useRemoteRelationship(table, relationship);
|
||||
|
||||
@ -31,6 +34,7 @@ const EditorWrapper: React.FC<Props> = ({
|
||||
remoteSchemas={remoteSchemas}
|
||||
isLast={isLast}
|
||||
state={state}
|
||||
allFunctions={allFunctions}
|
||||
dispatch={dispatch}
|
||||
reduxDispatch={reduxDispatch}
|
||||
/>
|
||||
|
@ -3,11 +3,13 @@ import { RemoteRelationshipServer } from '../utils';
|
||||
import RemoteRelationshipEditor from './RemoteRelEditorWrapper';
|
||||
import { Dispatch } from '../../../../../../types';
|
||||
import { Table } from '../../../../../../dataSources/types';
|
||||
import { PGFunction } from '../../../../../../dataSources/services/postgresql/types';
|
||||
|
||||
type Props = {
|
||||
relationships: RemoteRelationshipServer[];
|
||||
table: Table;
|
||||
remoteSchemas: string[];
|
||||
allFunctions: PGFunction[];
|
||||
reduxDispatch: Dispatch;
|
||||
};
|
||||
|
||||
@ -15,6 +17,7 @@ const RemoteRelationshipList: React.FC<Props> = ({
|
||||
relationships,
|
||||
table,
|
||||
remoteSchemas,
|
||||
allFunctions,
|
||||
reduxDispatch,
|
||||
}) => {
|
||||
return (
|
||||
@ -26,6 +29,7 @@ const RemoteRelationshipList: React.FC<Props> = ({
|
||||
table={table}
|
||||
remoteSchemas={remoteSchemas}
|
||||
reduxDispatch={reduxDispatch}
|
||||
allFunctions={allFunctions}
|
||||
isLast={false}
|
||||
/>
|
||||
))}
|
||||
@ -33,6 +37,7 @@ const RemoteRelationshipList: React.FC<Props> = ({
|
||||
key="add-remote-rel"
|
||||
table={table}
|
||||
remoteSchemas={remoteSchemas}
|
||||
allFunctions={allFunctions}
|
||||
reduxDispatch={reduxDispatch}
|
||||
isLast
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user