mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-13 19:33:55 +03:00
console: Support custom comments for root fields
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3930 Co-authored-by: Martin Mark <74692114+martin-hasura@users.noreply.github.com> GitOrigin-RevId: 91c71d8ab2c4886b395f5237ca71cace9ec61d1a
This commit is contained in:
parent
adb648b429
commit
cb1722694e
@ -159,6 +159,7 @@ function:
|
||||
- console: enable searching tables within a schema
|
||||
- console: fixed the ability to create updated_at and created_at in the modify page (#8239)
|
||||
- console: disable search indexing with HTML meta tag
|
||||
- console: add support for setting comments on the custom root fields of tables/views
|
||||
- cli: fix inherited roles metadata not being updated when dropping all roles (#7872)
|
||||
- cli: add support for customization field in sources metadata (#8292)
|
||||
- ci: ubuntu and centos flavoured graphql-engine images are now available
|
||||
|
@ -0,0 +1,79 @@
|
||||
import React, { ReactText } from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
export type SelectItem = {
|
||||
label: ReactText;
|
||||
value: ReactText;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export type SelectInputSplitFieldProps = {
|
||||
inputType?: 'text' | 'email' | 'password';
|
||||
selectOptions: SelectItem[];
|
||||
size?: 'full' | 'medium';
|
||||
placeholder?: string;
|
||||
inputDisabled?: boolean;
|
||||
selectDisabled?: boolean;
|
||||
inputValue: string;
|
||||
selectValue: string;
|
||||
inputOnChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
selectOnChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||
};
|
||||
|
||||
export const SelectInputSplitField = ({
|
||||
inputType = 'text',
|
||||
size = 'full',
|
||||
selectOptions,
|
||||
placeholder,
|
||||
inputDisabled,
|
||||
selectDisabled,
|
||||
inputValue,
|
||||
selectValue,
|
||||
inputOnChange,
|
||||
selectOnChange,
|
||||
}: SelectInputSplitFieldProps) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx('flex rounded', size === 'medium' ? 'w-1/2' : 'w-full')}
|
||||
>
|
||||
<select
|
||||
className="inline-flex form-control"
|
||||
style={{
|
||||
width: 'max-content',
|
||||
borderTopRightRadius: 0,
|
||||
borderBottomRightRadius: 0,
|
||||
borderRight: 0,
|
||||
paddingRight: '1.75rem',
|
||||
}}
|
||||
disabled={selectDisabled}
|
||||
onChange={selectOnChange}
|
||||
>
|
||||
{selectOptions.map(({ label, value, disabled = false }) => (
|
||||
<option
|
||||
key={value}
|
||||
selected={selectValue === value}
|
||||
{...{ value, disabled }}
|
||||
>
|
||||
{label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<input
|
||||
type={inputType}
|
||||
className={clsx(
|
||||
'flex-1 min-w-0 form-control',
|
||||
inputDisabled ? 'disabled' : ''
|
||||
)}
|
||||
style={{
|
||||
borderTopLeftRadius: 0,
|
||||
borderBottomLeftRadius: 0,
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
value={inputValue}
|
||||
disabled={inputDisabled}
|
||||
onChange={inputOnChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,56 @@
|
||||
import { SelectInputSplitField } from '@/components/Common/SelectInputSplitField/SelectInputSplitField';
|
||||
import React, { ChangeEvent, useCallback } from 'react';
|
||||
|
||||
export type CommentProps = {
|
||||
value: string | null;
|
||||
defaultComment: string;
|
||||
onChange: (comment: string | null) => void;
|
||||
};
|
||||
|
||||
const selectOptions = [
|
||||
{ label: 'Value', value: 'Value' },
|
||||
{ label: 'Disabled', value: 'Disabled' },
|
||||
];
|
||||
|
||||
export const CommentInput = ({
|
||||
value,
|
||||
defaultComment,
|
||||
onChange,
|
||||
}: CommentProps) => {
|
||||
const inputValue = value ?? '';
|
||||
const selectValue = value === '' ? 'Disabled' : 'Value';
|
||||
const placeholder = selectValue === 'Value' ? defaultComment : '';
|
||||
|
||||
const inputOnChange = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => {
|
||||
if (selectValue === 'Disabled') {
|
||||
onChange('');
|
||||
} else {
|
||||
onChange(e.target.value === '' ? null : e.target.value);
|
||||
}
|
||||
},
|
||||
[selectValue, onChange]
|
||||
);
|
||||
|
||||
const selectOnChange = useCallback(
|
||||
(e: ChangeEvent<HTMLSelectElement>) => {
|
||||
if (e.target.value === selectValue) return; // No change
|
||||
|
||||
const newComment = e.target.value === 'Disabled' ? '' : null;
|
||||
onChange(newComment);
|
||||
},
|
||||
[selectValue, onChange]
|
||||
);
|
||||
|
||||
return (
|
||||
<SelectInputSplitField
|
||||
inputValue={inputValue}
|
||||
inputOnChange={inputOnChange}
|
||||
inputDisabled={selectValue === 'Disabled'}
|
||||
selectOptions={selectOptions}
|
||||
selectValue={selectValue}
|
||||
selectOnChange={selectOnChange}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
);
|
||||
};
|
@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
CustomRootField,
|
||||
CustomRootFields,
|
||||
} from '../../../../../dataSources/types';
|
||||
import { CustomRootFields } from '../../../../../dataSources/types';
|
||||
import CollapsibleToggle from '../../../../Common/CollapsibleToggle/CollapsibleToggle';
|
||||
|
||||
import { getRootFieldLabel } from './utils';
|
||||
import { Nullable } from '../../../../../components/Common/utils/tsUtils';
|
||||
import { getTableCustomRootFieldName } from '../../../../../dataSources';
|
||||
import {
|
||||
getTableCustomRootFieldComment,
|
||||
getTableCustomRootFieldName,
|
||||
} from '../../../../../dataSources';
|
||||
import { CommentInput } from './CommentInput';
|
||||
|
||||
interface RootFieldEditorProps {
|
||||
rootFields: CustomRootFields;
|
||||
@ -15,7 +15,7 @@ interface RootFieldEditorProps {
|
||||
tableName: string;
|
||||
tableSchema: string;
|
||||
customName?: string;
|
||||
customNameOnChange: ChangeHandler;
|
||||
customNameOnChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
selectOnChange: ChangeHandler;
|
||||
selectByPkOnChange: ChangeHandler;
|
||||
selectAggOnChange: ChangeHandler;
|
||||
@ -27,7 +27,22 @@ interface RootFieldEditorProps {
|
||||
deleteByPkOnChange: ChangeHandler;
|
||||
}
|
||||
|
||||
type ChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
interface ChangeHandler {
|
||||
onNameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
onCommentChange: (comment: string | null) => void;
|
||||
}
|
||||
|
||||
export const rootFieldLabels: Record<keyof CustomRootFields, string> = {
|
||||
select: 'Select',
|
||||
select_by_pk: 'Select by PK',
|
||||
select_aggregate: 'Select Aggregate',
|
||||
insert: 'Insert',
|
||||
insert_one: 'Insert One',
|
||||
update: 'Update',
|
||||
update_by_pk: 'Update by PK',
|
||||
delete: 'Delete',
|
||||
delete_by_pk: 'Delete by PK',
|
||||
};
|
||||
|
||||
const RootFieldEditor: React.FC<RootFieldEditorProps> = ({
|
||||
rootFields,
|
||||
@ -46,17 +61,19 @@ const RootFieldEditor: React.FC<RootFieldEditorProps> = ({
|
||||
customName,
|
||||
tableSchema,
|
||||
}) => {
|
||||
const {
|
||||
select,
|
||||
select_by_pk: selectByPk,
|
||||
select_aggregate: selectAgg,
|
||||
insert,
|
||||
insert_one: insertOne,
|
||||
update,
|
||||
update_by_pk: updateByPk,
|
||||
delete: _delete,
|
||||
delete_by_pk: deleteByPk,
|
||||
} = rootFields;
|
||||
const qualifiedTableName =
|
||||
tableSchema === '' ? `"${tableName}"` : `"${tableSchema}.${tableName}"`;
|
||||
const rootFieldDefaultComments: Record<keyof CustomRootFields, string> = {
|
||||
select: `fetch data from the table: ${qualifiedTableName}`,
|
||||
select_by_pk: `fetch data from the table: ${qualifiedTableName} using primary key columns`,
|
||||
select_aggregate: `fetch aggregated fields from the table: ${qualifiedTableName}`,
|
||||
insert: `insert data into the table: ${qualifiedTableName}`,
|
||||
insert_one: `insert a single row into the table: ${qualifiedTableName}`,
|
||||
update: `update data of the table: ${qualifiedTableName}`,
|
||||
update_by_pk: `update single row of the table: ${qualifiedTableName}`,
|
||||
delete: `delete data from the table: ${qualifiedTableName}`,
|
||||
delete_by_pk: `delete single row from the table: ${qualifiedTableName}`,
|
||||
};
|
||||
|
||||
const getRootField = () => {
|
||||
if (customName) {
|
||||
@ -85,27 +102,53 @@ const RootFieldEditor: React.FC<RootFieldEditorProps> = ({
|
||||
return `${rfType}_${rootField}`;
|
||||
};
|
||||
|
||||
const getRow = (
|
||||
rfType: string,
|
||||
value: Nullable<string> | CustomRootField,
|
||||
onChange: ChangeHandler
|
||||
const getCustomNameRow = (
|
||||
value: Nullable<string>,
|
||||
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
|
||||
) => (
|
||||
<div className="flex items-center">
|
||||
<div className="text-gray-600">{getRootFieldLabel(rfType)}</div>
|
||||
<div className="ml-auto w-6/12">
|
||||
<div className="flex items-center space-x-4 ">
|
||||
<div className="text-gray-600 w-2/12">Custom Table Name</div>
|
||||
<div className="w-4/12">
|
||||
<input
|
||||
type="text"
|
||||
value={getTableCustomRootFieldName(value) || ''}
|
||||
placeholder={`${getDefaultRootField(rfType)} (default)`}
|
||||
value={value || ''}
|
||||
placeholder={`${getDefaultRootField('custom_name')} (default)`}
|
||||
className="form-control"
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-6/12" />
|
||||
</div>
|
||||
);
|
||||
|
||||
const getSection = (rfType: string) => {
|
||||
const getRootFieldRow = (
|
||||
rfType: keyof CustomRootFields,
|
||||
onChange: ChangeHandler
|
||||
) => (
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="text-gray-600 w-2/12">{rootFieldLabels[rfType]}</div>
|
||||
<div className="w-4/12">
|
||||
<input
|
||||
type="text"
|
||||
value={getTableCustomRootFieldName(rootFields[rfType]) || ''}
|
||||
placeholder={`${getDefaultRootField(rfType)} (default)`}
|
||||
className="form-control"
|
||||
onChange={onChange.onNameChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-6/12">
|
||||
<CommentInput
|
||||
value={getTableCustomRootFieldComment(rootFields[rfType])}
|
||||
defaultComment={rootFieldDefaultComments[rfType]}
|
||||
onChange={onChange.onCommentChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const getSection = (rfType: 'query' | 'mutation') => {
|
||||
return (
|
||||
<div>
|
||||
<CollapsibleToggle
|
||||
@ -113,33 +156,37 @@ const RootFieldEditor: React.FC<RootFieldEditorProps> = ({
|
||||
useDefaultTitleStyle
|
||||
isOpen
|
||||
>
|
||||
<div className="flex items-center space-x-4 pb-2">
|
||||
<div className="text-gray-600 w-2/12" />
|
||||
<div className="text-gray-600 w-4/12">Field Name</div>
|
||||
<div className="text-gray-600 w-6/12">Comment </div>
|
||||
</div>
|
||||
{rfType === 'query' && (
|
||||
<div className="space-y-md mb-md">
|
||||
{getRow('select', select, selectOnChange)}
|
||||
{getRow('select_by_pk', selectByPk, selectByPkOnChange)}
|
||||
{getRow('select_aggregate', selectAgg, selectAggOnChange)}
|
||||
{getRootFieldRow('select', selectOnChange)}
|
||||
{getRootFieldRow('select_by_pk', selectByPkOnChange)}
|
||||
{getRootFieldRow('select_aggregate', selectAggOnChange)}
|
||||
</div>
|
||||
)}
|
||||
{rfType === 'mutation' && (
|
||||
<div className="space-y-md mb-md">
|
||||
{getRow('insert', insert, insertOnChange)}
|
||||
{getRow('insert_one', insertOne, insertOneOnChange)}
|
||||
{getRow('update', update, updateOnChange)}
|
||||
{getRow('update_by_pk', updateByPk, updateByPkOnChange)}
|
||||
{getRow('delete', _delete, deleteOnChange)}
|
||||
{getRow('delete_by_pk', deleteByPk, deleteByPkOnChange)}
|
||||
{getRootFieldRow('insert', insertOnChange)}
|
||||
{getRootFieldRow('insert_one', insertOneOnChange)}
|
||||
{getRootFieldRow('update', updateOnChange)}
|
||||
{getRootFieldRow('update_by_pk', updateByPkOnChange)}
|
||||
{getRootFieldRow('delete', deleteOnChange)}
|
||||
{getRootFieldRow('delete_by_pk', deleteByPkOnChange)}
|
||||
</div>
|
||||
)}
|
||||
</CollapsibleToggle>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<div className="mb-md">
|
||||
{getRow('custom_name', customName, customNameOnChange)}
|
||||
{getCustomNameRow(customName, customNameOnChange)}
|
||||
</div>
|
||||
{getSection('query')}
|
||||
{getSection('mutation')}
|
||||
|
@ -110,19 +110,3 @@ export const getKeyDef = (config, constraintName) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const getRootFieldLabel = rfType => {
|
||||
const labels = {
|
||||
custom_name: 'Custom Table Name',
|
||||
select: 'Select',
|
||||
select_by_pk: 'Select by PK',
|
||||
select_aggregate: 'Select Aggregate',
|
||||
insert: 'Insert',
|
||||
insert_one: 'Insert One',
|
||||
update: 'Update',
|
||||
update_by_pk: 'Update by PK',
|
||||
delete: 'Delete',
|
||||
delete_by_pk: 'Delete by PK',
|
||||
};
|
||||
return labels[rfType];
|
||||
};
|
||||
|
@ -145,15 +145,17 @@ const ColumnEditorList = ({
|
||||
const keyPropertiesString = propertiesList.join(', ');
|
||||
|
||||
propertiesDisplay.push(
|
||||
<span className="ml-xs mr-2 font-normal" key={'props'}>
|
||||
<span className="ml-xs font-normal" key={'props'}>
|
||||
{keyPropertiesString}
|
||||
</span>
|
||||
);
|
||||
|
||||
propertiesDisplay.push(
|
||||
<span key={'comment'} className={styles.text_gray}>
|
||||
{columnProperties.comment && `${columnProperties.comment}`}
|
||||
</span>
|
||||
<div>
|
||||
<span key={'comment'} className="text-gray-600 text-sm">
|
||||
{columnProperties.comment && `${columnProperties.comment}`}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
return propertiesDisplay;
|
||||
@ -161,15 +163,13 @@ const ColumnEditorList = ({
|
||||
|
||||
const collapsedLabel = () => {
|
||||
return (
|
||||
<div className="flex items-center" key={colName}>
|
||||
<div>
|
||||
<span className="font-semibold">{colName}</span>
|
||||
<span className="ml-xs font-semibold">
|
||||
{columnProperties.customFieldName &&
|
||||
` → ${columnProperties.customFieldName}`}
|
||||
</span>
|
||||
</div>{' '}
|
||||
{gqlCompatibilityWarning()} - {keyProperties()}
|
||||
<div key={colName}>
|
||||
<span className="font-semibold">{colName}</span>
|
||||
<span className="mr-xs">
|
||||
{columnProperties.customFieldName &&
|
||||
` → ${columnProperties.customFieldName}`}
|
||||
</span>
|
||||
- {gqlCompatibilityWarning()} {keyProperties()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -217,7 +217,7 @@ class ModifyTable extends React.Component {
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="w-full sm:w-6/12">
|
||||
<div className="w-full sm:w-full">
|
||||
<h3 className="text-sm tracking-widest text-gray-400 uppercase font-semibold mb-sm">
|
||||
Configure Fields
|
||||
</h3>
|
||||
|
@ -8,9 +8,14 @@ import {
|
||||
} from './ModifyActions';
|
||||
|
||||
import { Dispatch } from '../../../../types';
|
||||
import { CustomRootFields } from '../../../../dataSources/types';
|
||||
import {
|
||||
CustomRootField,
|
||||
CustomRootFields,
|
||||
} from '../../../../dataSources/types';
|
||||
import {
|
||||
getTableCustomRootFieldComment,
|
||||
getTableCustomRootFieldName,
|
||||
setTableCustomRootFieldComment,
|
||||
setTableCustomRootFieldName,
|
||||
} from '../../../../dataSources';
|
||||
|
||||
@ -37,56 +42,69 @@ const RootFieldsEditor = ({
|
||||
dispatch(modifyRootFields(rf));
|
||||
};
|
||||
|
||||
const onChange = (field: keyof CustomRootFields, customField: string) => {
|
||||
const newRootFields = {
|
||||
...rootFieldsEdit,
|
||||
[field]: setTableCustomRootFieldName(rootFieldsEdit[field], customField),
|
||||
};
|
||||
dispatch(modifyRootFields(newRootFields));
|
||||
};
|
||||
const onRootFieldChange = (field: keyof CustomRootFields) => ({
|
||||
onNameChange: (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newRootFields = {
|
||||
...rootFieldsEdit,
|
||||
[field]: setTableCustomRootFieldName(
|
||||
rootFieldsEdit[field],
|
||||
e.target.value
|
||||
),
|
||||
};
|
||||
dispatch(modifyRootFields(newRootFields));
|
||||
},
|
||||
|
||||
onCommentChange: (comment: string | null) => {
|
||||
const newRootFields = {
|
||||
...rootFieldsEdit,
|
||||
[field]: setTableCustomRootFieldComment(rootFieldsEdit[field], comment),
|
||||
};
|
||||
dispatch(modifyRootFields(newRootFields));
|
||||
},
|
||||
});
|
||||
|
||||
const onChangeCustomName = (newName: string) => {
|
||||
dispatch(modifyTableCustomName(newName));
|
||||
};
|
||||
|
||||
const getRootFieldNames = (
|
||||
rootFields: CustomRootFields
|
||||
): Record<string, string> => {
|
||||
const rootFieldNames = Object.entries(rootFields).map(([key, value]) =>
|
||||
value ? { [key]: getTableCustomRootFieldName(value) } : {}
|
||||
const renderCustomRootFieldLabel = (
|
||||
rootFieldName: string,
|
||||
rootFieldConfig: string | CustomRootField
|
||||
) => {
|
||||
const rfCustomName = getTableCustomRootFieldName(rootFieldConfig);
|
||||
const rfComment = getTableCustomRootFieldComment(rootFieldConfig);
|
||||
return (
|
||||
<div className="mb-xs" key={rootFieldName}>
|
||||
<span className="flex items-center">
|
||||
<span className="font-semibold mr-xs">{rootFieldName}</span>
|
||||
{rfCustomName ? (
|
||||
<>
|
||||
<span className="mr-xs">→</span>
|
||||
<span>{rfCustomName}</span>
|
||||
</>
|
||||
) : null}
|
||||
</span>
|
||||
<span className="text-gray-600 text-sm">{rfComment}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
return Object.assign({}, ...rootFieldNames);
|
||||
};
|
||||
|
||||
const collapsedLabel = () => {
|
||||
const customRootFieldLabels: React.ReactNode[] = [];
|
||||
const customNameLabel = existingCustomName
|
||||
? [renderCustomRootFieldLabel('custom_table_name', existingCustomName)]
|
||||
: [];
|
||||
|
||||
if (existingCustomName) {
|
||||
customRootFieldLabels.push(
|
||||
<span className="flex items-center" key={existingCustomName}>
|
||||
<span className="font-semibold mr-xs">custom_table_name</span>{' '}
|
||||
<span className="mr-xs">→</span>{' '}
|
||||
<span>{existingCustomName}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
Object.entries(getRootFieldNames(existingRootFields)).forEach(
|
||||
([rootField, customRootField]) => {
|
||||
customRootFieldLabels.push(
|
||||
<>
|
||||
<span className="flex items-center" key={rootField}>
|
||||
<span className="font-semibold mr-xs">{rootField}</span>
|
||||
<span className="mr-xs">→</span>
|
||||
<span>{customRootField}</span>
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
const existingRootFieldLabels = Object.entries(
|
||||
existingRootFields
|
||||
).map(([rootField, customRootField]) =>
|
||||
customRootField === null
|
||||
? []
|
||||
: [renderCustomRootFieldLabel(rootField, customRootField)]
|
||||
);
|
||||
|
||||
return <div>{customRootFieldLabels}</div>;
|
||||
const allLabels = customNameLabel.concat(...existingRootFieldLabels);
|
||||
|
||||
return <div>{allLabels}</div>;
|
||||
};
|
||||
|
||||
const editorExpanded = () => (
|
||||
@ -99,33 +117,15 @@ const RootFieldsEditor = ({
|
||||
customNameOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChangeCustomName(e.target.value);
|
||||
}}
|
||||
selectOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('select', e.target.value);
|
||||
}}
|
||||
selectByPkOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('select_by_pk', e.target.value);
|
||||
}}
|
||||
selectAggOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('select_aggregate', e.target.value);
|
||||
}}
|
||||
insertOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('insert', e.target.value);
|
||||
}}
|
||||
insertOneOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('insert_one', e.target.value);
|
||||
}}
|
||||
updateOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('update', e.target.value);
|
||||
}}
|
||||
updateByPkOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('update_by_pk', e.target.value);
|
||||
}}
|
||||
deleteOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('delete', e.target.value);
|
||||
}}
|
||||
deleteByPkOnChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange('delete_by_pk', e.target.value);
|
||||
}}
|
||||
selectOnChange={onRootFieldChange('select')}
|
||||
selectByPkOnChange={onRootFieldChange('select_by_pk')}
|
||||
selectAggOnChange={onRootFieldChange('select_aggregate')}
|
||||
insertOnChange={onRootFieldChange('insert')}
|
||||
insertOneOnChange={onRootFieldChange('insert_one')}
|
||||
updateOnChange={onRootFieldChange('update')}
|
||||
updateByPkOnChange={onRootFieldChange('update_by_pk')}
|
||||
deleteOnChange={onRootFieldChange('delete')}
|
||||
deleteByPkOnChange={onRootFieldChange('delete_by_pk')}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -57,7 +57,8 @@ export const sanitiseRootFields = rootFields => {
|
||||
rootField = rootField.trim() || null;
|
||||
} else if (rootField) {
|
||||
rootField.name = rootField.name ? rootField.name.trim() : null;
|
||||
rootField.comment = rootField.comment ? rootField.comment.trim() : null;
|
||||
rootField.comment =
|
||||
typeof rootField.comment === 'string' ? rootField.comment.trim() : null;
|
||||
}
|
||||
santisedRootFields[rootFieldType] = rootField;
|
||||
});
|
||||
|
@ -312,6 +312,40 @@ export const setTableCustomRootFieldName = (
|
||||
return newName;
|
||||
};
|
||||
|
||||
export const getTableCustomRootFieldComment = (
|
||||
rootFieldValue: Nullable<string> | CustomRootField
|
||||
): string | null => {
|
||||
if (rootFieldValue) {
|
||||
if (
|
||||
typeof rootFieldValue === 'string' ||
|
||||
rootFieldValue.comment === undefined
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return rootFieldValue.comment;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const setTableCustomRootFieldComment = (
|
||||
existingRootFieldValue: Nullable<string> | CustomRootField,
|
||||
newComment: string | null
|
||||
): Nullable<string> | CustomRootField => {
|
||||
if (typeof existingRootFieldValue === 'string') {
|
||||
return {
|
||||
name: existingRootFieldValue,
|
||||
comment: newComment,
|
||||
};
|
||||
} else if (typeof existingRootFieldValue === 'object') {
|
||||
return {
|
||||
...existingRootFieldValue,
|
||||
comment: newComment,
|
||||
};
|
||||
}
|
||||
return { comment: newComment };
|
||||
};
|
||||
|
||||
export const getTableColumnConfig = (table: NormalizedTable) =>
|
||||
table?.configuration?.column_config || {};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user