这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@

Added a component that allows adding check constraints while creating a new table in the same way as it can be done on the `Modify` view.

### Select dropdown for Enum columns (console)

If a table has a field referencing an Enum table via a foreign key, then there will be a select dropdown with all possible enum values on `Insert Row` and `Edit Row` views on the Console.

(close #3748) (#3810)

### Other changes

- console: disable editing action relationships
Expand Down
47 changes: 47 additions & 0 deletions console/src/components/Common/utils/pgUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,53 @@ export function getRelationshipRefTable(table, relationship) {
return _refTable;
}

/**
* @param {string} currentSchema
* @param {string} currentTable
* @param {Array<{[key: string]: any}>} allSchemas
*
* @returns {Array<{
* columnName: string,
* enumTableName: string,
* enumColumnName: string,
* }>}
*/
export const getEnumColumnMappings = (allSchemas, tableName, tableSchema) => {
const currentTable = findTable(
allSchemas,
generateTableDef(tableName, tableSchema)
);

const relationsMap = [];
if (!currentTable.foreign_key_constraints.length) return;

currentTable.foreign_key_constraints.map(
({ ref_table, ref_table_table_schema, column_mapping }) => {
const refTableSchema = findTable(
allSchemas,
generateTableDef(ref_table, ref_table_table_schema)
);
if (!refTableSchema.is_enum) return;

const keys = Object.keys(column_mapping);
if (!keys.length) return;

const _columnName = keys[0];
const _enumColumnName = column_mapping[_columnName];

if (_columnName && _enumColumnName) {
relationsMap.push({
columnName: _columnName,
enumTableName: ref_table,
enumColumnName: _enumColumnName,
});
}
}
);

return relationsMap;
};

/*** Table/View permissions utils ***/

export const getTablePermissions = (table, role = null, action = null) => {
Expand Down
13 changes: 13 additions & 0 deletions console/src/components/Common/utils/v1QueryUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,16 @@ export const getDeleteQuery = (pkClause, tableName, schemaName) => {

export const getBulkDeleteQuery = (pkClauses, tableName, schemaName) =>
pkClauses.map(pkClause => getDeleteQuery(pkClause, tableName, schemaName));

export const getEnumOptionsQuery = (request, currentSchema) => {
return {
type: 'select',
args: {
table: {
name: request.enumTableName,
schema: currentSchema,
},
columns: [request.enumColumnName],
},
};
};
4 changes: 2 additions & 2 deletions console/src/components/Services/Data/Add/AddTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import React, { Component } from 'react';
import Helmet from 'react-helmet';

import Button from '../../../Common/Button/Button';
import PrimaryKeySelector from '../Common/ReusableComponents/PrimaryKeySelector';
import PrimaryKeySelector from '../Common/Components/PrimaryKeySelector';
import ForeignKeyWrapper from './ForeignKeyWrapper';
import UniqueKeyWrapper from './UniqueKeyWrapper';
import FrequentlyUsedColumnSelector from '../Common/ReusableComponents/FrequentlyUsedColumnSelector';
import FrequentlyUsedColumnSelector from '../Common/Components/FrequentlyUsedColumnSelector';

import { showErrorNotification } from '../../Common/Notification';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';

import ExpandableEditor from '../../../Common/Layout/ExpandableEditor/Editor';
import { removeCheckConstraint, setCheckConstraints } from './AddActions';
import { ConstraintExpandedContent } from '../Common/ReusableComponents/ConstraintExpandedContent';
import { ConstraintExpandedContent } from '../Common/Components/ConstraintExpandedContent';

const CheckConstraints = ({ dispatch, constraints }) => {
const [addConstraintsState, setAddConstraintsState] = useState([]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ExpandableEditor from '../../../Common/Layout/ExpandableEditor/Editor';
import ForeignKeySelector from '../Common/ReusableComponents/ForeignKeySelector';
import { getForeignKeyConfig } from '../Common/ReusableComponents/utils';
import ForeignKeySelector from '../Common/Components/ForeignKeySelector';
import { getForeignKeyConfig } from '../Common/Components/utils';
import { setForeignKeys, toggleFk, clearFkToggle } from './AddActions';

const ForeignKeyWrapper = ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import React from 'react';
import ExpandableEditor from '../../../Common/Layout/ExpandableEditor/Editor';
import UniqueKeySelector from '../Common/ReusableComponents/UniqueKeySelector';
import {
getUkeyPkeyConfig,
getKeyDef,
} from '../Common/ReusableComponents/utils';
import UniqueKeySelector from '../Common/Components/UniqueKeySelector';
import { getUkeyPkeyConfig, getKeyDef } from '../Common/Components/utils';

const UniqueKeyWrapper = ({
// allSchemas,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ const PrimaryKeySelector = ({ primaryKeys, columns, setPk, dispatch }) => {
<div key={i} className={`form-group ${styles.pkEditorWrapper}`}>
<select
value={pk || ''}
className={`${styles.select} ${styles.sample} form-control ${
styles.add_pad_left
}`}
className={`${styles.select} ${styles.sample} form-control ${styles.add_pad_left}`}
onChange={dispatchSet}
data-test={`primary-key-select-${i}`}
>
Expand Down
122 changes: 122 additions & 0 deletions console/src/components/Services/Data/Common/Components/TypedInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React from 'react';

import { JSONB, JSONDTYPE, TEXT, BOOLEAN, getPlaceholder } from '../../utils';
import JsonInput from '../../../../Common/CustomInputTypes/JsonInput';
import TextInput from '../../../../Common/CustomInputTypes/TextInput';
import styles from '../../../../Common/TableCommon/Table.scss';
import { isColumnAutoIncrement } from '../../../../Common/utils/pgUtils';

export const TypedInput = ({
enumOptions,
col,
index,
clone,
inputRef,
onChange,
onFocus,
prevValue,
hasDefault,
}) => {
const {
column_name: colName,
data_type: colType,
column_default: colDefault,
} = col;

const isAutoIncrement = isColumnAutoIncrement(col);
const placeHolder = hasDefault ? colDefault : getPlaceholder(colType);
const getDefaultValue = () => {
if (prevValue) return prevValue;
if (clone && colName in clone) return clone[colName];
return '';
};

const onClick = e => {
e.target
.closest('.radio-inline')
.querySelector('input[type="radio"]').checked = true;
e.target.focus();
};

const standardInputProps = {
onChange,
onFocus,
onClick,
ref: inputRef,
'data-test': `typed-input-${index}`,
className: `form-control ${styles.insertBox}`,
defaultValue: getDefaultValue(),
type: 'text',
placeholder: 'text',
};
if (enumOptions && enumOptions[colName]) {
return (
<select
{...standardInputProps}
className={`form-control ${styles.insertBox}`}
defaultValue={prevValue || ''}
>
<option disabled value="">
-- enum value --
</option>
{enumOptions[colName].map(option => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
);
}

if (isAutoIncrement) {
return <input {...standardInputProps} readOnly placeholder={placeHolder} />;
}

if (prevValue && typeof prevValue === 'object') {
return (
<JsonInput
standardProps={{
...standardInputProps,
defaultValue: JSON.stringify(prevValue),
}}
placeholderProp={getPlaceholder(colType)}
/>
);
}

switch (colType) {
case JSONB:
case JSONDTYPE:
return (
<JsonInput
{...standardInputProps}
defaultValue={
prevValue ? JSON.stringify(prevValue) : getDefaultValue()
}
placeholderProp={placeHolder}
/>
);

case TEXT:
return (
<TextInput
standardProps={standardInputProps}
placeholderProp={placeHolder}
/>
);

case BOOLEAN:
return (
<select {...standardInputProps} defaultValue={placeHolder}>
<option value="" disabled>
-- bool --
</option>
<option value="true">True</option>
<option value="false">False</option>
</select>
);

default:
return <input {...standardInputProps} placeholder={placeHolder} />;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ const UniqueKeySelector = ({
return (
<div key={i} className={`form-group ${styles.pkEditorWrapper}`}>
<select
className={`${styles.select} ${styles.sample} form-control ${
styles.add_pad_left
}`}
className={`${styles.select} ${styles.sample} form-control ${styles.add_pad_left}`}
data-test={`unique-key-${index}-column-${i}`}
value={uk}
onChange={setUniqueCol}
Expand All @@ -87,9 +85,7 @@ const UniqueKeySelector = ({
return (
<div key={numCols} className={`form-group ${styles.pkEditorWrapper}`}>
<select
className={`${styles.select} ${styles.sample} form-control ${
styles.add_pad_left
}`}
className={`${styles.select} ${styles.sample} form-control ${styles.add_pad_left}`}
data-test={`unique-key-${index}-column-${numCols}`}
onChange={selectUniqueCol}
value={''}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const generateFKConstraintName = (
tableName,
lCols,
existingConstraints,
ignoreConstraints = []
ignoreConstraints = [],
) => {
const expectedName = `${tableName}_${lCols
.map(lc => lc.replace(/"/g, ''))
Expand Down
2 changes: 1 addition & 1 deletion console/src/components/Services/Data/Schema/Schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { isEmpty } from '../../../Common/utils/jsUtils';
import { getConfirmation } from '../../../Common/utils/jsUtils';
import ToolTip from '../../../Common/Tooltip/Tooltip';
import KnowMoreLink from '../../../Common/KnowMoreLink/KnowMoreLink';
import RawSqlButton from '../Common/ReusableComponents/RawSqlButton';
import RawSqlButton from '../Common/Components/RawSqlButton';

class Schema extends Component {
constructor(props) {
Expand Down
Loading