Skip to content

Commit 0094ca5

Browse files
sozercanprydonius
authored andcommitted
Delete confirmation dialog (#63)
* add deprovision * add confirmDialog component * remove delete url * integrate confirmDialog with deprovision button * setting modal style * add apprepolistitem and confirm dialog for apprepolist * danger! * review changes
1 parent fefc313 commit 0094ca5

File tree

6 files changed

+180
-30
lines changed

6 files changed

+180
-30
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"@types/react-router-dom": "^4.2.3",
5555
"@types/react-router-redux": "^5.0.11",
5656
"@types/react-test-renderer": "^16.0.0",
57-
"husky": "^0.14.3",
57+
"husky": "0.14.3",
5858
"lint-staged": "^6.1.0",
5959
"prettier": "^1.10.2",
6060
"tslint": "^5.9.1",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as React from "react";
2+
import { IAppRepository } from "shared/types";
3+
import ConfirmDialog from "../ConfirmDialog";
4+
5+
interface IAppRepoListItemProps {
6+
repo: IAppRepository;
7+
deleteRepo: (name: string) => Promise<any>;
8+
resyncRepo: (name: string) => Promise<any>;
9+
}
10+
11+
interface IAppRepoListItemState {
12+
modalIsOpen: boolean;
13+
}
14+
15+
export class AppRepoListItem extends React.Component<IAppRepoListItemProps, IAppRepoListItemState> {
16+
public state: IAppRepoListItemState = {
17+
modalIsOpen: false,
18+
};
19+
20+
public render() {
21+
const { repo } = this.props;
22+
return (
23+
<tr key={repo.metadata.name}>
24+
<td>{repo.metadata.name}</td>
25+
<td>{repo.spec && repo.spec.url}</td>
26+
<td>
27+
<ConfirmDialog
28+
onConfirm={this.handleDeleteClick(repo.metadata.name)}
29+
modalIsOpen={this.state.modalIsOpen}
30+
closeModal={this.closeModal}
31+
/>
32+
33+
<button className="button button-secondary" onClick={this.openModel}>
34+
Delete
35+
</button>
36+
37+
<button
38+
className="button button-secondary"
39+
onClick={this.handleResyncClick(repo.metadata.name)}
40+
>
41+
Refresh
42+
</button>
43+
</td>
44+
</tr>
45+
);
46+
}
47+
48+
public openModel = () => {
49+
this.setState({
50+
modalIsOpen: true,
51+
});
52+
};
53+
54+
public closeModal = async () => {
55+
this.setState({
56+
modalIsOpen: false,
57+
});
58+
};
59+
60+
private handleDeleteClick(repoName: string) {
61+
return async () => {
62+
this.props.deleteRepo(repoName);
63+
this.setState({ modalIsOpen: false });
64+
};
65+
}
66+
67+
private handleResyncClick(repoName: string) {
68+
return () => {
69+
this.props.resyncRepo(repoName);
70+
};
71+
}
72+
}

src/components/AppRepoList/index.tsx

+10-26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from "react";
22

33
import { IAppRepository } from "../../shared/types";
44
import { AppRepoAddButton } from "./AppRepoButton";
5+
import { AppRepoListItem } from "./AppRepoListItem";
56

67
export interface IAppRepoListProps {
78
repos: IAppRepository[];
@@ -17,7 +18,7 @@ export class AppRepoList extends React.Component<IAppRepoListProps> {
1718
}
1819

1920
public render() {
20-
const { repos, install } = this.props;
21+
const { repos, install, deleteRepo, resyncRepo } = this.props;
2122
return (
2223
<div className="app-repo-list">
2324
<h1>App Repositories</h1>
@@ -30,35 +31,18 @@ export class AppRepoList extends React.Component<IAppRepoListProps> {
3031
</tr>
3132
</thead>
3233
<tbody>
33-
{repos.map(repo => {
34-
return (
35-
<tr key={repo.metadata.name}>
36-
<td>{repo.metadata.name}</td>
37-
<td>{repo.spec && repo.spec.url}</td>
38-
<td>
39-
<button
40-
className="button button-secondary"
41-
onClick={this.handleDeleteClick(repo.metadata.name)}
42-
>
43-
Delete
44-
</button>
45-
<button
46-
className="button button-secondary"
47-
onClick={this.handleResyncClick(repo.metadata.name)}
48-
>
49-
Refresh
50-
</button>
51-
</td>
52-
</tr>
53-
);
54-
})}
34+
{repos.map(repo => (
35+
<AppRepoListItem
36+
key={repo.metadata.uid}
37+
deleteRepo={deleteRepo}
38+
resyncRepo={resyncRepo}
39+
repo={repo}
40+
/>
41+
))}
5542
</tbody>
5643
</table>
5744
<AppRepoAddButton install={install} />
5845
</div>
5946
);
6047
}
61-
62-
private handleDeleteClick = (repoName: string) => () => this.props.deleteRepo(repoName);
63-
private handleResyncClick = (repoName: string) => () => this.props.resyncRepo(repoName);
6448
}
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import * as React from "react";
2+
import * as Modal from "react-modal";
3+
4+
interface IConfirmDialogProps {
5+
modalIsOpen: boolean;
6+
onConfirm: () => Promise<any>;
7+
closeModal: () => Promise<any>;
8+
}
9+
10+
interface IConfirmDialogState {
11+
error?: string;
12+
modalIsOpen: boolean;
13+
}
14+
15+
class ConfirmDialog extends React.Component<IConfirmDialogProps, IConfirmDialogState> {
16+
public state: IConfirmDialogState = {
17+
error: undefined,
18+
modalIsOpen: this.props.modalIsOpen,
19+
};
20+
21+
public render() {
22+
return (
23+
<div className="ConfirmDialog">
24+
<Modal
25+
style={{
26+
content: {
27+
bottom: "auto",
28+
left: "50%",
29+
marginRight: "-50%",
30+
right: "auto",
31+
top: "50%",
32+
transform: "translate(-50%, -50%)",
33+
},
34+
}}
35+
isOpen={this.props.modalIsOpen}
36+
onRequestClose={this.closeModal}
37+
contentLabel="Modal"
38+
>
39+
{this.state.error && (
40+
<div className="container padding-v-small bg-action">{this.state.error}</div>
41+
)}
42+
<div>Are you sure you want to delete this?</div>
43+
<div>
44+
<button className="button" onClick={this.props.closeModal}>
45+
Cancel
46+
</button>
47+
<button
48+
className="button button-primary button-danger"
49+
type="submit"
50+
onClick={this.props.onConfirm}
51+
>
52+
Delete
53+
</button>
54+
</div>
55+
</Modal>
56+
</div>
57+
);
58+
}
59+
60+
public openModel = () => {
61+
this.setState({
62+
modalIsOpen: true,
63+
});
64+
};
65+
66+
public closeModal = () => {
67+
this.setState({
68+
modalIsOpen: false,
69+
});
70+
};
71+
}
72+
73+
export default ConfirmDialog;

src/components/DeprovisionButton/index.tsx

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from "react";
22
import { IServiceInstance } from "../../shared/ServiceInstance";
3+
import ConfirmDialog from "../ConfirmDialog";
34

45
interface IDeprovisionButtonProps {
56
instance: IServiceInstance;
@@ -10,18 +11,20 @@ interface IDeprovisionButtonState {
1011
error: string | undefined;
1112
instance: IServiceInstance | undefined;
1213
isDeprovisioning: boolean;
14+
modalIsOpen: boolean;
1315
}
1416

1517
class DeprovisionButton extends React.Component<IDeprovisionButtonProps, IDeprovisionButtonState> {
1618
public state: IDeprovisionButtonState = {
1719
error: undefined,
1820
instance: this.props.instance,
1921
isDeprovisioning: false,
22+
modalIsOpen: false,
2023
};
2124

2225
public handleDeprovision = async () => {
2326
const { deprovision, instance } = this.props;
24-
this.setState({ isDeprovisioning: true });
27+
this.setState({ isDeprovisioning: true, modalIsOpen: false });
2528

2629
try {
2730
await deprovision(instance);
@@ -35,16 +38,34 @@ class DeprovisionButton extends React.Component<IDeprovisionButtonProps, IDeprov
3538
return (
3639
<div className="DeprovisionButton">
3740
{this.state.isDeprovisioning && <div>Deprovisioning...</div>}
41+
<ConfirmDialog
42+
onConfirm={this.handleDeprovision}
43+
modalIsOpen={this.state.modalIsOpen}
44+
closeModal={this.closeModal}
45+
/>
46+
3847
<button
3948
className="button button-primary button-small button-danger"
4049
disabled={this.state.isDeprovisioning}
41-
onClick={this.handleDeprovision}
50+
onClick={this.openModel}
4251
>
4352
Deprovision
4453
</button>
4554
</div>
4655
);
4756
}
57+
58+
public openModel = () => {
59+
this.setState({
60+
modalIsOpen: true,
61+
});
62+
};
63+
64+
public closeModal = async () => {
65+
this.setState({
66+
modalIsOpen: false,
67+
});
68+
};
4869
}
4970

5071
export default DeprovisionButton;

yarn.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -2829,7 +2829,7 @@ https-browserify@^1.0.0:
28292829
version "1.0.0"
28302830
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
28312831

2832-
husky@^0.14.3:
2832+
28332833
version "0.14.3"
28342834
resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3"
28352835
dependencies:

0 commit comments

Comments
 (0)