diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.ui.js index 523bd8f94..5f64e58cd 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.ui.js @@ -15,7 +15,7 @@ export function getNodeExclusionConstraintSchema(treeNodeInfo, itemNodeData, pgB spcname: ()=>getNodeListByName('tablespace', treeNodeInfo, itemNodeData, {}, (m)=>{ return (m.label != 'pg_global'); }), - getOperClass: (urlParams)=>getNodeAjaxOptions('get_oper_class', tableNode, treeNodeInfo, itemNodeData, {urlParams: urlParams}, (data)=>{ + getOperClass: (urlParams)=>getNodeAjaxOptions('get_oper_class', tableNode, treeNodeInfo, itemNodeData, {urlParams: urlParams, useCache:false}, (data)=>{ let res = []; if (data && _.isArray(data)) { _.each(data, function(d) { @@ -24,7 +24,7 @@ export function getNodeExclusionConstraintSchema(treeNodeInfo, itemNodeData, pgB } return res; }), - getOperator: (urlParams)=>getNodeAjaxOptions('get_operator', tableNode, treeNodeInfo, itemNodeData, {urlParams: urlParams}, (data)=>{ + getOperator: (urlParams)=>getNodeAjaxOptions('get_operator', tableNode, treeNodeInfo, itemNodeData, {urlParams: urlParams, useCache:false}, (data)=>{ let res = []; if (data && _.isArray(data)) { _.each(data, function(d) { @@ -33,7 +33,7 @@ export function getNodeExclusionConstraintSchema(treeNodeInfo, itemNodeData, pgB } return res; }), - }); + }, treeNodeInfo); } class ExclusionColHeaderSchema extends BaseUISchema { @@ -168,9 +168,7 @@ class ExclusionColumnSchema extends BaseUISchema { },{ id: 'operator', label: gettext('Operator'), type: 'select', width: 95, - editable: function() { - return obj.isNewExCons; - }, + editable: obj.isEditable, cell: (state)=>{ return { cell: 'select', @@ -185,7 +183,7 @@ class ExclusionColumnSchema extends BaseUISchema { } export default class ExclusionConstraintSchema extends BaseUISchema { - constructor(fieldOptions={}, nodeInfo, getColumns) { + constructor(fieldOptions={}, nodeInfo) { super({ name: undefined, oid: undefined, @@ -202,7 +200,7 @@ export default class ExclusionConstraintSchema extends BaseUISchema { this.nodeInfo = nodeInfo; this.fieldOptions = fieldOptions; - this.exHeaderSchema = new ExclusionColHeaderSchema(fieldOptions.columns, getColumns); + this.exHeaderSchema = new ExclusionColHeaderSchema(fieldOptions.columns); this.exColumnSchema = new ExclusionColumnSchema(fieldOptions.getOperator); this.exHeaderSchema.exColumnSchema = this.exColumnSchema; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js index f6a49eb3d..aa71e3732 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/partition.utils.ui.js @@ -161,7 +161,7 @@ export class PartitionsSchema extends BaseUISchema { return true; }, },{ - id: 'partition_name', label: gettext('Name'), + id: 'partition_name', label: gettext('Name'), deps: ['is_attach'], type: (state)=>{ if(state.is_attach) { return { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py index e13dbd1e7..e0099396e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py @@ -2072,10 +2072,10 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings): for old_data_row in old_data[vacuum_key]: if data_row['name'] == old_data_row['name'] and \ 'value' in data_row: - if data_row['value'] is not None: + if data_row['value'] is not None and \ + data_row['value'] != '': set_values.append(data_row) - elif data_row['value'] is None and \ - 'value' in old_data_row: + elif 'value' in old_data_row: reset_values.append(data_row) if len(set_values) > 0: diff --git a/web/pgadmin/static/js/SchemaView/DataGridView.jsx b/web/pgadmin/static/js/SchemaView/DataGridView.jsx index a7d93f522..8363c6b13 100644 --- a/web/pgadmin/static/js/SchemaView/DataGridView.jsx +++ b/web/pgadmin/static/js/SchemaView/DataGridView.jsx @@ -29,6 +29,7 @@ import { confirmDeleteRow } from '../helpers/legacyConnector'; import CustomPropTypes from 'sources/custom_prop_types'; import { evalFunc } from 'sources/utils'; import { DepListenerContext } from './DepListener'; +import { useIsMounted } from '../custom_hooks'; const useStyles = makeStyles((theme)=>({ grid: { @@ -179,17 +180,19 @@ function DataTableRow({row, totalRows, isResizing, schema, schemaRef, accessPath }, []); useEffect(()=>{ - schema.fields.forEach((field)=>{ + schemaRef.current.fields.forEach((field)=>{ /* Self change is also dep change */ - if(field.depChange) { - depListener?.addDepListener(accessPath.concat(field.id), accessPath.concat(field.id), field.depChange); + if(field.depChange || field.deferredDepChange) { + depListener.addDepListener(accessPath.concat(field.id), accessPath.concat(field.id), field.depChange, field.deferredDepChange); } (evalFunc(null, field.deps) || []).forEach((dep)=>{ let source = accessPath.concat(dep); if(_.isArray(dep)) { source = dep; } - depListener?.addDepListener(source, accessPath.concat(field.id), field.depChange); + if(field.depChange) { + depListener.addDepListener(source, accessPath.concat(field.id), field.depChange); + } }); }); return ()=>{ @@ -244,6 +247,7 @@ export default function DataGridView({ fixedRows, ...props}) { const classes = useStyles(); const stateUtils = useContext(StateUtilsContext); + const checkIsMounted = useIsMounted(); /* Using ref so that schema variable is not frozen in columns closure */ const schemaRef = useRef(schema); @@ -432,7 +436,7 @@ export default function DataGridView({ ); useEffect(()=>{ - let rowsPromise = fixedRows, umounted=false; + let rowsPromise = fixedRows; /* If fixedRows is defined, fetch the details */ if(typeof rowsPromise === 'function') { @@ -442,12 +446,11 @@ export default function DataGridView({ Promise.resolve(rowsPromise) .then((res)=>{ /* If component unmounted, dont update state */ - if(!umounted) { + if(checkIsMounted()) { stateUtils.initOrigData(accessPath, res); } }); } - return ()=>umounted=true; }, []); const isResizing = _.flatMap(headerGroups, headerGroup => headerGroup.headers.map(col=>col.isResizing)).includes(true); diff --git a/web/pgadmin/static/js/SchemaView/FormView.jsx b/web/pgadmin/static/js/SchemaView/FormView.jsx index 03f63ae5b..17371202e 100644 --- a/web/pgadmin/static/js/SchemaView/FormView.jsx +++ b/web/pgadmin/static/js/SchemaView/FormView.jsx @@ -237,7 +237,6 @@ export default function FormView({ ); } else if(field.type === 'collection') { /* If its a collection, let data grid view handle it */ - let depsMap = [value[field.id]]; /* Pass on the top schema */ if(isNested) { field.schema.top = schemaRef.current.top; @@ -245,8 +244,6 @@ export default function FormView({ field.schema.top = schemaRef.current; } - depsMap.push(canAdd, canEdit, canDelete, visible); - if(!_.isUndefined(field.fixedRows)) { canAdd = false; canDelete = false; diff --git a/web/pgadmin/static/js/SchemaView/index.jsx b/web/pgadmin/static/js/SchemaView/index.jsx index 62d3ec3e9..e5e82b8d7 100644 --- a/web/pgadmin/static/js/SchemaView/index.jsx +++ b/web/pgadmin/static/js/SchemaView/index.jsx @@ -121,6 +121,7 @@ function getChangedData(topSchema, viewHelperProps, sessData, stringify=false) { /* Will be called recursively as data can be nested */ const parseChanges = (schema, origVal, sessVal)=>{ let levelChanges = {}; + parseChanges.depth = _.isUndefined(parseChanges.depth) ? 0 : parseChanges.depth+1; /* The comparator and setter */ const attrChanged = (id, change, force=false)=>{ @@ -131,8 +132,9 @@ function getChangedData(topSchema, viewHelperProps, sessData, stringify=false) { if(stringify && (_.isArray(change) || _.isObject(change))) { change = JSON.stringify(change); } - /* Null values are not passed in URL params, pass it as an empty string */ - if(_.isNull(change)) { + /* Null values are not passed in URL params, pass it as an empty string + Nested values does not need this */ + if(_.isNull(change) && parseChanges.depth === 0) { change = ''; } return levelChanges[id] = change; @@ -234,6 +236,7 @@ function getChangedData(topSchema, viewHelperProps, sessData, stringify=false) { } }); + parseChanges.depth--; return levelChanges; }; @@ -480,7 +483,7 @@ function SchemaDialogView({ /* tell the callbacks the data has changed */ props.onDataChange && props.onDataChange(isDataChanged, changedData); - }, [sessData]); + }, [sessData, formReady]); useEffect(()=>{ if(sessData.__deferred__?.length > 0) { @@ -488,7 +491,6 @@ function SchemaDialogView({ type: SCHEMA_STATE_ACTIONS.CLEAR_DEFERRED_QUEUE, }); - // let deferredDepChang = sessData.__deferred__[0]; let item = sessData.__deferred__[0]; item.promise.then((resFunc)=>{ sessDispatch({ @@ -526,7 +528,6 @@ function SchemaDialogView({ }); setFormReady(true); setLoaderText(''); - }); } else { /* Use the defaults as the initital data */ diff --git a/web/pgadmin/static/js/helpers/legacyConnector.js b/web/pgadmin/static/js/helpers/legacyConnector.js index 9257a8219..2f09c2a19 100644 --- a/web/pgadmin/static/js/helpers/legacyConnector.js +++ b/web/pgadmin/static/js/helpers/legacyConnector.js @@ -47,12 +47,16 @@ export function showFileDialog(dialogParams, onFileSelect) { pgAdmin.FileManager.init(); pgAdmin.FileManager.show_dialog(params); + const onFileSelectClose = (value)=>{ + removeListeners(); + onFileSelect(value); + }; const onDialogClose = ()=>removeListeners(); - pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:' + params.dialog_type, onFileSelect); + pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:' + params.dialog_type, onFileSelectClose); pgAdmin.Browser.Events.on('pgadmin-storage:cancel_btn:' + params.dialog_type, onDialogClose); const removeListeners = ()=>{ - pgAdmin.Browser.Events.off('pgadmin-storage:finish_btn:' + params.dialog_type, onFileSelect); + pgAdmin.Browser.Events.off('pgadmin-storage:finish_btn:' + params.dialog_type, onFileSelectClose); pgAdmin.Browser.Events.off('pgadmin-storage:cancel_btn:' + params.dialog_type, onDialogClose); }; }