mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 01:12:56 +03:00
This commit is contained in:
parent
de09c29003
commit
0b3defd314
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import Select, { components } from 'react-select';
|
||||
import Select, { components, createFilter } from 'react-select';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/*
|
||||
@ -16,6 +16,14 @@ const CustomOption = props => {
|
||||
);
|
||||
};
|
||||
|
||||
const getPrefixFilter = () => {
|
||||
const prefixFilterOptions = {
|
||||
matchFrom: 'start',
|
||||
};
|
||||
|
||||
return createFilter(prefixFilterOptions);
|
||||
};
|
||||
|
||||
/*
|
||||
* Searchable select box component
|
||||
* 1) options: Accepts options
|
||||
@ -30,6 +38,7 @@ const SearchableSelectBox = ({
|
||||
value,
|
||||
bsClass,
|
||||
styleOverrides,
|
||||
filterOption,
|
||||
}) => {
|
||||
/* Select element style customization */
|
||||
|
||||
@ -45,6 +54,15 @@ const SearchableSelectBox = ({
|
||||
});
|
||||
}
|
||||
|
||||
let customFilter;
|
||||
switch (filterOption) {
|
||||
case 'prefix':
|
||||
customFilter = getPrefixFilter();
|
||||
break;
|
||||
default:
|
||||
customFilter = {};
|
||||
}
|
||||
|
||||
return (
|
||||
<Select
|
||||
isSearchable
|
||||
@ -55,6 +73,7 @@ const SearchableSelectBox = ({
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
styles={customStyles}
|
||||
filterOption={customFilter}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -65,6 +84,7 @@ SearchableSelectBox.propTypes = {
|
||||
options: PropTypes.array.isRequired,
|
||||
bsClass: PropTypes.string,
|
||||
customStyle: PropTypes.object,
|
||||
filterOption: PropTypes.object,
|
||||
};
|
||||
|
||||
export default SearchableSelectBox;
|
||||
|
@ -91,6 +91,7 @@ const TableColumn = props => {
|
||||
value={column.type && columnTypeValueMap[column.type]}
|
||||
bsClass={`col-type-${i} add_table_column_selector`}
|
||||
styleOverrides={customSelectBoxStyles}
|
||||
filterOption={'prefix'}
|
||||
/>
|
||||
</span>
|
||||
<input
|
||||
|
@ -34,23 +34,27 @@ const getAllDataTypeMap = allDataTypes => {
|
||||
return dTIndex;
|
||||
};
|
||||
|
||||
const getDataTypeInfo = (row, categoryInfo, colId) => {
|
||||
const getDataTypeInfo = (row, categoryInfo, colId, cached = {}) => {
|
||||
const columnTypeValueMap = {};
|
||||
|
||||
const { typInfo, typDisplayName, typDescription } = splitDbRow(row);
|
||||
|
||||
// Create option object for every valid type
|
||||
const currTypeObj = typInfo.map((t, i) => {
|
||||
const optObj = {
|
||||
value: t,
|
||||
label: typDisplayName[i],
|
||||
key: `${categoryInfo}_${i}`,
|
||||
colIdentifier: colId,
|
||||
description: typDescription[i],
|
||||
};
|
||||
// Memoizing option for later use
|
||||
columnTypeValueMap[t] = optObj;
|
||||
return optObj;
|
||||
const currTypeObj = [];
|
||||
typInfo.forEach((t, i) => {
|
||||
/* Don't add types which are part of frequently used types */
|
||||
if (!(t in cached)) {
|
||||
const optObj = {
|
||||
value: t,
|
||||
label: typDisplayName[i],
|
||||
key: `${categoryInfo}_${i}`,
|
||||
colIdentifier: colId,
|
||||
description: typDescription[i],
|
||||
};
|
||||
// Memoizing option for later use
|
||||
columnTypeValueMap[t] = optObj;
|
||||
currTypeObj.push(optObj);
|
||||
}
|
||||
});
|
||||
return { typInfo: currTypeObj, typValueMap: columnTypeValueMap };
|
||||
};
|
||||
@ -99,7 +103,8 @@ const getDataOptions = (commonDataTypes, restTypes, identifier) => {
|
||||
const { typInfo, typValueMap } = getDataTypeInfo(
|
||||
categoryRow[0],
|
||||
pgCategoryCode[category],
|
||||
identifier
|
||||
identifier,
|
||||
columnTypeValueMap
|
||||
);
|
||||
columnTypeValueMap = { ...columnTypeValueMap, ...typValueMap };
|
||||
columnDataTypes.push({
|
||||
|
@ -697,7 +697,7 @@ const dataReducer = (state = defaultState, action) => {
|
||||
return {
|
||||
...state,
|
||||
columnDataTypes: action.data,
|
||||
columnDataTypeFetchErr: 'Error fetching data',
|
||||
columnDataTypeFetchErr: defaultState.columnDataTypeFetchErr,
|
||||
};
|
||||
|
||||
case FETCH_COLUMN_TYPE_LIST_FAIL:
|
||||
@ -710,7 +710,7 @@ const dataReducer = (state = defaultState, action) => {
|
||||
return {
|
||||
...state,
|
||||
columnDataTypes: [...defaultState.columnDataTypes],
|
||||
columnDataTypeFetchErr: defaultState.columnDataTypes,
|
||||
columnDataTypeFetchErr: defaultState.columnDataTypeFetchErr,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
|
@ -152,6 +152,7 @@ const ColumnCreator = ({ dispatch, tableName, dataTypes: restTypes = [] }) => {
|
||||
value={colType.value && columnTypeValueMap[colType.value]}
|
||||
bsClass={`col-type-${0} modify_select`}
|
||||
styleOverrides={customSelectBoxStyles}
|
||||
filterOption={'prefix'}
|
||||
/>
|
||||
</span>
|
||||
<input
|
||||
|
@ -2,20 +2,6 @@ import React, { useEffect } from 'react';
|
||||
|
||||
import SearchableSelectBox from '../../../Common/SearchableSelect/SearchableSelect';
|
||||
|
||||
/*
|
||||
import {
|
||||
INTEGER,
|
||||
SERIAL,
|
||||
BIGINT,
|
||||
BIGSERIAL,
|
||||
UUID,
|
||||
JSONDTYPE,
|
||||
JSONB,
|
||||
TIMESTAMP,
|
||||
TIME,
|
||||
} from '../../../../constants';
|
||||
*/
|
||||
|
||||
import { getValidAlterOptions } from './utils';
|
||||
|
||||
const ColumnEditor = ({
|
||||
@ -113,6 +99,7 @@ const ColumnEditor = ({
|
||||
value={columnTypePG && alterOptionsValueMap[columnTypePG]}
|
||||
bsClass={`col-type-${0} modify_select`}
|
||||
styleOverrides={customSelectBoxStyles}
|
||||
filterOption={'prefix'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,10 +34,10 @@ const getValidAlterOptions = (alterTypeOptions, colName) => {
|
||||
const fetchColumnCastsQuery = `
|
||||
SELECT ts.typname AS "Source Type",
|
||||
pg_catalog.format_type(castsource, NULL) AS "Source Info",
|
||||
pg_catalog.obj_description(castsource, 'pg_type') as "Source Descriptions",
|
||||
coalesce(pg_catalog.obj_description(castsource, 'pg_type'), '') as "Source Descriptions",
|
||||
string_agg(tt.typname, ',') AS "Target Type",
|
||||
string_agg(pg_catalog.format_type(casttarget, NULL), ',') AS "Target Info",
|
||||
string_agg(pg_catalog.obj_description(casttarget, 'pg_type'), ':') as "Target Descriptions",
|
||||
string_agg(coalesce(pg_catalog.obj_description(casttarget, 'pg_type'), ''), ':') as "Target Descriptions",
|
||||
string_agg(CASE WHEN castfunc = 0 THEN '(binary coercible)'
|
||||
ELSE p.proname
|
||||
END, ',') as "Function"
|
||||
@ -59,15 +59,26 @@ ORDER BY 1, 2;
|
||||
|
||||
`;
|
||||
|
||||
const getCreatePkSql = ({ schemaName, tableName, selectedPkColumns, constraintName }) => {
|
||||
const getCreatePkSql = ({
|
||||
schemaName,
|
||||
tableName,
|
||||
selectedPkColumns,
|
||||
constraintName,
|
||||
}) => {
|
||||
return `alter table "${schemaName}"."${tableName}"
|
||||
add constraint "${constraintName}" primary key ( ${selectedPkColumns
|
||||
.map(pkc => `"${pkc}"`)
|
||||
.join(', ')} );`;
|
||||
.map(pkc => `"${pkc}"`)
|
||||
.join(', ')} );`;
|
||||
};
|
||||
|
||||
const getDropPkSql = ({ schemaName, tableName, constraintName }) => {
|
||||
return `alter table "${schemaName}"."${tableName}" drop constraint "${constraintName}";`;
|
||||
};
|
||||
|
||||
export { convertArrayToJson, getValidAlterOptions, fetchColumnCastsQuery, getCreatePkSql, getDropPkSql };
|
||||
export {
|
||||
convertArrayToJson,
|
||||
getValidAlterOptions,
|
||||
fetchColumnCastsQuery,
|
||||
getCreatePkSql,
|
||||
getDropPkSql,
|
||||
};
|
||||
|
@ -569,16 +569,20 @@ export const commonDataTypes = [
|
||||
},
|
||||
];
|
||||
|
||||
/*
|
||||
* Fetch non-composite types, primitive types like text, varchar etc,
|
||||
* Filter types whose typename is unknown and type category is not 'Pseudo' and it is valid and available to be used
|
||||
* */
|
||||
export const fetchColumnTypesQuery = `
|
||||
SELECT
|
||||
string_agg(t.typname, ',') as "Type Name",
|
||||
string_agg(pg_catalog.format_type(t.oid, NULL), ',') as "Display Name",
|
||||
string_agg(pg_catalog.obj_description(t.oid, 'pg_type'), ':') as "Descriptions",
|
||||
string_agg(coalesce(pg_catalog.obj_description(t.oid, 'pg_type'), ''), ':') as "Descriptions",
|
||||
t.typcategory
|
||||
FROM pg_catalog.pg_type t
|
||||
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
||||
WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))
|
||||
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
|
||||
WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))
|
||||
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
|
||||
AND pg_catalog.pg_type_is_visible(t.oid)
|
||||
AND t.typname != 'unknown'
|
||||
AND t.typcategory != 'P'
|
||||
|
@ -225,7 +225,7 @@ const ViewRows = ({
|
||||
};
|
||||
|
||||
const successIcon = (
|
||||
<i className={styles.invocationSuccess + 'fa fa-check'} />
|
||||
<i className={styles.invocationSuccess + ' fa fa-check'} />
|
||||
);
|
||||
|
||||
const failureIcon = (
|
||||
@ -437,26 +437,26 @@ const ViewRows = ({
|
||||
>
|
||||
{finalResponse.status_code
|
||||
? [
|
||||
'Status Code: ',
|
||||
verifySuccessStatus(
|
||||
finalResponse.status_code
|
||||
)
|
||||
? successIcon
|
||||
: failureIcon,
|
||||
finalResponse.status_code,
|
||||
' ',
|
||||
<OverlayTrigger
|
||||
placement="top"
|
||||
overlay={
|
||||
tooltip.statusCodeDescription
|
||||
}
|
||||
>
|
||||
<i
|
||||
className="fa fa-question-circle"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</OverlayTrigger>,
|
||||
]
|
||||
'Status Code: ',
|
||||
verifySuccessStatus(
|
||||
finalResponse.status_code
|
||||
)
|
||||
? successIcon
|
||||
: failureIcon,
|
||||
finalResponse.status_code,
|
||||
' ',
|
||||
<OverlayTrigger
|
||||
placement="top"
|
||||
overlay={
|
||||
tooltip.statusCodeDescription
|
||||
}
|
||||
>
|
||||
<i
|
||||
className="fa fa-question-circle"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</OverlayTrigger>,
|
||||
]
|
||||
: null}
|
||||
</div>
|
||||
<AceEditor
|
||||
|
Loading…
Reference in New Issue
Block a user