mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-12-22 07:03:56 -06:00
Change button labels and color in delete confirmation dialog for all objects to improve UX. #6513
This commit is contained in:
parent
2ba4f79a46
commit
8af25ba0c1
@ -270,6 +270,8 @@ define('pgadmin.node.database', [
|
||||
t.deselect(item);
|
||||
},
|
||||
function() { return true;},
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel')
|
||||
);
|
||||
}
|
||||
|
||||
@ -557,11 +559,13 @@ define('pgadmin.node.database', [
|
||||
if (notify) {
|
||||
pgAdmin.Browser.notifier.confirm(
|
||||
gettext('Disconnect from database'),
|
||||
gettext('Are you sure you want to disconnect from database - %s?', d.label),
|
||||
gettext('Are you sure you want to disconnect from the database - <b>%s</b>?', d.label),
|
||||
function() {
|
||||
disconnect();
|
||||
},
|
||||
function() { return true; }
|
||||
function() { return true; },
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel')
|
||||
);
|
||||
} else {
|
||||
disconnect();
|
||||
|
@ -259,6 +259,8 @@ define('pgadmin.node.server', [
|
||||
}, 100);
|
||||
},
|
||||
function() { return true;},
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel'),
|
||||
);
|
||||
}
|
||||
return false;
|
||||
@ -862,9 +864,11 @@ define('pgadmin.node.server', [
|
||||
if (notify) {
|
||||
pgAdmin.Browser.notifier.confirm(
|
||||
gettext('Disconnect from server'),
|
||||
gettext('Are you sure you want to disconnect from the server %s?', label),
|
||||
gettext('Are you sure you want to disconnect from the server <b>%s</b>?', label),
|
||||
function() { disconnect(); },
|
||||
function() { return true;},
|
||||
gettext('Disconnect'),
|
||||
gettext('Cancel')
|
||||
);
|
||||
} else {
|
||||
disconnect();
|
||||
|
@ -525,7 +525,7 @@ define('pgadmin.browser.node', [
|
||||
title = gettext('Delete FORCE %s?', obj.label);
|
||||
|
||||
} else if (input.url == 'delete') {
|
||||
msg = gettext('Are you sure you want to delete %s <b>"%s"</b> and all the objects that depend on it?',
|
||||
msg = gettext('Are you sure you want to delete the %s <b>"%s"</b> and all the objects that depend on it?',
|
||||
obj.label.toLowerCase(), d.label);
|
||||
title = gettext('Delete CASCADE %s?', obj.label);
|
||||
|
||||
@ -539,10 +539,10 @@ define('pgadmin.browser.node', [
|
||||
}
|
||||
} else {
|
||||
if (obj.dropAsRemove) {
|
||||
msg = gettext('Are you sure you want to remove %s "%s"?', obj.label.toLowerCase(), d.label);
|
||||
msg = gettext('Are you sure you want to remove the %s <b>"%s"</b>?', obj.label.toLowerCase(), d.label);
|
||||
title = gettext('Remove %s?', obj.label);
|
||||
} else {
|
||||
msg = gettext('Are you sure you want to delete %s <b>"%s"</b>?', obj.label.toLowerCase(), d.label);
|
||||
msg = gettext('Are you sure you want to delete the %s <b>"%s"</b>?', obj.label.toLowerCase(), d.label);
|
||||
title = gettext('Delete %s?', obj.label);
|
||||
}
|
||||
|
||||
@ -555,7 +555,7 @@ define('pgadmin.browser.node', [
|
||||
return;
|
||||
}
|
||||
}
|
||||
pgAdmin.Browser.notifier.confirm(title, msg,
|
||||
pgAdmin.Browser.notifier.confirmDelete(title, msg,
|
||||
function() {
|
||||
getApiInstance().delete(
|
||||
obj.generate_url(i, input.url, d, true),
|
||||
@ -592,7 +592,10 @@ define('pgadmin.browser.node', [
|
||||
}
|
||||
pgAdmin.Browser.notifier.alert(gettext('Error dropping/removing %s: "%s"', obj.label, objName), errmsg);
|
||||
});
|
||||
}
|
||||
},
|
||||
() => {},
|
||||
gettext('Delete'),
|
||||
gettext('Cancel'),
|
||||
);
|
||||
},
|
||||
// Callback for creating script(s) & opening them in Query editor
|
||||
|
@ -197,7 +197,7 @@ export default function CollectionNodeProperties({
|
||||
};
|
||||
|
||||
if (confirm) {
|
||||
pgAdmin.Browser.notifier.confirm(title, msg, dropNodeProperties, null);
|
||||
pgAdmin.Browser.notifier.confirmDelete(title, msg, dropNodeProperties, null, gettext('Delete'), gettext('Cancel'));
|
||||
} else {
|
||||
dropNodeProperties();
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ export default function(basicSettings) {
|
||||
light: '#1e1e1e',
|
||||
contrastText: '#fff',
|
||||
lighter: '#1e1e1e',
|
||||
hoverMain: darken('#da6758', 0.25),
|
||||
hoverBorderColor: darken('#da6758', 0.25),
|
||||
},
|
||||
warning: {
|
||||
main: '#eea236',
|
||||
|
@ -42,6 +42,8 @@ export default function(basicSettings) {
|
||||
main: '#EE7A55',
|
||||
light: '#010B15',
|
||||
contrastText: '#010B15',
|
||||
hoverMain: '#fff',
|
||||
hoverBorderColor: '#fff',
|
||||
},
|
||||
warning: {
|
||||
main: '#F4D35E',
|
||||
|
@ -42,6 +42,8 @@ export default function(basicSettings) {
|
||||
main: '#CC0000',
|
||||
light: '#FAECEC',
|
||||
contrastText: '#fff',
|
||||
hoverMain: darken('#CC0000', 0.25),
|
||||
hoverBorderColor: darken('#CC0000', 0.25),
|
||||
},
|
||||
warning: {
|
||||
main: '#eea236',
|
||||
|
@ -15,7 +15,7 @@ import ShortcutTitle from './ShortcutTitle';
|
||||
import { styled } from '@mui/material/styles';
|
||||
|
||||
|
||||
const StyledButton = styled(Button)(({theme}) => ({
|
||||
const StyledButton = styled(Button)(({theme, color}) => ({
|
||||
'&.Buttons-primaryButton': {
|
||||
border: '1px solid '+theme.palette.primary.main,
|
||||
'&.Mui-disabled': {
|
||||
@ -37,18 +37,19 @@ const StyledButton = styled(Button)(({theme}) => ({
|
||||
}
|
||||
},
|
||||
'&.Buttons-defaultButton': {
|
||||
backgroundColor: theme.palette.default.main,
|
||||
color: theme.palette.default.contrastText,
|
||||
border: '1px solid '+theme.palette.default.borderColor,
|
||||
// Use the color prop to determine the background color and text color.
|
||||
backgroundColor: theme.palette[color]?.main ?? theme.palette.default.main,
|
||||
border: '1px solid '+ theme.palette.default.borderColor,
|
||||
color: theme.palette[color]?.contrastText ?? theme.palette.default.contrastText,
|
||||
whiteSpace: 'nowrap',
|
||||
'&.Mui-disabled': {
|
||||
color: [theme.palette.default.disabledContrastText, '!important'],
|
||||
borderColor: theme.palette.default.disabledBorderColor
|
||||
},
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.default.hoverMain,
|
||||
color: theme.palette.default.hoverContrastText,
|
||||
borderColor: theme.palette.default.hoverBorderColor,
|
||||
backgroundColor: theme.palette[color]?.hoverMain ?? theme.palette.default.hoverMain,
|
||||
color: theme.palette[color]?.contrastText ?? theme.palette.default.hoverContrastText,
|
||||
borderColor: theme.palette[color]?.hoverBorderColor ?? theme.palette.default.hoverBorderColor,
|
||||
},
|
||||
'&.Buttons-noBorder': {
|
||||
border: 0,
|
||||
@ -143,16 +144,19 @@ PrimaryButton.propTypes = {
|
||||
|
||||
/* pgAdmin default button */
|
||||
export const DefaultButton = forwardRef((props, ref)=>{
|
||||
let {children, className, size, noBorder, ...otherProps} = props;
|
||||
let {children, className, size, noBorder, color, ...otherProps} = props;
|
||||
let variant = 'outlined';
|
||||
let allClassName = ['Buttons-defaultButton', className];
|
||||
if(size == 'xs') {
|
||||
size = undefined;
|
||||
allClassName.push('Buttons-xsButton');
|
||||
} else if(color !== 'default'){
|
||||
variant='contained';
|
||||
}
|
||||
noBorder && allClassName.push('Buttons-noBorder');
|
||||
const dataLabel = typeof(children) == 'string' ? children : undefined;
|
||||
return (
|
||||
<StyledButton variant="outlined" ref={ref} size={size} className={allClassName.join(' ')} data-label={dataLabel} color="default" {...otherProps}>{children}</StyledButton>
|
||||
<StyledButton variant={variant} ref={ref} size={size} className={allClassName.join(' ')} data-label={dataLabel} {...otherProps} color={color ?? 'default'} >{children}</StyledButton>
|
||||
);
|
||||
});
|
||||
DefaultButton.displayName = 'DefaultButton';
|
||||
@ -161,6 +165,7 @@ DefaultButton.propTypes = {
|
||||
noBorder: PropTypes.bool,
|
||||
children: CustomPropTypes.children,
|
||||
className: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||
color: PropTypes.string,
|
||||
};
|
||||
|
||||
|
||||
|
@ -44,11 +44,11 @@ export function useModal() {
|
||||
function renderExtraButtons(button) {
|
||||
switch(button.type) {
|
||||
case 'primary':
|
||||
return <PrimaryButton className='Alert-margin' startIcon={button.icon} onClick={button.onclick}>{button.label}</PrimaryButton>;
|
||||
return <PrimaryButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick}>{button.label}</PrimaryButton>;
|
||||
case 'default':
|
||||
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onclick}>{button.label}</DefaultButton>;
|
||||
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick} color={button?.color}>{button.label}</DefaultButton>;
|
||||
default:
|
||||
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onclick}>{button.label}</DefaultButton>;
|
||||
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onClick}>{button.label}</DefaultButton>;
|
||||
};
|
||||
}
|
||||
|
||||
@ -58,13 +58,13 @@ function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = ge
|
||||
<Box flexGrow="1" p={2}>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
|
||||
<Box className='Alert-footer'>
|
||||
{confirm &&
|
||||
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick} >{cancelLabel}</DefaultButton>
|
||||
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick} autoFocus={true}>{cancelLabel}</DefaultButton>
|
||||
}
|
||||
{
|
||||
extraButtons?.length ?
|
||||
extraButtons.map(button=>renderExtraButtons(button))
|
||||
:
|
||||
<PrimaryButton className='Alert-margin' startIcon={<CheckRoundedIcon />} onClick={onOkClick} autoFocus={true} >{okLabel}</PrimaryButton>
|
||||
<PrimaryButton className='Alert-margin' startIcon={<CheckRoundedIcon />} onClick={onOkClick}>{okLabel}</PrimaryButton>
|
||||
}
|
||||
</Box>
|
||||
</StyledBox>
|
||||
@ -100,17 +100,17 @@ function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes')
|
||||
onCancelClick?.();
|
||||
closeModal();
|
||||
};
|
||||
|
||||
const onOkClickClose = () => {
|
||||
onOkClick?.();
|
||||
closeModal();
|
||||
};
|
||||
const extraButtons = extras?.(closeModal);
|
||||
const extraButtons = extras?.(closeModal);
|
||||
return (
|
||||
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} extraButtons={extraButtons} />
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export default function ModalProvider({ children }) {
|
||||
const [modals, setModals] = React.useState([]);
|
||||
|
||||
|
@ -181,6 +181,25 @@ class Notifier {
|
||||
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, extras);
|
||||
}
|
||||
|
||||
confirmDelete(title, text, onOkClick, onCancelClick,okLabel = gettext('Yes'), cancelLabel = gettext('No')){
|
||||
|
||||
const extraButtons = (closeModal) => {
|
||||
return [
|
||||
{
|
||||
type: 'default',
|
||||
icon: <CheckRoundedIcon />,
|
||||
label: okLabel,
|
||||
onClick: ()=>{
|
||||
onOkClick();
|
||||
closeModal();
|
||||
},
|
||||
color: 'error',
|
||||
},
|
||||
];
|
||||
};
|
||||
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, extraButtons);
|
||||
}
|
||||
|
||||
showModal(title, content, modalOptions) {
|
||||
this.modal.showModal(title, content, modalOptions);
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ export default class ERDTool extends React.Component {
|
||||
}
|
||||
|
||||
onDeleteNode() {
|
||||
pgAdmin.Browser.notifier.confirm(
|
||||
pgAdmin.Browser.notifier.confirmDelete(
|
||||
gettext('Delete ?'),
|
||||
gettext('You have selected %s tables and %s links.', this.diagram.getSelectedNodes().length, this.diagram.getSelectedLinks().length)
|
||||
+ '<br />' + gettext('Are you sure you want to delete ?'),
|
||||
@ -516,7 +516,9 @@ export default class ERDTool extends React.Component {
|
||||
}
|
||||
this.diagram.repaint();
|
||||
},
|
||||
() => {/*This is intentional (SonarQube)*/}
|
||||
() => {/*This is intentional (SonarQube)*/},
|
||||
gettext('Delete'),
|
||||
gettext('Cancel'),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ class PgadminPage:
|
||||
self.click_element(self.find_by_css_selector(
|
||||
"li[data-label='Remove Server']"))
|
||||
self.driver.switch_to.default_content()
|
||||
self.click_modal('Yes')
|
||||
self.click_modal('Delete')
|
||||
time.sleep(1)
|
||||
else:
|
||||
print(server_config['name'] + " server is not removed",
|
||||
|
@ -28,7 +28,7 @@ describe('components Buttons', ()=>{
|
||||
let ThemedBtn = withTheme(DefaultButton);
|
||||
render(<ThemedBtn className="testClass">Test</ThemedBtn>);
|
||||
const btn = screen.getByRole('button');
|
||||
expect(btn.classList.contains('MuiButton-outlined')).toBe(true);
|
||||
expect(btn.classList.contains('MuiButton-outlined')).toBe(false);
|
||||
expect(btn.classList.contains('testClass')).toBe(true);
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user