Don't show 'Types of objects' for the 'Cluster' operation. Fixes #7884

This commit is contained in:
Ashesh Vashi 2024-09-18 07:48:09 +05:30 committed by GitHub
parent a361fd94ff
commit 441cc57bb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 132 additions and 104 deletions

View File

@ -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',
}];
}
}

View File

@ -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',
},
];
}

View File

@ -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,6 +187,8 @@ export default class RoleSchema extends BaseUISchema {
type: 'collection',
schema: obj.membershipSchema,
disabled: obj.readOnly,
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.'),
},
{

View File

@ -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(()=>({
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)=>{
reject(err instanceof Error ? err : Error(gettext('Something went wrong')));
});
}
}).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 == ''){

View File

@ -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') {
onClick: () => {
const schemaState = obj.state;
if (!schemaState) return;
const state = schemaState.data;
setTimeout(() => {
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')));
});
obj.fieldOptions.verification_ack();
}
}).catch((err) => {
// FIXME:: Show error message.
console.error(
err instanceof Error ?
err : Error(gettext('Something went wrong'))
);
});
})
.catch((err)=>{
reject(err instanceof Error ? err : Error(gettext('Something went wrong')));
});
}, 0);
},
},
];
}
});
}
}
];}
}
class GoogleProjectDetailsSchema extends BaseUISchema {

View File

@ -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 (
<SchemaView

View File

@ -36,6 +36,19 @@ const StyledBox = styled(Box)(({theme}) => ({
'& .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 (
<StyledBox>
<Box className='DataGridFormHeader-border'>
<Box className='DataGridView-gridHeader'>
<Box className='DataGridFormHeader-gridHeader'>
{label && <Box className='DataGridView-gridHeaderText'>{label}</Box>}
<Box className='DataGridView-gridHeaderText' style={{flex: 1}}>
<Box className='DataGridFormHeader-gridHeader-search'>
<SearchBox/>
</Box>
</Box>

View File

@ -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(
() => <MappedCellControl {...props}/>, memDeps
() => <MappedCellControl {...props}/>,
[...(depVals || []), ...flatternObject(colOptions), value, row.index]
);
};

View File

@ -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();

View File

@ -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);
@ -67,27 +73,14 @@ export default function SchemaDialogView({
const pgAdmin = usePgAdmin();
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}
/>
</Box>
@ -235,7 +228,7 @@ export default function SchemaDialogView({
</Box>
}
</SchemaStateContext.Provider>
</StyledBox>, [schema._id, viewHelperProps.mode]
</StyledBox>, [schema._id, viewHelperProps.mode, resetKey]
);
}

View File

@ -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;

View File

@ -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;

View File

@ -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 <InputText {...props}/>;
};

View File

@ -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;