mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-08 17:27:32 +03:00
Added modal window for server deletion
This commit is contained in:
parent
0de191ac0b
commit
168b24344e
7 changed files with 120 additions and 38 deletions
|
@ -1,45 +1,49 @@
|
||||||
import React from 'react';
|
|
||||||
import { NavLink } from 'react-router-dom';
|
|
||||||
import listIcon from '@fortawesome/fontawesome-free-solid/faBars';
|
import listIcon from '@fortawesome/fontawesome-free-solid/faBars';
|
||||||
import createIcon from '@fortawesome/fontawesome-free-solid/faPlus';
|
import createIcon from '@fortawesome/fontawesome-free-solid/faPlus';
|
||||||
import deleteIcon from '@fortawesome/fontawesome-free-solid/faMinusCircle';
|
|
||||||
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
||||||
|
import React from 'react';
|
||||||
|
import { NavLink } from 'react-router-dom';
|
||||||
|
import DeleteServerButton from '../servers/DeleteServerButton';
|
||||||
import './AsideMenu.scss';
|
import './AsideMenu.scss';
|
||||||
|
|
||||||
export default function AsideMenu({ selectedServer }) {
|
export default class AsideMenu extends React.Component {
|
||||||
const serverId = selectedServer ? selectedServer.id : '';
|
render() {
|
||||||
const isListShortUrlsActive = (match, { pathname }) => {
|
const { selectedServer, history } = this.props;
|
||||||
// FIXME. Should use the 'match' params, but they are not being properly resolved. Investigate
|
const serverId = selectedServer ? selectedServer.id : '';
|
||||||
const serverIdFromPathname = pathname.split('/')[2];
|
const isListShortUrlsActive = (match, { pathname }) => {
|
||||||
return serverIdFromPathname === serverId && pathname.indexOf('list-short-urls') !== -1;
|
// FIXME. Should use the 'match' params, but they are not being properly resolved. Investigate
|
||||||
};
|
const serverIdFromPathname = pathname.split('/')[2];
|
||||||
|
return serverIdFromPathname === serverId && pathname.indexOf('list-short-urls') !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className="aside-menu col-md-2 col-sm-2">
|
<aside className="aside-menu col-md-2 col-sm-2">
|
||||||
<nav className="nav flex-column aside-menu__nav">
|
<nav className="nav flex-column aside-menu__nav">
|
||||||
<NavLink
|
<NavLink
|
||||||
className="aside-menu__item"
|
className="aside-menu__item"
|
||||||
activeClassName="aside-menu__item--selected"
|
activeClassName="aside-menu__item--selected"
|
||||||
to={`/server/${serverId}/list-short-urls/1`}
|
to={`/server/${serverId}/list-short-urls/1`}
|
||||||
isActive={isListShortUrlsActive}
|
isActive={isListShortUrlsActive}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={listIcon} />
|
<FontAwesomeIcon icon={listIcon} />
|
||||||
<span className="aside-menu__item-text">List short URLs</span>
|
<span className="aside-menu__item-text">List short URLs</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<NavLink
|
<NavLink
|
||||||
className="aside-menu__item"
|
className="aside-menu__item"
|
||||||
activeClassName="aside-menu__item--selected"
|
activeClassName="aside-menu__item--selected"
|
||||||
to={`/server/${serverId}/create-short-url`}
|
to={`/server/${serverId}/create-short-url`}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={createIcon} />
|
<FontAwesomeIcon icon={createIcon} />
|
||||||
<span className="aside-menu__item-text">Create short code</span>
|
<span className="aside-menu__item-text">Create short code</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<span className="aside-menu__item--divider" />
|
<span className="aside-menu__item--divider" />
|
||||||
<span className="aside-menu__item aside-menu__item--danger">
|
<DeleteServerButton
|
||||||
<FontAwesomeIcon icon={deleteIcon} />
|
className="aside-menu__item aside-menu__item--danger"
|
||||||
<span className="aside-menu__item-text">Delete this server</span>
|
history={history}
|
||||||
</span>
|
server={selectedServer}
|
||||||
</nav>
|
/>
|
||||||
</aside>
|
</nav>
|
||||||
);
|
</aside>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@import "../utils/base";
|
@import "../utils/base";
|
||||||
|
@import "../utils/mixins/border-radius";
|
||||||
|
|
||||||
.aside-menu {
|
.aside-menu {
|
||||||
position: fixed !important;
|
position: fixed !important;
|
||||||
|
@ -44,6 +45,8 @@
|
||||||
|
|
||||||
.aside-menu__item--danger {
|
.aside-menu__item--danger {
|
||||||
color: $dangerColor;
|
color: $dangerColor;
|
||||||
|
margin: 0;
|
||||||
|
@include border-radius(4px);
|
||||||
}
|
}
|
||||||
.aside-menu__item--danger:hover {
|
.aside-menu__item--danger:hover {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
32
src/servers/DeleteServerButton.js
Normal file
32
src/servers/DeleteServerButton.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import deleteIcon from '@fortawesome/fontawesome-free-solid/faMinusCircle';
|
||||||
|
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
||||||
|
import React from 'react';
|
||||||
|
import DeleteServerModal from './DeleteServerModal';
|
||||||
|
|
||||||
|
export default class DeleteServerButton extends React.Component {
|
||||||
|
state = { isModalOpen: false };
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { history, server } = this.props;
|
||||||
|
|
||||||
|
return [
|
||||||
|
(
|
||||||
|
<span
|
||||||
|
className={this.props.className}
|
||||||
|
onClick={() => this.setState({ isModalOpen: true })}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={deleteIcon} />
|
||||||
|
<span className="aside-menu__item-text">Delete this server</span>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
(
|
||||||
|
<DeleteServerModal
|
||||||
|
isOpen={this.state.isModalOpen}
|
||||||
|
toggle={() => this.setState({ isModalOpen: !this.state.isModalOpen })}
|
||||||
|
history={history}
|
||||||
|
server={server}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
25
src/servers/DeleteServerModal.js
Normal file
25
src/servers/DeleteServerModal.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
|
import { deleteServer } from './reducers/server';
|
||||||
|
|
||||||
|
export const DeleteServerModal = ({ server, deleteServer, toggle, history, isOpen }) => {
|
||||||
|
const closeModal = () => {
|
||||||
|
deleteServer(server);
|
||||||
|
toggle();
|
||||||
|
history.push('/');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} toggle={toggle} centered={true}>
|
||||||
|
<ModalHeader toggle={toggle}>Delete server</ModalHeader>
|
||||||
|
<ModalBody>Are you sure you want to delete server <b>{server ? server.name : ''}</b>.</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<button className="btn btn-link" onClick={toggle}>Cancel</button>
|
||||||
|
<button className="btn btn-danger" onClick={() => closeModal()}>Delete</button>
|
||||||
|
</ModalFooter>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(null, { deleteServer })(DeleteServerModal);
|
|
@ -2,10 +2,12 @@ import ServersService from '../services';
|
||||||
|
|
||||||
const FETCH_SERVERS = 'shlink/servers/FETCH_SERVERS';
|
const FETCH_SERVERS = 'shlink/servers/FETCH_SERVERS';
|
||||||
const CREATE_SERVER = 'shlink/servers/CREATE_SERVER';
|
const CREATE_SERVER = 'shlink/servers/CREATE_SERVER';
|
||||||
|
const DELETE_SERVER = 'shlink/servers/DELETE_SERVER';
|
||||||
|
|
||||||
export default function reducer(state = {}, action) {
|
export default function reducer(state = {}, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case FETCH_SERVERS:
|
case FETCH_SERVERS:
|
||||||
|
case DELETE_SERVER:
|
||||||
return action.servers;
|
return action.servers;
|
||||||
case CREATE_SERVER:
|
case CREATE_SERVER:
|
||||||
const server = action.server;
|
const server = action.server;
|
||||||
|
@ -26,3 +28,8 @@ export const createServer = server => {
|
||||||
ServersService.createServer(server);
|
ServersService.createServer(server);
|
||||||
return listServers();
|
return listServers();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteServer = server => {
|
||||||
|
ServersService.deleteServer(server);
|
||||||
|
return listServers();
|
||||||
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Storage from '../../utils/Storage';
|
import Storage from '../../utils/Storage';
|
||||||
|
import { dissoc } from 'ramda';
|
||||||
|
|
||||||
const SERVERS_STORAGE_KEY = 'servers';
|
const SERVERS_STORAGE_KEY = 'servers';
|
||||||
|
|
||||||
|
@ -21,6 +22,11 @@ export class ServersService {
|
||||||
servers[server.id] = server;
|
servers[server.id] = server;
|
||||||
this.storage.set(SERVERS_STORAGE_KEY, servers);
|
this.storage.set(SERVERS_STORAGE_KEY, servers);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
deleteServer = server => {
|
||||||
|
const servers = dissoc(server.id, this.listServers());
|
||||||
|
this.storage.set(SERVERS_STORAGE_KEY, servers);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new ServersService(Storage);
|
export default new ServersService(Storage);
|
||||||
|
|
5
src/utils/mixins/border-radius.scss
Normal file
5
src/utils/mixins/border-radius.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
@mixin border-radius($radius) {
|
||||||
|
border-radius: $radius;
|
||||||
|
-webkit-border-radius: $radius;
|
||||||
|
-moz-border-radius: $radius;
|
||||||
|
}
|
Loading…
Reference in a new issue