/
discard-changes-dialog.tsx
156 lines (140 loc) · 4.19 KB
/
discard-changes-dialog.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import * as React from 'react'
import { Repository } from '../../models/repository'
import { Dispatcher } from '../../lib/dispatcher'
import { WorkingDirectoryFileChange } from '../../models/status'
import { Button } from '../lib/button'
import { ButtonGroup } from '../lib/button-group'
import { Dialog, DialogContent, DialogFooter } from '../dialog'
import { PathText } from '../lib/path-text'
import { Monospaced } from '../lib/monospaced'
import { Checkbox, CheckboxValue } from '../lib/checkbox'
import { TrashNameLabel } from '../lib/context-menu'
interface IDiscardChangesProps {
readonly repository: Repository
readonly dispatcher: Dispatcher
readonly files: ReadonlyArray<WorkingDirectoryFileChange>
readonly confirmDiscardChanges: boolean
/**
* Determines whether to show the option
* to ask for confirmation when discarding
* changes
*/
readonly showDiscardChangesSetting: boolean
readonly onDismissed: () => void
readonly onConfirmDiscardChangesChanged: (optOut: boolean) => void
}
interface IDiscardChangesState {
/**
* Whether or not we're currently in the process of discarding
* changes. This is used to display a loading state
*/
readonly isDiscardingChanges: boolean
readonly confirmDiscardChanges: boolean
}
/**
* If we're discarding any more than this number, we won't bother listing them
* all.
*/
const MaxFilesToList = 10
/** A component to confirm and then discard changes. */
export class DiscardChanges extends React.Component<
IDiscardChangesProps,
IDiscardChangesState
> {
public constructor(props: IDiscardChangesProps) {
super(props)
this.state = {
isDiscardingChanges: false,
confirmDiscardChanges: this.props.confirmDiscardChanges,
}
}
public render() {
return (
<Dialog
id="discard-changes"
title={
__DARWIN__ ? 'Confirm Discard Changes' : 'Confirm discard changes'
}
onDismissed={this.props.onDismissed}
type="warning"
>
<DialogContent>
{this.renderFileList()}
<p>
Changes can be restored by retrieving them from the {TrashNameLabel}
.
</p>
{this.renderConfirmDiscardChanges()}
</DialogContent>
<DialogFooter>
<ButtonGroup destructive={true}>
<Button type="submit">Cancel</Button>
<Button onClick={this.discard}>
{__DARWIN__ ? 'Discard Changes' : 'Discard changes'}
</Button>
</ButtonGroup>
</DialogFooter>
</Dialog>
)
}
private renderConfirmDiscardChanges() {
if (this.props.showDiscardChangesSetting) {
return (
<Checkbox
label="Do not show this message again"
value={
this.state.confirmDiscardChanges
? CheckboxValue.Off
: CheckboxValue.On
}
onChange={this.onConfirmDiscardChangesChanged}
/>
)
} else {
// since we ignore the users option to not show
// confirmation, we don't want to show a checkbox
// that will have no effect
return null
}
}
private renderFileList() {
if (this.props.files.length > MaxFilesToList) {
return (
<p>
Are you sure you want to discard all {this.props.files.length} changed
files?
</p>
)
} else {
return (
<div>
<p>Are you sure you want to discard all changes to:</p>
<ul>
{this.props.files.map(p => (
<li key={p.id}>
<Monospaced>
<PathText path={p.path} />
</Monospaced>
</li>
))}
</ul>
</div>
)
}
}
private discard = async () => {
this.setState({ isDiscardingChanges: true })
await this.props.dispatcher.discardChanges(
this.props.repository,
this.props.files
)
this.props.onConfirmDiscardChangesChanged(this.state.confirmDiscardChanges)
this.props.onDismissed()
}
private onConfirmDiscardChangesChanged = (
event: React.FormEvent<HTMLInputElement>
) => {
const value = !event.currentTarget.checked
this.setState({ confirmDiscardChanges: value })
}
}