Merge pull request #515 from Tert0/master
Add Delete All Button confirmation
This commit is contained in:
commit
fb7d910a1b
|
|
@ -6,7 +6,7 @@
|
|||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"bracketSpacing": false,
|
||||
"jsxBracketSameLine": true,
|
||||
"bracketSameLine": true,
|
||||
"arrowParens": "always",
|
||||
"parser": "typescript"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,7 @@ export default class AddDialog extends Component<IProps, IState> {
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
id="app-dialog"
|
||||
>
|
||||
id="app-dialog">
|
||||
<DialogTitle id="form-dialog-title">Create an application</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
|
|
@ -70,8 +69,7 @@ export default class AddDialog extends Component<IProps, IState> {
|
|||
disabled={!submitEnabled}
|
||||
onClick={submitAndClose}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
variant="contained">
|
||||
Create
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -53,13 +53,11 @@ class Applications extends Component<Stores<'appStore'>> {
|
|||
id="create-app"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => (this.createDialog = true)}
|
||||
>
|
||||
onClick={() => (this.createDialog = true)}>
|
||||
Create Application
|
||||
</Button>
|
||||
}
|
||||
maxWidth={1000}
|
||||
>
|
||||
maxWidth={1000}>
|
||||
<Grid item xs={12}>
|
||||
<Paper elevation={6}>
|
||||
<Table id="app-table">
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ export default class UpdateDialog extends Component<IProps, IState> {
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
id="app-dialog"
|
||||
>
|
||||
id="app-dialog">
|
||||
<DialogTitle id="form-dialog-title">Update an application</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
|
|
@ -80,8 +79,7 @@ export default class UpdateDialog extends Component<IProps, IState> {
|
|||
disabled={!submitEnabled}
|
||||
onClick={submitAndClose}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
variant="contained">
|
||||
Update
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@ export default class AddDialog extends Component<IProps, {name: string}> {
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
id="client-dialog"
|
||||
>
|
||||
id="client-dialog">
|
||||
<DialogTitle id="form-dialog-title">Create a client</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
|
|
@ -47,16 +46,14 @@ export default class AddDialog extends Component<IProps, {name: string}> {
|
|||
<Button onClick={fClose}>Cancel</Button>
|
||||
<Tooltip
|
||||
placement={'bottom-start'}
|
||||
title={submitEnabled ? '' : 'name is required'}
|
||||
>
|
||||
title={submitEnabled ? '' : 'name is required'}>
|
||||
<div>
|
||||
<Button
|
||||
className="create"
|
||||
disabled={!submitEnabled}
|
||||
onClick={submitAndClose}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
variant="contained">
|
||||
Create
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -48,12 +48,10 @@ class Clients extends Component<Stores<'clientStore'>> {
|
|||
id="create-client"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => (this.showDialog = true)}
|
||||
>
|
||||
onClick={() => (this.showDialog = true)}>
|
||||
Create Client
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
}>
|
||||
<Grid item xs={12}>
|
||||
<Paper elevation={6}>
|
||||
<Table id="client-table">
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ export default class UpdateDialog extends Component<IProps, IState> {
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
id="client-dialog"
|
||||
>
|
||||
id="client-dialog">
|
||||
<DialogTitle id="form-dialog-title">Update a Client</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
|
|
@ -69,8 +68,7 @@ export default class UpdateDialog extends Component<IProps, IState> {
|
|||
disabled={!submitEnabled}
|
||||
onClick={submitAndClose}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
variant="contained">
|
||||
Update
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ export default function ConfirmDialog({title, text, fClose, fOnSubmit}: IProps)
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
className="confirm-dialog"
|
||||
>
|
||||
className="confirm-dialog">
|
||||
<DialogTitle id="form-dialog-title">{title}</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>{text}</DialogContentText>
|
||||
|
|
@ -38,8 +37,7 @@ export default function ConfirmDialog({title, text, fClose, fOnSubmit}: IProps)
|
|||
autoFocus
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className="confirm"
|
||||
>
|
||||
className="confirm">
|
||||
Yes
|
||||
</Button>
|
||||
</DialogActions>
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ export const ConnectionErrorBanner = ({height, retry, message}: ConnectionErrorB
|
|||
width: '100%',
|
||||
zIndex: 1300,
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
<Typography align="center" variant="h6" style={{lineHeight: `${height}px`}}>
|
||||
{message}{' '}
|
||||
<Button variant="outlined" onClick={retry}>
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ class ScrollUpButton extends Component {
|
|||
display: this.state.display,
|
||||
opacity: this.state.opacity,
|
||||
}}
|
||||
onClick={this.scrollUp}
|
||||
>
|
||||
onClick={this.scrollUp}>
|
||||
<KeyboardArrowUp />
|
||||
</Fab>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ class SettingsDialog extends Component<IProps & Stores<'currentUser'>> {
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
id="changepw-dialog"
|
||||
>
|
||||
id="changepw-dialog">
|
||||
<DialogTitle id="form-dialog-title">Change Password</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
|
|
@ -55,8 +54,7 @@ class SettingsDialog extends Component<IProps & Stores<'currentUser'>> {
|
|||
disabled={pass.length === 0}
|
||||
onClick={submitAndClose}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
variant="contained">
|
||||
Change
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -106,8 +106,7 @@ class Header extends Component<IProps> {
|
|||
</Link>
|
||||
<a
|
||||
href={'https://github.com/gotify/server/releases/tag/v' + version}
|
||||
className={classes.link}
|
||||
>
|
||||
className={classes.link}>
|
||||
<Typography variant="button" color="inherit">
|
||||
@{version}
|
||||
</Typography>
|
||||
|
|
@ -123,8 +122,7 @@ class Header extends Component<IProps> {
|
|||
href="https://github.com/gotify/server"
|
||||
className={classes.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
rel="noopener noreferrer">
|
||||
<IconButton color="inherit">
|
||||
<GitHubIcon />
|
||||
</IconButton>
|
||||
|
|
|
|||
|
|
@ -57,8 +57,7 @@ class Navigation extends Component<
|
|||
onClick={() => setNavOpen(false)}
|
||||
className={`${classes.link} item`}
|
||||
to={'/messages/' + app.id}
|
||||
key={app.id}
|
||||
>
|
||||
key={app.id}>
|
||||
<ListItem button>
|
||||
<ListItemText primary={app.name} />
|
||||
</ListItem>
|
||||
|
|
@ -79,8 +78,7 @@ class Navigation extends Component<
|
|||
classes={{root: classes.root, paper: classes.drawerPaper}}
|
||||
navOpen={navOpen}
|
||||
setNavOpen={setNavOpen}
|
||||
id="message-navigation"
|
||||
>
|
||||
id="message-navigation">
|
||||
<div className={classes.toolbar} />
|
||||
<Link className={classes.link} to="/" onClick={() => setNavOpen(false)}>
|
||||
<ListItem button disabled={!loggedIn} className="all">
|
||||
|
|
@ -96,8 +94,7 @@ class Navigation extends Component<
|
|||
onClick={() => {
|
||||
requestPermission();
|
||||
this.setState({showRequestNotification: false});
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
Enable Notifications
|
||||
</Button>
|
||||
) : null}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {inject, Stores} from '../inject';
|
|||
import {observable} from 'mobx';
|
||||
import ReactInfinite from 'react-infinite';
|
||||
import {IMessage} from '../types';
|
||||
import ConfirmDialog from '../common/ConfirmDialog';
|
||||
|
||||
type IProps = RouteComponentProps<{id: string}>;
|
||||
|
||||
|
|
@ -22,6 +23,8 @@ interface IState {
|
|||
class Messages extends Component<IProps & Stores<'messagesStore' | 'appStore'>, IState> {
|
||||
@observable
|
||||
private heights: Record<string, number> = {};
|
||||
@observable
|
||||
private deleteAll = false;
|
||||
|
||||
private static appId(props: IProps) {
|
||||
if (props === undefined) {
|
||||
|
|
@ -70,8 +73,7 @@ class Messages extends Component<IProps & Stores<'messagesStore' | 'appStore'>,
|
|||
disabled={!hasMessages}
|
||||
color="primary"
|
||||
onClick={() => messagesStore.refreshByApp(appId)}
|
||||
style={{marginRight: 5}}
|
||||
>
|
||||
style={{marginRight: 5}}>
|
||||
Refresh
|
||||
</Button>
|
||||
<Button
|
||||
|
|
@ -79,21 +81,20 @@ class Messages extends Component<IProps & Stores<'messagesStore' | 'appStore'>,
|
|||
variant="contained"
|
||||
disabled={!hasMessages}
|
||||
color="primary"
|
||||
onClick={() => messagesStore.removeByApp(appId)}
|
||||
>
|
||||
onClick={() => {
|
||||
this.deleteAll = true;
|
||||
}}>
|
||||
Delete All
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
}>
|
||||
{hasMessages ? (
|
||||
<div style={{width: '100%'}} id="messages">
|
||||
<ReactInfinite
|
||||
key={appId}
|
||||
useWindowAsScrollContainer
|
||||
preloadBatchSize={window.innerHeight * 3}
|
||||
elementHeight={messages.map((m) => this.heights[m.id] || 1)}
|
||||
>
|
||||
elementHeight={messages.map((m) => this.heights[m.id] || 1)}>
|
||||
{messages.map(this.renderMessage)}
|
||||
</ReactInfinite>
|
||||
|
||||
|
|
@ -108,6 +109,15 @@ class Messages extends Component<IProps & Stores<'messagesStore' | 'appStore'>,
|
|||
) : (
|
||||
this.label('No messages')
|
||||
)}
|
||||
|
||||
{this.deleteAll && (
|
||||
<ConfirmDialog
|
||||
title="Confirm Delete"
|
||||
text={'Delete all messages?'}
|
||||
fClose={() => (this.deleteAll = false)}
|
||||
fOnSubmit={() => messagesStore.removeByApp(appId)}
|
||||
/>
|
||||
)}
|
||||
</DefaultPage>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,8 +79,7 @@ class PluginDetailView extends Component<IProps & Stores<'pluginStore'>, IState>
|
|||
name={'Configurer'}
|
||||
description={'This is the configuration panel for this plugin.'}
|
||||
icon={Build}
|
||||
refresh={this.refreshConfigurer.bind(this)}
|
||||
>
|
||||
refresh={this.refreshConfigurer.bind(this)}>
|
||||
<ConfigurerPanel
|
||||
pluginInfo={pluginInfo}
|
||||
initialConfig={
|
||||
|
|
@ -100,8 +99,7 @@ class PluginDetailView extends Component<IProps & Stores<'pluginStore'>, IState>
|
|||
name={'Displayer'}
|
||||
description={'This is the information generated by the plugin.'}
|
||||
refresh={this.refreshDisplayer.bind(this)}
|
||||
icon={Subject}
|
||||
>
|
||||
icon={Subject}>
|
||||
<DisplayerPanel
|
||||
pluginInfo={pluginInfo}
|
||||
displayText={
|
||||
|
|
@ -147,8 +145,7 @@ const PanelWrapper: React.FC<IPanelWrapperProps> = ({
|
|||
style={{float: 'right'}}
|
||||
onClick={() => {
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
<Refresh />
|
||||
</Button>
|
||||
) : null}
|
||||
|
|
@ -202,8 +199,7 @@ class ConfigurerPanel extends Component<IConfigurerPanelProps, {unsavedChanges:
|
|||
this.props.save(newConfig!).then(() => {
|
||||
this.setState({unsavedChanges: null});
|
||||
});
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
<Typography variant="button">Save</Typography>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -264,8 +260,7 @@ class PluginInfo extends Component<{pluginInfo: IPlugin}> {
|
|||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="custom-route"
|
||||
>
|
||||
className="custom-route">
|
||||
{url}
|
||||
</a>
|
||||
))(`${config.get('url')}plugin/${id}/custom/${token}/`)}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ class SnackBarHandler extends Component<Stores<'snackManager'>> {
|
|||
key="close"
|
||||
aria-label="Close"
|
||||
color="inherit"
|
||||
onClick={this.closeCurrentSnack}
|
||||
>
|
||||
onClick={this.closeCurrentSnack}>
|
||||
<Close />
|
||||
</IconButton>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,6 +219,8 @@ describe('Messages', () => {
|
|||
it('deletes all linux messages', async () => {
|
||||
await navigate('Linux');
|
||||
await page.click('#delete-all');
|
||||
await page.waitForSelector(selector.$confirmDialog.selector());
|
||||
await page.click(selector.$confirmDialog.button('.confirm'));
|
||||
await page.waitForSelector('#delete-all:disabled');
|
||||
await expectMessages({
|
||||
all: [windows3, backup1, windows1],
|
||||
|
|
@ -250,6 +252,9 @@ describe('Messages', () => {
|
|||
it('deletes all messages', async () => {
|
||||
await navigate('All Messages');
|
||||
await page.click('#delete-all');
|
||||
await page.waitForSelector(selector.$confirmDialog.selector());
|
||||
await page.click(selector.$confirmDialog.button('.confirm'));
|
||||
await page.waitForSelector('#delete-all:disabled');
|
||||
await expectMessages({
|
||||
all: [],
|
||||
windows: [],
|
||||
|
|
@ -269,6 +274,8 @@ describe('Messages', () => {
|
|||
it('deletes all backup messages and navigates to all messages', async () => {
|
||||
await navigate('Backup');
|
||||
await page.click('#delete-all');
|
||||
await page.waitForSelector(selector.$confirmDialog.selector());
|
||||
await page.click(selector.$confirmDialog.button('.confirm'));
|
||||
await page.waitForSelector('#delete-all:disabled');
|
||||
await navigate('All Messages');
|
||||
await createMessage(backup3, backupServerToken);
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ export default class AddEditDialog extends Component<IProps, IState> {
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
id="add-edit-user-dialog"
|
||||
>
|
||||
id="add-edit-user-dialog">
|
||||
<DialogTitle id="form-dialog-title">
|
||||
{isEdit ? 'Edit ' + this.props.name : 'Add a user'}
|
||||
</DialogTitle>
|
||||
|
|
@ -91,16 +90,14 @@ export default class AddEditDialog extends Component<IProps, IState> {
|
|||
? ''
|
||||
: 'password is required'
|
||||
: 'name is required'
|
||||
}
|
||||
>
|
||||
}>
|
||||
<div>
|
||||
<Button
|
||||
className="save-create"
|
||||
disabled={!passPresent || !namePresent}
|
||||
onClick={submitAndClose}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
variant="contained">
|
||||
{isEdit ? 'Save' : 'Create'}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ class Login extends Component<Stores<'currentUser'>> {
|
|||
color="primary"
|
||||
disabled={!!this.props.currentUser.connectionErrorMessage}
|
||||
style={{marginTop: 15, marginBottom: 5}}
|
||||
onClick={this.login}
|
||||
>
|
||||
onClick={this.login}>
|
||||
Login
|
||||
</Button>
|
||||
</form>
|
||||
|
|
@ -81,8 +80,7 @@ class Login extends Component<Stores<'currentUser'>> {
|
|||
id="register"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => (this.registerDialog = true)}
|
||||
>
|
||||
onClick={() => (this.registerDialog = true)}>
|
||||
Register
|
||||
</Button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ export default class RegistrationDialog extends Component<IProps, IState> {
|
|||
open={true}
|
||||
onClose={fClose}
|
||||
aria-labelledby="form-dialog-title"
|
||||
id="add-edit-user-dialog"
|
||||
>
|
||||
id="add-edit-user-dialog">
|
||||
<DialogTitle id="form-dialog-title">Registration</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
|
|
@ -75,16 +74,14 @@ export default class RegistrationDialog extends Component<IProps, IState> {
|
|||
? ''
|
||||
: 'password is required'
|
||||
: 'name is required'
|
||||
}
|
||||
>
|
||||
}>
|
||||
<div>
|
||||
<Button
|
||||
className="save-create"
|
||||
disabled={!passPresent || !namePresent}
|
||||
onClick={submitAndClose}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
>
|
||||
variant="contained">
|
||||
Register
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -75,12 +75,10 @@ class Users extends Component<WithStyles<'wrapper'> & Stores<'userStore'>> {
|
|||
id="create-user"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => (this.createDialog = true)}
|
||||
>
|
||||
onClick={() => (this.createDialog = true)}>
|
||||
Create User
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
}>
|
||||
<Grid item xs={12}>
|
||||
<Paper elevation={6}>
|
||||
<Table id="user-table">
|
||||
|
|
|
|||
Loading…
Reference in New Issue