ToolJet/frontend/src/TooljetDatabase/Forms/ColumnsForm.jsx
Manish Kushare e1d7fbb2bb Feature: Add JSON datatype to ToolJet Database (#2492)
* feat: jsonb datatype support in tooljet database inprogress

* feat: jsonb support added for tooljet database column operations as well as create and edit table

* feat: added support to query JSONB values in JOIN operation

* added dto validation for join operation

* Added json data type in tjdb

* single line editor bug fixed

* Basic UI implementation for create table drawer for jsonb column type

* removed the console

* Added the sanitization for json default value in the dto

* Added jsonb svg for jsonb column type

* Updated UI for created column form

* Updated UI for edit column form

* Change the UI for create row

* Updated UI for edit row form

* Show dummy {...} value on table cell

* Setting up the codehinter in tjdb dashboard

* Created codehinter wrapper for tjdb table celljsonb data type

* Codehineter for tjdb cell

* Made changes in tjdb column and row drawers

* removed unwanted code

* Added maximum height for codehinter wrapper in each drawers

Avoided keydown event in create column drawer

* Set max height to codehinter for tjdb table cell

* Added jsonb path option for list row operation [rebase]

* Added filtering out column with json datatype in udpate rows operation

* Added filter option with jsonpath in delete row operation

* Made changes for join tables

* added json path in jon filter condition

* fix: parsing the jsonb default values in view table api

* Made on change and initial value value changes for all tjdb dashboard changes

* updated intial value and component name for codehinter in all drawers for tooljetdb

* Table cell edit codehinter initial value

* Updated codehinter onchange and initial value

* Added json path field for join sort section

* TJDB query manager updates for jsonb column type

* Tjdb dashboard bug fixes

* fix: joins jsonbpath expression can be sent without single quotes

* Added error validation for JSON in codehinter

* Removed console

* Added codehinter wrapper for tjdb cell

* Made default functional

* Made set to null functionality working

* Toggle functionality for default value

* Toggle null functionality

* Clean code

* create row form added handle disable input click

* cutom-footer css and add new data css

* Fixed tooltip

* Updated tooltip for join codehinters in query manager

* fix: jsonb column values validation in server side

* Made the initial value empty string if value is undefined

* active tab in edit row form bug

* Error state in tjdb hinter inside cell

* code mirror breaks, on the initial render

* Added placeholder and adjusted icon size in dropdown

* Fixed: Opening the cell with keyboard nav shows ‘enter to save’.

* bug fixed

* json icon alignment in the dropdown fixed

* In create and edit table, codehinter text is vertcially centered aligned

* Create row and update row info message for jsonb column type fixed

* SHowing popover when clicked on the jsonb cell

* Showing unique constraint in disable state for jsonb

* bugfix: bulkupload in tjdb for jsonb datatype should accept different json format

* Bug fixed for cellhinter and row form

* Avoided flickering in column form

* removed console

* zindex issue for codehinter in react portal for table cell

* Single line editor file changes removed

* row form bug fixed

* single quotes string escaped as it needs to be inserted as default value in JSONB column

* Bug fixed

* Edit and create row active tab bug fixed

* If value is empty, then dont show error in the codehinter

* fix: error handling for invalid jsonpath in join expression

* Handled null and Null edge cases for edit and create row

* Removed console

* Bug fix for save chages button in edit and create row drawer

* Error toast message for invalid syntax

* removed debounce time

* Copied all query manager and codehinter changes from editor to appbuilder directory

* Updated imports of codehinter in tjdb forms inside dashboard

* Discarded all changes made to editor directory

* Removed console

* Fixed flickering effect in the edit and create row drawer in TJDB dashboard

* Added focused state to codehinter in tjdb drawer, updated font size for the same

* Updated error message

* bug fixed : Pop up icon not visible inside codehinter

* Fixed : border issue in tjdb codehinter

* bugfix: array is not allowed to insert in JSONB column (#2734)

* Error message in tjdb drawers

* Error state for table schema

* Error message for cell hinter wrapper

* fixed : space between {} and table name in popup

* Spacing issue in create and update column UI in query manager fixed

* Show tooltip in fk column dropdown

* Bug fixed: edit drawer on first render cutom value is always empty

* Bug fixed

* Reverting react portal changes

* bug fixed for error copyright

* z index issue fixed for tableschema

* reverting back the changes for table form from last commit

* Bug fix: Flickering issue in table schema for codehinter input

* Bug fixed : toggle bwtween null and default value

* Handled spacing between the component name in react portal

* added new schema definition as we have introduced jsonb datatype default values can have Object and Array

* fix: removed the support for error code mapping for undefined function error  because database has different error text for it based on the scenario like jsonb aggregates etc

---------

Co-authored-by: Ganesh Kumar <ganesh8056234@gmail.com>
Co-authored-by: Ganesh Kumar <40178541+ganesh8056@users.noreply.github.com>
Co-authored-by: Akshay <akshaysasidharan93@gmail.com>
2024-12-04 13:49:24 +05:30

167 lines
5.7 KiB
JavaScript

import React, { useEffect, useState } from 'react';
import cx from 'classnames';
import ColumnName from '../Icons/ColumnName.svg';
import TableSchema from './TableSchema';
import ForeignKeyRelation from './ForeignKeyRelation';
import AddRectangle from '@/_ui/Icon/bulkIcons/AddRectangle';
import { ButtonSolid } from '@/_ui/AppButton/AppButton';
import _, { isEmpty } from 'lodash';
const ColumnsForm = ({
columns,
setColumns,
isEditMode,
editColumns,
tableName,
setForeignKeyDetails,
isRequiredFieldsExistForCreateTableOperation,
foreignKeyDetails,
organizationId,
existingForeignKeyDetails,
setCreateForeignKeyInEdit,
createForeignKeyInEdit = false,
selectedTable,
setForeignKeys,
handleInputError,
}) => {
const [columnSelection, setColumnSelection] = useState({ index: 0, value: '', configurations: {} });
const [hoveredColumn, setHoveredColumn] = useState(null);
const [isForeignKeyDraweOpen, setIsForeignKeyDraweOpen] = useState(false);
const handleDelete = (index) => {
const newColumns = { ...columns };
delete newColumns[index];
setColumns(newColumns);
};
const onMouseHover = (char = []) => {
const isNameAvailable = Object.values(columns).some((obj) => {
return Object.values(obj).some((value) => {
return char.includes(value);
});
});
const index = Object.values(columns).findIndex((obj) => {
return Object.values(obj).some((value) => {
return char.includes(value);
});
});
if (isNameAvailable === true) {
setHoveredColumn(index);
setTimeout(() => {
setHoveredColumn(null);
}, 3000);
} else {
setHoveredColumn(null);
}
};
// const handleDeleteEditColumn = (index) => {
// const newColumns = { ...editColumns };
// delete newColumns[index];
// setColumns(newColumns);
// };
// const isNameAvailable = Object.values(columns).some((obj) => Object.values(obj).includes(char));
const darkMode = localStorage.getItem('darkMode') === 'true';
return (
<div className="create-column-drawer">
<div className="card-header">
<h3 className={cx('card-sub-title', { 'card-sub-title-light': !darkMode })} data-cy="add-columns-header">
Table schema
</h3>
</div>
<div className="card-body">
<div
className={cx('list-group-item', {
'text-white': darkMode,
})}
>
<div className="row">
<div className="m-0 d-flex align-items-center column-name-description">
<ColumnName />
<span style={{ marginLeft: '6px' }} data-cy="name-input-field-label">
Column name
</span>
</div>
<div className="m-0 dataType-description">
<span data-cy="type-input-field-label">Type</span>
</div>
<div className="m-0 defaultValue-description">
<span data-cy="default-input-field-label">Default value</span>
</div>
<div className="m-0 primaryKey-description">
<span data-cy="default-input-field-label">Primary</span>
</div>
</div>
</div>
<TableSchema
columns={columns}
editColumns={editColumns}
setColumns={setColumns}
darkMode={darkMode}
columnSelection={columnSelection}
setColumnSelection={setColumnSelection}
handleDelete={handleDelete}
isEditMode={isEditMode}
setForeignKeyDetails={setForeignKeyDetails}
isActiveForeignKey={
!isEmpty(foreignKeyDetails?.column_names) &&
!isEmpty(foreignKeyDetails?.referenced_column_names) &&
!isEmpty(foreignKeyDetails?.referenced_table_name) &&
!isEmpty(foreignKeyDetails?.on_delete) &&
!isEmpty(foreignKeyDetails?.on_update)
}
indexHover={hoveredColumn}
foreignKeyDetails={foreignKeyDetails}
existingForeignKeyDetails={existingForeignKeyDetails} // foreignKeys from context state
handleInputError={handleInputError}
/>
<div className="d-flex mb-2 mt-2 border-none" style={{ maxHeight: '32px' }}>
<ButtonSolid
variant="ghostBlue"
size="sm"
style={{ fontSize: '14px' }}
onClick={() => {
setColumns((prevColumns) => ({
...prevColumns,
[+Object.keys(prevColumns).pop() + 1 || 0]: { configurations: {} },
})),
setColumnSelection({ index: 0, value: '', configurations: {} });
}}
data-cy="add-more-columns-button"
>
<AddRectangle width="14" height="14" fill="#3E63DD" opacity="1" secondaryFill="#ffffff" />
<span className="add-text">Add more columns</span>
</ButtonSolid>
</div>
<ForeignKeyRelation
onMouseHoverFunction={onMouseHover}
setHoveredColumn={setHoveredColumn}
tableName={tableName}
columns={columns}
setColumns={setColumns}
isEditMode={isEditMode}
setForeignKeyDetails={setForeignKeyDetails}
isRequiredFieldsExistForCreateTableOperation={isRequiredFieldsExistForCreateTableOperation}
foreignKeyDetails={foreignKeyDetails}
organizationId={organizationId}
existingForeignKeyDetails={existingForeignKeyDetails}
setForeignKeys={setForeignKeys}
setCreateForeignKeyInEdit={setCreateForeignKeyInEdit}
createForeignKeyInEdit={createForeignKeyInEdit}
selectedTable={selectedTable}
setIsForeignKeyDraweOpen={setIsForeignKeyDraweOpen}
isForeignKeyDraweOpen={isForeignKeyDraweOpen}
/>
</div>
</div>
);
};
export default ColumnsForm;