diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.ui.js index 7ca1a7fc7..fc1abdc91 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/static/js/fts_configuration.ui.js @@ -16,14 +16,15 @@ class TokenHeaderSchema extends BaseUISchema { constructor(tokenOptions) { super({ token: undefined, + isNew: false, }); this.tokenOptions = tokenOptions; - this.isNewFTSConf = true; } - addDisabled() { - return this.isNewFTSConf; + set isNewFTSConf(flag) { + if (!this.state) return; + this.state.data = {...this.state.data, isNew: flag}; } getNewData(data) { @@ -36,8 +37,14 @@ class TokenHeaderSchema extends BaseUISchema { get baseFields() { let obj = this; return [{ - id: 'token', label: gettext('Tokens'), type:'select', editable: false, - options: this.tokenOptions, disabled: function() { return obj.isNewFTSConf; } + id: 'token', label: gettext('Tokens'), deps: ['isNew'], + type: () => ({ + type: 'select', + options: this.tokenOptions, + }), + disabled: function() { return obj.isNewFTSConf; } + }, { + id: 'isNew', visible: false, type: 'text', }]; } } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.ui.js index dea0b1b1f..eaceecfaa 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/rules/static/js/rule.ui.js @@ -13,10 +13,15 @@ import BaseUISchema from 'sources/SchemaView/base_schema.ui'; export default class RuleSchema extends BaseUISchema { constructor(fieldOptions={}) { + const schemaNode = fieldOptions?.nodeInfo['schema']; + const schema = schemaNode?.label || ''; + const view = fieldOptions?.nodeData?.label; + super({ oid: undefined, name: undefined, - schema: undefined + schema: schema, + view: view, }); this.fieldOptions = { @@ -42,7 +47,11 @@ export default class RuleSchema extends BaseUISchema { if (state.name == '_RETURN') { return true; } - return !(obj.isNew(state) || obj.fieldOptions.nodeInfo.server.version >= 90400); + + return !( + obj.isNew(state) || + obj.fieldOptions.nodeInfo.server.version >= 90400 + ); }, noEmpty: true }, { @@ -50,25 +59,18 @@ export default class RuleSchema extends BaseUISchema { type: 'text', mode: ['properties'], }, { - id: 'schema', label:'', - type: 'text', visible: false, disabled: (state) => { - // It is used while generating sql - state.schema = ('schema' in obj.fieldOptions.nodeInfo) ? obj.fieldOptions.nodeInfo.schema.label : ''; - }, + id: 'schema', label:'', type: 'text', visible: false, }, { - id: 'view', label:'', - type: 'text', visible: false, disabled: (state) => { - // It is used while generating sql - state.view = obj.fieldOptions.nodeData.label; - }, + id: 'view', label:'', type: 'text', visible: false, }, { id: 'is_enable_rule', label: gettext('Rule enabled?'), mode: ['edit', 'properties'], group: gettext('Definition'), type: 'select', disabled: () => { - return 'catalog' in obj.fieldOptions.nodeInfo || 'view' in obj.fieldOptions.nodeInfo; + return 'catalog' in obj.fieldOptions.nodeInfo || + 'view' in obj.fieldOptions.nodeInfo; }, options: [ {label: gettext('Enable'), value: 'O'}, @@ -90,13 +92,12 @@ export default class RuleSchema extends BaseUISchema { ], }, { - id: 'do_instead', label: gettext('Do instead?'), group: gettext('Definition'), - type: 'switch', + id: 'do_instead', label: gettext('Do instead?'), type: 'switch', + group: gettext('Definition'), }, { id: 'condition', label: gettext('Condition'), type: 'sql', isFullTab: true, group: gettext('Condition'), - }, { id: 'statements', label: gettext('Commands'), @@ -107,7 +108,8 @@ export default class RuleSchema extends BaseUISchema { type: 'switch', mode: ['properties'], }, { - id: 'comment', label: gettext('Comment'), cell: 'text', type: 'multiline', + id: 'comment', label: gettext('Comment'), cell: 'text', + type: 'multiline', }, ]; } diff --git a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.ui.js b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.ui.js index 8ab594d20..f363df4ea 100644 --- a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.ui.js +++ b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.ui.js @@ -165,6 +165,8 @@ export default class RoleSchema extends BaseUISchema { disabled: obj.readOnly, mode: ['edit', 'create'], cell: 'text', type: 'collection', + canDelete: (state) => !obj.readOnly(state), + canDeleteRow: true, schema: obj.membershipSchema, helpMessage: obj.isReadOnly ? gettext('Select the checkbox for roles to include WITH ADMIN OPTION.') : gettext('Roles shown with a check mark have the WITH ADMIN OPTION set.'), }, @@ -185,7 +187,9 @@ export default class RoleSchema extends BaseUISchema { type: 'collection', schema: obj.membershipSchema, disabled: obj.readOnly, - helpMessage: obj.isReadOnly ? gettext('Select the checkbox for roles to include WITH ADMIN OPTION.') : gettext('Roles shown with a check mark have the WITH ADMIN OPTION set.') , + canDelete: (state) => !obj.readOnly(state), + canDeleteRow: true, + helpMessage: obj.isReadOnly ? gettext('Select the checkbox for roles to include WITH ADMIN OPTION.') : gettext('Roles shown with a check mark have the WITH ADMIN OPTION set.'), }, { id: 'rolmembers', label: gettext('Members'), group: gettext('Membership'), diff --git a/web/pgadmin/misc/cloud/static/js/azure_schema.ui.js b/web/pgadmin/misc/cloud/static/js/azure_schema.ui.js index de1a059b4..1ca89769e 100644 --- a/web/pgadmin/misc/cloud/static/js/azure_schema.ui.js +++ b/web/pgadmin/misc/cloud/static/js/azure_schema.ui.js @@ -101,31 +101,34 @@ class AzureCredSchema extends BaseUISchema { helpMessage: gettext( 'After clicking the button above you will be redirected to the Microsoft Azure authentication page in a new browser tab if the Interactive Browser option is selected.' ), - depChange: (state, source)=> { - if(source == 'auth_type' || source == 'azure_tenant_id'){ - return {is_authenticated: false, auth_code: ''}; - } - if(source == 'auth_btn') { - return {is_authenticating: true}; - } - }, - deferredDepChange: (state, source)=>{ - return new Promise((resolve, reject)=>{ - /* button clicked */ - if(source == 'auth_btn') { - obj.fieldOptions.authenticateAzure(state.auth_type, state.azure_tenant_id) - .then(()=>{ - resolve(()=>({ - is_authenticated: true, - is_authenticating: false, - auth_code: '' - })); - }) - .catch((err)=>{ - reject(err instanceof Error ? err : Error(gettext('Something went wrong'))); - }); - } - }); + onClick: () => { + const schemaState = obj.state; + if (!schemaState) return; + + const state = schemaState.data; + const setSchemaData = (data) => { + schemaState.data = {...schemaState.data, ...data}; + }; + + setTimeout(() => { + setSchemaData({is_authenticating: true}); + + obj.fieldOptions.authenticateAzure( + state.auth_type, state.azure_tenant_id + ).then(() => { + setSchemaData({ + is_authenticated: true, + is_authenticating: false, + auth_code: '' + }); + }).catch((err) => { + // TODO:: Show error message. + console.error( + err instanceof Error ? + err : Error(gettext('Something went wrong')) + ); + }); + }, 0); }, disabled: (state)=> { if(state.auth_type == 'interactive_browser_credential' && state.azure_tenant_id == ''){ diff --git a/web/pgadmin/misc/cloud/static/js/google_schema.ui.js b/web/pgadmin/misc/cloud/static/js/google_schema.ui.js index b6d75c60c..dc97c6b90 100644 --- a/web/pgadmin/misc/cloud/static/js/google_schema.ui.js +++ b/web/pgadmin/misc/cloud/static/js/google_schema.ui.js @@ -55,33 +55,30 @@ class GoogleCredSchema extends BaseUISchema{ disabled: (state)=>{ return !state.client_secret_file; }, - deferredDepChange: (state, source)=>{ - return new Promise((resolve, reject)=>{ - /* button clicked */ - if(source == 'auth_btn') { - obj.fieldOptions.authenticateGoogle(state.client_secret_file) - .then((apiRes)=>{ - resolve(()=>{ - if(apiRes){ - obj.fieldOptions.verification_ack() - .then(()=>{ - resolve(); - }) - .catch((err)=>{ - reject(err instanceof Error ? err : Error(gettext('Something went wrong'))); - }); - } - }); - }) - .catch((err)=>{ - reject(err instanceof Error ? err : Error(gettext('Something went wrong'))); - }); - } - }); - } - } - ];} + onClick: () => { + const schemaState = obj.state; + if (!schemaState) return; + const state = schemaState.data; + + setTimeout(() => { + obj.fieldOptions.authenticateGoogle(state.client_secret_file) + .then((apiRes) => { + if(apiRes) { + obj.fieldOptions.verification_ack(); + } + }).catch((err) => { + // FIXME:: Show error message. + console.error( + err instanceof Error ? + err : Error(gettext('Something went wrong')) + ); + }); + }, 0); + }, + }, + ]; + } } class GoogleProjectDetailsSchema extends BaseUISchema { diff --git a/web/pgadmin/misc/properties/ObjectNodeProperties.jsx b/web/pgadmin/misc/properties/ObjectNodeProperties.jsx index 99ee891b2..7968a97b1 100644 --- a/web/pgadmin/misc/properties/ObjectNodeProperties.jsx +++ b/web/pgadmin/misc/properties/ObjectNodeProperties.jsx @@ -242,6 +242,10 @@ export default function ObjectNodeProperties({panelId, node, treeNodeInfo, nodeD return nodeData?._id + '-' + staleCounter.current; }, [isActive, nodeData?._id, isStale]); + if(!isActive && actionType == 'properties') { + return <>; + } + /* Fire at will, mount the DOM */ return ( ({ '& .DataGridFormHeader-border': { ...theme.mixins.panelBorder, borderBottom: 0, + '& .DataGridFormHeader-gridHeader': { + display: 'flex', + flexWrap: 'wrap', + }, + '& .DataGridView-gridHeaderText': { + padding: theme.spacing(0.5, 1), + fontWeight: theme.typography.fontWeightBold, + }, + '& .DataGridFormHeader-gridHeader-search': { + flex: 1, + padding: 0, + display: 'flex', + }, '& .DataGridFormHeader-body': { padding: '0', backgroundColor: theme.palette.grey[400], @@ -125,9 +138,9 @@ export function DataGridFormHeader({tableEleRef}) { return ( - + {label && {label}} - + diff --git a/web/pgadmin/static/js/SchemaView/DataGridView/mappedCell.jsx b/web/pgadmin/static/js/SchemaView/DataGridView/mappedCell.jsx index 1c29fa228..353169e6a 100644 --- a/web/pgadmin/static/js/SchemaView/DataGridView/mappedCell.jsx +++ b/web/pgadmin/static/js/SchemaView/DataGridView/mappedCell.jsx @@ -43,7 +43,9 @@ export function getMappedCell({field}) { subscriberManager.current?.signal(...args); }; - listenDepChanges( + + + const depVals = listenDepChanges( colAccessPath, field, schemaState, rerenderCellOnDepChange ); @@ -98,13 +100,9 @@ export function getMappedCell({field}) { props.cell = 'unknown'; } - const memDeps = [ - ...flatternObject(colOptions), value, row.index, - field?.deps?.map((dep) => rowValue[dep]) - ]; - return useMemo( - () => , memDeps + () => , + [...(depVals || []), ...flatternObject(colOptions), value, row.index] ); }; diff --git a/web/pgadmin/static/js/SchemaView/FormView.jsx b/web/pgadmin/static/js/SchemaView/FormView.jsx index 2a16dfec7..e82b094aa 100644 --- a/web/pgadmin/static/js/SchemaView/FormView.jsx +++ b/web/pgadmin/static/js/SchemaView/FormView.jsx @@ -101,6 +101,7 @@ export default function FormView({ 'select:not(disabled)', 'textarea', '[tabindex]:not([tabindex="-1"]):not([data-test="tabpanel"])', + 'div[class="cm-content"]:not([aria-readonly="true"])', ].join(', ')); if (firstFocussableElement) firstFocussableElement.focus(); diff --git a/web/pgadmin/static/js/SchemaView/SchemaDialogView.jsx b/web/pgadmin/static/js/SchemaView/SchemaDialogView.jsx index 7a9da51ba..b13fc5af9 100644 --- a/web/pgadmin/static/js/SchemaView/SchemaDialogView.jsx +++ b/web/pgadmin/static/js/SchemaView/SchemaDialogView.jsx @@ -7,7 +7,7 @@ // ////////////////////////////////////////////////////////////// -import React, { useEffect, useMemo } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import CloseIcon from '@mui/icons-material/Close'; import DoneIcon from '@mui/icons-material/Done'; @@ -47,6 +47,7 @@ export default function SchemaDialogView({ }) { // View helper properties const onDataChange = props.onDataChange; + const [resetKey, setResetKey] = useState(0); // Schema data state manager const {schemaState, dataDispatch, reset} = useSchemaState({ @@ -55,6 +56,11 @@ export default function SchemaDialogView({ loadingText, }); + const resetView = () => { + reset(); + setResetKey(Date.now()); + }; + // Is saving operation in progress? const setSaving = (val) => schemaState.isSaving = val; const setLoaderText = (val) => schemaState.setMessage(val); @@ -68,26 +74,13 @@ export default function SchemaDialogView({ const Notifier = props.Notifier || pgAdmin.Browser.notifier; useEffect(() => { - /* - * Docker on load focusses itself, so our focus should execute later. - */ - let focusTimeout = setTimeout(()=>{ - }, 250); - - // Clear the focus timeout if unmounted. - return () => { - clearTimeout(focusTimeout); - }; - }, []); - - useEffect(()=>{ if (!props.resetKey) return; - reset(); + resetView(); }, [props.resetKey]); const onResetClick = () => { const resetIt = () => { - reset(); + resetView(); return true; }; @@ -194,7 +187,7 @@ export default function SchemaDialogView({ hasSQLTab={props.hasSQL} getSQLValue={getSQLValue} isTabView={isTabView} className={props.formClassName} - showError={true} resetKey={props.resetKey} + showError={true} resetKey={resetKey} focusOnFirstInput={true} /> @@ -235,7 +228,7 @@ export default function SchemaDialogView({ } - , [schema._id, viewHelperProps.mode] + , [schema._id, viewHelperProps.mode, resetKey] ); } diff --git a/web/pgadmin/static/js/SchemaView/SchemaState/reducer.js b/web/pgadmin/static/js/SchemaView/SchemaState/reducer.js index f80f815c9..dca8a1eac 100644 --- a/web/pgadmin/static/js/SchemaView/SchemaState/reducer.js +++ b/web/pgadmin/static/js/SchemaView/SchemaState/reducer.js @@ -64,7 +64,9 @@ export const sessDataReducer = (state, action) => { _.set(data, action.path, action.value); // If there is any dep listeners get the changes. data = getDepChange(action.path, data, state, action); - deferredList = getDeferredDepChange(action.path, data, state, action); + deferredList = getDeferredDepChange( + action.path, _.cloneDeep(data), state, action + ); data.__deferred__ = deferredList || []; break; diff --git a/web/pgadmin/static/js/SchemaView/utils/createFieldControls.jsx b/web/pgadmin/static/js/SchemaView/utils/createFieldControls.jsx index 0bf5867da..79b88819a 100644 --- a/web/pgadmin/static/js/SchemaView/utils/createFieldControls.jsx +++ b/web/pgadmin/static/js/SchemaView/utils/createFieldControls.jsx @@ -76,7 +76,7 @@ export const createFieldControls = ({ const { visible } = schemaState.options(accessPath.concat(field.id)); currentGroup = createGroup( - field.id, field.label, visible, field, true + field.id, field.group || field.label, visible, field, true ); } else { const { group } = field; diff --git a/web/pgadmin/static/js/components/SearchInputText.jsx b/web/pgadmin/static/js/components/SearchInputText.jsx index 51cd06b3c..d222e003c 100644 --- a/web/pgadmin/static/js/components/SearchInputText.jsx +++ b/web/pgadmin/static/js/components/SearchInputText.jsx @@ -31,11 +31,14 @@ export const SearchInputText = ({ placeholder: placeholder || gettext('Search'), style: { width: size == SEARCH_INPUT_SIZE.FULL ? '100%' : '50%', - float: alignment == SEARCH_INPUT_ALIGNMENT.RIGHT ? 'right' : 'left', }, value: searchText, onChange, }; + if (alignment == SEARCH_INPUT_ALIGNMENT.RIGHT) + props.style['margin-left'] = 'auto'; + else + props.style['margin-right'] = 'auto'; return ; }; diff --git a/web/pgadmin/tools/maintenance/static/js/maintenance.ui.js b/web/pgadmin/tools/maintenance/static/js/maintenance.ui.js index 79913fad4..a1bb97fff 100644 --- a/web/pgadmin/tools/maintenance/static/js/maintenance.ui.js +++ b/web/pgadmin/tools/maintenance/static/js/maintenance.ui.js @@ -395,6 +395,7 @@ export default class MaintenanceSchema extends BaseUISchema { label: gettext('Type of objects'), schema: obj.getVacuumSchema(), group: gettext('Options'), + deps: ['op'], visible: function(state) { if (state?.op == 'ANALYZE') { return obj?.nodeInfo?.server?.version >= 120000;