mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-22 17:10:26 +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 createIcon from '@fortawesome/fontawesome-free-solid/faPlus';
|
||||
import deleteIcon from '@fortawesome/fontawesome-free-solid/faMinusCircle';
|
||||
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
||||
import React from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import DeleteServerButton from '../servers/DeleteServerButton';
|
||||
import './AsideMenu.scss';
|
||||
|
||||
export default function AsideMenu({ selectedServer }) {
|
||||
const serverId = selectedServer ? selectedServer.id : '';
|
||||
const isListShortUrlsActive = (match, { pathname }) => {
|
||||
// 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;
|
||||
};
|
||||
export default class AsideMenu extends React.Component {
|
||||
render() {
|
||||
const { selectedServer, history } = this.props;
|
||||
const serverId = selectedServer ? selectedServer.id : '';
|
||||
const isListShortUrlsActive = (match, { pathname }) => {
|
||||
// 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 (
|
||||
<aside className="aside-menu col-md-2 col-sm-2">
|
||||
<nav className="nav flex-column aside-menu__nav">
|
||||
<NavLink
|
||||
className="aside-menu__item"
|
||||
activeClassName="aside-menu__item--selected"
|
||||
to={`/server/${serverId}/list-short-urls/1`}
|
||||
isActive={isListShortUrlsActive}
|
||||
>
|
||||
<FontAwesomeIcon icon={listIcon} />
|
||||
<span className="aside-menu__item-text">List short URLs</span>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
className="aside-menu__item"
|
||||
activeClassName="aside-menu__item--selected"
|
||||
to={`/server/${serverId}/create-short-url`}
|
||||
>
|
||||
<FontAwesomeIcon icon={createIcon} />
|
||||
<span className="aside-menu__item-text">Create short code</span>
|
||||
</NavLink>
|
||||
<span className="aside-menu__item--divider" />
|
||||
<span className="aside-menu__item aside-menu__item--danger">
|
||||
<FontAwesomeIcon icon={deleteIcon} />
|
||||
<span className="aside-menu__item-text">Delete this server</span>
|
||||
</span>
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
return (
|
||||
<aside className="aside-menu col-md-2 col-sm-2">
|
||||
<nav className="nav flex-column aside-menu__nav">
|
||||
<NavLink
|
||||
className="aside-menu__item"
|
||||
activeClassName="aside-menu__item--selected"
|
||||
to={`/server/${serverId}/list-short-urls/1`}
|
||||
isActive={isListShortUrlsActive}
|
||||
>
|
||||
<FontAwesomeIcon icon={listIcon} />
|
||||
<span className="aside-menu__item-text">List short URLs</span>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
className="aside-menu__item"
|
||||
activeClassName="aside-menu__item--selected"
|
||||
to={`/server/${serverId}/create-short-url`}
|
||||
>
|
||||
<FontAwesomeIcon icon={createIcon} />
|
||||
<span className="aside-menu__item-text">Create short code</span>
|
||||
</NavLink>
|
||||
<span className="aside-menu__item--divider" />
|
||||
<DeleteServerButton
|
||||
className="aside-menu__item aside-menu__item--danger"
|
||||
history={history}
|
||||
server={selectedServer}
|
||||
/>
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@import "../utils/base";
|
||||
@import "../utils/mixins/border-radius";
|
||||
|
||||
.aside-menu {
|
||||
position: fixed !important;
|
||||
|
@ -44,6 +45,8 @@
|
|||
|
||||
.aside-menu__item--danger {
|
||||
color: $dangerColor;
|
||||
margin: 0;
|
||||
@include border-radius(4px);
|
||||
}
|
||||
.aside-menu__item--danger:hover {
|
||||
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 CREATE_SERVER = 'shlink/servers/CREATE_SERVER';
|
||||
const DELETE_SERVER = 'shlink/servers/DELETE_SERVER';
|
||||
|
||||
export default function reducer(state = {}, action) {
|
||||
switch (action.type) {
|
||||
case FETCH_SERVERS:
|
||||
case DELETE_SERVER:
|
||||
return action.servers;
|
||||
case CREATE_SERVER:
|
||||
const server = action.server;
|
||||
|
@ -26,3 +28,8 @@ export const createServer = server => {
|
|||
ServersService.createServer(server);
|
||||
return listServers();
|
||||
};
|
||||
|
||||
export const deleteServer = server => {
|
||||
ServersService.deleteServer(server);
|
||||
return listServers();
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Storage from '../../utils/Storage';
|
||||
import { dissoc } from 'ramda';
|
||||
|
||||
const SERVERS_STORAGE_KEY = 'servers';
|
||||
|
||||
|
@ -21,6 +22,11 @@ export class ServersService {
|
|||
servers[server.id] = server;
|
||||
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);
|
||||
|
|
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