Show More
@@ -1,1371 +1,1371 b'' | |||
|
1 | 1 | .swal2-popup.swal2-toast { |
|
2 | 2 | flex-direction: row; |
|
3 | 3 | align-items: center; |
|
4 | 4 | width: auto; |
|
5 | 5 | padding: 0.625em; |
|
6 | 6 | overflow-y: hidden; |
|
7 | 7 | background: #fff; |
|
8 | 8 | box-shadow: 0 0 0.625em #d9d9d9; |
|
9 | 9 | } |
|
10 | 10 | .swal2-popup.swal2-toast .swal2-header { |
|
11 | 11 | flex-direction: row; |
|
12 | 12 | } |
|
13 | 13 | .swal2-popup.swal2-toast .swal2-title { |
|
14 | 14 | flex-grow: 1; |
|
15 | 15 | justify-content: flex-start; |
|
16 | 16 | margin: 0 0.6em; |
|
17 | 17 | font-size: 1em; |
|
18 | 18 | } |
|
19 | 19 | .swal2-popup.swal2-toast .swal2-footer { |
|
20 | 20 | margin: 0.5em 0 0; |
|
21 | 21 | padding: 0.5em 0 0; |
|
22 | 22 | font-size: 0.8em; |
|
23 | 23 | } |
|
24 | 24 | .swal2-popup.swal2-toast .swal2-close { |
|
25 | 25 | position: static; |
|
26 | 26 | width: 0.8em; |
|
27 | 27 | height: 0.8em; |
|
28 | 28 | line-height: 0.8; |
|
29 | 29 | } |
|
30 | 30 | .swal2-popup.swal2-toast .swal2-content { |
|
31 | 31 | justify-content: flex-start; |
|
32 | 32 | font-size: 1em; |
|
33 | 33 | } |
|
34 | 34 | .swal2-popup.swal2-toast .swal2-icon { |
|
35 | 35 | width: 2em; |
|
36 | 36 | min-width: 2em; |
|
37 | 37 | height: 2em; |
|
38 | 38 | margin: 0; |
|
39 | 39 | } |
|
40 | 40 | .swal2-popup.swal2-toast .swal2-icon .swal2-icon-content { |
|
41 | 41 | display: flex; |
|
42 | 42 | align-items: center; |
|
43 | 43 | font-size: 1.8em; |
|
44 | 44 | font-weight: bold; |
|
45 | 45 | } |
|
46 | 46 | @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { |
|
47 | 47 | .swal2-popup.swal2-toast .swal2-icon .swal2-icon-content { |
|
48 | 48 | font-size: 0.25em; |
|
49 | 49 | } |
|
50 | 50 | } |
|
51 | 51 | .swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring { |
|
52 | 52 | width: 2em; |
|
53 | 53 | height: 2em; |
|
54 | 54 | } |
|
55 | 55 | .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line] { |
|
56 | 56 | top: 0.875em; |
|
57 | 57 | width: 1.375em; |
|
58 | 58 | } |
|
59 | 59 | .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left] { |
|
60 | 60 | left: 0.3125em; |
|
61 | 61 | } |
|
62 | 62 | .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right] { |
|
63 | 63 | right: 0.3125em; |
|
64 | 64 | } |
|
65 | 65 | .swal2-popup.swal2-toast .swal2-actions { |
|
66 | 66 | flex-basis: auto !important; |
|
67 | 67 | width: auto; |
|
68 | 68 | height: auto; |
|
69 | 69 | margin: 0 0.3125em; |
|
70 | 70 | } |
|
71 | 71 | .swal2-popup.swal2-toast .swal2-styled { |
|
72 | 72 | margin: 0 0.3125em; |
|
73 | 73 | padding: 0.3125em 0.625em; |
|
74 | 74 | font-size: 1em; |
|
75 | 75 | } |
|
76 | 76 | .swal2-popup.swal2-toast .swal2-styled:focus { |
|
77 | 77 | box-shadow: 0 0 0 1px #fff, 0 0 0 3px rgba(50, 100, 150, 0.4); |
|
78 | 78 | } |
|
79 | 79 | .swal2-popup.swal2-toast .swal2-success { |
|
80 | 80 | border-color: @alert1; |
|
81 | 81 | } |
|
82 | 82 | .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line] { |
|
83 | 83 | position: absolute; |
|
84 | 84 | width: 1.6em; |
|
85 | 85 | height: 3em; |
|
86 | 86 | transform: rotate(45deg); |
|
87 | 87 | border-radius: 50%; |
|
88 | 88 | } |
|
89 | 89 | .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left] { |
|
90 | 90 | top: -0.8em; |
|
91 | 91 | left: -0.5em; |
|
92 | 92 | transform: rotate(-45deg); |
|
93 | 93 | transform-origin: 2em 2em; |
|
94 | 94 | border-radius: 4em 0 0 4em; |
|
95 | 95 | } |
|
96 | 96 | .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right] { |
|
97 | 97 | top: -0.25em; |
|
98 | 98 | left: 0.9375em; |
|
99 | 99 | transform-origin: 0 1.5em; |
|
100 | 100 | border-radius: 0 4em 4em 0; |
|
101 | 101 | } |
|
102 | 102 | .swal2-popup.swal2-toast .swal2-success .swal2-success-ring { |
|
103 | 103 | width: 2em; |
|
104 | 104 | height: 2em; |
|
105 | 105 | } |
|
106 | 106 | .swal2-popup.swal2-toast .swal2-success .swal2-success-fix { |
|
107 | 107 | top: 0; |
|
108 | 108 | left: 0.4375em; |
|
109 | 109 | width: 0.4375em; |
|
110 | 110 | height: 2.6875em; |
|
111 | 111 | } |
|
112 | 112 | .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line] { |
|
113 | 113 | height: 0.3125em; |
|
114 | 114 | } |
|
115 | 115 | .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip] { |
|
116 | 116 | top: 1.125em; |
|
117 | 117 | left: 0.1875em; |
|
118 | 118 | width: 0.75em; |
|
119 | 119 | } |
|
120 | 120 | .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long] { |
|
121 | 121 | top: 0.9375em; |
|
122 | 122 | right: 0.1875em; |
|
123 | 123 | width: 1.375em; |
|
124 | 124 | } |
|
125 | 125 | .swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip { |
|
126 | 126 | -webkit-animation: swal2-toast-animate-success-line-tip 0.75s; |
|
127 | 127 | animation: swal2-toast-animate-success-line-tip 0.75s; |
|
128 | 128 | } |
|
129 | 129 | .swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long { |
|
130 | 130 | -webkit-animation: swal2-toast-animate-success-line-long 0.75s; |
|
131 | 131 | animation: swal2-toast-animate-success-line-long 0.75s; |
|
132 | 132 | } |
|
133 | 133 | .swal2-popup.swal2-toast.swal2-show { |
|
134 | 134 | -webkit-animation: swal2-toast-show 0.5s; |
|
135 | 135 | animation: swal2-toast-show 0.5s; |
|
136 | 136 | } |
|
137 | 137 | .swal2-popup.swal2-toast.swal2-hide { |
|
138 | 138 | -webkit-animation: swal2-toast-hide 0.1s forwards; |
|
139 | 139 | animation: swal2-toast-hide 0.1s forwards; |
|
140 | 140 | } |
|
141 | 141 | |
|
142 | 142 | .swal2-container { |
|
143 | 143 | display: flex; |
|
144 | 144 | position: fixed; |
|
145 | 145 | z-index: 1060; |
|
146 | 146 | top: 0; |
|
147 | 147 | right: 0; |
|
148 | 148 | bottom: 0; |
|
149 | 149 | left: 0; |
|
150 | 150 | flex-direction: row; |
|
151 | 151 | align-items: center; |
|
152 | 152 | justify-content: center; |
|
153 | 153 | padding: 0.625em; |
|
154 | 154 | overflow-x: hidden; |
|
155 | 155 | transition: background-color 0.1s; |
|
156 | 156 | -webkit-overflow-scrolling: touch; |
|
157 | 157 | } |
|
158 | 158 | .swal2-container.swal2-backdrop-show, .swal2-container.swal2-noanimation { |
|
159 | 159 | background: rgba(0, 0, 0, 0.4); |
|
160 | 160 | } |
|
161 | 161 | .swal2-container.swal2-backdrop-hide { |
|
162 | 162 | background: transparent !important; |
|
163 | 163 | } |
|
164 | 164 | .swal2-container.swal2-top { |
|
165 | 165 | align-items: flex-start; |
|
166 | 166 | } |
|
167 | 167 | .swal2-container.swal2-top-start, .swal2-container.swal2-top-left { |
|
168 | 168 | align-items: flex-start; |
|
169 | 169 | justify-content: flex-start; |
|
170 | 170 | } |
|
171 | 171 | .swal2-container.swal2-top-end, .swal2-container.swal2-top-right { |
|
172 | 172 | align-items: flex-start; |
|
173 | 173 | justify-content: flex-end; |
|
174 | 174 | } |
|
175 | 175 | .swal2-container.swal2-center { |
|
176 | 176 | align-items: center; |
|
177 | 177 | } |
|
178 | 178 | .swal2-container.swal2-center-start, .swal2-container.swal2-center-left { |
|
179 | 179 | align-items: center; |
|
180 | 180 | justify-content: flex-start; |
|
181 | 181 | } |
|
182 | 182 | .swal2-container.swal2-center-end, .swal2-container.swal2-center-right { |
|
183 | 183 | align-items: center; |
|
184 | 184 | justify-content: flex-end; |
|
185 | 185 | } |
|
186 | 186 | .swal2-container.swal2-bottom { |
|
187 | 187 | align-items: flex-end; |
|
188 | 188 | } |
|
189 | 189 | .swal2-container.swal2-bottom-start, .swal2-container.swal2-bottom-left { |
|
190 | 190 | align-items: flex-end; |
|
191 | 191 | justify-content: flex-start; |
|
192 | 192 | } |
|
193 | 193 | .swal2-container.swal2-bottom-end, .swal2-container.swal2-bottom-right { |
|
194 | 194 | align-items: flex-end; |
|
195 | 195 | justify-content: flex-end; |
|
196 | 196 | } |
|
197 | 197 | .swal2-container.swal2-bottom > :first-child, .swal2-container.swal2-bottom-start > :first-child, .swal2-container.swal2-bottom-left > :first-child, .swal2-container.swal2-bottom-end > :first-child, .swal2-container.swal2-bottom-right > :first-child { |
|
198 | 198 | margin-top: auto; |
|
199 | 199 | } |
|
200 | 200 | .swal2-container.swal2-grow-fullscreen > .swal2-modal { |
|
201 | 201 | display: flex !important; |
|
202 | 202 | flex: 1; |
|
203 | 203 | align-self: stretch; |
|
204 | 204 | justify-content: center; |
|
205 | 205 | } |
|
206 | 206 | .swal2-container.swal2-grow-row > .swal2-modal { |
|
207 | 207 | display: flex !important; |
|
208 | 208 | flex: 1; |
|
209 | 209 | align-content: center; |
|
210 | 210 | justify-content: center; |
|
211 | 211 | } |
|
212 | 212 | .swal2-container.swal2-grow-column { |
|
213 | 213 | flex: 1; |
|
214 | 214 | flex-direction: column; |
|
215 | 215 | } |
|
216 | 216 | .swal2-container.swal2-grow-column.swal2-top, .swal2-container.swal2-grow-column.swal2-center, .swal2-container.swal2-grow-column.swal2-bottom { |
|
217 | 217 | align-items: center; |
|
218 | 218 | } |
|
219 | 219 | .swal2-container.swal2-grow-column.swal2-top-start, .swal2-container.swal2-grow-column.swal2-center-start, .swal2-container.swal2-grow-column.swal2-bottom-start, .swal2-container.swal2-grow-column.swal2-top-left, .swal2-container.swal2-grow-column.swal2-center-left, .swal2-container.swal2-grow-column.swal2-bottom-left { |
|
220 | 220 | align-items: flex-start; |
|
221 | 221 | } |
|
222 | 222 | .swal2-container.swal2-grow-column.swal2-top-end, .swal2-container.swal2-grow-column.swal2-center-end, .swal2-container.swal2-grow-column.swal2-bottom-end, .swal2-container.swal2-grow-column.swal2-top-right, .swal2-container.swal2-grow-column.swal2-center-right, .swal2-container.swal2-grow-column.swal2-bottom-right { |
|
223 | 223 | align-items: flex-end; |
|
224 | 224 | } |
|
225 | 225 | .swal2-container.swal2-grow-column > .swal2-modal { |
|
226 | 226 | display: flex !important; |
|
227 | 227 | flex: 1; |
|
228 | 228 | align-content: center; |
|
229 | 229 | justify-content: center; |
|
230 | 230 | } |
|
231 | 231 | .swal2-container.swal2-no-transition { |
|
232 | 232 | transition: none !important; |
|
233 | 233 | } |
|
234 | 234 | .swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen) > .swal2-modal { |
|
235 | 235 | margin: auto; |
|
236 | 236 | } |
|
237 | 237 | @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { |
|
238 | 238 | .swal2-container .swal2-modal { |
|
239 | 239 | margin: 0 !important; |
|
240 | 240 | } |
|
241 | 241 | } |
|
242 | 242 | |
|
243 | 243 | .swal2-popup { |
|
244 | 244 | display: none; |
|
245 | 245 | position: relative; |
|
246 | 246 | box-sizing: border-box; |
|
247 | 247 | flex-direction: column; |
|
248 | 248 | justify-content: center; |
|
249 |
width: 3 |
|
|
249 | width: 38em; | |
|
250 | 250 | max-width: 100%; |
|
251 | 251 | padding: 1.25em; |
|
252 | 252 | border: none; |
|
253 | 253 | border-radius: 0.3125em; |
|
254 | 254 | background: #fff; |
|
255 | 255 | font-family: inherit; |
|
256 | 256 | font-size: 1rem; |
|
257 | 257 | } |
|
258 | 258 | .swal2-popup:focus { |
|
259 | 259 | outline: none; |
|
260 | 260 | } |
|
261 | 261 | .swal2-popup.swal2-loading { |
|
262 | 262 | overflow-y: hidden; |
|
263 | 263 | } |
|
264 | 264 | |
|
265 | 265 | .swal2-header { |
|
266 | 266 | display: flex; |
|
267 | 267 | flex-direction: column; |
|
268 | 268 | align-items: center; |
|
269 | 269 | } |
|
270 | 270 | |
|
271 | 271 | .swal2-title { |
|
272 | 272 | position: relative; |
|
273 | 273 | max-width: 100%; |
|
274 | 274 | margin: 0 0 0.4em; |
|
275 | 275 | padding: 0; |
|
276 | 276 | color: #595959; |
|
277 | 277 | font-size: 1.875em; |
|
278 | 278 | font-weight: 600; |
|
279 | 279 | text-align: center; |
|
280 | 280 | text-transform: none; |
|
281 | 281 | word-wrap: break-word; |
|
282 | 282 | } |
|
283 | 283 | |
|
284 | 284 | .swal2-actions { |
|
285 | 285 | display: flex; |
|
286 | 286 | z-index: 1; |
|
287 | 287 | flex-wrap: wrap; |
|
288 | 288 | align-items: center; |
|
289 | 289 | justify-content: center; |
|
290 | 290 | width: 100%; |
|
291 | 291 | margin: 1.25em auto 0; |
|
292 | 292 | } |
|
293 | 293 | .swal2-actions:not(.swal2-loading) .swal2-styled[disabled] { |
|
294 | 294 | opacity: 0.4; |
|
295 | 295 | } |
|
296 | 296 | .swal2-actions:not(.swal2-loading) .swal2-styled:hover { |
|
297 | 297 | background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)); |
|
298 | 298 | } |
|
299 | 299 | .swal2-actions:not(.swal2-loading) .swal2-styled:active { |
|
300 | 300 | background-image: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)); |
|
301 | 301 | } |
|
302 | 302 | .swal2-actions.swal2-loading .swal2-styled.swal2-confirm { |
|
303 | 303 | box-sizing: border-box; |
|
304 | 304 | width: 2.5em; |
|
305 | 305 | height: 2.5em; |
|
306 | 306 | margin: 0.46875em; |
|
307 | 307 | padding: 0; |
|
308 | 308 | -webkit-animation: swal2-rotate-loading 1.5s linear 0s infinite normal; |
|
309 | 309 | animation: swal2-rotate-loading 1.5s linear 0s infinite normal; |
|
310 | 310 | border: 0.25em solid transparent; |
|
311 | 311 | border-radius: 100%; |
|
312 | 312 | border-color: transparent; |
|
313 | 313 | background-color: transparent !important; |
|
314 | 314 | color: transparent !important; |
|
315 | 315 | cursor: default; |
|
316 | 316 | -webkit-user-select: none; |
|
317 | 317 | -moz-user-select: none; |
|
318 | 318 | -ms-user-select: none; |
|
319 | 319 | user-select: none; |
|
320 | 320 | } |
|
321 | 321 | .swal2-actions.swal2-loading .swal2-styled.swal2-cancel { |
|
322 | 322 | margin-right: 30px; |
|
323 | 323 | margin-left: 30px; |
|
324 | 324 | } |
|
325 | 325 | .swal2-actions.swal2-loading :not(.swal2-styled).swal2-confirm::after { |
|
326 | 326 | content: ""; |
|
327 | 327 | display: inline-block; |
|
328 | 328 | width: 15px; |
|
329 | 329 | height: 15px; |
|
330 | 330 | margin-left: 5px; |
|
331 | 331 | -webkit-animation: swal2-rotate-loading 1.5s linear 0s infinite normal; |
|
332 | 332 | animation: swal2-rotate-loading 1.5s linear 0s infinite normal; |
|
333 | 333 | border: 3px solid #999999; |
|
334 | 334 | border-radius: 50%; |
|
335 | 335 | border-right-color: transparent; |
|
336 | 336 | box-shadow: 1px 1px 1px #fff; |
|
337 | 337 | } |
|
338 | 338 | |
|
339 | 339 | .swal2-styled { |
|
340 | 340 | margin: 0.3125em; |
|
341 | 341 | padding: 0.625em 2em; |
|
342 | 342 | box-shadow: none; |
|
343 | 343 | font-weight: 500; |
|
344 | 344 | } |
|
345 | 345 | .swal2-styled:not([disabled]) { |
|
346 | 346 | cursor: pointer; |
|
347 | 347 | } |
|
348 | 348 | .swal2-styled.swal2-confirm { |
|
349 | 349 | border: 0; |
|
350 | 350 | border-radius: 0.25em; |
|
351 | 351 | background: initial; |
|
352 | 352 | background-color: @alert4; |
|
353 | 353 | color: #fff; |
|
354 | 354 | font-size: 1.0625em; |
|
355 | 355 | } |
|
356 | 356 | .swal2-styled.swal2-cancel { |
|
357 | 357 | border: 0; |
|
358 | 358 | border-radius: 0.25em; |
|
359 | 359 | background: initial; |
|
360 | 360 | background-color: #aaa; |
|
361 | 361 | color: #fff; |
|
362 | 362 | font-size: 1.0625em; |
|
363 | 363 | } |
|
364 | 364 | .swal2-styled:focus { |
|
365 | 365 | outline: none; |
|
366 | 366 | box-shadow: 0 0 0 1px #fff, 0 0 0 3px rgba(50, 100, 150, 0.4); |
|
367 | 367 | } |
|
368 | 368 | .swal2-styled::-moz-focus-inner { |
|
369 | 369 | border: 0; |
|
370 | 370 | } |
|
371 | 371 | |
|
372 | 372 | .swal2-footer { |
|
373 | 373 | justify-content: center; |
|
374 | 374 | margin: 1.25em 0 0; |
|
375 | 375 | padding: 1em 0 0; |
|
376 | 376 | border-top: 1px solid #eee; |
|
377 | 377 | color: #545454; |
|
378 | 378 | font-size: 1em; |
|
379 | 379 | } |
|
380 | 380 | |
|
381 | 381 | .swal2-timer-progress-bar-container { |
|
382 | 382 | position: absolute; |
|
383 | 383 | right: 0; |
|
384 | 384 | bottom: 0; |
|
385 | 385 | left: 0; |
|
386 | 386 | height: 0.25em; |
|
387 | 387 | overflow: hidden; |
|
388 | 388 | border-bottom-right-radius: 0.3125em; |
|
389 | 389 | border-bottom-left-radius: 0.3125em; |
|
390 | 390 | } |
|
391 | 391 | |
|
392 | 392 | .swal2-timer-progress-bar { |
|
393 | 393 | width: 100%; |
|
394 | 394 | height: 0.25em; |
|
395 | 395 | background: rgba(0, 0, 0, 0.2); |
|
396 | 396 | } |
|
397 | 397 | |
|
398 | 398 | .swal2-image { |
|
399 | 399 | max-width: 100%; |
|
400 | 400 | margin: 1.25em auto; |
|
401 | 401 | } |
|
402 | 402 | |
|
403 | 403 | .swal2-close { |
|
404 | 404 | position: absolute; |
|
405 | 405 | z-index: 2; |
|
406 | 406 | top: 0; |
|
407 | 407 | right: 0; |
|
408 | 408 | align-items: center; |
|
409 | 409 | justify-content: center; |
|
410 | 410 | width: 1.2em; |
|
411 | 411 | height: 1.2em; |
|
412 | 412 | padding: 0; |
|
413 | 413 | overflow: hidden; |
|
414 | 414 | transition: color 0.1s ease-out; |
|
415 | 415 | border: none; |
|
416 | 416 | border-radius: 0; |
|
417 | 417 | background: transparent; |
|
418 | 418 | color: #cccccc; |
|
419 | 419 | font-family: serif; |
|
420 | 420 | font-size: 2.5em; |
|
421 | 421 | line-height: 1.2; |
|
422 | 422 | cursor: pointer; |
|
423 | 423 | } |
|
424 | 424 | .swal2-close:hover { |
|
425 | 425 | transform: none; |
|
426 | 426 | background: transparent; |
|
427 | 427 | color: #f27474; |
|
428 | 428 | } |
|
429 | 429 | .swal2-close::-moz-focus-inner { |
|
430 | 430 | border: 0; |
|
431 | 431 | } |
|
432 | 432 | |
|
433 | 433 | .swal2-content { |
|
434 | 434 | z-index: 1; |
|
435 | 435 | justify-content: center; |
|
436 | 436 | margin: 0; |
|
437 | 437 | padding: 0; |
|
438 | 438 | color: #545454; |
|
439 | 439 | font-size: 1.125em; |
|
440 | 440 | font-weight: normal; |
|
441 | 441 | line-height: normal; |
|
442 | 442 | text-align: center; |
|
443 | 443 | word-wrap: break-word; |
|
444 | 444 | } |
|
445 | 445 | |
|
446 | 446 | .swal2-input, |
|
447 | 447 | .swal2-file, |
|
448 | 448 | .swal2-textarea, |
|
449 | 449 | .swal2-select, |
|
450 | 450 | .swal2-radio, |
|
451 | 451 | .swal2-checkbox { |
|
452 | 452 | margin: 1em auto; |
|
453 | 453 | } |
|
454 | 454 | |
|
455 | 455 | .swal2-input, |
|
456 | 456 | .swal2-file, |
|
457 | 457 | .swal2-textarea { |
|
458 | 458 | box-sizing: border-box; |
|
459 | 459 | width: 100%; |
|
460 | 460 | transition: border-color 0.3s, box-shadow 0.3s; |
|
461 | 461 | border: 1px solid #d9d9d9; |
|
462 | 462 | border-radius: 0.1875em; |
|
463 | 463 | background: inherit; |
|
464 | 464 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06); |
|
465 | 465 | color: inherit; |
|
466 | 466 | font-size: 1.125em; |
|
467 | 467 | } |
|
468 | 468 | .swal2-input.swal2-inputerror, |
|
469 | 469 | .swal2-file.swal2-inputerror, |
|
470 | 470 | .swal2-textarea.swal2-inputerror { |
|
471 | 471 | border-color: #f27474 !important; |
|
472 | 472 | box-shadow: 0 0 2px #f27474 !important; |
|
473 | 473 | } |
|
474 | 474 | .swal2-input:focus, |
|
475 | 475 | .swal2-file:focus, |
|
476 | 476 | .swal2-textarea:focus { |
|
477 | 477 | border: 1px solid #b4dbed; |
|
478 | 478 | outline: none; |
|
479 | 479 | box-shadow: 0 0 3px #c4e6f5; |
|
480 | 480 | } |
|
481 | 481 | .swal2-input::-webkit-input-placeholder, .swal2-file::-webkit-input-placeholder, .swal2-textarea::-webkit-input-placeholder { |
|
482 | 482 | color: #cccccc; |
|
483 | 483 | } |
|
484 | 484 | .swal2-input::-moz-placeholder, .swal2-file::-moz-placeholder, .swal2-textarea::-moz-placeholder { |
|
485 | 485 | color: #cccccc; |
|
486 | 486 | } |
|
487 | 487 | .swal2-input:-ms-input-placeholder, .swal2-file:-ms-input-placeholder, .swal2-textarea:-ms-input-placeholder { |
|
488 | 488 | color: #cccccc; |
|
489 | 489 | } |
|
490 | 490 | .swal2-input::-ms-input-placeholder, .swal2-file::-ms-input-placeholder, .swal2-textarea::-ms-input-placeholder { |
|
491 | 491 | color: #cccccc; |
|
492 | 492 | } |
|
493 | 493 | .swal2-input::placeholder, |
|
494 | 494 | .swal2-file::placeholder, |
|
495 | 495 | .swal2-textarea::placeholder { |
|
496 | 496 | color: #cccccc; |
|
497 | 497 | } |
|
498 | 498 | |
|
499 | 499 | .swal2-range { |
|
500 | 500 | margin: 1em auto; |
|
501 | 501 | background: #fff; |
|
502 | 502 | } |
|
503 | 503 | .swal2-range input { |
|
504 | 504 | width: 80%; |
|
505 | 505 | } |
|
506 | 506 | .swal2-range output { |
|
507 | 507 | width: 20%; |
|
508 | 508 | color: inherit; |
|
509 | 509 | font-weight: 600; |
|
510 | 510 | text-align: center; |
|
511 | 511 | } |
|
512 | 512 | .swal2-range input, |
|
513 | 513 | .swal2-range output { |
|
514 | 514 | height: 2.625em; |
|
515 | 515 | padding: 0; |
|
516 | 516 | font-size: 1.125em; |
|
517 | 517 | line-height: 2.625em; |
|
518 | 518 | } |
|
519 | 519 | |
|
520 | 520 | .swal2-input { |
|
521 | 521 | height: 2.625em; |
|
522 | 522 | padding: 0 0.75em; |
|
523 | 523 | } |
|
524 | 524 | .swal2-input[type=number] { |
|
525 | 525 | max-width: 10em; |
|
526 | 526 | } |
|
527 | 527 | |
|
528 | 528 | .swal2-file { |
|
529 | 529 | background: inherit; |
|
530 | 530 | font-size: 1.125em; |
|
531 | 531 | } |
|
532 | 532 | |
|
533 | 533 | .swal2-textarea { |
|
534 | 534 | height: 6.75em; |
|
535 | 535 | padding: 0.75em; |
|
536 | 536 | } |
|
537 | 537 | |
|
538 | 538 | .swal2-select { |
|
539 | 539 | min-width: 50%; |
|
540 | 540 | max-width: 100%; |
|
541 | 541 | padding: 0.375em 0.625em; |
|
542 | 542 | background: inherit; |
|
543 | 543 | color: inherit; |
|
544 | 544 | font-size: 1.125em; |
|
545 | 545 | } |
|
546 | 546 | |
|
547 | 547 | .swal2-radio, |
|
548 | 548 | .swal2-checkbox { |
|
549 | 549 | align-items: center; |
|
550 | 550 | justify-content: center; |
|
551 | 551 | background: #fff; |
|
552 | 552 | color: inherit; |
|
553 | 553 | } |
|
554 | 554 | .swal2-radio label, |
|
555 | 555 | .swal2-checkbox label { |
|
556 | 556 | margin: 0 0.6em; |
|
557 | 557 | font-size: 1.125em; |
|
558 | 558 | } |
|
559 | 559 | .swal2-radio input, |
|
560 | 560 | .swal2-checkbox input { |
|
561 | 561 | margin: 0 0.4em; |
|
562 | 562 | } |
|
563 | 563 | |
|
564 | 564 | .swal2-validation-message { |
|
565 | 565 | display: none; |
|
566 | 566 | align-items: center; |
|
567 | 567 | justify-content: center; |
|
568 | 568 | padding: 0.625em; |
|
569 | 569 | overflow: hidden; |
|
570 | 570 | background: #f0f0f0; |
|
571 | 571 | color: #666666; |
|
572 | 572 | font-size: 1em; |
|
573 | 573 | font-weight: 300; |
|
574 | 574 | } |
|
575 | 575 | .swal2-validation-message::before { |
|
576 | 576 | content: "!"; |
|
577 | 577 | display: inline-block; |
|
578 | 578 | width: 1.5em; |
|
579 | 579 | min-width: 1.5em; |
|
580 | 580 | height: 1.5em; |
|
581 | 581 | margin: 0 0.625em; |
|
582 | 582 | border-radius: 50%; |
|
583 | 583 | background-color: #f27474; |
|
584 | 584 | color: #fff; |
|
585 | 585 | font-weight: 600; |
|
586 | 586 | line-height: 1.5em; |
|
587 | 587 | text-align: center; |
|
588 | 588 | } |
|
589 | 589 | |
|
590 | 590 | .swal2-icon { |
|
591 | 591 | position: relative; |
|
592 | 592 | box-sizing: content-box; |
|
593 | 593 | justify-content: center; |
|
594 | 594 | width: 5em; |
|
595 | 595 | height: 5em; |
|
596 | 596 | margin: 1.25em auto 1.875em; |
|
597 | 597 | border: 0.25em solid transparent; |
|
598 | 598 | border-radius: 50%; |
|
599 | 599 | font-family: inherit; |
|
600 | 600 | line-height: 5em; |
|
601 | 601 | cursor: default; |
|
602 | 602 | -webkit-user-select: none; |
|
603 | 603 | -moz-user-select: none; |
|
604 | 604 | -ms-user-select: none; |
|
605 | 605 | user-select: none; |
|
606 | 606 | } |
|
607 | 607 | .swal2-icon .swal2-icon-content { |
|
608 | 608 | display: flex; |
|
609 | 609 | align-items: center; |
|
610 | 610 | font-size: 3.75em; |
|
611 | 611 | } |
|
612 | 612 | .swal2-icon.swal2-error { |
|
613 | 613 | border-color: @alert2; |
|
614 | 614 | color: @alert2; |
|
615 | 615 | } |
|
616 | 616 | .swal2-icon.swal2-error .swal2-x-mark { |
|
617 | 617 | position: relative; |
|
618 | 618 | flex-grow: 1; |
|
619 | 619 | } |
|
620 | 620 | .swal2-icon.swal2-error [class^=swal2-x-mark-line] { |
|
621 | 621 | display: block; |
|
622 | 622 | position: absolute; |
|
623 | 623 | top: 2.3125em; |
|
624 | 624 | width: 2.9375em; |
|
625 | 625 | height: 0.3125em; |
|
626 | 626 | border-radius: 0.125em; |
|
627 | 627 | background-color: @alert2; |
|
628 | 628 | } |
|
629 | 629 | .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left] { |
|
630 | 630 | left: 1.0625em; |
|
631 | 631 | transform: rotate(45deg); |
|
632 | 632 | } |
|
633 | 633 | .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right] { |
|
634 | 634 | right: 1em; |
|
635 | 635 | transform: rotate(-45deg); |
|
636 | 636 | } |
|
637 | 637 | .swal2-icon.swal2-error.swal2-icon-show { |
|
638 | 638 | //-webkit-animation: swal2-animate-error-icon 0.5s; |
|
639 | 639 | // animation: swal2-animate-error-icon 0.5s; |
|
640 | 640 | } |
|
641 | 641 | .swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark { |
|
642 | 642 | //-webkit-animation: swal2-animate-error-x-mark 0.5s; |
|
643 | 643 | // animation: swal2-animate-error-x-mark 0.5s; |
|
644 | 644 | } |
|
645 | 645 | .swal2-icon.swal2-warning { |
|
646 | 646 | border-color: @alert3; |
|
647 | 647 | color: @alert3; |
|
648 | 648 | } |
|
649 | 649 | .swal2-icon.swal2-info { |
|
650 | 650 | border-color: #9de0f6; |
|
651 | 651 | color: #3fc3ee; |
|
652 | 652 | } |
|
653 | 653 | .swal2-icon.swal2-question { |
|
654 | 654 | border-color: #c9dae1; |
|
655 | 655 | color: #87adbd; |
|
656 | 656 | } |
|
657 | 657 | .swal2-icon.swal2-success { |
|
658 | 658 | border-color: @alert1; |
|
659 | 659 | color: @alert1; |
|
660 | 660 | } |
|
661 | 661 | .swal2-icon.swal2-success [class^=swal2-success-circular-line] { |
|
662 | 662 | position: absolute; |
|
663 | 663 | width: 3.75em; |
|
664 | 664 | height: 7.5em; |
|
665 | 665 | transform: rotate(45deg); |
|
666 | 666 | border-radius: 50%; |
|
667 | 667 | } |
|
668 | 668 | .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left] { |
|
669 | 669 | top: -0.4375em; |
|
670 | 670 | left: -2.0635em; |
|
671 | 671 | transform: rotate(-45deg); |
|
672 | 672 | transform-origin: 3.75em 3.75em; |
|
673 | 673 | border-radius: 7.5em 0 0 7.5em; |
|
674 | 674 | } |
|
675 | 675 | .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right] { |
|
676 | 676 | top: -0.6875em; |
|
677 | 677 | left: 1.875em; |
|
678 | 678 | transform: rotate(-45deg); |
|
679 | 679 | transform-origin: 0 3.75em; |
|
680 | 680 | border-radius: 0 7.5em 7.5em 0; |
|
681 | 681 | } |
|
682 | 682 | .swal2-icon.swal2-success .swal2-success-ring { |
|
683 | 683 | position: absolute; |
|
684 | 684 | z-index: 2; |
|
685 | 685 | top: -0.25em; |
|
686 | 686 | left: -0.25em; |
|
687 | 687 | box-sizing: content-box; |
|
688 | 688 | width: 100%; |
|
689 | 689 | height: 100%; |
|
690 | 690 | border: 0.25em solid rgba(165, 220, 134, 0.3); |
|
691 | 691 | border-radius: 50%; |
|
692 | 692 | } |
|
693 | 693 | .swal2-icon.swal2-success .swal2-success-fix { |
|
694 | 694 | position: absolute; |
|
695 | 695 | z-index: 1; |
|
696 | 696 | top: 0.5em; |
|
697 | 697 | left: 1.625em; |
|
698 | 698 | width: 0.4375em; |
|
699 | 699 | height: 5.625em; |
|
700 | 700 | transform: rotate(-45deg); |
|
701 | 701 | } |
|
702 | 702 | .swal2-icon.swal2-success [class^=swal2-success-line] { |
|
703 | 703 | display: block; |
|
704 | 704 | position: absolute; |
|
705 | 705 | z-index: 2; |
|
706 | 706 | height: 0.3125em; |
|
707 | 707 | border-radius: 0.125em; |
|
708 | 708 | background-color: @alert1; |
|
709 | 709 | } |
|
710 | 710 | .swal2-icon.swal2-success [class^=swal2-success-line][class$=tip] { |
|
711 | 711 | top: 2.875em; |
|
712 | 712 | left: 0.8125em; |
|
713 | 713 | width: 1.5625em; |
|
714 | 714 | transform: rotate(45deg); |
|
715 | 715 | } |
|
716 | 716 | .swal2-icon.swal2-success [class^=swal2-success-line][class$=long] { |
|
717 | 717 | top: 2.375em; |
|
718 | 718 | right: 0.5em; |
|
719 | 719 | width: 2.9375em; |
|
720 | 720 | transform: rotate(-45deg); |
|
721 | 721 | } |
|
722 | 722 | .swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip { |
|
723 | 723 | -webkit-animation: swal2-animate-success-line-tip 0.75s; |
|
724 | 724 | animation: swal2-animate-success-line-tip 0.75s; |
|
725 | 725 | } |
|
726 | 726 | .swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long { |
|
727 | 727 | -webkit-animation: swal2-animate-success-line-long 0.75s; |
|
728 | 728 | animation: swal2-animate-success-line-long 0.75s; |
|
729 | 729 | } |
|
730 | 730 | .swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right { |
|
731 | 731 | -webkit-animation: swal2-rotate-success-circular-line 4.25s ease-in; |
|
732 | 732 | animation: swal2-rotate-success-circular-line 4.25s ease-in; |
|
733 | 733 | } |
|
734 | 734 | |
|
735 | 735 | .swal2-progress-steps { |
|
736 | 736 | align-items: center; |
|
737 | 737 | margin: 0 0 1.25em; |
|
738 | 738 | padding: 0; |
|
739 | 739 | background: inherit; |
|
740 | 740 | font-weight: 600; |
|
741 | 741 | } |
|
742 | 742 | .swal2-progress-steps li { |
|
743 | 743 | display: inline-block; |
|
744 | 744 | position: relative; |
|
745 | 745 | } |
|
746 | 746 | .swal2-progress-steps .swal2-progress-step { |
|
747 | 747 | z-index: 20; |
|
748 | 748 | width: 2em; |
|
749 | 749 | height: 2em; |
|
750 | 750 | border-radius: 2em; |
|
751 | 751 | background: #3085d6; |
|
752 | 752 | color: #fff; |
|
753 | 753 | line-height: 2em; |
|
754 | 754 | text-align: center; |
|
755 | 755 | } |
|
756 | 756 | .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step { |
|
757 | 757 | background: #3085d6; |
|
758 | 758 | } |
|
759 | 759 | .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step ~ .swal2-progress-step { |
|
760 | 760 | background: #add8e6; |
|
761 | 761 | color: #fff; |
|
762 | 762 | } |
|
763 | 763 | .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step ~ .swal2-progress-step-line { |
|
764 | 764 | background: #add8e6; |
|
765 | 765 | } |
|
766 | 766 | .swal2-progress-steps .swal2-progress-step-line { |
|
767 | 767 | z-index: 10; |
|
768 | 768 | width: 2.5em; |
|
769 | 769 | height: 0.4em; |
|
770 | 770 | margin: 0 -1px; |
|
771 | 771 | background: #3085d6; |
|
772 | 772 | } |
|
773 | 773 | |
|
774 | 774 | [class^=swal2] { |
|
775 | 775 | -webkit-tap-highlight-color: transparent; |
|
776 | 776 | } |
|
777 | 777 | |
|
778 | 778 | .swal2-show { |
|
779 | 779 | -webkit-animation: swal2-show 0.3s; |
|
780 | 780 | animation: swal2-show 0.3s; |
|
781 | 781 | } |
|
782 | 782 | |
|
783 | 783 | .swal2-hide { |
|
784 | 784 | -webkit-animation: swal2-hide 0.15s forwards; |
|
785 | 785 | animation: swal2-hide 0.15s forwards; |
|
786 | 786 | } |
|
787 | 787 | |
|
788 | 788 | .swal2-noanimation { |
|
789 | 789 | transition: none; |
|
790 | 790 | } |
|
791 | 791 | |
|
792 | 792 | .swal2-scrollbar-measure { |
|
793 | 793 | position: absolute; |
|
794 | 794 | top: -9999px; |
|
795 | 795 | width: 50px; |
|
796 | 796 | height: 50px; |
|
797 | 797 | overflow: scroll; |
|
798 | 798 | } |
|
799 | 799 | |
|
800 | 800 | .swal2-rtl .swal2-close { |
|
801 | 801 | right: auto; |
|
802 | 802 | left: 0; |
|
803 | 803 | } |
|
804 | 804 | .swal2-rtl .swal2-timer-progress-bar { |
|
805 | 805 | right: 0; |
|
806 | 806 | left: auto; |
|
807 | 807 | } |
|
808 | 808 | |
|
809 | 809 | @supports (-ms-accelerator: true) { |
|
810 | 810 | .swal2-range input { |
|
811 | 811 | width: 100% !important; |
|
812 | 812 | } |
|
813 | 813 | .swal2-range output { |
|
814 | 814 | display: none; |
|
815 | 815 | } |
|
816 | 816 | } |
|
817 | 817 | @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { |
|
818 | 818 | .swal2-range input { |
|
819 | 819 | width: 100% !important; |
|
820 | 820 | } |
|
821 | 821 | .swal2-range output { |
|
822 | 822 | display: none; |
|
823 | 823 | } |
|
824 | 824 | } |
|
825 | 825 | @-moz-document url-prefix() { |
|
826 | 826 | .swal2-close:focus { |
|
827 | 827 | outline: 2px solid rgba(50, 100, 150, 0.4); |
|
828 | 828 | } |
|
829 | 829 | } |
|
830 | 830 | @-webkit-keyframes swal2-toast-show { |
|
831 | 831 | 0% { |
|
832 | 832 | transform: translateY(-0.625em) rotateZ(2deg); |
|
833 | 833 | } |
|
834 | 834 | 33% { |
|
835 | 835 | transform: translateY(0) rotateZ(-2deg); |
|
836 | 836 | } |
|
837 | 837 | 66% { |
|
838 | 838 | transform: translateY(0.3125em) rotateZ(2deg); |
|
839 | 839 | } |
|
840 | 840 | 100% { |
|
841 | 841 | transform: translateY(0) rotateZ(0deg); |
|
842 | 842 | } |
|
843 | 843 | } |
|
844 | 844 | @keyframes swal2-toast-show { |
|
845 | 845 | 0% { |
|
846 | 846 | transform: translateY(-0.625em) rotateZ(2deg); |
|
847 | 847 | } |
|
848 | 848 | 33% { |
|
849 | 849 | transform: translateY(0) rotateZ(-2deg); |
|
850 | 850 | } |
|
851 | 851 | 66% { |
|
852 | 852 | transform: translateY(0.3125em) rotateZ(2deg); |
|
853 | 853 | } |
|
854 | 854 | 100% { |
|
855 | 855 | transform: translateY(0) rotateZ(0deg); |
|
856 | 856 | } |
|
857 | 857 | } |
|
858 | 858 | @-webkit-keyframes swal2-toast-hide { |
|
859 | 859 | 100% { |
|
860 | 860 | transform: rotateZ(1deg); |
|
861 | 861 | opacity: 0; |
|
862 | 862 | } |
|
863 | 863 | } |
|
864 | 864 | @keyframes swal2-toast-hide { |
|
865 | 865 | 100% { |
|
866 | 866 | transform: rotateZ(1deg); |
|
867 | 867 | opacity: 0; |
|
868 | 868 | } |
|
869 | 869 | } |
|
870 | 870 | @-webkit-keyframes swal2-toast-animate-success-line-tip { |
|
871 | 871 | 0% { |
|
872 | 872 | top: 0.5625em; |
|
873 | 873 | left: 0.0625em; |
|
874 | 874 | width: 0; |
|
875 | 875 | } |
|
876 | 876 | 54% { |
|
877 | 877 | top: 0.125em; |
|
878 | 878 | left: 0.125em; |
|
879 | 879 | width: 0; |
|
880 | 880 | } |
|
881 | 881 | 70% { |
|
882 | 882 | top: 0.625em; |
|
883 | 883 | left: -0.25em; |
|
884 | 884 | width: 1.625em; |
|
885 | 885 | } |
|
886 | 886 | 84% { |
|
887 | 887 | top: 1.0625em; |
|
888 | 888 | left: 0.75em; |
|
889 | 889 | width: 0.5em; |
|
890 | 890 | } |
|
891 | 891 | 100% { |
|
892 | 892 | top: 1.125em; |
|
893 | 893 | left: 0.1875em; |
|
894 | 894 | width: 0.75em; |
|
895 | 895 | } |
|
896 | 896 | } |
|
897 | 897 | @keyframes swal2-toast-animate-success-line-tip { |
|
898 | 898 | 0% { |
|
899 | 899 | top: 0.5625em; |
|
900 | 900 | left: 0.0625em; |
|
901 | 901 | width: 0; |
|
902 | 902 | } |
|
903 | 903 | 54% { |
|
904 | 904 | top: 0.125em; |
|
905 | 905 | left: 0.125em; |
|
906 | 906 | width: 0; |
|
907 | 907 | } |
|
908 | 908 | 70% { |
|
909 | 909 | top: 0.625em; |
|
910 | 910 | left: -0.25em; |
|
911 | 911 | width: 1.625em; |
|
912 | 912 | } |
|
913 | 913 | 84% { |
|
914 | 914 | top: 1.0625em; |
|
915 | 915 | left: 0.75em; |
|
916 | 916 | width: 0.5em; |
|
917 | 917 | } |
|
918 | 918 | 100% { |
|
919 | 919 | top: 1.125em; |
|
920 | 920 | left: 0.1875em; |
|
921 | 921 | width: 0.75em; |
|
922 | 922 | } |
|
923 | 923 | } |
|
924 | 924 | @-webkit-keyframes swal2-toast-animate-success-line-long { |
|
925 | 925 | 0% { |
|
926 | 926 | top: 1.625em; |
|
927 | 927 | right: 1.375em; |
|
928 | 928 | width: 0; |
|
929 | 929 | } |
|
930 | 930 | 65% { |
|
931 | 931 | top: 1.25em; |
|
932 | 932 | right: 0.9375em; |
|
933 | 933 | width: 0; |
|
934 | 934 | } |
|
935 | 935 | 84% { |
|
936 | 936 | top: 0.9375em; |
|
937 | 937 | right: 0; |
|
938 | 938 | width: 1.125em; |
|
939 | 939 | } |
|
940 | 940 | 100% { |
|
941 | 941 | top: 0.9375em; |
|
942 | 942 | right: 0.1875em; |
|
943 | 943 | width: 1.375em; |
|
944 | 944 | } |
|
945 | 945 | } |
|
946 | 946 | @keyframes swal2-toast-animate-success-line-long { |
|
947 | 947 | 0% { |
|
948 | 948 | top: 1.625em; |
|
949 | 949 | right: 1.375em; |
|
950 | 950 | width: 0; |
|
951 | 951 | } |
|
952 | 952 | 65% { |
|
953 | 953 | top: 1.25em; |
|
954 | 954 | right: 0.9375em; |
|
955 | 955 | width: 0; |
|
956 | 956 | } |
|
957 | 957 | 84% { |
|
958 | 958 | top: 0.9375em; |
|
959 | 959 | right: 0; |
|
960 | 960 | width: 1.125em; |
|
961 | 961 | } |
|
962 | 962 | 100% { |
|
963 | 963 | top: 0.9375em; |
|
964 | 964 | right: 0.1875em; |
|
965 | 965 | width: 1.375em; |
|
966 | 966 | } |
|
967 | 967 | } |
|
968 | 968 | @-webkit-keyframes swal2-show { |
|
969 | 969 | 0% { |
|
970 | 970 | transform: scale(0.7); |
|
971 | 971 | } |
|
972 | 972 | 45% { |
|
973 | 973 | transform: scale(1.05); |
|
974 | 974 | } |
|
975 | 975 | 80% { |
|
976 | 976 | transform: scale(0.95); |
|
977 | 977 | } |
|
978 | 978 | 100% { |
|
979 | 979 | transform: scale(1); |
|
980 | 980 | } |
|
981 | 981 | } |
|
982 | 982 | @keyframes swal2-show { |
|
983 | 983 | 0% { |
|
984 | 984 | transform: scale(0.7); |
|
985 | 985 | } |
|
986 | 986 | 45% { |
|
987 | 987 | transform: scale(1.05); |
|
988 | 988 | } |
|
989 | 989 | 80% { |
|
990 | 990 | transform: scale(0.95); |
|
991 | 991 | } |
|
992 | 992 | 100% { |
|
993 | 993 | transform: scale(1); |
|
994 | 994 | } |
|
995 | 995 | } |
|
996 | 996 | @-webkit-keyframes swal2-hide { |
|
997 | 997 | 0% { |
|
998 | 998 | transform: scale(1); |
|
999 | 999 | opacity: 1; |
|
1000 | 1000 | } |
|
1001 | 1001 | 100% { |
|
1002 | 1002 | transform: scale(0.5); |
|
1003 | 1003 | opacity: 0; |
|
1004 | 1004 | } |
|
1005 | 1005 | } |
|
1006 | 1006 | @keyframes swal2-hide { |
|
1007 | 1007 | 0% { |
|
1008 | 1008 | transform: scale(1); |
|
1009 | 1009 | opacity: 1; |
|
1010 | 1010 | } |
|
1011 | 1011 | 100% { |
|
1012 | 1012 | transform: scale(0.5); |
|
1013 | 1013 | opacity: 0; |
|
1014 | 1014 | } |
|
1015 | 1015 | } |
|
1016 | 1016 | @-webkit-keyframes swal2-animate-success-line-tip { |
|
1017 | 1017 | 0% { |
|
1018 | 1018 | top: 1.1875em; |
|
1019 | 1019 | left: 0.0625em; |
|
1020 | 1020 | width: 0; |
|
1021 | 1021 | } |
|
1022 | 1022 | 54% { |
|
1023 | 1023 | top: 1.0625em; |
|
1024 | 1024 | left: 0.125em; |
|
1025 | 1025 | width: 0; |
|
1026 | 1026 | } |
|
1027 | 1027 | 70% { |
|
1028 | 1028 | top: 2.1875em; |
|
1029 | 1029 | left: -0.375em; |
|
1030 | 1030 | width: 3.125em; |
|
1031 | 1031 | } |
|
1032 | 1032 | 84% { |
|
1033 | 1033 | top: 3em; |
|
1034 | 1034 | left: 1.3125em; |
|
1035 | 1035 | width: 1.0625em; |
|
1036 | 1036 | } |
|
1037 | 1037 | 100% { |
|
1038 | 1038 | top: 2.8125em; |
|
1039 | 1039 | left: 0.8125em; |
|
1040 | 1040 | width: 1.5625em; |
|
1041 | 1041 | } |
|
1042 | 1042 | } |
|
1043 | 1043 | @keyframes swal2-animate-success-line-tip { |
|
1044 | 1044 | 0% { |
|
1045 | 1045 | top: 1.1875em; |
|
1046 | 1046 | left: 0.0625em; |
|
1047 | 1047 | width: 0; |
|
1048 | 1048 | } |
|
1049 | 1049 | 54% { |
|
1050 | 1050 | top: 1.0625em; |
|
1051 | 1051 | left: 0.125em; |
|
1052 | 1052 | width: 0; |
|
1053 | 1053 | } |
|
1054 | 1054 | 70% { |
|
1055 | 1055 | top: 2.1875em; |
|
1056 | 1056 | left: -0.375em; |
|
1057 | 1057 | width: 3.125em; |
|
1058 | 1058 | } |
|
1059 | 1059 | 84% { |
|
1060 | 1060 | top: 3em; |
|
1061 | 1061 | left: 1.3125em; |
|
1062 | 1062 | width: 1.0625em; |
|
1063 | 1063 | } |
|
1064 | 1064 | 100% { |
|
1065 | 1065 | top: 2.8125em; |
|
1066 | 1066 | left: 0.8125em; |
|
1067 | 1067 | width: 1.5625em; |
|
1068 | 1068 | } |
|
1069 | 1069 | } |
|
1070 | 1070 | @-webkit-keyframes swal2-animate-success-line-long { |
|
1071 | 1071 | 0% { |
|
1072 | 1072 | top: 3.375em; |
|
1073 | 1073 | right: 2.875em; |
|
1074 | 1074 | width: 0; |
|
1075 | 1075 | } |
|
1076 | 1076 | 65% { |
|
1077 | 1077 | top: 3.375em; |
|
1078 | 1078 | right: 2.875em; |
|
1079 | 1079 | width: 0; |
|
1080 | 1080 | } |
|
1081 | 1081 | 84% { |
|
1082 | 1082 | top: 2.1875em; |
|
1083 | 1083 | right: 0; |
|
1084 | 1084 | width: 3.4375em; |
|
1085 | 1085 | } |
|
1086 | 1086 | 100% { |
|
1087 | 1087 | top: 2.375em; |
|
1088 | 1088 | right: 0.5em; |
|
1089 | 1089 | width: 2.9375em; |
|
1090 | 1090 | } |
|
1091 | 1091 | } |
|
1092 | 1092 | @keyframes swal2-animate-success-line-long { |
|
1093 | 1093 | 0% { |
|
1094 | 1094 | top: 3.375em; |
|
1095 | 1095 | right: 2.875em; |
|
1096 | 1096 | width: 0; |
|
1097 | 1097 | } |
|
1098 | 1098 | 65% { |
|
1099 | 1099 | top: 3.375em; |
|
1100 | 1100 | right: 2.875em; |
|
1101 | 1101 | width: 0; |
|
1102 | 1102 | } |
|
1103 | 1103 | 84% { |
|
1104 | 1104 | top: 2.1875em; |
|
1105 | 1105 | right: 0; |
|
1106 | 1106 | width: 3.4375em; |
|
1107 | 1107 | } |
|
1108 | 1108 | 100% { |
|
1109 | 1109 | top: 2.375em; |
|
1110 | 1110 | right: 0.5em; |
|
1111 | 1111 | width: 2.9375em; |
|
1112 | 1112 | } |
|
1113 | 1113 | } |
|
1114 | 1114 | @-webkit-keyframes swal2-rotate-success-circular-line { |
|
1115 | 1115 | 0% { |
|
1116 | 1116 | transform: rotate(-45deg); |
|
1117 | 1117 | } |
|
1118 | 1118 | 5% { |
|
1119 | 1119 | transform: rotate(-45deg); |
|
1120 | 1120 | } |
|
1121 | 1121 | 12% { |
|
1122 | 1122 | transform: rotate(-405deg); |
|
1123 | 1123 | } |
|
1124 | 1124 | 100% { |
|
1125 | 1125 | transform: rotate(-405deg); |
|
1126 | 1126 | } |
|
1127 | 1127 | } |
|
1128 | 1128 | @keyframes swal2-rotate-success-circular-line { |
|
1129 | 1129 | 0% { |
|
1130 | 1130 | transform: rotate(-45deg); |
|
1131 | 1131 | } |
|
1132 | 1132 | 5% { |
|
1133 | 1133 | transform: rotate(-45deg); |
|
1134 | 1134 | } |
|
1135 | 1135 | 12% { |
|
1136 | 1136 | transform: rotate(-405deg); |
|
1137 | 1137 | } |
|
1138 | 1138 | 100% { |
|
1139 | 1139 | transform: rotate(-405deg); |
|
1140 | 1140 | } |
|
1141 | 1141 | } |
|
1142 | 1142 | @-webkit-keyframes swal2-animate-error-x-mark { |
|
1143 | 1143 | 0% { |
|
1144 | 1144 | margin-top: 1.625em; |
|
1145 | 1145 | transform: scale(0.4); |
|
1146 | 1146 | opacity: 0; |
|
1147 | 1147 | } |
|
1148 | 1148 | 50% { |
|
1149 | 1149 | margin-top: 1.625em; |
|
1150 | 1150 | transform: scale(0.4); |
|
1151 | 1151 | opacity: 0; |
|
1152 | 1152 | } |
|
1153 | 1153 | 80% { |
|
1154 | 1154 | margin-top: -0.375em; |
|
1155 | 1155 | transform: scale(1.15); |
|
1156 | 1156 | } |
|
1157 | 1157 | 100% { |
|
1158 | 1158 | margin-top: 0; |
|
1159 | 1159 | transform: scale(1); |
|
1160 | 1160 | opacity: 1; |
|
1161 | 1161 | } |
|
1162 | 1162 | } |
|
1163 | 1163 | @keyframes swal2-animate-error-x-mark { |
|
1164 | 1164 | 0% { |
|
1165 | 1165 | margin-top: 1.625em; |
|
1166 | 1166 | transform: scale(0.4); |
|
1167 | 1167 | opacity: 0; |
|
1168 | 1168 | } |
|
1169 | 1169 | 50% { |
|
1170 | 1170 | margin-top: 1.625em; |
|
1171 | 1171 | transform: scale(0.4); |
|
1172 | 1172 | opacity: 0; |
|
1173 | 1173 | } |
|
1174 | 1174 | 80% { |
|
1175 | 1175 | margin-top: -0.375em; |
|
1176 | 1176 | transform: scale(1.15); |
|
1177 | 1177 | } |
|
1178 | 1178 | 100% { |
|
1179 | 1179 | margin-top: 0; |
|
1180 | 1180 | transform: scale(1); |
|
1181 | 1181 | opacity: 1; |
|
1182 | 1182 | } |
|
1183 | 1183 | } |
|
1184 | 1184 | @-webkit-keyframes swal2-animate-error-icon { |
|
1185 | 1185 | 0% { |
|
1186 | 1186 | transform: rotateX(100deg); |
|
1187 | 1187 | opacity: 0; |
|
1188 | 1188 | } |
|
1189 | 1189 | 100% { |
|
1190 | 1190 | transform: rotateX(0deg); |
|
1191 | 1191 | opacity: 1; |
|
1192 | 1192 | } |
|
1193 | 1193 | } |
|
1194 | 1194 | @keyframes swal2-animate-error-icon { |
|
1195 | 1195 | 0% { |
|
1196 | 1196 | transform: rotateX(100deg); |
|
1197 | 1197 | opacity: 0; |
|
1198 | 1198 | } |
|
1199 | 1199 | 100% { |
|
1200 | 1200 | transform: rotateX(0deg); |
|
1201 | 1201 | opacity: 1; |
|
1202 | 1202 | } |
|
1203 | 1203 | } |
|
1204 | 1204 | @-webkit-keyframes swal2-rotate-loading { |
|
1205 | 1205 | 0% { |
|
1206 | 1206 | transform: rotate(0deg); |
|
1207 | 1207 | } |
|
1208 | 1208 | 100% { |
|
1209 | 1209 | transform: rotate(360deg); |
|
1210 | 1210 | } |
|
1211 | 1211 | } |
|
1212 | 1212 | @keyframes swal2-rotate-loading { |
|
1213 | 1213 | 0% { |
|
1214 | 1214 | transform: rotate(0deg); |
|
1215 | 1215 | } |
|
1216 | 1216 | 100% { |
|
1217 | 1217 | transform: rotate(360deg); |
|
1218 | 1218 | } |
|
1219 | 1219 | } |
|
1220 | 1220 | body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) { |
|
1221 | 1221 | overflow: hidden; |
|
1222 | 1222 | } |
|
1223 | 1223 | body.swal2-height-auto { |
|
1224 | 1224 | height: auto !important; |
|
1225 | 1225 | } |
|
1226 | 1226 | body.swal2-no-backdrop .swal2-container { |
|
1227 | 1227 | top: auto; |
|
1228 | 1228 | right: auto; |
|
1229 | 1229 | bottom: auto; |
|
1230 | 1230 | left: auto; |
|
1231 | 1231 | max-width: calc(100% - 0.625em * 2); |
|
1232 | 1232 | background-color: transparent !important; |
|
1233 | 1233 | } |
|
1234 | 1234 | body.swal2-no-backdrop .swal2-container > .swal2-modal { |
|
1235 | 1235 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); |
|
1236 | 1236 | } |
|
1237 | 1237 | body.swal2-no-backdrop .swal2-container.swal2-top { |
|
1238 | 1238 | top: 0; |
|
1239 | 1239 | left: 50%; |
|
1240 | 1240 | transform: translateX(-50%); |
|
1241 | 1241 | } |
|
1242 | 1242 | body.swal2-no-backdrop .swal2-container.swal2-top-start, body.swal2-no-backdrop .swal2-container.swal2-top-left { |
|
1243 | 1243 | top: 0; |
|
1244 | 1244 | left: 0; |
|
1245 | 1245 | } |
|
1246 | 1246 | body.swal2-no-backdrop .swal2-container.swal2-top-end, body.swal2-no-backdrop .swal2-container.swal2-top-right { |
|
1247 | 1247 | top: 0; |
|
1248 | 1248 | right: 0; |
|
1249 | 1249 | } |
|
1250 | 1250 | body.swal2-no-backdrop .swal2-container.swal2-center { |
|
1251 | 1251 | top: 50%; |
|
1252 | 1252 | left: 50%; |
|
1253 | 1253 | transform: translate(-50%, -50%); |
|
1254 | 1254 | } |
|
1255 | 1255 | body.swal2-no-backdrop .swal2-container.swal2-center-start, body.swal2-no-backdrop .swal2-container.swal2-center-left { |
|
1256 | 1256 | top: 50%; |
|
1257 | 1257 | left: 0; |
|
1258 | 1258 | transform: translateY(-50%); |
|
1259 | 1259 | } |
|
1260 | 1260 | body.swal2-no-backdrop .swal2-container.swal2-center-end, body.swal2-no-backdrop .swal2-container.swal2-center-right { |
|
1261 | 1261 | top: 50%; |
|
1262 | 1262 | right: 0; |
|
1263 | 1263 | transform: translateY(-50%); |
|
1264 | 1264 | } |
|
1265 | 1265 | body.swal2-no-backdrop .swal2-container.swal2-bottom { |
|
1266 | 1266 | bottom: 0; |
|
1267 | 1267 | left: 50%; |
|
1268 | 1268 | transform: translateX(-50%); |
|
1269 | 1269 | } |
|
1270 | 1270 | body.swal2-no-backdrop .swal2-container.swal2-bottom-start, body.swal2-no-backdrop .swal2-container.swal2-bottom-left { |
|
1271 | 1271 | bottom: 0; |
|
1272 | 1272 | left: 0; |
|
1273 | 1273 | } |
|
1274 | 1274 | body.swal2-no-backdrop .swal2-container.swal2-bottom-end, body.swal2-no-backdrop .swal2-container.swal2-bottom-right { |
|
1275 | 1275 | right: 0; |
|
1276 | 1276 | bottom: 0; |
|
1277 | 1277 | } |
|
1278 | 1278 | @media print { |
|
1279 | 1279 | body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) { |
|
1280 | 1280 | overflow-y: scroll !important; |
|
1281 | 1281 | } |
|
1282 | 1282 | body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) > [aria-hidden=true] { |
|
1283 | 1283 | display: none; |
|
1284 | 1284 | } |
|
1285 | 1285 | body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container { |
|
1286 | 1286 | position: static !important; |
|
1287 | 1287 | } |
|
1288 | 1288 | } |
|
1289 | 1289 | body.swal2-toast-shown .swal2-container { |
|
1290 | 1290 | background-color: transparent; |
|
1291 | 1291 | } |
|
1292 | 1292 | body.swal2-toast-shown .swal2-container.swal2-top { |
|
1293 | 1293 | top: 0; |
|
1294 | 1294 | right: auto; |
|
1295 | 1295 | bottom: auto; |
|
1296 | 1296 | left: 50%; |
|
1297 | 1297 | transform: translateX(-50%); |
|
1298 | 1298 | } |
|
1299 | 1299 | body.swal2-toast-shown .swal2-container.swal2-top-end, body.swal2-toast-shown .swal2-container.swal2-top-right { |
|
1300 | 1300 | top: 0; |
|
1301 | 1301 | right: 0; |
|
1302 | 1302 | bottom: auto; |
|
1303 | 1303 | left: auto; |
|
1304 | 1304 | } |
|
1305 | 1305 | body.swal2-toast-shown .swal2-container.swal2-top-start, body.swal2-toast-shown .swal2-container.swal2-top-left { |
|
1306 | 1306 | top: 0; |
|
1307 | 1307 | right: auto; |
|
1308 | 1308 | bottom: auto; |
|
1309 | 1309 | left: 0; |
|
1310 | 1310 | } |
|
1311 | 1311 | body.swal2-toast-shown .swal2-container.swal2-center-start, body.swal2-toast-shown .swal2-container.swal2-center-left { |
|
1312 | 1312 | top: 50%; |
|
1313 | 1313 | right: auto; |
|
1314 | 1314 | bottom: auto; |
|
1315 | 1315 | left: 0; |
|
1316 | 1316 | transform: translateY(-50%); |
|
1317 | 1317 | } |
|
1318 | 1318 | body.swal2-toast-shown .swal2-container.swal2-center { |
|
1319 | 1319 | top: 50%; |
|
1320 | 1320 | right: auto; |
|
1321 | 1321 | bottom: auto; |
|
1322 | 1322 | left: 50%; |
|
1323 | 1323 | transform: translate(-50%, -50%); |
|
1324 | 1324 | } |
|
1325 | 1325 | body.swal2-toast-shown .swal2-container.swal2-center-end, body.swal2-toast-shown .swal2-container.swal2-center-right { |
|
1326 | 1326 | top: 50%; |
|
1327 | 1327 | right: 0; |
|
1328 | 1328 | bottom: auto; |
|
1329 | 1329 | left: auto; |
|
1330 | 1330 | transform: translateY(-50%); |
|
1331 | 1331 | } |
|
1332 | 1332 | body.swal2-toast-shown .swal2-container.swal2-bottom-start, body.swal2-toast-shown .swal2-container.swal2-bottom-left { |
|
1333 | 1333 | top: auto; |
|
1334 | 1334 | right: auto; |
|
1335 | 1335 | bottom: 0; |
|
1336 | 1336 | left: 0; |
|
1337 | 1337 | } |
|
1338 | 1338 | body.swal2-toast-shown .swal2-container.swal2-bottom { |
|
1339 | 1339 | top: auto; |
|
1340 | 1340 | right: auto; |
|
1341 | 1341 | bottom: 0; |
|
1342 | 1342 | left: 50%; |
|
1343 | 1343 | transform: translateX(-50%); |
|
1344 | 1344 | } |
|
1345 | 1345 | body.swal2-toast-shown .swal2-container.swal2-bottom-end, body.swal2-toast-shown .swal2-container.swal2-bottom-right { |
|
1346 | 1346 | top: auto; |
|
1347 | 1347 | right: 0; |
|
1348 | 1348 | bottom: 0; |
|
1349 | 1349 | left: auto; |
|
1350 | 1350 | } |
|
1351 | 1351 | body.swal2-toast-column .swal2-toast { |
|
1352 | 1352 | flex-direction: column; |
|
1353 | 1353 | align-items: stretch; |
|
1354 | 1354 | } |
|
1355 | 1355 | body.swal2-toast-column .swal2-toast .swal2-actions { |
|
1356 | 1356 | flex: 1; |
|
1357 | 1357 | align-self: stretch; |
|
1358 | 1358 | height: 2.2em; |
|
1359 | 1359 | margin-top: 0.3125em; |
|
1360 | 1360 | } |
|
1361 | 1361 | body.swal2-toast-column .swal2-toast .swal2-loading { |
|
1362 | 1362 | justify-content: center; |
|
1363 | 1363 | } |
|
1364 | 1364 | body.swal2-toast-column .swal2-toast .swal2-input { |
|
1365 | 1365 | height: 2em; |
|
1366 | 1366 | margin: 0.3125em auto; |
|
1367 | 1367 | font-size: 1em; |
|
1368 | 1368 | } |
|
1369 | 1369 | body.swal2-toast-column .swal2-toast .swal2-validation-message { |
|
1370 | 1370 | font-size: 1em; |
|
1371 | 1371 | } No newline at end of file |
@@ -1,947 +1,955 b'' | |||
|
1 | 1 | // # Copyright (C) 2010-2020 RhodeCode GmbH |
|
2 | 2 | // # |
|
3 | 3 | // # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | // # it under the terms of the GNU Affero General Public License, version 3 |
|
5 | 5 | // # (only), as published by the Free Software Foundation. |
|
6 | 6 | // # |
|
7 | 7 | // # This program is distributed in the hope that it will be useful, |
|
8 | 8 | // # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9 | 9 | // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
10 | 10 | // # GNU General Public License for more details. |
|
11 | 11 | // # |
|
12 | 12 | // # You should have received a copy of the GNU Affero General Public License |
|
13 | 13 | // # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
14 | 14 | // # |
|
15 | 15 | // # This program is dual-licensed. If you wish to learn more about the |
|
16 | 16 | // # RhodeCode Enterprise Edition, including its added features, Support services, |
|
17 | 17 | // # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
18 | 18 | |
|
19 | 19 | var firefoxAnchorFix = function() { |
|
20 | 20 | // hack to make anchor links behave properly on firefox, in our inline |
|
21 | 21 | // comments generation when comments are injected firefox is misbehaving |
|
22 | 22 | // when jumping to anchor links |
|
23 | 23 | if (location.href.indexOf('#') > -1) { |
|
24 | 24 | location.href += ''; |
|
25 | 25 | } |
|
26 | 26 | }; |
|
27 | 27 | |
|
28 | 28 | var linkifyComments = function(comments) { |
|
29 | 29 | var firstCommentId = null; |
|
30 | 30 | if (comments) { |
|
31 | 31 | firstCommentId = $(comments[0]).data('comment-id'); |
|
32 | 32 | } |
|
33 | 33 | |
|
34 | 34 | if (firstCommentId){ |
|
35 | 35 | $('#inline-comments-counter').attr('href', '#comment-' + firstCommentId); |
|
36 | 36 | } |
|
37 | 37 | }; |
|
38 | 38 | |
|
39 | 39 | var bindToggleButtons = function() { |
|
40 | 40 | $('.comment-toggle').on('click', function() { |
|
41 | 41 | $(this).parent().nextUntil('tr.line').toggle('inline-comments'); |
|
42 | 42 | }); |
|
43 | 43 | }; |
|
44 | 44 | |
|
45 | 45 | |
|
46 | 46 | |
|
47 | 47 | var _submitAjaxPOST = function(url, postData, successHandler, failHandler) { |
|
48 | 48 | failHandler = failHandler || function() {}; |
|
49 | 49 | postData = toQueryString(postData); |
|
50 | 50 | var request = $.ajax({ |
|
51 | 51 | url: url, |
|
52 | 52 | type: 'POST', |
|
53 | 53 | data: postData, |
|
54 | 54 | headers: {'X-PARTIAL-XHR': true} |
|
55 | 55 | }) |
|
56 | 56 | .done(function (data) { |
|
57 | 57 | successHandler(data); |
|
58 | 58 | }) |
|
59 | 59 | .fail(function (data, textStatus, errorThrown) { |
|
60 | 60 | failHandler(data, textStatus, errorThrown) |
|
61 | 61 | }); |
|
62 | 62 | return request; |
|
63 | 63 | }; |
|
64 | 64 | |
|
65 | 65 | |
|
66 | 66 | |
|
67 | 67 | |
|
68 | 68 | /* Comment form for main and inline comments */ |
|
69 | 69 | (function(mod) { |
|
70 | 70 | |
|
71 | 71 | if (typeof exports == "object" && typeof module == "object") { |
|
72 | 72 | // CommonJS |
|
73 | 73 | module.exports = mod(); |
|
74 | 74 | } |
|
75 | 75 | else { |
|
76 | 76 | // Plain browser env |
|
77 | 77 | (this || window).CommentForm = mod(); |
|
78 | 78 | } |
|
79 | 79 | |
|
80 | 80 | })(function() { |
|
81 | 81 | "use strict"; |
|
82 | 82 | |
|
83 | 83 | function CommentForm(formElement, commitId, pullRequestId, lineNo, initAutocompleteActions, resolvesCommentId) { |
|
84 | 84 | if (!(this instanceof CommentForm)) { |
|
85 | 85 | return new CommentForm(formElement, commitId, pullRequestId, lineNo, initAutocompleteActions, resolvesCommentId); |
|
86 | 86 | } |
|
87 | 87 | |
|
88 | 88 | // bind the element instance to our Form |
|
89 | 89 | $(formElement).get(0).CommentForm = this; |
|
90 | 90 | |
|
91 | 91 | this.withLineNo = function(selector) { |
|
92 | 92 | var lineNo = this.lineNo; |
|
93 | 93 | if (lineNo === undefined) { |
|
94 | 94 | return selector |
|
95 | 95 | } else { |
|
96 | 96 | return selector + '_' + lineNo; |
|
97 | 97 | } |
|
98 | 98 | }; |
|
99 | 99 | |
|
100 | 100 | this.commitId = commitId; |
|
101 | 101 | this.pullRequestId = pullRequestId; |
|
102 | 102 | this.lineNo = lineNo; |
|
103 | 103 | this.initAutocompleteActions = initAutocompleteActions; |
|
104 | 104 | |
|
105 | 105 | this.previewButton = this.withLineNo('#preview-btn'); |
|
106 | 106 | this.previewContainer = this.withLineNo('#preview-container'); |
|
107 | 107 | |
|
108 | 108 | this.previewBoxSelector = this.withLineNo('#preview-box'); |
|
109 | 109 | |
|
110 | 110 | this.editButton = this.withLineNo('#edit-btn'); |
|
111 | 111 | this.editContainer = this.withLineNo('#edit-container'); |
|
112 | 112 | this.cancelButton = this.withLineNo('#cancel-btn'); |
|
113 | 113 | this.commentType = this.withLineNo('#comment_type'); |
|
114 | 114 | |
|
115 | 115 | this.resolvesId = null; |
|
116 | 116 | this.resolvesActionId = null; |
|
117 | 117 | |
|
118 | 118 | this.closesPr = '#close_pull_request'; |
|
119 | 119 | |
|
120 | 120 | this.cmBox = this.withLineNo('#text'); |
|
121 | 121 | this.cm = initCommentBoxCodeMirror(this, this.cmBox, this.initAutocompleteActions); |
|
122 | 122 | |
|
123 | 123 | this.statusChange = this.withLineNo('#change_status'); |
|
124 | 124 | |
|
125 | 125 | this.submitForm = formElement; |
|
126 | 126 | this.submitButton = $(this.submitForm).find('input[type="submit"]'); |
|
127 | 127 | this.submitButtonText = this.submitButton.val(); |
|
128 | 128 | |
|
129 | 129 | this.previewUrl = pyroutes.url('repo_commit_comment_preview', |
|
130 | 130 | {'repo_name': templateContext.repo_name, |
|
131 | 131 | 'commit_id': templateContext.commit_data.commit_id}); |
|
132 | 132 | |
|
133 | 133 | if (resolvesCommentId){ |
|
134 | 134 | this.resolvesId = '#resolve_comment_{0}'.format(resolvesCommentId); |
|
135 | 135 | this.resolvesActionId = '#resolve_comment_action_{0}'.format(resolvesCommentId); |
|
136 | 136 | $(this.commentType).prop('disabled', true); |
|
137 | 137 | $(this.commentType).addClass('disabled'); |
|
138 | 138 | |
|
139 | 139 | // disable select |
|
140 | 140 | setTimeout(function() { |
|
141 | 141 | $(self.statusChange).select2('readonly', true); |
|
142 | 142 | }, 10); |
|
143 | 143 | |
|
144 | 144 | var resolvedInfo = ( |
|
145 | 145 | '<li class="resolve-action">' + |
|
146 | 146 | '<input type="hidden" id="resolve_comment_{0}" name="resolve_comment_{0}" value="{0}">' + |
|
147 | 147 | '<button id="resolve_comment_action_{0}" class="resolve-text btn btn-sm" onclick="return Rhodecode.comments.submitResolution({0})">{1} #{0}</button>' + |
|
148 | 148 | '</li>' |
|
149 | 149 | ).format(resolvesCommentId, _gettext('resolve comment')); |
|
150 | 150 | $(resolvedInfo).insertAfter($(this.commentType).parent()); |
|
151 | 151 | } |
|
152 | 152 | |
|
153 | 153 | // based on commitId, or pullRequestId decide where do we submit |
|
154 | 154 | // out data |
|
155 | 155 | if (this.commitId){ |
|
156 | 156 | this.submitUrl = pyroutes.url('repo_commit_comment_create', |
|
157 | 157 | {'repo_name': templateContext.repo_name, |
|
158 | 158 | 'commit_id': this.commitId}); |
|
159 | 159 | this.selfUrl = pyroutes.url('repo_commit', |
|
160 | 160 | {'repo_name': templateContext.repo_name, |
|
161 | 161 | 'commit_id': this.commitId}); |
|
162 | 162 | |
|
163 | 163 | } else if (this.pullRequestId) { |
|
164 | 164 | this.submitUrl = pyroutes.url('pullrequest_comment_create', |
|
165 | 165 | {'repo_name': templateContext.repo_name, |
|
166 | 166 | 'pull_request_id': this.pullRequestId}); |
|
167 | 167 | this.selfUrl = pyroutes.url('pullrequest_show', |
|
168 | 168 | {'repo_name': templateContext.repo_name, |
|
169 | 169 | 'pull_request_id': this.pullRequestId}); |
|
170 | 170 | |
|
171 | 171 | } else { |
|
172 | 172 | throw new Error( |
|
173 | 173 | 'CommentForm requires pullRequestId, or commitId to be specified.') |
|
174 | 174 | } |
|
175 | 175 | |
|
176 | 176 | // FUNCTIONS and helpers |
|
177 | 177 | var self = this; |
|
178 | 178 | |
|
179 | 179 | this.isInline = function(){ |
|
180 | 180 | return this.lineNo && this.lineNo != 'general'; |
|
181 | 181 | }; |
|
182 | 182 | |
|
183 | 183 | this.getCmInstance = function(){ |
|
184 | 184 | return this.cm |
|
185 | 185 | }; |
|
186 | 186 | |
|
187 | 187 | this.setPlaceholder = function(placeholder) { |
|
188 | 188 | var cm = this.getCmInstance(); |
|
189 | 189 | if (cm){ |
|
190 | 190 | cm.setOption('placeholder', placeholder); |
|
191 | 191 | } |
|
192 | 192 | }; |
|
193 | 193 | |
|
194 | 194 | this.getCommentStatus = function() { |
|
195 | 195 | return $(this.submitForm).find(this.statusChange).val(); |
|
196 | 196 | }; |
|
197 | 197 | this.getCommentType = function() { |
|
198 | 198 | return $(this.submitForm).find(this.commentType).val(); |
|
199 | 199 | }; |
|
200 | 200 | |
|
201 | 201 | this.getResolvesId = function() { |
|
202 | 202 | return $(this.submitForm).find(this.resolvesId).val() || null; |
|
203 | 203 | }; |
|
204 | 204 | |
|
205 | 205 | this.getClosePr = function() { |
|
206 | 206 | return $(this.submitForm).find(this.closesPr).val() || null; |
|
207 | 207 | }; |
|
208 | 208 | |
|
209 | 209 | this.markCommentResolved = function(resolvedCommentId){ |
|
210 | 210 | $('#comment-label-{0}'.format(resolvedCommentId)).find('.resolved').show(); |
|
211 | 211 | $('#comment-label-{0}'.format(resolvedCommentId)).find('.resolve').hide(); |
|
212 | 212 | }; |
|
213 | 213 | |
|
214 | 214 | this.isAllowedToSubmit = function() { |
|
215 | 215 | return !$(this.submitButton).prop('disabled'); |
|
216 | 216 | }; |
|
217 | 217 | |
|
218 | 218 | this.initStatusChangeSelector = function(){ |
|
219 | 219 | var formatChangeStatus = function(state, escapeMarkup) { |
|
220 | 220 | var originalOption = state.element; |
|
221 | 221 | var tmpl = '<i class="icon-circle review-status-{0}"></i><span>{1}</span>'.format($(originalOption).data('status'), escapeMarkup(state.text)); |
|
222 | 222 | return tmpl |
|
223 | 223 | }; |
|
224 | 224 | var formatResult = function(result, container, query, escapeMarkup) { |
|
225 | 225 | return formatChangeStatus(result, escapeMarkup); |
|
226 | 226 | }; |
|
227 | 227 | |
|
228 | 228 | var formatSelection = function(data, container, escapeMarkup) { |
|
229 | 229 | return formatChangeStatus(data, escapeMarkup); |
|
230 | 230 | }; |
|
231 | 231 | |
|
232 | 232 | $(this.submitForm).find(this.statusChange).select2({ |
|
233 | 233 | placeholder: _gettext('Status Review'), |
|
234 | 234 | formatResult: formatResult, |
|
235 | 235 | formatSelection: formatSelection, |
|
236 | 236 | containerCssClass: "drop-menu status_box_menu", |
|
237 | 237 | dropdownCssClass: "drop-menu-dropdown", |
|
238 | 238 | dropdownAutoWidth: true, |
|
239 | 239 | minimumResultsForSearch: -1 |
|
240 | 240 | }); |
|
241 | 241 | $(this.submitForm).find(this.statusChange).on('change', function() { |
|
242 | 242 | var status = self.getCommentStatus(); |
|
243 | 243 | |
|
244 | 244 | if (status && !self.isInline()) { |
|
245 | 245 | $(self.submitButton).prop('disabled', false); |
|
246 | 246 | } |
|
247 | 247 | |
|
248 | 248 | var placeholderText = _gettext('Comment text will be set automatically based on currently selected status ({0}) ...').format(status); |
|
249 | 249 | self.setPlaceholder(placeholderText) |
|
250 | 250 | }) |
|
251 | 251 | }; |
|
252 | 252 | |
|
253 | 253 | // reset the comment form into it's original state |
|
254 | 254 | this.resetCommentFormState = function(content) { |
|
255 | 255 | content = content || ''; |
|
256 | 256 | |
|
257 | 257 | $(this.editContainer).show(); |
|
258 | 258 | $(this.editButton).parent().addClass('active'); |
|
259 | 259 | |
|
260 | 260 | $(this.previewContainer).hide(); |
|
261 | 261 | $(this.previewButton).parent().removeClass('active'); |
|
262 | 262 | |
|
263 | 263 | this.setActionButtonsDisabled(true); |
|
264 | 264 | self.cm.setValue(content); |
|
265 | 265 | self.cm.setOption("readOnly", false); |
|
266 | 266 | |
|
267 | 267 | if (this.resolvesId) { |
|
268 | 268 | // destroy the resolve action |
|
269 | 269 | $(this.resolvesId).parent().remove(); |
|
270 | 270 | } |
|
271 | 271 | // reset closingPR flag |
|
272 | 272 | $('.close-pr-input').remove(); |
|
273 | 273 | |
|
274 | 274 | $(this.statusChange).select2('readonly', false); |
|
275 | 275 | }; |
|
276 | 276 | |
|
277 | 277 | this.globalSubmitSuccessCallback = function(){ |
|
278 | 278 | // default behaviour is to call GLOBAL hook, if it's registered. |
|
279 | 279 | if (window.commentFormGlobalSubmitSuccessCallback !== undefined){ |
|
280 | 280 | commentFormGlobalSubmitSuccessCallback() |
|
281 | 281 | } |
|
282 | 282 | }; |
|
283 | 283 | |
|
284 | 284 | this.submitAjaxPOST = function(url, postData, successHandler, failHandler) { |
|
285 | 285 | return _submitAjaxPOST(url, postData, successHandler, failHandler); |
|
286 | 286 | }; |
|
287 | 287 | |
|
288 | 288 | // overwrite a submitHandler, we need to do it for inline comments |
|
289 | 289 | this.setHandleFormSubmit = function(callback) { |
|
290 | 290 | this.handleFormSubmit = callback; |
|
291 | 291 | }; |
|
292 | 292 | |
|
293 | 293 | // overwrite a submitSuccessHandler |
|
294 | 294 | this.setGlobalSubmitSuccessCallback = function(callback) { |
|
295 | 295 | this.globalSubmitSuccessCallback = callback; |
|
296 | 296 | }; |
|
297 | 297 | |
|
298 | 298 | // default handler for for submit for main comments |
|
299 | 299 | this.handleFormSubmit = function() { |
|
300 | 300 | var text = self.cm.getValue(); |
|
301 | 301 | var status = self.getCommentStatus(); |
|
302 | 302 | var commentType = self.getCommentType(); |
|
303 | 303 | var resolvesCommentId = self.getResolvesId(); |
|
304 | 304 | var closePullRequest = self.getClosePr(); |
|
305 | 305 | |
|
306 | 306 | if (text === "" && !status) { |
|
307 | 307 | return; |
|
308 | 308 | } |
|
309 | 309 | |
|
310 | 310 | var excludeCancelBtn = false; |
|
311 | 311 | var submitEvent = true; |
|
312 | 312 | self.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent); |
|
313 | 313 | self.cm.setOption("readOnly", true); |
|
314 | 314 | |
|
315 | 315 | var postData = { |
|
316 | 316 | 'text': text, |
|
317 | 317 | 'changeset_status': status, |
|
318 | 318 | 'comment_type': commentType, |
|
319 | 319 | 'csrf_token': CSRF_TOKEN |
|
320 | 320 | }; |
|
321 | 321 | |
|
322 | 322 | if (resolvesCommentId) { |
|
323 | 323 | postData['resolves_comment_id'] = resolvesCommentId; |
|
324 | 324 | } |
|
325 | 325 | |
|
326 | 326 | if (closePullRequest) { |
|
327 | 327 | postData['close_pull_request'] = true; |
|
328 | 328 | } |
|
329 | 329 | |
|
330 | 330 | var submitSuccessCallback = function(o) { |
|
331 | 331 | // reload page if we change status for single commit. |
|
332 | 332 | if (status && self.commitId) { |
|
333 | 333 | location.reload(true); |
|
334 | 334 | } else { |
|
335 | 335 | $('#injected_page_comments').append(o.rendered_text); |
|
336 | 336 | self.resetCommentFormState(); |
|
337 | 337 | timeagoActivate(); |
|
338 | 338 | tooltipActivate(); |
|
339 | 339 | |
|
340 | 340 | // mark visually which comment was resolved |
|
341 | 341 | if (resolvesCommentId) { |
|
342 | 342 | self.markCommentResolved(resolvesCommentId); |
|
343 | 343 | } |
|
344 | 344 | } |
|
345 | 345 | |
|
346 | 346 | // run global callback on submit |
|
347 | 347 | self.globalSubmitSuccessCallback(); |
|
348 | 348 | |
|
349 | 349 | }; |
|
350 | 350 | var submitFailCallback = function(jqXHR, textStatus, errorThrown) { |
|
351 | 351 | var prefix = "Error while submitting comment.\n" |
|
352 | 352 | var message = formatErrorMessage(jqXHR, textStatus, errorThrown, prefix); |
|
353 | 353 | ajaxErrorSwal(message); |
|
354 | 354 | self.resetCommentFormState(text); |
|
355 | 355 | }; |
|
356 | 356 | self.submitAjaxPOST( |
|
357 | 357 | self.submitUrl, postData, submitSuccessCallback, submitFailCallback); |
|
358 | 358 | }; |
|
359 | 359 | |
|
360 | 360 | this.previewSuccessCallback = function(o) { |
|
361 | 361 | $(self.previewBoxSelector).html(o); |
|
362 | 362 | $(self.previewBoxSelector).removeClass('unloaded'); |
|
363 | 363 | |
|
364 | 364 | // swap buttons, making preview active |
|
365 | 365 | $(self.previewButton).parent().addClass('active'); |
|
366 | 366 | $(self.editButton).parent().removeClass('active'); |
|
367 | 367 | |
|
368 | 368 | // unlock buttons |
|
369 | 369 | self.setActionButtonsDisabled(false); |
|
370 | 370 | }; |
|
371 | 371 | |
|
372 | 372 | this.setActionButtonsDisabled = function(state, excludeCancelBtn, submitEvent) { |
|
373 | 373 | excludeCancelBtn = excludeCancelBtn || false; |
|
374 | 374 | submitEvent = submitEvent || false; |
|
375 | 375 | |
|
376 | 376 | $(this.editButton).prop('disabled', state); |
|
377 | 377 | $(this.previewButton).prop('disabled', state); |
|
378 | 378 | |
|
379 | 379 | if (!excludeCancelBtn) { |
|
380 | 380 | $(this.cancelButton).prop('disabled', state); |
|
381 | 381 | } |
|
382 | 382 | |
|
383 | 383 | var submitState = state; |
|
384 | 384 | if (!submitEvent && this.getCommentStatus() && !self.isInline()) { |
|
385 | 385 | // if the value of commit review status is set, we allow |
|
386 | 386 | // submit button, but only on Main form, isInline means inline |
|
387 | 387 | submitState = false |
|
388 | 388 | } |
|
389 | 389 | |
|
390 | 390 | $(this.submitButton).prop('disabled', submitState); |
|
391 | 391 | if (submitEvent) { |
|
392 | 392 | $(this.submitButton).val(_gettext('Submitting...')); |
|
393 | 393 | } else { |
|
394 | 394 | $(this.submitButton).val(this.submitButtonText); |
|
395 | 395 | } |
|
396 | 396 | |
|
397 | 397 | }; |
|
398 | 398 | |
|
399 | 399 | // lock preview/edit/submit buttons on load, but exclude cancel button |
|
400 | 400 | var excludeCancelBtn = true; |
|
401 | 401 | this.setActionButtonsDisabled(true, excludeCancelBtn); |
|
402 | 402 | |
|
403 | 403 | // anonymous users don't have access to initialized CM instance |
|
404 | 404 | if (this.cm !== undefined){ |
|
405 | 405 | this.cm.on('change', function(cMirror) { |
|
406 | 406 | if (cMirror.getValue() === "") { |
|
407 | 407 | self.setActionButtonsDisabled(true, excludeCancelBtn) |
|
408 | 408 | } else { |
|
409 | 409 | self.setActionButtonsDisabled(false, excludeCancelBtn) |
|
410 | 410 | } |
|
411 | 411 | }); |
|
412 | 412 | } |
|
413 | 413 | |
|
414 | 414 | $(this.editButton).on('click', function(e) { |
|
415 | 415 | e.preventDefault(); |
|
416 | 416 | |
|
417 | 417 | $(self.previewButton).parent().removeClass('active'); |
|
418 | 418 | $(self.previewContainer).hide(); |
|
419 | 419 | |
|
420 | 420 | $(self.editButton).parent().addClass('active'); |
|
421 | 421 | $(self.editContainer).show(); |
|
422 | 422 | |
|
423 | 423 | }); |
|
424 | 424 | |
|
425 | 425 | $(this.previewButton).on('click', function(e) { |
|
426 | 426 | e.preventDefault(); |
|
427 | 427 | var text = self.cm.getValue(); |
|
428 | 428 | |
|
429 | 429 | if (text === "") { |
|
430 | 430 | return; |
|
431 | 431 | } |
|
432 | 432 | |
|
433 | 433 | var postData = { |
|
434 | 434 | 'text': text, |
|
435 | 435 | 'renderer': templateContext.visual.default_renderer, |
|
436 | 436 | 'csrf_token': CSRF_TOKEN |
|
437 | 437 | }; |
|
438 | 438 | |
|
439 | 439 | // lock ALL buttons on preview |
|
440 | 440 | self.setActionButtonsDisabled(true); |
|
441 | 441 | |
|
442 | 442 | $(self.previewBoxSelector).addClass('unloaded'); |
|
443 | 443 | $(self.previewBoxSelector).html(_gettext('Loading ...')); |
|
444 | 444 | |
|
445 | 445 | $(self.editContainer).hide(); |
|
446 | 446 | $(self.previewContainer).show(); |
|
447 | 447 | |
|
448 | 448 | // by default we reset state of comment preserving the text |
|
449 | 449 | var previewFailCallback = function(jqXHR, textStatus, errorThrown) { |
|
450 | 450 | var prefix = "Error while preview of comment.\n" |
|
451 | 451 | var message = formatErrorMessage(jqXHR, textStatus, errorThrown, prefix); |
|
452 | 452 | ajaxErrorSwal(message); |
|
453 | 453 | |
|
454 | 454 | self.resetCommentFormState(text) |
|
455 | 455 | }; |
|
456 | 456 | self.submitAjaxPOST( |
|
457 | 457 | self.previewUrl, postData, self.previewSuccessCallback, |
|
458 | 458 | previewFailCallback); |
|
459 | 459 | |
|
460 | 460 | $(self.previewButton).parent().addClass('active'); |
|
461 | 461 | $(self.editButton).parent().removeClass('active'); |
|
462 | 462 | }); |
|
463 | 463 | |
|
464 | 464 | $(this.submitForm).submit(function(e) { |
|
465 | 465 | e.preventDefault(); |
|
466 | 466 | var allowedToSubmit = self.isAllowedToSubmit(); |
|
467 | 467 | if (!allowedToSubmit){ |
|
468 | 468 | return false; |
|
469 | 469 | } |
|
470 | 470 | self.handleFormSubmit(); |
|
471 | 471 | }); |
|
472 | 472 | |
|
473 | 473 | } |
|
474 | 474 | |
|
475 | 475 | return CommentForm; |
|
476 | 476 | }); |
|
477 | 477 | |
|
478 | 478 | /* comments controller */ |
|
479 | 479 | var CommentsController = function() { |
|
480 | 480 | var mainComment = '#text'; |
|
481 | 481 | var self = this; |
|
482 | 482 | |
|
483 | 483 | this.cancelComment = function(node) { |
|
484 | 484 | var $node = $(node); |
|
485 | 485 | var $td = $node.closest('td'); |
|
486 | 486 | $node.closest('.comment-inline-form').remove(); |
|
487 | 487 | return false; |
|
488 | 488 | }; |
|
489 | 489 | |
|
490 | 490 | this.getLineNumber = function(node) { |
|
491 | 491 | var $node = $(node); |
|
492 | 492 | var lineNo = $node.closest('td').attr('data-line-no'); |
|
493 | 493 | if (lineNo === undefined && $node.data('commentInline')){ |
|
494 | 494 | lineNo = $node.data('commentLineNo') |
|
495 | 495 | } |
|
496 | 496 | |
|
497 | 497 | return lineNo |
|
498 | 498 | }; |
|
499 | 499 | |
|
500 | 500 | this.scrollToComment = function(node, offset, outdated) { |
|
501 | 501 | if (offset === undefined) { |
|
502 | 502 | offset = 0; |
|
503 | 503 | } |
|
504 | 504 | var outdated = outdated || false; |
|
505 | 505 | var klass = outdated ? 'div.comment-outdated' : 'div.comment-current'; |
|
506 | 506 | |
|
507 | 507 | if (!node) { |
|
508 | 508 | node = $('.comment-selected'); |
|
509 | 509 | if (!node.length) { |
|
510 | 510 | node = $('comment-current') |
|
511 | 511 | } |
|
512 | 512 | } |
|
513 | 513 | |
|
514 | 514 | $wrapper = $(node).closest('div.comment'); |
|
515 | 515 | |
|
516 | 516 | // show hidden comment when referenced. |
|
517 | 517 | if (!$wrapper.is(':visible')){ |
|
518 | 518 | $wrapper.show(); |
|
519 | 519 | } |
|
520 | 520 | |
|
521 | 521 | $comment = $(node).closest(klass); |
|
522 | 522 | $comments = $(klass); |
|
523 | 523 | |
|
524 | 524 | $('.comment-selected').removeClass('comment-selected'); |
|
525 | 525 | |
|
526 | 526 | var nextIdx = $(klass).index($comment) + offset; |
|
527 | 527 | if (nextIdx >= $comments.length) { |
|
528 | 528 | nextIdx = 0; |
|
529 | 529 | } |
|
530 | 530 | var $next = $(klass).eq(nextIdx); |
|
531 | 531 | |
|
532 | 532 | var $cb = $next.closest('.cb'); |
|
533 | 533 | $cb.removeClass('cb-collapsed'); |
|
534 | 534 | |
|
535 | 535 | var $filediffCollapseState = $cb.closest('.filediff').prev(); |
|
536 | 536 | $filediffCollapseState.prop('checked', false); |
|
537 | 537 | $next.addClass('comment-selected'); |
|
538 | 538 | scrollToElement($next); |
|
539 | 539 | return false; |
|
540 | 540 | }; |
|
541 | 541 | |
|
542 | 542 | this.nextComment = function(node) { |
|
543 | 543 | return self.scrollToComment(node, 1); |
|
544 | 544 | }; |
|
545 | 545 | |
|
546 | 546 | this.prevComment = function(node) { |
|
547 | 547 | return self.scrollToComment(node, -1); |
|
548 | 548 | }; |
|
549 | 549 | |
|
550 | 550 | this.nextOutdatedComment = function(node) { |
|
551 | 551 | return self.scrollToComment(node, 1, true); |
|
552 | 552 | }; |
|
553 | 553 | |
|
554 | 554 | this.prevOutdatedComment = function(node) { |
|
555 | 555 | return self.scrollToComment(node, -1, true); |
|
556 | 556 | }; |
|
557 | 557 | |
|
558 | 558 | this._deleteComment = function(node) { |
|
559 | 559 | var $node = $(node); |
|
560 | 560 | var $td = $node.closest('td'); |
|
561 | 561 | var $comment = $node.closest('.comment'); |
|
562 | 562 | var comment_id = $comment.attr('data-comment-id'); |
|
563 | 563 | var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id); |
|
564 | 564 | var postData = { |
|
565 | 565 | 'csrf_token': CSRF_TOKEN |
|
566 | 566 | }; |
|
567 | 567 | |
|
568 | 568 | $comment.addClass('comment-deleting'); |
|
569 | 569 | $comment.hide('fast'); |
|
570 | 570 | |
|
571 | 571 | var success = function(response) { |
|
572 | 572 | $comment.remove(); |
|
573 | 573 | return false; |
|
574 | 574 | }; |
|
575 | 575 | var failure = function(jqXHR, textStatus, errorThrown) { |
|
576 | 576 | var prefix = "Error while deleting this comment.\n" |
|
577 | 577 | var message = formatErrorMessage(jqXHR, textStatus, errorThrown, prefix); |
|
578 | 578 | ajaxErrorSwal(message); |
|
579 | 579 | |
|
580 | 580 | $comment.show('fast'); |
|
581 | 581 | $comment.removeClass('comment-deleting'); |
|
582 | 582 | return false; |
|
583 | 583 | }; |
|
584 | 584 | ajaxPOST(url, postData, success, failure); |
|
585 | 585 | } |
|
586 | 586 | |
|
587 | 587 | this.deleteComment = function(node) { |
|
588 | 588 | var $comment = $(node).closest('.comment'); |
|
589 | 589 | var comment_id = $comment.attr('data-comment-id'); |
|
590 | 590 | |
|
591 | 591 | Swal.fire({ |
|
592 | 592 | title: 'Delete this comment?', |
|
593 | 593 | icon: 'warning', |
|
594 | 594 | showCancelButton: true, |
|
595 | 595 | confirmButtonColor: '#84a5d2', |
|
596 | 596 | cancelButtonColor: '#e85e4d', |
|
597 | confirmButtonText: _gettext('Yes, delete comment #{0}!').format(comment_id) | |
|
597 | confirmButtonText: _gettext('Yes, delete comment #{0}!').format(comment_id), | |
|
598 | showClass: { | |
|
599 | popup: 'swal2-noanimation', | |
|
600 | backdrop: 'swal2-noanimation' | |
|
601 | }, | |
|
602 | hideClass: { | |
|
603 | popup: '', | |
|
604 | backdrop: '' | |
|
605 | } | |
|
598 | 606 | }).then(function(result) { |
|
599 | 607 | if (result.value) { |
|
600 | 608 | self._deleteComment(node); |
|
601 | 609 | } |
|
602 | 610 | }) |
|
603 | 611 | }; |
|
604 | 612 | |
|
605 | 613 | this.toggleWideMode = function (node) { |
|
606 | 614 | if ($('#content').hasClass('wrapper')) { |
|
607 | 615 | $('#content').removeClass("wrapper"); |
|
608 | 616 | $('#content').addClass("wide-mode-wrapper"); |
|
609 | 617 | $(node).addClass('btn-success'); |
|
610 | 618 | return true |
|
611 | 619 | } else { |
|
612 | 620 | $('#content').removeClass("wide-mode-wrapper"); |
|
613 | 621 | $('#content').addClass("wrapper"); |
|
614 | 622 | $(node).removeClass('btn-success'); |
|
615 | 623 | return false |
|
616 | 624 | } |
|
617 | 625 | |
|
618 | 626 | }; |
|
619 | 627 | |
|
620 | 628 | this.toggleComments = function(node, show) { |
|
621 | 629 | var $filediff = $(node).closest('.filediff'); |
|
622 | 630 | if (show === true) { |
|
623 | 631 | $filediff.removeClass('hide-comments'); |
|
624 | 632 | } else if (show === false) { |
|
625 | 633 | $filediff.find('.hide-line-comments').removeClass('hide-line-comments'); |
|
626 | 634 | $filediff.addClass('hide-comments'); |
|
627 | 635 | } else { |
|
628 | 636 | $filediff.find('.hide-line-comments').removeClass('hide-line-comments'); |
|
629 | 637 | $filediff.toggleClass('hide-comments'); |
|
630 | 638 | } |
|
631 | 639 | return false; |
|
632 | 640 | }; |
|
633 | 641 | |
|
634 | 642 | this.toggleLineComments = function(node) { |
|
635 | 643 | self.toggleComments(node, true); |
|
636 | 644 | var $node = $(node); |
|
637 | 645 | // mark outdated comments as visible before the toggle; |
|
638 | 646 | $(node.closest('tr')).find('.comment-outdated').show(); |
|
639 | 647 | $node.closest('tr').toggleClass('hide-line-comments'); |
|
640 | 648 | }; |
|
641 | 649 | |
|
642 | 650 | this.createCommentForm = function(formElement, lineno, placeholderText, initAutocompleteActions, resolvesCommentId){ |
|
643 | 651 | var pullRequestId = templateContext.pull_request_data.pull_request_id; |
|
644 | 652 | var commitId = templateContext.commit_data.commit_id; |
|
645 | 653 | |
|
646 | 654 | var commentForm = new CommentForm( |
|
647 | 655 | formElement, commitId, pullRequestId, lineno, initAutocompleteActions, resolvesCommentId); |
|
648 | 656 | var cm = commentForm.getCmInstance(); |
|
649 | 657 | |
|
650 | 658 | if (resolvesCommentId){ |
|
651 | 659 | var placeholderText = _gettext('Leave a resolution comment, or click resolve button to resolve TODO comment #{0}').format(resolvesCommentId); |
|
652 | 660 | } |
|
653 | 661 | |
|
654 | 662 | setTimeout(function() { |
|
655 | 663 | // callbacks |
|
656 | 664 | if (cm !== undefined) { |
|
657 | 665 | commentForm.setPlaceholder(placeholderText); |
|
658 | 666 | if (commentForm.isInline()) { |
|
659 | 667 | cm.focus(); |
|
660 | 668 | cm.refresh(); |
|
661 | 669 | } |
|
662 | 670 | } |
|
663 | 671 | }, 10); |
|
664 | 672 | |
|
665 | 673 | // trigger scrolldown to the resolve comment, since it might be away |
|
666 | 674 | // from the clicked |
|
667 | 675 | if (resolvesCommentId){ |
|
668 | 676 | var actionNode = $(commentForm.resolvesActionId).offset(); |
|
669 | 677 | |
|
670 | 678 | setTimeout(function() { |
|
671 | 679 | if (actionNode) { |
|
672 | 680 | $('body, html').animate({scrollTop: actionNode.top}, 10); |
|
673 | 681 | } |
|
674 | 682 | }, 100); |
|
675 | 683 | } |
|
676 | 684 | |
|
677 | 685 | // add dropzone support |
|
678 | 686 | var insertAttachmentText = function (cm, attachmentName, attachmentStoreUrl, isRendered) { |
|
679 | 687 | var renderer = templateContext.visual.default_renderer; |
|
680 | 688 | if (renderer == 'rst') { |
|
681 | 689 | var attachmentUrl = '`#{0} <{1}>`_'.format(attachmentName, attachmentStoreUrl); |
|
682 | 690 | if (isRendered){ |
|
683 | 691 | attachmentUrl = '\n.. image:: {0}'.format(attachmentStoreUrl); |
|
684 | 692 | } |
|
685 | 693 | } else if (renderer == 'markdown') { |
|
686 | 694 | var attachmentUrl = '[{0}]({1})'.format(attachmentName, attachmentStoreUrl); |
|
687 | 695 | if (isRendered){ |
|
688 | 696 | attachmentUrl = '!' + attachmentUrl; |
|
689 | 697 | } |
|
690 | 698 | } else { |
|
691 | 699 | var attachmentUrl = '{}'.format(attachmentStoreUrl); |
|
692 | 700 | } |
|
693 | 701 | cm.replaceRange(attachmentUrl+'\n', CodeMirror.Pos(cm.lastLine())); |
|
694 | 702 | |
|
695 | 703 | return false; |
|
696 | 704 | }; |
|
697 | 705 | |
|
698 | 706 | //see: https://www.dropzonejs.com/#configuration |
|
699 | 707 | var storeUrl = pyroutes.url('repo_commit_comment_attachment_upload', |
|
700 | 708 | {'repo_name': templateContext.repo_name, |
|
701 | 709 | 'commit_id': templateContext.commit_data.commit_id}) |
|
702 | 710 | |
|
703 | 711 | var previewTmpl = $(formElement).find('.comment-attachment-uploader-template').get(0); |
|
704 | 712 | if (previewTmpl !== undefined){ |
|
705 | 713 | var selectLink = $(formElement).find('.pick-attachment').get(0); |
|
706 | 714 | $(formElement).find('.comment-attachment-uploader').dropzone({ |
|
707 | 715 | url: storeUrl, |
|
708 | 716 | headers: {"X-CSRF-Token": CSRF_TOKEN}, |
|
709 | 717 | paramName: function () { |
|
710 | 718 | return "attachment" |
|
711 | 719 | }, // The name that will be used to transfer the file |
|
712 | 720 | clickable: selectLink, |
|
713 | 721 | parallelUploads: 1, |
|
714 | 722 | maxFiles: 10, |
|
715 | 723 | maxFilesize: templateContext.attachment_store.max_file_size_mb, |
|
716 | 724 | uploadMultiple: false, |
|
717 | 725 | autoProcessQueue: true, // if false queue will not be processed automatically. |
|
718 | 726 | createImageThumbnails: false, |
|
719 | 727 | previewTemplate: previewTmpl.innerHTML, |
|
720 | 728 | |
|
721 | 729 | accept: function (file, done) { |
|
722 | 730 | done(); |
|
723 | 731 | }, |
|
724 | 732 | init: function () { |
|
725 | 733 | |
|
726 | 734 | this.on("sending", function (file, xhr, formData) { |
|
727 | 735 | $(formElement).find('.comment-attachment-uploader').find('.dropzone-text').hide(); |
|
728 | 736 | $(formElement).find('.comment-attachment-uploader').find('.dropzone-upload').show(); |
|
729 | 737 | }); |
|
730 | 738 | |
|
731 | 739 | this.on("success", function (file, response) { |
|
732 | 740 | $(formElement).find('.comment-attachment-uploader').find('.dropzone-text').show(); |
|
733 | 741 | $(formElement).find('.comment-attachment-uploader').find('.dropzone-upload').hide(); |
|
734 | 742 | |
|
735 | 743 | var isRendered = false; |
|
736 | 744 | var ext = file.name.split('.').pop(); |
|
737 | 745 | var imageExts = templateContext.attachment_store.image_ext; |
|
738 | 746 | if (imageExts.indexOf(ext) !== -1){ |
|
739 | 747 | isRendered = true; |
|
740 | 748 | } |
|
741 | 749 | |
|
742 | 750 | insertAttachmentText(cm, file.name, response.repo_fqn_access_path, isRendered) |
|
743 | 751 | }); |
|
744 | 752 | |
|
745 | 753 | this.on("error", function (file, errorMessage, xhr) { |
|
746 | 754 | $(formElement).find('.comment-attachment-uploader').find('.dropzone-upload').hide(); |
|
747 | 755 | |
|
748 | 756 | var error = null; |
|
749 | 757 | |
|
750 | 758 | if (xhr !== undefined){ |
|
751 | 759 | var httpStatus = xhr.status + " " + xhr.statusText; |
|
752 | 760 | if (xhr !== undefined && xhr.status >= 500) { |
|
753 | 761 | error = httpStatus; |
|
754 | 762 | } |
|
755 | 763 | } |
|
756 | 764 | |
|
757 | 765 | if (error === null) { |
|
758 | 766 | error = errorMessage.error || errorMessage || httpStatus; |
|
759 | 767 | } |
|
760 | 768 | $(file.previewElement).find('.dz-error-message').html('ERROR: {0}'.format(error)); |
|
761 | 769 | |
|
762 | 770 | }); |
|
763 | 771 | } |
|
764 | 772 | }); |
|
765 | 773 | } |
|
766 | 774 | return commentForm; |
|
767 | 775 | }; |
|
768 | 776 | |
|
769 | 777 | this.createGeneralComment = function (lineNo, placeholderText, resolvesCommentId) { |
|
770 | 778 | |
|
771 | 779 | var tmpl = $('#cb-comment-general-form-template').html(); |
|
772 | 780 | tmpl = tmpl.format(null, 'general'); |
|
773 | 781 | var $form = $(tmpl); |
|
774 | 782 | |
|
775 | 783 | var $formPlaceholder = $('#cb-comment-general-form-placeholder'); |
|
776 | 784 | var curForm = $formPlaceholder.find('form'); |
|
777 | 785 | if (curForm){ |
|
778 | 786 | curForm.remove(); |
|
779 | 787 | } |
|
780 | 788 | $formPlaceholder.append($form); |
|
781 | 789 | |
|
782 | 790 | var _form = $($form[0]); |
|
783 | 791 | var autocompleteActions = ['approve', 'reject', 'as_note', 'as_todo']; |
|
784 | 792 | var commentForm = this.createCommentForm( |
|
785 | 793 | _form, lineNo, placeholderText, autocompleteActions, resolvesCommentId); |
|
786 | 794 | commentForm.initStatusChangeSelector(); |
|
787 | 795 | |
|
788 | 796 | return commentForm; |
|
789 | 797 | }; |
|
790 | 798 | |
|
791 | 799 | this.createComment = function(node, resolutionComment) { |
|
792 | 800 | var resolvesCommentId = resolutionComment || null; |
|
793 | 801 | var $node = $(node); |
|
794 | 802 | var $td = $node.closest('td'); |
|
795 | 803 | var $form = $td.find('.comment-inline-form'); |
|
796 | 804 | |
|
797 | 805 | if (!$form.length) { |
|
798 | 806 | |
|
799 | 807 | var $filediff = $node.closest('.filediff'); |
|
800 | 808 | $filediff.removeClass('hide-comments'); |
|
801 | 809 | var f_path = $filediff.attr('data-f-path'); |
|
802 | 810 | var lineno = self.getLineNumber(node); |
|
803 | 811 | // create a new HTML from template |
|
804 | 812 | var tmpl = $('#cb-comment-inline-form-template').html(); |
|
805 | 813 | tmpl = tmpl.format(escapeHtml(f_path), lineno); |
|
806 | 814 | $form = $(tmpl); |
|
807 | 815 | |
|
808 | 816 | var $comments = $td.find('.inline-comments'); |
|
809 | 817 | if (!$comments.length) { |
|
810 | 818 | $comments = $( |
|
811 | 819 | $('#cb-comments-inline-container-template').html()); |
|
812 | 820 | $td.append($comments); |
|
813 | 821 | } |
|
814 | 822 | |
|
815 | 823 | $td.find('.cb-comment-add-button').before($form); |
|
816 | 824 | |
|
817 | 825 | var placeholderText = _gettext('Leave a comment on line {0}.').format(lineno); |
|
818 | 826 | var _form = $($form[0]).find('form'); |
|
819 | 827 | var autocompleteActions = ['as_note', 'as_todo']; |
|
820 | 828 | var commentForm = this.createCommentForm( |
|
821 | 829 | _form, lineno, placeholderText, autocompleteActions, resolvesCommentId); |
|
822 | 830 | |
|
823 | 831 | $.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({ |
|
824 | 832 | form: _form, |
|
825 | 833 | parent: $td[0], |
|
826 | 834 | lineno: lineno, |
|
827 | 835 | f_path: f_path} |
|
828 | 836 | ); |
|
829 | 837 | |
|
830 | 838 | // set a CUSTOM submit handler for inline comments. |
|
831 | 839 | commentForm.setHandleFormSubmit(function(o) { |
|
832 | 840 | var text = commentForm.cm.getValue(); |
|
833 | 841 | var commentType = commentForm.getCommentType(); |
|
834 | 842 | var resolvesCommentId = commentForm.getResolvesId(); |
|
835 | 843 | |
|
836 | 844 | if (text === "") { |
|
837 | 845 | return; |
|
838 | 846 | } |
|
839 | 847 | |
|
840 | 848 | if (lineno === undefined) { |
|
841 | 849 | alert('missing line !'); |
|
842 | 850 | return; |
|
843 | 851 | } |
|
844 | 852 | if (f_path === undefined) { |
|
845 | 853 | alert('missing file path !'); |
|
846 | 854 | return; |
|
847 | 855 | } |
|
848 | 856 | |
|
849 | 857 | var excludeCancelBtn = false; |
|
850 | 858 | var submitEvent = true; |
|
851 | 859 | commentForm.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent); |
|
852 | 860 | commentForm.cm.setOption("readOnly", true); |
|
853 | 861 | var postData = { |
|
854 | 862 | 'text': text, |
|
855 | 863 | 'f_path': f_path, |
|
856 | 864 | 'line': lineno, |
|
857 | 865 | 'comment_type': commentType, |
|
858 | 866 | 'csrf_token': CSRF_TOKEN |
|
859 | 867 | }; |
|
860 | 868 | if (resolvesCommentId){ |
|
861 | 869 | postData['resolves_comment_id'] = resolvesCommentId; |
|
862 | 870 | } |
|
863 | 871 | |
|
864 | 872 | var submitSuccessCallback = function(json_data) { |
|
865 | 873 | $form.remove(); |
|
866 | 874 | try { |
|
867 | 875 | var html = json_data.rendered_text; |
|
868 | 876 | var lineno = json_data.line_no; |
|
869 | 877 | var target_id = json_data.target_id; |
|
870 | 878 | |
|
871 | 879 | $comments.find('.cb-comment-add-button').before(html); |
|
872 | 880 | |
|
873 | 881 | //mark visually which comment was resolved |
|
874 | 882 | if (resolvesCommentId) { |
|
875 | 883 | commentForm.markCommentResolved(resolvesCommentId); |
|
876 | 884 | } |
|
877 | 885 | |
|
878 | 886 | // run global callback on submit |
|
879 | 887 | commentForm.globalSubmitSuccessCallback(); |
|
880 | 888 | |
|
881 | 889 | } catch (e) { |
|
882 | 890 | console.error(e); |
|
883 | 891 | } |
|
884 | 892 | |
|
885 | 893 | // re trigger the linkification of next/prev navigation |
|
886 | 894 | linkifyComments($('.inline-comment-injected')); |
|
887 | 895 | timeagoActivate(); |
|
888 | 896 | tooltipActivate(); |
|
889 | 897 | |
|
890 | 898 | if (window.updateSticky !== undefined) { |
|
891 | 899 | // potentially our comments change the active window size, so we |
|
892 | 900 | // notify sticky elements |
|
893 | 901 | updateSticky() |
|
894 | 902 | } |
|
895 | 903 | |
|
896 | 904 | commentForm.setActionButtonsDisabled(false); |
|
897 | 905 | |
|
898 | 906 | }; |
|
899 | 907 | var submitFailCallback = function(jqXHR, textStatus, errorThrown) { |
|
900 | 908 | var prefix = "Error while submitting comment.\n" |
|
901 | 909 | var message = formatErrorMessage(jqXHR, textStatus, errorThrown, prefix); |
|
902 | 910 | ajaxErrorSwal(message); |
|
903 | 911 | commentForm.resetCommentFormState(text) |
|
904 | 912 | }; |
|
905 | 913 | commentForm.submitAjaxPOST( |
|
906 | 914 | commentForm.submitUrl, postData, submitSuccessCallback, submitFailCallback); |
|
907 | 915 | }); |
|
908 | 916 | } |
|
909 | 917 | |
|
910 | 918 | $form.addClass('comment-inline-form-open'); |
|
911 | 919 | }; |
|
912 | 920 | |
|
913 | 921 | this.createResolutionComment = function(commentId){ |
|
914 | 922 | // hide the trigger text |
|
915 | 923 | $('#resolve-comment-{0}'.format(commentId)).hide(); |
|
916 | 924 | |
|
917 | 925 | var comment = $('#comment-'+commentId); |
|
918 | 926 | var commentData = comment.data(); |
|
919 | 927 | if (commentData.commentInline) { |
|
920 | 928 | this.createComment(comment, commentId) |
|
921 | 929 | } else { |
|
922 | 930 | Rhodecode.comments.createGeneralComment('general', "$placeholder", commentId) |
|
923 | 931 | } |
|
924 | 932 | |
|
925 | 933 | return false; |
|
926 | 934 | }; |
|
927 | 935 | |
|
928 | 936 | this.submitResolution = function(commentId){ |
|
929 | 937 | var form = $('#resolve_comment_{0}'.format(commentId)).closest('form'); |
|
930 | 938 | var commentForm = form.get(0).CommentForm; |
|
931 | 939 | |
|
932 | 940 | var cm = commentForm.getCmInstance(); |
|
933 | 941 | var renderer = templateContext.visual.default_renderer; |
|
934 | 942 | if (renderer == 'rst'){ |
|
935 | 943 | var commentUrl = '`#{0} <{1}#comment-{0}>`_'.format(commentId, commentForm.selfUrl); |
|
936 | 944 | } else if (renderer == 'markdown') { |
|
937 | 945 | var commentUrl = '[#{0}]({1}#comment-{0})'.format(commentId, commentForm.selfUrl); |
|
938 | 946 | } else { |
|
939 | 947 | var commentUrl = '{1}#comment-{0}'.format(commentId, commentForm.selfUrl); |
|
940 | 948 | } |
|
941 | 949 | |
|
942 | 950 | cm.setValue(_gettext('TODO from comment {0} was fixed.').format(commentUrl)); |
|
943 | 951 | form.submit(); |
|
944 | 952 | return false; |
|
945 | 953 | }; |
|
946 | 954 | |
|
947 | 955 | }; |
@@ -1,123 +1,159 b'' | |||
|
1 | 1 | // # Copyright (C) 2010-2020 RhodeCode GmbH |
|
2 | 2 | // # |
|
3 | 3 | // # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | // # it under the terms of the GNU Affero General Public License, version 3 |
|
5 | 5 | // # (only), as published by the Free Software Foundation. |
|
6 | 6 | // # |
|
7 | 7 | // # This program is distributed in the hope that it will be useful, |
|
8 | 8 | // # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9 | 9 | // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
10 | 10 | // # GNU General Public License for more details. |
|
11 | 11 | // # |
|
12 | 12 | // # You should have received a copy of the GNU Affero General Public License |
|
13 | 13 | // # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
14 | 14 | // # |
|
15 | 15 | // # This program is dual-licensed. If you wish to learn more about the |
|
16 | 16 | // # RhodeCode Enterprise Edition, including its added features, Support services, |
|
17 | 17 | // # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
18 | 18 | |
|
19 | 19 | /** |
|
20 | 20 | * turns objects into GET query string |
|
21 | 21 | */ |
|
22 | 22 | var toQueryString = function(o) { |
|
23 | 23 | if(typeof o === 'string') { |
|
24 | 24 | return o; |
|
25 | 25 | } |
|
26 | 26 | if(typeof o !== 'object') { |
|
27 | 27 | return false; |
|
28 | 28 | } |
|
29 | 29 | var _p, _qs = []; |
|
30 | 30 | for(_p in o) { |
|
31 | 31 | _qs.push(encodeURIComponent(_p) + '=' + encodeURIComponent(o[_p])); |
|
32 | 32 | } |
|
33 | 33 | return _qs.join('&'); |
|
34 | 34 | }; |
|
35 | 35 | |
|
36 | 36 | /** |
|
37 | 37 | * ajax call wrappers |
|
38 | 38 | */ |
|
39 | 39 | |
|
40 | 40 | var ajaxGET = function (url, success, failure) { |
|
41 | 41 | var sUrl = url; |
|
42 | 42 | var request = $.ajax({ |
|
43 | 43 | url: sUrl, |
|
44 | 44 | headers: {'X-PARTIAL-XHR': true} |
|
45 | 45 | }) |
|
46 | 46 | .done(function (data) { |
|
47 | 47 | success(data); |
|
48 | 48 | }) |
|
49 | 49 | .fail(function (jqXHR, textStatus, errorThrown) { |
|
50 | 50 | if (failure) { |
|
51 | 51 | failure(jqXHR, textStatus, errorThrown); |
|
52 | 52 | } else { |
|
53 | 53 | var message = formatErrorMessage(jqXHR, textStatus, errorThrown); |
|
54 | 54 | ajaxErrorSwal(message); |
|
55 | 55 | } |
|
56 | 56 | }); |
|
57 | 57 | return request; |
|
58 | 58 | }; |
|
59 | 59 | |
|
60 | 60 | var ajaxPOST = function (url, postData, success, failure) { |
|
61 | 61 | var sUrl = url; |
|
62 | 62 | var postData = toQueryString(postData); |
|
63 | 63 | var request = $.ajax({ |
|
64 | 64 | type: 'POST', |
|
65 | 65 | url: sUrl, |
|
66 | 66 | data: postData, |
|
67 | 67 | headers: {'X-PARTIAL-XHR': true} |
|
68 | 68 | }) |
|
69 | 69 | .done(function (data) { |
|
70 | 70 | success(data); |
|
71 | 71 | }) |
|
72 | 72 | .fail(function (jqXHR, textStatus, errorThrown) { |
|
73 | 73 | if (failure) { |
|
74 | 74 | failure(jqXHR, textStatus, errorThrown); |
|
75 | 75 | } else { |
|
76 | 76 | var message = formatErrorMessage(jqXHR, textStatus, errorThrown); |
|
77 | 77 | ajaxErrorSwal(message); |
|
78 | 78 | } |
|
79 | 79 | }); |
|
80 | 80 | return request; |
|
81 | 81 | }; |
|
82 | 82 | |
|
83 | 83 | function formatErrorMessage(jqXHR, textStatus, errorThrown, prefix) { |
|
84 | 84 | if(typeof prefix === "undefined") { |
|
85 | 85 | prefix = '' |
|
86 | 86 | } |
|
87 | 87 | |
|
88 | 88 | if (jqXHR.status === 0) { |
|
89 | 89 | return (prefix + 'Not connected.\nPlease verify your network connection.'); |
|
90 | 90 | } else if (jqXHR.status == 401) { |
|
91 | 91 | return (prefix + 'Unauthorized access. [401]'); |
|
92 | 92 | } else if (jqXHR.status == 404) { |
|
93 | 93 | return (prefix + 'The requested page not found. [404]'); |
|
94 | 94 | } else if (jqXHR.status == 500) { |
|
95 | 95 | return (prefix + 'Internal Server Error [500].'); |
|
96 | 96 | } else if (jqXHR.status == 503) { |
|
97 | 97 | return (prefix + 'Service unavailable [503].'); |
|
98 | 98 | } else if (errorThrown === 'parsererror') { |
|
99 | 99 | return (prefix + 'Requested JSON parse failed.'); |
|
100 | 100 | } else if (errorThrown === 'timeout') { |
|
101 | 101 | return (prefix + 'Time out error.'); |
|
102 | 102 | } else if (errorThrown === 'abort') { |
|
103 | 103 | return (prefix + 'Ajax request aborted.'); |
|
104 | 104 | } else { |
|
105 | 105 | return (prefix + 'Uncaught Error.\n' + jqXHR.responseText); |
|
106 | 106 | } |
|
107 | 107 | } |
|
108 | 108 | |
|
109 | 109 | function ajaxErrorSwal(message) { |
|
110 | 110 | Swal.fire({ |
|
111 | 111 | icon: 'error', |
|
112 | 112 | title: _gettext('Ajax Error'), |
|
113 | 113 | html: '<span style="white-space: pre-line">{0}</span>'.format(message), |
|
114 | 114 | showClass: { |
|
115 | 115 | popup: 'swal2-noanimation', |
|
116 | 116 | backdrop: 'swal2-noanimation' |
|
117 | 117 | }, |
|
118 | 118 | hideClass: { |
|
119 | 119 | popup: '', |
|
120 | 120 | backdrop: '' |
|
121 | 121 | } |
|
122 | 122 | }) |
|
123 | } | |
|
124 | ||
|
125 | /* | |
|
126 | * use in onclick attributes e.g | |
|
127 | * onclick="submitConfirm(event, this, _gettext('Confirm to delete '), _gettext('Confirm Delete'), 'what we delete')"> | |
|
128 | * */ | |
|
129 | function submitConfirm(event, self, question, confirmText, htmlText) { | |
|
130 | if (htmlText === "undefined") { | |
|
131 | htmlText = null; | |
|
132 | } | |
|
133 | if (confirmText === "undefined") { | |
|
134 | confirmText = _gettext('Delete') | |
|
135 | } | |
|
136 | event.preventDefault(); | |
|
137 | ||
|
138 | Swal.fire({ | |
|
139 | title: question, | |
|
140 | icon: 'warning', | |
|
141 | html: htmlText, | |
|
142 | showClass: { | |
|
143 | popup: 'swal2-noanimation', | |
|
144 | backdrop: 'swal2-noanimation' | |
|
145 | }, | |
|
146 | hideClass: { | |
|
147 | popup: '', | |
|
148 | backdrop: '' | |
|
149 | }, | |
|
150 | showCancelButton: true, | |
|
151 | confirmButtonColor: '#84a5d2', | |
|
152 | cancelButtonColor: '#e85e4d', | |
|
153 | confirmButtonText: confirmText | |
|
154 | }).then(function(result) { | |
|
155 | if (result.value) { | |
|
156 | $(self).closest("form").submit(); | |
|
157 | } | |
|
158 | }) | |
|
123 | 159 | } No newline at end of file |
@@ -1,110 +1,113 b'' | |||
|
1 | 1 | ## -*- coding: utf-8 -*- |
|
2 | 2 | <%inherit file="/base/base.mako"/> |
|
3 | 3 | <%namespace name="dt" file="/data_table/_dt_elements.mako"/> |
|
4 | 4 | |
|
5 | 5 | <%def name="robots()"> |
|
6 | 6 | %if c.gist.gist_type != 'public': |
|
7 | 7 | <meta name="robots" content="noindex, nofollow"> |
|
8 | 8 | %else: |
|
9 | 9 | ${parent.robots()} |
|
10 | 10 | %endif |
|
11 | 11 | </%def> |
|
12 | 12 | |
|
13 | 13 | <%def name="title()"> |
|
14 | 14 | ${_('Gist')} · ${c.gist.gist_access_id} |
|
15 | 15 | %if c.rhodecode_name: |
|
16 | 16 | · ${h.branding(c.rhodecode_name)} |
|
17 | 17 | %endif |
|
18 | 18 | </%def> |
|
19 | 19 | |
|
20 | 20 | <%def name="breadcrumbs_links()"> |
|
21 | 21 | ${_('Gist')} · ${c.gist.gist_access_id} |
|
22 | 22 | </%def> |
|
23 | 23 | |
|
24 | 24 | <%def name="menu_bar_nav()"> |
|
25 | 25 | ${self.menu_items(active='gists')} |
|
26 | 26 | </%def> |
|
27 | 27 | |
|
28 | 28 | <%def name="main()"> |
|
29 | 29 | <div class="box"> |
|
30 | 30 | <!-- box / title --> |
|
31 | 31 | |
|
32 | 32 | <div class="table"> |
|
33 | 33 | <div id="files_data"> |
|
34 | 34 | <div id="codeblock" class="codeblock"> |
|
35 | 35 | <div class="code-header"> |
|
36 | 36 | <div class="gist_url"> |
|
37 | 37 | <div class="pull-left"> |
|
38 | 38 | <code> |
|
39 | 39 | ${dt.gist_type(c.gist.gist_type)} |
|
40 | 40 | <span class="tag disabled">${c.gist.gist_access_id}</span> |
|
41 | 41 | ${c.gist.gist_url()} <span class="icon-clipboard clipboard-action" data-clipboard-text="${c.gist.gist_url()}" title="${_('Copy the url')}"></span> |
|
42 | 42 | </code> |
|
43 | 43 | </div> |
|
44 | 44 | |
|
45 | 45 | <div class="pull-right buttons"> |
|
46 | 46 | ## only owner should see that |
|
47 | 47 | <a href="#copySource" onclick="return false;" class="btn btn-mini icon-clipboard no-grey clipboard-action" data-clipboard-text="${c.files[0].content}">${_('Copy content')}</a> |
|
48 | 48 | |
|
49 | 49 | %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id: |
|
50 | 50 | ${h.link_to(_('Edit'), h.route_path('gist_edit', gist_id=c.gist.gist_access_id), class_="btn btn-mini")} |
|
51 | 51 | %endif |
|
52 | 52 | ${h.link_to(_('Show as Raw'), h.route_path('gist_show_formatted', gist_id=c.gist.gist_access_id, revision='tip', format='raw'), class_="btn btn-mini")} |
|
53 | 53 | |
|
54 | 54 | %if c.is_super_admin or c.gist.gist_owner == c.rhodecode_user.user_id: |
|
55 | 55 | <div class="pull-right remove_gist"> |
|
56 | 56 | ${h.secure_form(h.route_path('gist_delete', gist_id=c.gist.gist_access_id), request=request)} |
|
57 | ${h.submit('remove_gist', _('Delete'),class_="btn btn-mini btn-danger",onclick="return confirm('"+_('Confirm to delete this Gist')+"');")} | |
|
57 | <input class="btn btn-mini btn-danger" id="remove_gist" name="remove_gist" | |
|
58 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this gist'), _gettext('Delete'), '${c.gist.gist_access_id}')" | |
|
59 | type="submit" value="${_('Delete')}" | |
|
60 | > | |
|
58 | 61 | ${h.end_form()} |
|
59 | 62 | </div> |
|
60 | 63 | %endif |
|
61 | 64 | </div> |
|
62 | 65 | </div> |
|
63 | 66 | |
|
64 | 67 | <div class="gist-desc"> |
|
65 | 68 | <code>${c.gist.gist_description}</code> |
|
66 | 69 | </div> |
|
67 | 70 | |
|
68 | 71 | <div class="author"> |
|
69 | 72 | <div title="${h.tooltip(c.file_last_commit.author)}"> |
|
70 | 73 | ${self.gravatar_with_user(c.file_last_commit.author, 16, tooltip=True)} - ${_('created')} ${h.age_component(c.file_last_commit.date)}, |
|
71 | 74 | ${_('expires')}: |
|
72 | 75 | %if c.gist.gist_expires == -1: |
|
73 | 76 | ${_('never')} |
|
74 | 77 | %else: |
|
75 | 78 | ${h.age_component(h.time_to_utcdatetime(c.gist.gist_expires))} |
|
76 | 79 | %endif |
|
77 | 80 | </span> |
|
78 | 81 | </div> |
|
79 | 82 | |
|
80 | 83 | </div> |
|
81 | 84 | <div class="commit">${h.urlify_commit_message(c.file_last_commit.message, None)}</div> |
|
82 | 85 | </div> |
|
83 | 86 | |
|
84 | 87 | ## iterate over the files |
|
85 | 88 | % for gist_file in c.files: |
|
86 | 89 | <% renderer = c.render and h.renderer_from_filename(gist_file.path, exclude=['.txt', '.TXT'])%> |
|
87 | 90 | <!-- |
|
88 | 91 | <div id="${h.FID('G', gist_file.path)}" class="stats" > |
|
89 | 92 | <a href="${c.gist.gist_url()}">ΒΆ</a> |
|
90 | 93 | <b >${gist_file.path}</b> |
|
91 | 94 | <div> |
|
92 | 95 | ${h.link_to(_('Show as raw'), h.route_path('gist_show_formatted_path', gist_id=c.gist.gist_access_id, revision=gist_file.commit.raw_id, format='raw', f_path=gist_file.path), class_="btn btn-mini")} |
|
93 | 96 | </div> |
|
94 | 97 | </div> |
|
95 | 98 | --> |
|
96 | 99 | <div class="code-body textarea text-area editor"> |
|
97 | 100 | %if renderer: |
|
98 | 101 | ${h.render(gist_file.content, renderer=renderer)} |
|
99 | 102 | %else: |
|
100 | 103 | ${h.pygmentize(gist_file,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")} |
|
101 | 104 | %endif |
|
102 | 105 | </div> |
|
103 | 106 | %endfor |
|
104 | 107 | </div> |
|
105 | 108 | </div> |
|
106 | 109 | </div> |
|
107 | 110 | |
|
108 | 111 | |
|
109 | 112 | </div> |
|
110 | 113 | </%def> |
@@ -1,190 +1,191 b'' | |||
|
1 | 1 | <div class="panel panel-default"> |
|
2 | 2 | <div class="panel-heading"> |
|
3 | 3 | <h3 class="panel-title">${_('Authentication Tokens')}</h3> |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | 6 | <div class="apikeys_wrap"> |
|
7 | 7 | <p> |
|
8 | 8 | ${_('Authentication tokens can be used to interact with the API, or VCS-over-http. ' |
|
9 | 9 | 'Each token can have a role. Token with a role can be used only in given context, ' |
|
10 | 10 | 'e.g. VCS tokens can be used together with the authtoken auth plugin for git/hg/svn operations only.')} |
|
11 | 11 | </p> |
|
12 | 12 | <table class="rctable auth_tokens"> |
|
13 | 13 | <tr> |
|
14 | 14 | <th>${_('Token')}</th> |
|
15 | 15 | <th>${_('Description')}</th> |
|
16 | 16 | <th>${_('Role')}</th> |
|
17 | 17 | <th>${_('Repository Scope')}</th> |
|
18 | 18 | <th>${_('Expiration')}</th> |
|
19 | 19 | <th>${_('Action')}</th> |
|
20 | 20 | </tr> |
|
21 | 21 | %if c.user_auth_tokens: |
|
22 | 22 | %for auth_token in c.user_auth_tokens: |
|
23 | 23 | <tr class="${('expired' if auth_token.expired else '')}"> |
|
24 | 24 | <td class="truncate-wrap td-authtoken"> |
|
25 | 25 | <div class="user_auth_tokens truncate autoexpand"> |
|
26 | 26 | <code>${auth_token.api_key}</code> |
|
27 | 27 | </div> |
|
28 | 28 | </td> |
|
29 | 29 | <td class="td-wrap">${auth_token.description}</td> |
|
30 | 30 | <td class="td-tags"> |
|
31 | 31 | <span class="tag disabled">${auth_token.role_humanized}</span> |
|
32 | 32 | </td> |
|
33 | 33 | <td class="td">${auth_token.scope_humanized}</td> |
|
34 | 34 | <td class="td-exp"> |
|
35 | 35 | %if auth_token.expires == -1: |
|
36 | 36 | ${_('never')} |
|
37 | 37 | %else: |
|
38 | 38 | %if auth_token.expired: |
|
39 | 39 | <span style="text-decoration: line-through">${h.age_component(h.time_to_utcdatetime(auth_token.expires))}</span> |
|
40 | 40 | %else: |
|
41 | 41 | ${h.age_component(h.time_to_utcdatetime(auth_token.expires))} |
|
42 | 42 | %endif |
|
43 | 43 | %endif |
|
44 | 44 | </td> |
|
45 | 45 | <td class="td-action"> |
|
46 | 46 | ${h.secure_form(h.route_path('my_account_auth_tokens_delete'), request=request)} |
|
47 | 47 | ${h.hidden('del_auth_token', auth_token.user_api_key_id)} |
|
48 | 48 | <button class="btn btn-link btn-danger" type="submit" |
|
49 |
onclick=" |
|
|
49 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this auth token'), _gettext('Delete'), '${auth_token.token_obfuscated}')" | |
|
50 | > | |
|
50 | 51 | ${_('Delete')} |
|
51 | 52 | </button> |
|
52 | 53 | ${h.end_form()} |
|
53 | 54 | </td> |
|
54 | 55 | </tr> |
|
55 | 56 | %endfor |
|
56 | 57 | %else: |
|
57 | 58 | <tr><td><div class="ip">${_('No additional auth tokens specified')}</div></td></tr> |
|
58 | 59 | %endif |
|
59 | 60 | </table> |
|
60 | 61 | </div> |
|
61 | 62 | |
|
62 | 63 | <div class="user_auth_tokens"> |
|
63 | 64 | ${h.secure_form(h.route_path('my_account_auth_tokens_add'), request=request)} |
|
64 | 65 | <div class="form form-vertical"> |
|
65 | 66 | <!-- fields --> |
|
66 | 67 | <div class="fields"> |
|
67 | 68 | <div class="field"> |
|
68 | 69 | <div class="label"> |
|
69 | 70 | <label for="new_email">${_('New authentication token')}:</label> |
|
70 | 71 | </div> |
|
71 | 72 | <div class="input"> |
|
72 | 73 | ${h.text('description', class_='medium', placeholder=_('Description'))} |
|
73 | 74 | ${h.hidden('lifetime')} |
|
74 | 75 | ${h.select('role', request.GET.get('token_role', ''), c.role_options)} |
|
75 | 76 | |
|
76 | 77 | % if c.allow_scoped_tokens: |
|
77 | 78 | ${h.hidden('scope_repo_id')} |
|
78 | 79 | % else: |
|
79 | 80 | ${h.select('scope_repo_id_disabled', '', ['Scopes available in EE edition'], disabled='disabled')} |
|
80 | 81 | % endif |
|
81 | 82 | </div> |
|
82 | 83 | <p class="help-block"> |
|
83 | 84 | ${_('Repository scope works only with tokens with VCS type.')} |
|
84 | 85 | </p> |
|
85 | 86 | </div> |
|
86 | 87 | <div class="buttons"> |
|
87 | 88 | ${h.submit('save',_('Add'),class_="btn")} |
|
88 | 89 | ${h.reset('reset',_('Reset'),class_="btn")} |
|
89 | 90 | </div> |
|
90 | 91 | </div> |
|
91 | 92 | </div> |
|
92 | 93 | ${h.end_form()} |
|
93 | 94 | </div> |
|
94 | 95 | </div> |
|
95 | 96 | </div> |
|
96 | 97 | |
|
97 | 98 | <script> |
|
98 | 99 | $(document).ready(function(){ |
|
99 | 100 | |
|
100 | 101 | var select2Options = { |
|
101 | 102 | 'containerCssClass': "drop-menu", |
|
102 | 103 | 'dropdownCssClass': "drop-menu-dropdown", |
|
103 | 104 | 'dropdownAutoWidth': true |
|
104 | 105 | }; |
|
105 | 106 | $("#role").select2(select2Options); |
|
106 | 107 | |
|
107 | 108 | var preloadData = { |
|
108 | 109 | results: [ |
|
109 | 110 | % for entry in c.lifetime_values: |
|
110 | 111 | {id:${entry[0]}, text:"${entry[1]}"}${'' if loop.last else ','} |
|
111 | 112 | % endfor |
|
112 | 113 | ] |
|
113 | 114 | }; |
|
114 | 115 | |
|
115 | 116 | $("#lifetime").select2({ |
|
116 | 117 | containerCssClass: "drop-menu", |
|
117 | 118 | dropdownCssClass: "drop-menu-dropdown", |
|
118 | 119 | dropdownAutoWidth: true, |
|
119 | 120 | data: preloadData, |
|
120 | 121 | placeholder: "${_('Select or enter expiration date')}", |
|
121 | 122 | query: function(query) { |
|
122 | 123 | feedLifetimeOptions(query, preloadData); |
|
123 | 124 | } |
|
124 | 125 | }); |
|
125 | 126 | |
|
126 | 127 | |
|
127 | 128 | var repoFilter = function(data) { |
|
128 | 129 | var results = []; |
|
129 | 130 | |
|
130 | 131 | if (!data.results[0]) { |
|
131 | 132 | return data |
|
132 | 133 | } |
|
133 | 134 | |
|
134 | 135 | $.each(data.results[0].children, function() { |
|
135 | 136 | // replace name to ID for submision |
|
136 | 137 | this.id = this.repo_id; |
|
137 | 138 | results.push(this); |
|
138 | 139 | }); |
|
139 | 140 | |
|
140 | 141 | data.results[0].children = results; |
|
141 | 142 | return data; |
|
142 | 143 | }; |
|
143 | 144 | |
|
144 | 145 | $("#scope_repo_id_disabled").select2(select2Options); |
|
145 | 146 | |
|
146 | 147 | var selectVcsScope = function() { |
|
147 | 148 | // select vcs scope and disable input |
|
148 | 149 | $("#role").select2("val", "${c.role_vcs}").trigger('change'); |
|
149 | 150 | $("#role").select2("readonly", true) |
|
150 | 151 | }; |
|
151 | 152 | |
|
152 | 153 | $("#scope_repo_id").select2({ |
|
153 | 154 | cachedDataSource: {}, |
|
154 | 155 | minimumInputLength: 2, |
|
155 | 156 | placeholder: "${_('repository scope')}", |
|
156 | 157 | dropdownAutoWidth: true, |
|
157 | 158 | containerCssClass: "drop-menu", |
|
158 | 159 | dropdownCssClass: "drop-menu-dropdown", |
|
159 | 160 | formatResult: formatRepoResult, |
|
160 | 161 | query: $.debounce(250, function(query){ |
|
161 | 162 | self = this; |
|
162 | 163 | var cacheKey = query.term; |
|
163 | 164 | var cachedData = self.cachedDataSource[cacheKey]; |
|
164 | 165 | |
|
165 | 166 | if (cachedData) { |
|
166 | 167 | query.callback({results: cachedData.results}); |
|
167 | 168 | } else { |
|
168 | 169 | $.ajax({ |
|
169 | 170 | url: pyroutes.url('repo_list_data'), |
|
170 | 171 | data: {'query': query.term}, |
|
171 | 172 | dataType: 'json', |
|
172 | 173 | type: 'GET', |
|
173 | 174 | success: function(data) { |
|
174 | 175 | data = repoFilter(data); |
|
175 | 176 | self.cachedDataSource[cacheKey] = data; |
|
176 | 177 | query.callback({results: data.results}); |
|
177 | 178 | }, |
|
178 | 179 | error: function(data, textStatus, errorThrown) { |
|
179 | 180 | alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText)); |
|
180 | 181 | } |
|
181 | 182 | }) |
|
182 | 183 | } |
|
183 | 184 | }) |
|
184 | 185 | }); |
|
185 | 186 | $("#scope_repo_id").on('select2-selecting', function(e){ |
|
186 | 187 | selectVcsScope() |
|
187 | 188 | }); |
|
188 | 189 | |
|
189 | 190 | }); |
|
190 | 191 | </script> |
@@ -1,60 +1,61 b'' | |||
|
1 | 1 | <%namespace name="base" file="/base/base.mako"/> |
|
2 | 2 | |
|
3 | 3 | <div class="panel panel-default"> |
|
4 | 4 | <div class="panel-heading"> |
|
5 | 5 | <h3 class="panel-title">${_('Account Emails')}</h3> |
|
6 | 6 | </div> |
|
7 | 7 | |
|
8 | 8 | <div class="panel-body"> |
|
9 | 9 | <div class="emails_wrap"> |
|
10 | 10 | <table class="rctable account_emails"> |
|
11 | 11 | <tr> |
|
12 | 12 | <td class="td-user"> |
|
13 | 13 | ${base.gravatar(c.user.email, 16)} |
|
14 | 14 | <span class="user email">${c.user.email}</span> |
|
15 | 15 | </td> |
|
16 | 16 | <td class="td-tags"> |
|
17 | 17 | <span class="tag tag1">${_('Primary')}</span> |
|
18 | 18 | </td> |
|
19 | 19 | </tr> |
|
20 | 20 | %if c.user_email_map: |
|
21 | 21 | %for em in c.user_email_map: |
|
22 | 22 | <tr> |
|
23 | 23 | <td class="td-user"> |
|
24 | 24 | ${base.gravatar(em.email, 16)} |
|
25 | 25 | <span class="user email">${em.email}</span> |
|
26 | 26 | </td> |
|
27 | 27 | <td class="td-action"> |
|
28 | 28 | ${h.secure_form(h.route_path('my_account_emails_delete'), request=request)} |
|
29 | 29 | ${h.hidden('del_email_id',em.email_id)} |
|
30 | 30 | <button class="btn btn-link btn-danger" type="submit" id="${'remove_email_%s'.format(em.email_id)}" |
|
31 |
onclick=" |
|
|
31 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this email'), _gettext('Delete'), '${em.email}')" | |
|
32 | > | |
|
32 | 33 | ${_('Delete')} |
|
33 | 34 | </button> |
|
34 | 35 | ${h.end_form()} |
|
35 | 36 | </td> |
|
36 | 37 | </tr> |
|
37 | 38 | %endfor |
|
38 | 39 | %else: |
|
39 | 40 | <tr class="noborder"> |
|
40 | 41 | <td colspan="3"> |
|
41 | 42 | <div class="td-email"> |
|
42 | 43 | ${_('No additional emails specified')} |
|
43 | 44 | </div> |
|
44 | 45 | </td> |
|
45 | 46 | </tr> |
|
46 | 47 | %endif |
|
47 | 48 | </table> |
|
48 | 49 | </div> |
|
49 | 50 | |
|
50 | 51 | % if c.user.extern_type != 'rhodecode': |
|
51 | 52 | <p>${_('Your user account details are managed by an external source. Details cannot be managed here.')} |
|
52 | 53 | <br/>${_('Source type')}: <strong>${c.user.extern_type}</strong> |
|
53 | 54 | </p> |
|
54 | 55 | % else: |
|
55 | 56 | <div> |
|
56 | 57 | ${c.form.render() | n} |
|
57 | 58 | </div> |
|
58 | 59 | % endif |
|
59 | 60 | </div> |
|
60 | 61 | </div> |
@@ -1,91 +1,92 b'' | |||
|
1 | 1 | <div class="panel panel-default"> |
|
2 | 2 | <div class="panel-heading"> |
|
3 | 3 | <h3 class="panel-title">${_('SSH Keys')}</h3> |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | 6 | <div class="sshkeys_wrap"> |
|
7 | 7 | <table class="rctable ssh_keys"> |
|
8 | 8 | <tr> |
|
9 | 9 | <th>${_('Fingerprint')}</th> |
|
10 | 10 | <th>${_('Description')}</th> |
|
11 | 11 | <th>${_('Created on')}</th> |
|
12 | 12 | <th>${_('Accessed on')}</th> |
|
13 | 13 | <th>${_('Action')}</th> |
|
14 | 14 | </tr> |
|
15 | 15 | % if not c.ssh_enabled: |
|
16 | 16 | <tr><td colspan="4"><div class="">${_('SSH Keys usage is currently disabled, please ask your administrator to enable them.')}</div></td></tr> |
|
17 | 17 | % else: |
|
18 | 18 | %if c.user_ssh_keys: |
|
19 | 19 | %for ssh_key in c.user_ssh_keys: |
|
20 | 20 | <tr class=""> |
|
21 | 21 | <td class=""> |
|
22 | 22 | <code>${ssh_key.ssh_key_fingerprint}</code> |
|
23 | 23 | </td> |
|
24 | 24 | <td class="td-wrap">${ssh_key.description}</td> |
|
25 | 25 | <td class="td-tags">${h.format_date(ssh_key.created_on)}</td> |
|
26 | 26 | <td class="td-tags">${h.format_date(ssh_key.accessed_on)}</td> |
|
27 | 27 | |
|
28 | 28 | <td class="td-action"> |
|
29 | 29 | ${h.secure_form(h.route_path('my_account_ssh_keys_delete'), request=request)} |
|
30 | 30 | ${h.hidden('del_ssh_key', ssh_key.ssh_key_id)} |
|
31 | 31 | <button class="btn btn-link btn-danger" type="submit" |
|
32 |
onclick=" |
|
|
32 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this ssh key'), _gettext('Delete'), '${ssh_key.ssh_key_fingerprint}')" | |
|
33 | > | |
|
33 | 34 | ${_('Delete')} |
|
34 | 35 | </button> |
|
35 | 36 | ${h.end_form()} |
|
36 | 37 | </td> |
|
37 | 38 | </tr> |
|
38 | 39 | %endfor |
|
39 | 40 | %else: |
|
40 | 41 | <tr><td colspan="4"><div class="">${_('No additional ssh keys specified')}</div></td></tr> |
|
41 | 42 | %endif |
|
42 | 43 | % endif |
|
43 | 44 | </table> |
|
44 | 45 | </div> |
|
45 | 46 | |
|
46 | 47 | % if c.ssh_enabled: |
|
47 | 48 | <div class="user_ssh_keys"> |
|
48 | 49 | ${h.secure_form(h.route_path('my_account_ssh_keys_add'), request=request)} |
|
49 | 50 | <div class="form form-vertical"> |
|
50 | 51 | <!-- fields --> |
|
51 | 52 | <div class="fields"> |
|
52 | 53 | <div class="field"> |
|
53 | 54 | <div class="label"> |
|
54 | 55 | <label for="new_email">${_('New ssh key')}:</label> |
|
55 | 56 | </div> |
|
56 | 57 | <div class="input"> |
|
57 | 58 | ${h.text('description', class_='medium', placeholder=_('Description'))} |
|
58 | 59 | % if c.ssh_key_generator_enabled: |
|
59 | 60 | <a href="${h.route_path('my_account_ssh_keys_generate')}">${_('Generate random RSA key')}</a> |
|
60 | 61 | % endif |
|
61 | 62 | </div> |
|
62 | 63 | </div> |
|
63 | 64 | |
|
64 | 65 | <div class="field"> |
|
65 | 66 | <div class="textarea text-area editor"> |
|
66 | 67 | ${h.textarea('key_data',c.default_key, size=30, placeholder=_("Public key, begins with 'ssh-rsa', 'ssh-dss', 'ssh-ed25519', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', or 'ecdsa-sha2-nistp521'"))} |
|
67 | 68 | </div> |
|
68 | 69 | </div> |
|
69 | 70 | |
|
70 | 71 | <div class="buttons"> |
|
71 | 72 | ${h.submit('save',_('Add'),class_="btn")} |
|
72 | 73 | ${h.reset('reset',_('Reset'),class_="btn")} |
|
73 | 74 | </div> |
|
74 | 75 | % if c.default_key: |
|
75 | 76 | ${_('Click add to use this generated SSH key')} |
|
76 | 77 | % endif |
|
77 | 78 | </div> |
|
78 | 79 | </div> |
|
79 | 80 | ${h.end_form()} |
|
80 | 81 | </div> |
|
81 | 82 | % endif |
|
82 | 83 | </div> |
|
83 | 84 | </div> |
|
84 | 85 | |
|
85 | 86 | <script> |
|
86 | 87 | |
|
87 | 88 | $(document).ready(function(){ |
|
88 | 89 | |
|
89 | 90 | |
|
90 | 91 | }); |
|
91 | 92 | </script> |
@@ -1,295 +1,299 b'' | |||
|
1 | 1 | <%namespace name="base" file="/base/base.mako"/> |
|
2 | 2 | |
|
3 | 3 | <% |
|
4 | 4 | elems = [ |
|
5 | 5 | (_('Repository ID'), c.rhodecode_db_repo.repo_id, '', ''), |
|
6 | 6 | (_('Owner'), lambda:base.gravatar_with_user(c.rhodecode_db_repo.user.email, tooltip=True), '', ''), |
|
7 | 7 | (_('Created on'), h.format_date(c.rhodecode_db_repo.created_on), '', ''), |
|
8 | 8 | (_('Updated on'), h.format_date(c.rhodecode_db_repo.updated_on), '', ''), |
|
9 | 9 | (_('Cached Commit id'), lambda: h.link_to(c.rhodecode_db_repo.changeset_cache.get('short_id'), h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.changeset_cache.get('raw_id'))), '', ''), |
|
10 | 10 | (_('Cached Commit date'), c.rhodecode_db_repo.changeset_cache.get('date'), '', ''), |
|
11 | 11 | (_('Cached Commit data'), lambda: h.link_to('refresh now', h.current_route_path(request, update_commit_cache=1)), '', ''), |
|
12 | 12 | (_('Attached scoped tokens'), len(c.rhodecode_db_repo.scoped_tokens), '', [x.user for x in c.rhodecode_db_repo.scoped_tokens]), |
|
13 | 13 | (_('Pull requests source'), len(c.rhodecode_db_repo.pull_requests_source), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.source_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_source]), |
|
14 | 14 | (_('Pull requests target'), len(c.rhodecode_db_repo.pull_requests_target), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.target_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_target]), |
|
15 | 15 | (_('Attached Artifacts'), len(c.rhodecode_db_repo.artifacts), '', ''), |
|
16 | 16 | ] |
|
17 | 17 | %> |
|
18 | 18 | |
|
19 | 19 | <div class="panel panel-default"> |
|
20 | 20 | <div class="panel-heading" id="advanced-info" > |
|
21 | 21 | <h3 class="panel-title">${_('Repository: %s') % c.rhodecode_db_repo.repo_name} <a class="permalink" href="#advanced-info"> ΒΆ</a></h3> |
|
22 | 22 | </div> |
|
23 | 23 | <div class="panel-body"> |
|
24 | 24 | ${base.dt_info_panel(elems)} |
|
25 | 25 | </div> |
|
26 | 26 | </div> |
|
27 | 27 | |
|
28 | 28 | |
|
29 | 29 | <div class="panel panel-default"> |
|
30 | 30 | <div class="panel-heading" id="advanced-fork"> |
|
31 | 31 | <h3 class="panel-title">${_('Fork Reference')} <a class="permalink" href="#advanced-fork"> ΒΆ</a></h3> |
|
32 | 32 | </div> |
|
33 | 33 | <div class="panel-body"> |
|
34 | 34 | ${h.secure_form(h.route_path('edit_repo_advanced_fork', repo_name=c.rhodecode_db_repo.repo_name), request=request)} |
|
35 | 35 | |
|
36 | 36 | % if c.rhodecode_db_repo.fork: |
|
37 | 37 | <div class="panel-body-title-text">${h.literal(_('This repository is a fork of %(repo_link)s') % {'repo_link': h.link_to_if(c.has_origin_repo_read_perm,c.rhodecode_db_repo.fork.repo_name, h.route_path('repo_summary', repo_name=c.rhodecode_db_repo.fork.repo_name))})} |
|
38 | 38 | | <button class="btn btn-link btn-danger" type="submit">Remove fork reference</button></div> |
|
39 | 39 | % endif |
|
40 | 40 | |
|
41 | 41 | <div class="field"> |
|
42 | 42 | ${h.hidden('id_fork_of')} |
|
43 | 43 | ${h.submit('set_as_fork_%s' % c.rhodecode_db_repo.repo_name,_('Set'),class_="btn btn-small",)} |
|
44 | 44 | </div> |
|
45 | 45 | <div class="field"> |
|
46 | 46 | <span class="help-block">${_('Manually set this repository as a fork of another from the list')}</span> |
|
47 | 47 | </div> |
|
48 | 48 | ${h.end_form()} |
|
49 | 49 | </div> |
|
50 | 50 | </div> |
|
51 | 51 | |
|
52 | 52 | |
|
53 | 53 | <div class="panel panel-default"> |
|
54 | 54 | <div class="panel-heading" id="advanced-journal"> |
|
55 | 55 | <h3 class="panel-title">${_('Public Journal Visibility')} <a class="permalink" href="#advanced-journal"> ΒΆ</a></h3> |
|
56 | 56 | </div> |
|
57 | 57 | <div class="panel-body"> |
|
58 | 58 | ${h.secure_form(h.route_path('edit_repo_advanced_journal', repo_name=c.rhodecode_db_repo.repo_name), request=request)} |
|
59 | 59 | <div class="field"> |
|
60 | 60 | %if c.in_public_journal: |
|
61 | 61 | <button class="btn btn-small" type="submit"> |
|
62 | 62 | ${_('Remove from Public Journal')} |
|
63 | 63 | </button> |
|
64 | 64 | %else: |
|
65 | 65 | <button class="btn btn-small" type="submit"> |
|
66 | 66 | ${_('Add to Public Journal')} |
|
67 | 67 | </button> |
|
68 | 68 | %endif |
|
69 | 69 | </div> |
|
70 | 70 | <div class="field" > |
|
71 | 71 | <span class="help-block">${_('All actions made on this repository will be visible to everyone following the public journal.')}</span> |
|
72 | 72 | </div> |
|
73 | 73 | ${h.end_form()} |
|
74 | 74 | </div> |
|
75 | 75 | </div> |
|
76 | 76 | |
|
77 | 77 | |
|
78 | 78 | <div class="panel panel-default"> |
|
79 | 79 | <div class="panel-heading" id="advanced-locking"> |
|
80 | 80 | <h3 class="panel-title">${_('Locking state')} <a class="permalink" href="#advanced-locking"> ΒΆ</a></h3> |
|
81 | 81 | </div> |
|
82 | 82 | <div class="panel-body"> |
|
83 | 83 | ${h.secure_form(h.route_path('edit_repo_advanced_locking', repo_name=c.rhodecode_db_repo.repo_name), request=request)} |
|
84 | 84 | |
|
85 | 85 | %if c.rhodecode_db_repo.locked[0]: |
|
86 | 86 | <div class="panel-body-title-text">${'Locked by %s on %s. Lock reason: %s' % (h.person_by_id(c.rhodecode_db_repo.locked[0]), |
|
87 | 87 | h.format_date(h. time_to_datetime(c.rhodecode_db_repo.locked[1])), c.rhodecode_db_repo.locked[2])}</div> |
|
88 | 88 | %else: |
|
89 | 89 | <div class="panel-body-title-text">${_('This Repository is not currently locked.')}</div> |
|
90 | 90 | %endif |
|
91 | 91 | |
|
92 | 92 | <div class="field" > |
|
93 | 93 | %if c.rhodecode_db_repo.locked[0]: |
|
94 | 94 | ${h.hidden('set_unlock', '1')} |
|
95 | 95 | <button class="btn btn-small" type="submit" |
|
96 |
onclick=" |
|
|
96 | onclick="submitConfirm(event, this, _gettext('Confirm to unlock this repository'), _gettext('Unlock'), '${c.rhodecode_db_repo.repo_name}')" | |
|
97 | > | |
|
97 | 98 | <i class="icon-unlock"></i> |
|
98 | 99 | ${_('Unlock repository')} |
|
99 | 100 | </button> |
|
100 | 101 | %else: |
|
101 | 102 | ${h.hidden('set_lock', '1')} |
|
102 | 103 | <button class="btn btn-small" type="submit" |
|
103 |
onclick=" |
|
|
104 | onclick="submitConfirm(event, this, _gettext('Confirm to lock this repository'), _gettext('lock'), '${c.rhodecode_db_repo.repo_name}')" | |
|
105 | > | |
|
104 | 106 | <i class="icon-lock"></i> |
|
105 | 107 | ${_('Lock repository')} |
|
106 | 108 | </button> |
|
107 | 109 | %endif |
|
108 | 110 | </div> |
|
109 | 111 | <div class="field" > |
|
110 | 112 | <span class="help-block"> |
|
111 | 113 | ${_('Force repository locking. This only works when anonymous access is disabled. Pulling from the repository locks the repository to that user until the same user pushes to that repository again.')} |
|
112 | 114 | </span> |
|
113 | 115 | </div> |
|
114 | 116 | ${h.end_form()} |
|
115 | 117 | </div> |
|
116 | 118 | </div> |
|
117 | 119 | |
|
118 | 120 | |
|
119 | 121 | <div class="panel panel-default"> |
|
120 | 122 | <div class="panel-heading" id="advanced-hooks"> |
|
121 | 123 | <h3 class="panel-title">${_('Hooks')} <a class="permalink" href="#advanced-hooks"> ΒΆ</a></h3> |
|
122 | 124 | </div> |
|
123 | 125 | <div class="panel-body"> |
|
124 | 126 | <table class="rctable"> |
|
125 | 127 | <th>${_('Hook type')}</th> |
|
126 | 128 | <th>${_('Hook version')}</th> |
|
127 | 129 | <th>${_('Current version')}</th> |
|
128 | 130 | % if c.ver_info_dict: |
|
129 | 131 | <tr> |
|
130 | 132 | <td>${_('PRE HOOK')}</td> |
|
131 | 133 | <td>${c.ver_info_dict['pre_version']}</td> |
|
132 | 134 | <td>${c.rhodecode_version}</td> |
|
133 | 135 | </tr> |
|
134 | 136 | <tr> |
|
135 | 137 | <td>${_('POST HOOK')}</td> |
|
136 | 138 | <td>${c.ver_info_dict['post_version']}</td> |
|
137 | 139 | <td>${c.rhodecode_version}</td> |
|
138 | 140 | </tr> |
|
139 | 141 | % else: |
|
140 | 142 | <tr> |
|
141 | 143 | <td>${_('Unable to read hook information from VCS Server')}</td> |
|
142 | 144 | </tr> |
|
143 | 145 | % endif |
|
144 | 146 | </table> |
|
145 | 147 | |
|
146 | 148 | <a class="btn btn-primary" href="${h.route_path('edit_repo_advanced_hooks', repo_name=c.repo_name)}" |
|
147 | 149 | onclick="return confirm('${_('Confirm to reinstall hooks for this repository.')}');"> |
|
148 | 150 | ${_('Update Hooks')} |
|
149 | 151 | </a> |
|
150 | 152 | % if c.hooks_outdated: |
|
151 | 153 | <span class="alert-error" style="padding: 10px"> |
|
152 | 154 | ${_('Outdated hooks detected, please update hooks using `Update Hooks` action.')} |
|
153 | 155 | </span> |
|
154 | 156 | % endif |
|
155 | 157 | </div> |
|
156 | 158 | </div> |
|
157 | 159 | |
|
158 | 160 | <div class="panel panel-warning"> |
|
159 | 161 | <div class="panel-heading" id="advanced-archive"> |
|
160 | 162 | <h3 class="panel-title">${_('Archive repository')} <a class="permalink" href="#advanced-archive"> ΒΆ</a></h3> |
|
161 | 163 | </div> |
|
162 | 164 | <div class="panel-body"> |
|
163 | 165 | ${h.secure_form(h.route_path('edit_repo_advanced_archive', repo_name=c.repo_name), request=request)} |
|
164 | 166 | |
|
165 | 167 | <div style="margin: 0 0 20px 0" class="fake-space"></div> |
|
166 | 168 | |
|
167 | 169 | <div class="field"> |
|
168 | 170 | <button class="btn btn-small btn-warning" type="submit" |
|
169 |
onclick=" |
|
|
171 | onclick="submitConfirm(event, this, _gettext('Confirm to archive this repository'), _gettext('Archive'), '${c.rhodecode_db_repo.repo_name}')" | |
|
172 | > | |
|
170 | 173 | ${_('Archive this repository')} |
|
171 | 174 | </button> |
|
172 | 175 | </div> |
|
173 | 176 | <div class="field"> |
|
174 | 177 | <span class="help-block"> |
|
175 | 178 | ${_('Archiving the repository will make it entirely read-only. The repository cannot be committed to.' |
|
176 | 179 | 'It is hidden from the search results and dashboard. ')} |
|
177 | 180 | </span> |
|
178 | 181 | </div> |
|
179 | 182 | |
|
180 | 183 | ${h.end_form()} |
|
181 | 184 | </div> |
|
182 | 185 | </div> |
|
183 | 186 | |
|
184 | 187 | |
|
185 | 188 | <div class="panel panel-danger"> |
|
186 | 189 | <div class="panel-heading" id="advanced-delete"> |
|
187 | 190 | <h3 class="panel-title">${_('Delete repository')} <a class="permalink" href="#advanced-delete"> ΒΆ</a></h3> |
|
188 | 191 | </div> |
|
189 | 192 | <div class="panel-body"> |
|
190 | 193 | ${h.secure_form(h.route_path('edit_repo_advanced_delete', repo_name=c.repo_name), request=request)} |
|
191 | 194 | <table class="display"> |
|
192 | 195 | <tr> |
|
193 | 196 | <td> |
|
194 | 197 | ${_ungettext('This repository has %s fork.', 'This repository has %s forks.', c.rhodecode_db_repo.forks.count()) % c.rhodecode_db_repo.forks.count()} |
|
195 | 198 | </td> |
|
196 | 199 | <td> |
|
197 | 200 | %if c.rhodecode_db_repo.forks.count(): |
|
198 | 201 | <input type="radio" name="forks" value="detach_forks" checked="checked"/> <label for="forks">${_('Detach forks')}</label> |
|
199 | 202 | %endif |
|
200 | 203 | </td> |
|
201 | 204 | <td> |
|
202 | 205 | %if c.rhodecode_db_repo.forks.count(): |
|
203 | 206 | <input type="radio" name="forks" value="delete_forks"/> <label for="forks">${_('Delete forks')}</label> |
|
204 | 207 | %endif |
|
205 | 208 | </td> |
|
206 | 209 | </tr> |
|
207 | 210 | <% attached_prs = len(c.rhodecode_db_repo.pull_requests_source + c.rhodecode_db_repo.pull_requests_target) %> |
|
208 | 211 | % if c.rhodecode_db_repo.pull_requests_source or c.rhodecode_db_repo.pull_requests_target: |
|
209 | 212 | <tr> |
|
210 | 213 | <td> |
|
211 | 214 | ${_ungettext('This repository has %s attached pull request.', 'This repository has %s attached pull requests.', attached_prs) % attached_prs} |
|
212 | 215 | <br/> |
|
213 | 216 | ${_('Consider to archive this repository instead.')} |
|
214 | 217 | </td> |
|
215 | 218 | <td></td> |
|
216 | 219 | <td></td> |
|
217 | 220 | </tr> |
|
218 | 221 | % endif |
|
219 | 222 | </table> |
|
220 | 223 | <div style="margin: 0 0 20px 0" class="fake-space"></div> |
|
221 | 224 | |
|
222 | 225 | <div class="field"> |
|
223 | 226 | <button class="btn btn-small btn-danger" type="submit" |
|
224 |
onclick=" |
|
|
227 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository'), _gettext('Delete'), '${c.rhodecode_db_repo.repo_name}')" | |
|
228 | > | |
|
225 | 229 | ${_('Delete this repository')} |
|
226 | 230 | </button> |
|
227 | 231 | </div> |
|
228 | 232 | <div class="field"> |
|
229 | 233 | <span class="help-block"> |
|
230 | 234 | ${_('This repository will be renamed in a special way in order to make it inaccessible to RhodeCode Enterprise and its VCS systems. If you need to fully delete it from the file system, please do it manually, or with rhodecode-cleanup-repos command available in rhodecode-tools.')} |
|
231 | 235 | </span> |
|
232 | 236 | </div> |
|
233 | 237 | |
|
234 | 238 | ${h.end_form()} |
|
235 | 239 | </div> |
|
236 | 240 | </div> |
|
237 | 241 | |
|
238 | 242 | |
|
239 | 243 | <script> |
|
240 | 244 | |
|
241 | 245 | var currentRepoId = ${c.rhodecode_db_repo.repo_id}; |
|
242 | 246 | |
|
243 | 247 | var repoTypeFilter = function(data) { |
|
244 | 248 | var results = []; |
|
245 | 249 | |
|
246 | 250 | if (!data.results[0]) { |
|
247 | 251 | return data |
|
248 | 252 | } |
|
249 | 253 | |
|
250 | 254 | $.each(data.results[0].children, function() { |
|
251 | 255 | // filter out the SAME repo, it cannot be used as fork of itself |
|
252 | 256 | if (this.repo_id != currentRepoId) { |
|
253 | 257 | this.id = this.repo_id; |
|
254 | 258 | results.push(this) |
|
255 | 259 | } |
|
256 | 260 | }); |
|
257 | 261 | data.results[0].children = results; |
|
258 | 262 | return data; |
|
259 | 263 | }; |
|
260 | 264 | |
|
261 | 265 | $("#id_fork_of").select2({ |
|
262 | 266 | cachedDataSource: {}, |
|
263 | 267 | minimumInputLength: 2, |
|
264 | 268 | placeholder: "${_('Change repository') if c.rhodecode_db_repo.fork else _('Pick repository')}", |
|
265 | 269 | dropdownAutoWidth: true, |
|
266 | 270 | containerCssClass: "drop-menu", |
|
267 | 271 | dropdownCssClass: "drop-menu-dropdown", |
|
268 | 272 | formatResult: formatRepoResult, |
|
269 | 273 | query: $.debounce(250, function(query){ |
|
270 | 274 | self = this; |
|
271 | 275 | var cacheKey = query.term; |
|
272 | 276 | var cachedData = self.cachedDataSource[cacheKey]; |
|
273 | 277 | |
|
274 | 278 | if (cachedData) { |
|
275 | 279 | query.callback({results: cachedData.results}); |
|
276 | 280 | } else { |
|
277 | 281 | $.ajax({ |
|
278 | 282 | url: pyroutes.url('repo_list_data'), |
|
279 | 283 | data: {'query': query.term, repo_type: '${c.rhodecode_db_repo.repo_type}'}, |
|
280 | 284 | dataType: 'json', |
|
281 | 285 | type: 'GET', |
|
282 | 286 | success: function(data) { |
|
283 | 287 | data = repoTypeFilter(data); |
|
284 | 288 | self.cachedDataSource[cacheKey] = data; |
|
285 | 289 | query.callback({results: data.results}); |
|
286 | 290 | }, |
|
287 | 291 | error: function(data, textStatus, errorThrown) { |
|
288 | 292 | alert("Error while fetching entries.\nError code {0} ({1}).".format(data.status, data.statusText)); |
|
289 | 293 | } |
|
290 | 294 | }) |
|
291 | 295 | } |
|
292 | 296 | }) |
|
293 | 297 | }); |
|
294 | 298 | </script> |
|
295 | 299 |
@@ -1,154 +1,158 b'' | |||
|
1 | 1 | <div class="panel panel-default"> |
|
2 | 2 | <div class="panel-heading"> |
|
3 | 3 | <h3 class="panel-title">${_('Invalidate Cache for Repository')}</h3> |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | 6 | |
|
7 | 7 | <h4>${_('Manually invalidate the repository cache. On the next access a repository cache will be recreated.')}</h4> |
|
8 | 8 | |
|
9 | 9 | <p> |
|
10 | 10 | ${_('Cache purge can be automated by such api call. Can be called periodically in crontab etc.')} |
|
11 | 11 | <br/> |
|
12 | 12 | <code> |
|
13 | 13 | ${h.api_call_example(method='invalidate_cache', args={"repoid": c.rhodecode_db_repo.repo_name})} |
|
14 | 14 | </code> |
|
15 | 15 | </p> |
|
16 | 16 | |
|
17 | 17 | ${h.secure_form(h.route_path('edit_repo_caches', repo_name=c.repo_name), request=request)} |
|
18 | 18 | <div class="form"> |
|
19 | 19 | <div class="fields"> |
|
20 | ${h.submit('reset_cache_%s' % c.rhodecode_db_repo.repo_name,_('Invalidate repository cache'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to invalidate repository cache')+"');")} | |
|
20 | <input class="btn btn-small" id="reset_cache_${c.rhodecode_db_repo.repo_id}" | |
|
21 | name="reset_cache_${c.rhodecode_db_repo.repo_id}" | |
|
22 | onclick="submitConfirm(event, this, _gettext('Confirm to invalidate repository cache'), _gettext('Invalidate Cache'), '${c.rhodecode_db_repo.repo_name}')" | |
|
23 | type="submit" value="${_('Invalidate repository cache')}" | |
|
24 | > | |
|
21 | 25 | </div> |
|
22 | 26 | </div> |
|
23 | 27 | ${h.end_form()} |
|
24 | 28 | |
|
25 | 29 | </div> |
|
26 | 30 | </div> |
|
27 | 31 | |
|
28 | 32 | |
|
29 | 33 | <div class="panel panel-default"> |
|
30 | 34 | <div class="panel-heading"> |
|
31 | 35 | <h3 class="panel-title"> |
|
32 | 36 | ${_('Invalidation keys')} |
|
33 | 37 | </h3> |
|
34 | 38 | </div> |
|
35 | 39 | <div class="panel-body"> |
|
36 | 40 | <p> |
|
37 | 41 | Cache keys used to signal repository state changes after operations such as push, strip etc. |
|
38 | 42 | </p> |
|
39 | 43 | <div class="field"> |
|
40 | 44 | <a href="#showKeys" onclick="$('#signal-keys').toggle()">${_('Show all')} ${len(c.rhodecode_db_repo.cache_keys)}</a> |
|
41 | 45 | |
|
42 | 46 | <table class="rctable edit_cache" id="signal-keys" style="display: none"> |
|
43 | 47 | <tr> |
|
44 | 48 | <th>${_('Key')}</th> |
|
45 | 49 | <th>${_('State UID')}</th> |
|
46 | 50 | <th>${_('Namespace')}</th> |
|
47 | 51 | <th>${_('Active')}</th> |
|
48 | 52 | </tr> |
|
49 | 53 | %for cache in c.rhodecode_db_repo.cache_keys: |
|
50 | 54 | <tr> |
|
51 | 55 | <td class="td-prefix"><code>${cache.cache_key}</code></td> |
|
52 | 56 | <td class="td-cachekey"><code>${cache.cache_state_uid}</code></td> |
|
53 | 57 | <td class="td-cachekey"><code>${cache.cache_args}</code></td> |
|
54 | 58 | <td class="td-active">${h.bool2icon(cache.cache_active)}</td> |
|
55 | 59 | </tr> |
|
56 | 60 | %endfor |
|
57 | 61 | </table> |
|
58 | 62 | </div> |
|
59 | 63 | </div> |
|
60 | 64 | </div> |
|
61 | 65 | |
|
62 | 66 | <div class="panel panel-default"> |
|
63 | 67 | <div class="panel-heading"> |
|
64 | 68 | <h3 class="panel-title"> |
|
65 | 69 | ${_('Cache keys')} |
|
66 | 70 | </h3> |
|
67 | 71 | </div> |
|
68 | 72 | <div class="panel-body"> |
|
69 | 73 | <p> |
|
70 | 74 | Cache keys used for storing cached values of repository stats, |
|
71 | 75 | file tree history and file tree search. |
|
72 | 76 | Invalidating the cache will remove those entries. |
|
73 | 77 | </p> |
|
74 | 78 | <pre> |
|
75 | 79 | backend: ${c.region.actual_backend.__class__} |
|
76 | 80 | % if c.rhodecode_user.is_admin: |
|
77 | 81 | store: ${c.region.actual_backend.get_store()} |
|
78 | 82 | % else: |
|
79 | 83 | store: ${c.region.actual_backend.get_store().__class__} |
|
80 | 84 | % endif |
|
81 | 85 | </pre> |
|
82 | 86 | |
|
83 | 87 | <div class="field"> |
|
84 | 88 | <a href="#showKeys" onclick="$('#cache-keys').toggle()">${_('Show all')} ${len(c.repo_keys)}</a> |
|
85 | 89 | |
|
86 | 90 | <table class="rctable edit_cache" id="cache-keys" style="display: none"> |
|
87 | 91 | <tr> |
|
88 | 92 | <th>${_('Key')}</th> |
|
89 | 93 | <th>${_('Region')}</th> |
|
90 | 94 | </tr> |
|
91 | 95 | %for cache_key in c.repo_keys: |
|
92 | 96 | <tr> |
|
93 | 97 | <td class="td-prefix"><code>${cache_key}</code></td> |
|
94 | 98 | <td class="td-cachekey">${c.region.name}</td> |
|
95 | 99 | </tr> |
|
96 | 100 | %endfor |
|
97 | 101 | </table> |
|
98 | 102 | </div> |
|
99 | 103 | |
|
100 | 104 | </div> |
|
101 | 105 | </div> |
|
102 | 106 | |
|
103 | 107 | |
|
104 | 108 | <div class="panel panel-default"> |
|
105 | 109 | <div class="panel-heading"> |
|
106 | 110 | <h3 class="panel-title">${_('Shadow Repositories')}</h3> |
|
107 | 111 | </div> |
|
108 | 112 | <div class="panel-body"> |
|
109 | 113 | <table class="rctable edit_cache"> |
|
110 | 114 | % if c.shadow_repos: |
|
111 | 115 | % for shadow_repo in c.shadow_repos: |
|
112 | 116 | <tr> |
|
113 | 117 | <td>${shadow_repo}</td> |
|
114 | 118 | </tr> |
|
115 | 119 | % endfor |
|
116 | 120 | % else: |
|
117 | 121 | <tr> |
|
118 | 122 | <td>${_('No Shadow repositories exist for this repository.')}</td> |
|
119 | 123 | </tr> |
|
120 | 124 | % endif |
|
121 | 125 | |
|
122 | 126 | </table> |
|
123 | 127 | </div> |
|
124 | 128 | </div> |
|
125 | 129 | |
|
126 | 130 | |
|
127 | 131 | <div class="panel panel-default"> |
|
128 | 132 | <div class="panel-heading"> |
|
129 | 133 | <h3 class="panel-title">${_('Diff Caches')}</h3> |
|
130 | 134 | </div> |
|
131 | 135 | <div class="panel-body"> |
|
132 | 136 | <p> |
|
133 | 137 | Number and size of stored cached diff for commits and pull requests. |
|
134 | 138 | </p> |
|
135 | 139 | <table class="rctable edit_cache"> |
|
136 | 140 | <tr> |
|
137 | 141 | <td>${_('Cached diff name')}:</td> |
|
138 | 142 | % if c.rhodecode_user.is_admin: |
|
139 | 143 | <td>${c.rhodecode_db_repo.cached_diffs_dir}</td> |
|
140 | 144 | % else: |
|
141 | 145 | <td>${c.rhodecode_db_repo.cached_diffs_relative_dir}</td> |
|
142 | 146 | % endif |
|
143 | 147 | </tr> |
|
144 | 148 | <tr> |
|
145 | 149 | <td>${_('Cached diff files')}:</td> |
|
146 | 150 | <td>${c.cached_diff_count}</td> |
|
147 | 151 | </tr> |
|
148 | 152 | <tr> |
|
149 | 153 | <td>${_('Cached diff size')}:</td> |
|
150 | 154 | <td>${h.format_byte_size(c.cached_diff_size)}</td> |
|
151 | 155 | </tr> |
|
152 | 156 | </table> |
|
153 | 157 | </div> |
|
154 | 158 | </div> |
@@ -1,68 +1,73 b'' | |||
|
1 | 1 | <div class="panel panel-default"> |
|
2 | 2 | <div class="panel-heading"> |
|
3 | 3 | <h3 class="panel-title">${_('Remote Sync')}</h3> |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | 6 | |
|
7 | 7 | <h4>${_('Manually pull/push changes from/to external URLs.')}</h4> |
|
8 | 8 | |
|
9 | 9 | <table> |
|
10 | 10 | <tr> |
|
11 | 11 | <td><div style="min-width: 80px"><strong>${_('Pull url')}</strong></div></td> |
|
12 | 12 | <td> |
|
13 | 13 | % if c.rhodecode_db_repo.clone_uri: |
|
14 | 14 | <a href="${c.rhodecode_db_repo.clone_uri}">${c.rhodecode_db_repo.clone_uri_hidden}</a> |
|
15 | 15 | % else: |
|
16 | 16 | ${_('This repository does not have any pull url set.')} |
|
17 | 17 | <a href="${h.route_path('edit_repo', repo_name=c.rhodecode_db_repo.repo_name)}">${_('Set remote url.')}</a> |
|
18 | 18 | % endif |
|
19 | 19 | </td> |
|
20 | 20 | </tr> |
|
21 | 21 | % if c.rhodecode_db_repo.clone_uri: |
|
22 | 22 | <tr> |
|
23 | 23 | <td></td> |
|
24 | 24 | <td> |
|
25 | 25 | <p> |
|
26 | 26 | ${_('Pull can be automated by such api call. Can be called periodically in crontab etc.')} |
|
27 | 27 | <br/> |
|
28 | 28 | <code> |
|
29 | 29 | ${h.api_call_example(method='pull', args={"repoid": c.rhodecode_db_repo.repo_name})} |
|
30 | 30 | </code> |
|
31 | 31 | </p> |
|
32 | 32 | </td> |
|
33 | 33 | </tr> |
|
34 | 34 | <tr> |
|
35 | 35 | <td></td> |
|
36 | 36 | <td> |
|
37 | 37 | ${h.secure_form(h.route_path('edit_repo_remote_pull', repo_name=c.repo_name), request=request)} |
|
38 | 38 | <div class="form"> |
|
39 | 39 | <div class="fields"> |
|
40 | ${h.submit('remote_pull_%s' % c.rhodecode_db_repo.repo_name,_('Pull changes from remote location'),class_="btn btn-small",onclick="return confirm('"+_('Confirm to pull changes from remote side')+"');")} | |
|
40 | <input class="btn btn-small" | |
|
41 | id="remote_pull_${c.rhodecode_db_repo.repo_id}" | |
|
42 | name="remote_pull_${c.rhodecode_db_repo.repo_id}" | |
|
43 | onclick="submitConfirm(event, this, _gettext('Confirm pull changes from remote side'), _gettext('Pull changes'), '${c.rhodecode_db_repo.clone_uri_hidden}')" | |
|
44 | type="submit" value="${_('Pull changes from remote location')}" | |
|
45 | > | |
|
41 | 46 | </div> |
|
42 | 47 | </div> |
|
43 | 48 | ${h.end_form()} |
|
44 | 49 | </td> |
|
45 | 50 | </tr> |
|
46 | 51 | % endif |
|
47 | 52 | |
|
48 | 53 | <tr> |
|
49 | 54 | <td><div style="min-width: 80px"><strong>${_('Push url')}</strong></div></td> |
|
50 | 55 | <td> |
|
51 | 56 | % if c.rhodecode_db_repo.push_uri: |
|
52 | 57 | <a href="${c.rhodecode_db_repo.push_uri_hidden}">${c.rhodecode_db_repo.push_uri_hidden}</a> |
|
53 | 58 | % else: |
|
54 | 59 | ${_('This repository does not have any push url set.')} |
|
55 | 60 | <a href="${h.route_path('edit_repo', repo_name=c.rhodecode_db_repo.repo_name)}">${_('Set remote url.')}</a> |
|
56 | 61 | % endif |
|
57 | 62 | </td> |
|
58 | 63 | </tr> |
|
59 | 64 | <tr> |
|
60 | 65 | <td></td> |
|
61 | 66 | <td> |
|
62 | 67 | ${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n} |
|
63 | 68 | </td> |
|
64 | 69 | </tr> |
|
65 | 70 | |
|
66 | 71 | </table> |
|
67 | 72 | </div> |
|
68 | 73 | </div> |
@@ -1,47 +1,47 b'' | |||
|
1 | 1 | <div class="panel panel-default"> |
|
2 | 2 | <div class="panel-heading"> |
|
3 | 3 | <h3 class="panel-title">${_('Exceptions Tracker - Exception ID')}: ${c.exception_id}</h3> |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | 6 | % if c.traceback: |
|
7 | 7 | |
|
8 | 8 | <h4>${_('Exception `{}` generated on UTC date: {}').format(c.traceback.get('exc_type', 'NO_TYPE'), c.traceback.get('exc_utc_date', 'NO_DATE'))}</h4> |
|
9 | 9 | % if c.traceback.get('url'): |
|
10 | 10 | Request: |
|
11 | 11 | <code>${c.traceback.get('method')} ${c.traceback.get('url')}</code><br/> |
|
12 | 12 | <code>${c.traceback.get('client_address')} ${c.traceback.get('user_agent')}</code> |
|
13 | 13 | <br/> |
|
14 | 14 | <br/> |
|
15 | 15 | % endif |
|
16 | 16 | |
|
17 | 17 | <pre>${c.traceback.get('exc_message', 'NO_MESSAGE')}</pre> |
|
18 | 18 | |
|
19 | 19 | |
|
20 | 20 | % else: |
|
21 | 21 | ${_('Unable to Read Exception. It might be removed or non-existing.')} |
|
22 | 22 | % endif |
|
23 | 23 | </div> |
|
24 | 24 | </div> |
|
25 | 25 | |
|
26 | 26 | |
|
27 | 27 | % if c.traceback: |
|
28 | 28 | <div class="panel panel-danger"> |
|
29 | 29 | <div class="panel-heading" id="advanced-delete"> |
|
30 | 30 | <h3 class="panel-title">${_('Delete this Exception')}</h3> |
|
31 | 31 | </div> |
|
32 | 32 | <div class="panel-body"> |
|
33 | 33 | ${h.secure_form(h.route_path('admin_settings_exception_tracker_delete', exception_id=c.exception_id), request=request)} |
|
34 | 34 | <div style="margin: 0 0 20px 0" class="fake-space"></div> |
|
35 | 35 | |
|
36 | 36 | <div class="field"> |
|
37 | 37 | <button class="btn btn-small btn-danger" type="submit" |
|
38 |
onclick=" |
|
|
38 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this exception'), _gettext('Delete'), ${c.exception_id})"> | |
|
39 | 39 | <i class="icon-remove"></i> |
|
40 | 40 | ${_('Delete This Exception')} |
|
41 | 41 | </button> |
|
42 | 42 | </div> |
|
43 | 43 | |
|
44 | 44 | ${h.end_form()} |
|
45 | 45 | </div> |
|
46 | 46 | </div> |
|
47 | 47 | % endif |
@@ -1,65 +1,66 b'' | |||
|
1 | 1 | <div class="panel panel-default"> |
|
2 | 2 | <div class="panel-heading"> |
|
3 | 3 | <h3 class="panel-title">${_('Exceptions Tracker ')}</h3> |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | 6 | % if c.exception_list_count == 1: |
|
7 | 7 | ${_('There is {} stored exception.').format(c.exception_list_count)} |
|
8 | 8 | % else: |
|
9 | 9 | ${_('There are total {} stored exceptions.').format(c.exception_list_count)} |
|
10 | 10 | % endif |
|
11 | 11 | <br/> |
|
12 | 12 | ${_('Store directory')}: ${c.exception_store_dir} |
|
13 | 13 | |
|
14 | 14 | ${h.secure_form(h.route_path('admin_settings_exception_tracker_delete_all'), request=request)} |
|
15 | 15 | <div style="margin: 0 0 20px 0" class="fake-space"></div> |
|
16 | 16 | <input type="hidden" name="type_filter", value="${c.type_filter}"> |
|
17 | 17 | <div class="field"> |
|
18 | 18 | <button class="btn btn-small btn-danger" type="submit" |
|
19 |
onclick=" |
|
|
19 | onclick="submitConfirm(event, this, _gettext('Confirm to delete all exceptions'), _gettext('Delete'), '${'total:{}'.format(c.exception_list_count)}')" | |
|
20 | > | |
|
20 | 21 | <i class="icon-remove"></i> |
|
21 | 22 | % if c.type_filter: |
|
22 | 23 | ${_('Delete All `{}`').format(c.type_filter)} |
|
23 | 24 | % else: |
|
24 | 25 | ${_('Delete All')} |
|
25 | 26 | % endif |
|
26 | 27 | |
|
27 | 28 | </button> |
|
28 | 29 | </div> |
|
29 | 30 | |
|
30 | 31 | ${h.end_form()} |
|
31 | 32 | |
|
32 | 33 | </div> |
|
33 | 34 | </div> |
|
34 | 35 | |
|
35 | 36 | |
|
36 | 37 | <div class="panel panel-default"> |
|
37 | 38 | <div class="panel-heading"> |
|
38 | 39 | <h3 class="panel-title">${_('Exceptions Tracker - Showing the last {} Exceptions').format(c.limit)}.</h3> |
|
39 | 40 | <a class="panel-edit" href="${h.current_route_path(request, limit=c.next_limit)}">${_('Show more')}</a> |
|
40 | 41 | </div> |
|
41 | 42 | <div class="panel-body"> |
|
42 | 43 | <table class="rctable"> |
|
43 | 44 | <tr> |
|
44 | 45 | <th>#</th> |
|
45 | 46 | <th>Exception ID</th> |
|
46 | 47 | <th>Date</th> |
|
47 | 48 | <th>App Type</th> |
|
48 | 49 | <th>Exc Type</th> |
|
49 | 50 | </tr> |
|
50 | 51 | <% cnt = len(c.exception_list)%> |
|
51 | 52 | % for tb in c.exception_list: |
|
52 | 53 | <tr> |
|
53 | 54 | <td>${cnt}</td> |
|
54 | 55 | <td><a href="${h.route_path('admin_settings_exception_tracker_show', exception_id=tb['exc_id'])}"><code>${tb['exc_id']}</code></a></td> |
|
55 | 56 | <td>${h.format_date(tb['exc_utc_date'])}</td> |
|
56 | 57 | <td>${tb['app_type']}</td> |
|
57 | 58 | <td> |
|
58 | 59 | <a href="${h.current_route_path(request, type_filter=tb['exc_type'])}">${tb['exc_type']}</a> |
|
59 | 60 | </td> |
|
60 | 61 | </tr> |
|
61 | 62 | <% cnt -=1 %> |
|
62 | 63 | % endfor |
|
63 | 64 | </table> |
|
64 | 65 | </div> |
|
65 | 66 | </div> |
@@ -1,479 +1,489 b'' | |||
|
1 | 1 | ## DATA TABLE RE USABLE ELEMENTS |
|
2 | 2 | ## usage: |
|
3 | 3 | ## <%namespace name="dt" file="/data_table/_dt_elements.mako"/> |
|
4 | 4 | <%namespace name="base" file="/base/base.mako"/> |
|
5 | 5 | |
|
6 | 6 | <%def name="metatags_help()"> |
|
7 | 7 | <table> |
|
8 | 8 | <% |
|
9 | 9 | example_tags = [ |
|
10 | 10 | ('state','[stable]'), |
|
11 | 11 | ('state','[stale]'), |
|
12 | 12 | ('state','[featured]'), |
|
13 | 13 | ('state','[dev]'), |
|
14 | 14 | ('state','[dead]'), |
|
15 | 15 | ('state','[deprecated]'), |
|
16 | 16 | |
|
17 | 17 | ('label','[personal]'), |
|
18 | 18 | ('generic','[v2.0.0]'), |
|
19 | 19 | |
|
20 | 20 | ('lang','[lang => JavaScript]'), |
|
21 | 21 | ('license','[license => LicenseName]'), |
|
22 | 22 | |
|
23 | 23 | ('ref','[requires => RepoName]'), |
|
24 | 24 | ('ref','[recommends => GroupName]'), |
|
25 | 25 | ('ref','[conflicts => SomeName]'), |
|
26 | 26 | ('ref','[base => SomeName]'), |
|
27 | 27 | ('url','[url => [linkName](https://rhodecode.com)]'), |
|
28 | 28 | ('see','[see => http://rhodecode.com]'), |
|
29 | 29 | ] |
|
30 | 30 | %> |
|
31 | 31 | % for tag_type, tag in example_tags: |
|
32 | 32 | <tr> |
|
33 | 33 | <td>${tag|n}</td> |
|
34 | 34 | <td>${h.style_metatag(tag_type, tag)|n}</td> |
|
35 | 35 | </tr> |
|
36 | 36 | % endfor |
|
37 | 37 | </table> |
|
38 | 38 | </%def> |
|
39 | 39 | |
|
40 | 40 | <%def name="render_description(description, stylify_metatags)"> |
|
41 | 41 | <% |
|
42 | 42 | tags = [] |
|
43 | 43 | if stylify_metatags: |
|
44 | 44 | tags, description = h.extract_metatags(description) |
|
45 | 45 | %> |
|
46 | 46 | % for tag_type, tag in tags: |
|
47 | 47 | ${h.style_metatag(tag_type, tag)|n,trim} |
|
48 | 48 | % endfor |
|
49 | 49 | <code style="white-space: pre-wrap">${description}</code> |
|
50 | 50 | </%def> |
|
51 | 51 | |
|
52 | 52 | ## REPOSITORY RENDERERS |
|
53 | 53 | <%def name="quick_menu(repo_name)"> |
|
54 | 54 | <i class="icon-more"></i> |
|
55 | 55 | <div class="menu_items_container hidden"> |
|
56 | 56 | <ul class="menu_items"> |
|
57 | 57 | <li> |
|
58 | 58 | <a title="${_('Summary')}" href="${h.route_path('repo_summary',repo_name=repo_name)}"> |
|
59 | 59 | <span>${_('Summary')}</span> |
|
60 | 60 | </a> |
|
61 | 61 | </li> |
|
62 | 62 | <li> |
|
63 | 63 | <a title="${_('Commits')}" href="${h.route_path('repo_commits',repo_name=repo_name)}"> |
|
64 | 64 | <span>${_('Commits')}</span> |
|
65 | 65 | </a> |
|
66 | 66 | </li> |
|
67 | 67 | <li> |
|
68 | 68 | <a title="${_('Files')}" href="${h.route_path('repo_files:default_commit',repo_name=repo_name)}"> |
|
69 | 69 | <span>${_('Files')}</span> |
|
70 | 70 | </a> |
|
71 | 71 | </li> |
|
72 | 72 | <li> |
|
73 | 73 | <a title="${_('Fork')}" href="${h.route_path('repo_fork_new',repo_name=repo_name)}"> |
|
74 | 74 | <span>${_('Fork')}</span> |
|
75 | 75 | </a> |
|
76 | 76 | </li> |
|
77 | 77 | </ul> |
|
78 | 78 | </div> |
|
79 | 79 | </%def> |
|
80 | 80 | |
|
81 | 81 | <%def name="repo_name(name,rtype,rstate,private,archived,fork_of,short_name=False,admin=False)"> |
|
82 | 82 | <% |
|
83 | 83 | def get_name(name,short_name=short_name): |
|
84 | 84 | if short_name: |
|
85 | 85 | return name.split('/')[-1] |
|
86 | 86 | else: |
|
87 | 87 | return name |
|
88 | 88 | %> |
|
89 | 89 | <div class="${'repo_state_pending' if rstate == 'repo_state_pending' else ''} truncate"> |
|
90 | 90 | ##NAME |
|
91 | 91 | <a href="${h.route_path('edit_repo',repo_name=name) if admin else h.route_path('repo_summary',repo_name=name)}"> |
|
92 | 92 | |
|
93 | 93 | ##TYPE OF REPO |
|
94 | 94 | %if h.is_hg(rtype): |
|
95 | 95 | <span title="${_('Mercurial repository')}"><i class="icon-hg" style="font-size: 14px;"></i></span> |
|
96 | 96 | %elif h.is_git(rtype): |
|
97 | 97 | <span title="${_('Git repository')}"><i class="icon-git" style="font-size: 14px"></i></span> |
|
98 | 98 | %elif h.is_svn(rtype): |
|
99 | 99 | <span title="${_('Subversion repository')}"><i class="icon-svn" style="font-size: 14px"></i></span> |
|
100 | 100 | %endif |
|
101 | 101 | |
|
102 | 102 | ##PRIVATE/PUBLIC |
|
103 | 103 | %if private is True and c.visual.show_private_icon: |
|
104 | 104 | <i class="icon-lock" title="${_('Private repository')}"></i> |
|
105 | 105 | %elif private is False and c.visual.show_public_icon: |
|
106 | 106 | <i class="icon-unlock-alt" title="${_('Public repository')}"></i> |
|
107 | 107 | %else: |
|
108 | 108 | <span></span> |
|
109 | 109 | %endif |
|
110 | 110 | ${get_name(name)} |
|
111 | 111 | </a> |
|
112 | 112 | %if fork_of: |
|
113 | 113 | <a href="${h.route_path('repo_summary',repo_name=fork_of.repo_name)}"><i class="icon-code-fork"></i></a> |
|
114 | 114 | %endif |
|
115 | 115 | %if rstate == 'repo_state_pending': |
|
116 | 116 | <span class="creation_in_progress tooltip" title="${_('This repository is being created in a background task')}"> |
|
117 | 117 | (${_('creating...')}) |
|
118 | 118 | </span> |
|
119 | 119 | %endif |
|
120 | 120 | |
|
121 | 121 | </div> |
|
122 | 122 | </%def> |
|
123 | 123 | |
|
124 | 124 | <%def name="repo_desc(description, stylify_metatags)"> |
|
125 | 125 | <% |
|
126 | 126 | tags, description = h.extract_metatags(description) |
|
127 | 127 | %> |
|
128 | 128 | |
|
129 | 129 | <div class="truncate-wrap"> |
|
130 | 130 | % if stylify_metatags: |
|
131 | 131 | % for tag_type, tag in tags: |
|
132 | 132 | ${h.style_metatag(tag_type, tag)|n} |
|
133 | 133 | % endfor |
|
134 | 134 | % endif |
|
135 | 135 | ${description} |
|
136 | 136 | </div> |
|
137 | 137 | |
|
138 | 138 | </%def> |
|
139 | 139 | |
|
140 | 140 | <%def name="last_change(last_change)"> |
|
141 | 141 | ${h.age_component(last_change, time_is_local=True)} |
|
142 | 142 | </%def> |
|
143 | 143 | |
|
144 | 144 | <%def name="revision(repo_name, rev, commit_id, author, last_msg, commit_date)"> |
|
145 | 145 | <div> |
|
146 | 146 | %if rev >= 0: |
|
147 | 147 | <code><a class="tooltip-hovercard" data-hovercard-alt=${h.tooltip(last_msg)} data-hovercard-url="${h.route_path('hovercard_repo_commit', repo_name=repo_name, commit_id=commit_id)}" href="${h.route_path('repo_commit',repo_name=repo_name,commit_id=commit_id)}">${'r{}:{}'.format(rev,h.short_id(commit_id))}</a></code> |
|
148 | 148 | %else: |
|
149 | 149 | ${_('No commits yet')} |
|
150 | 150 | %endif |
|
151 | 151 | </div> |
|
152 | 152 | </%def> |
|
153 | 153 | |
|
154 | 154 | <%def name="rss(name)"> |
|
155 | 155 | %if c.rhodecode_user.username != h.DEFAULT_USER: |
|
156 | 156 | <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a> |
|
157 | 157 | %else: |
|
158 | 158 | <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a> |
|
159 | 159 | %endif |
|
160 | 160 | </%def> |
|
161 | 161 | |
|
162 | 162 | <%def name="atom(name)"> |
|
163 | 163 | %if c.rhodecode_user.username != h.DEFAULT_USER: |
|
164 | 164 | <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a> |
|
165 | 165 | %else: |
|
166 | 166 | <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a> |
|
167 | 167 | %endif |
|
168 | 168 | </%def> |
|
169 | 169 | |
|
170 | 170 | <%def name="repo_actions(repo_name, super_user=True)"> |
|
171 | 171 | <div> |
|
172 | 172 | <div class="grid_edit"> |
|
173 | 173 | <a href="${h.route_path('edit_repo',repo_name=repo_name)}" title="${_('Edit')}"> |
|
174 | 174 | Edit |
|
175 | 175 | </a> |
|
176 | 176 | </div> |
|
177 | 177 | <div class="grid_delete"> |
|
178 | 178 | ${h.secure_form(h.route_path('edit_repo_advanced_delete', repo_name=repo_name), request=request)} |
|
179 | ${h.submit('remove_%s' % repo_name,_('Delete'),class_="btn btn-link btn-danger", | |
|
180 |
onclick=" |
|
|
179 | <input class="btn btn-link btn-danger" id="remove_${repo_name}" name="remove_${repo_name}" | |
|
180 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository'), _gettext('Delete'), '${repo_name}')" | |
|
181 | type="submit" value="Delete" | |
|
182 | > | |
|
181 | 183 | ${h.end_form()} |
|
182 | 184 | </div> |
|
183 | 185 | </div> |
|
184 | 186 | </%def> |
|
185 | 187 | |
|
186 | 188 | <%def name="repo_state(repo_state)"> |
|
187 | 189 | <div> |
|
188 | 190 | %if repo_state == 'repo_state_pending': |
|
189 | 191 | <div class="tag tag4">${_('Creating')}</div> |
|
190 | 192 | %elif repo_state == 'repo_state_created': |
|
191 | 193 | <div class="tag tag1">${_('Created')}</div> |
|
192 | 194 | %else: |
|
193 | 195 | <div class="tag alert2" title="${h.tooltip(repo_state)}">invalid</div> |
|
194 | 196 | %endif |
|
195 | 197 | </div> |
|
196 | 198 | </%def> |
|
197 | 199 | |
|
198 | 200 | |
|
199 | 201 | ## REPO GROUP RENDERERS |
|
200 | 202 | <%def name="quick_repo_group_menu(repo_group_name)"> |
|
201 | 203 | <i class="icon-more"></i> |
|
202 | 204 | <div class="menu_items_container hidden"> |
|
203 | 205 | <ul class="menu_items"> |
|
204 | 206 | <li> |
|
205 | 207 | <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">${_('Summary')}</a> |
|
206 | 208 | </li> |
|
207 | 209 | |
|
208 | 210 | </ul> |
|
209 | 211 | </div> |
|
210 | 212 | </%def> |
|
211 | 213 | |
|
212 | 214 | <%def name="repo_group_name(repo_group_name, children_groups=None)"> |
|
213 | 215 | <div> |
|
214 | 216 | <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}"> |
|
215 | 217 | <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i> |
|
216 | 218 | %if children_groups: |
|
217 | 219 | ${h.literal(' » '.join(children_groups))} |
|
218 | 220 | %else: |
|
219 | 221 | ${repo_group_name} |
|
220 | 222 | %endif |
|
221 | 223 | </a> |
|
222 | 224 | </div> |
|
223 | 225 | </%def> |
|
224 | 226 | |
|
225 | 227 | <%def name="repo_group_desc(description, personal, stylify_metatags)"> |
|
226 | 228 | |
|
227 | 229 | <% |
|
228 | 230 | if stylify_metatags: |
|
229 | 231 | tags, description = h.extract_metatags(description) |
|
230 | 232 | %> |
|
231 | 233 | |
|
232 | 234 | <div class="truncate-wrap"> |
|
233 | 235 | % if personal: |
|
234 | 236 | <div class="metatag" tag="personal">${_('personal')}</div> |
|
235 | 237 | % endif |
|
236 | 238 | |
|
237 | 239 | % if stylify_metatags: |
|
238 | 240 | % for tag_type, tag in tags: |
|
239 | 241 | ${h.style_metatag(tag_type, tag)|n} |
|
240 | 242 | % endfor |
|
241 | 243 | % endif |
|
242 | 244 | ${description} |
|
243 | 245 | </div> |
|
244 | 246 | |
|
245 | 247 | </%def> |
|
246 | 248 | |
|
247 | 249 | <%def name="repo_group_actions(repo_group_id, repo_group_name, gr_count)"> |
|
248 | 250 | <div class="grid_edit"> |
|
249 | 251 | <a href="${h.route_path('edit_repo_group',repo_group_name=repo_group_name)}" title="${_('Edit')}">Edit</a> |
|
250 | 252 | </div> |
|
251 | 253 | <div class="grid_delete"> |
|
252 | 254 | ${h.secure_form(h.route_path('edit_repo_group_advanced_delete', repo_group_name=repo_group_name), request=request)} |
|
253 | ${h.submit('remove_%s' % repo_group_name,_('Delete'),class_="btn btn-link btn-danger", | |
|
254 | onclick="return confirm('"+_ungettext('Confirm to delete this group: %s with %s repository','Confirm to delete this group: %s with %s repositories',gr_count) % (repo_group_name, gr_count)+"');")} | |
|
255 | <input class="btn btn-link btn-danger" id="remove_${repo_group_name}" name="remove_${repo_group_name}" | |
|
256 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository group'), _gettext('Delete'), '${_ungettext('`{}` with {} repository','`{}` with {} repositories',gr_count).format(repo_group_name, gr_count)}')" | |
|
257 | type="submit" value="Delete" | |
|
258 | > | |
|
255 | 259 | ${h.end_form()} |
|
256 | 260 | </div> |
|
257 | 261 | </%def> |
|
258 | 262 | |
|
259 | 263 | |
|
260 | 264 | <%def name="user_actions(user_id, username)"> |
|
261 | 265 | <div class="grid_edit"> |
|
262 | 266 | <a href="${h.route_path('user_edit',user_id=user_id)}" title="${_('Edit')}"> |
|
263 | 267 | ${_('Edit')} |
|
264 | 268 | </a> |
|
265 | 269 | </div> |
|
266 | 270 | <div class="grid_delete"> |
|
267 | 271 | ${h.secure_form(h.route_path('user_delete', user_id=user_id), request=request)} |
|
268 | ${h.submit('remove_',_('Delete'),id="remove_user_%s" % user_id, class_="btn btn-link btn-danger", | |
|
269 |
onclick=" |
|
|
272 | <input class="btn btn-link btn-danger" id="remove_user_${user_id}" name="remove_user_${user_id}" | |
|
273 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this user'), _gettext('Delete'), '${username}')" | |
|
274 | type="submit" value="Delete" | |
|
275 | > | |
|
270 | 276 | ${h.end_form()} |
|
271 | 277 | </div> |
|
272 | 278 | </%def> |
|
273 | 279 | |
|
274 | 280 | <%def name="user_group_actions(user_group_id, user_group_name)"> |
|
275 | 281 | <div class="grid_edit"> |
|
276 | 282 | <a href="${h.route_path('edit_user_group', user_group_id=user_group_id)}" title="${_('Edit')}">Edit</a> |
|
277 | 283 | </div> |
|
278 | 284 | <div class="grid_delete"> |
|
279 | 285 | ${h.secure_form(h.route_path('user_groups_delete', user_group_id=user_group_id), request=request)} |
|
280 | ${h.submit('remove_',_('Delete'),id="remove_group_%s" % user_group_id, class_="btn btn-link btn-danger", | |
|
281 |
onclick=" |
|
|
286 | <input class="btn btn-link btn-danger" id="remove_group_${user_group_id}" name="remove_group_${user_group_id}" | |
|
287 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this user group'), _gettext('Delete'), '${user_group_name}')" | |
|
288 | type="submit" value="Delete" | |
|
289 | > | |
|
282 | 290 | ${h.end_form()} |
|
283 | 291 | </div> |
|
284 | 292 | </%def> |
|
285 | 293 | |
|
286 | 294 | |
|
287 | 295 | <%def name="user_name(user_id, username)"> |
|
288 | 296 | ${h.link_to(h.person(username, 'username_or_name_or_email'), h.route_path('user_edit', user_id=user_id))} |
|
289 | 297 | </%def> |
|
290 | 298 | |
|
291 | 299 | <%def name="user_profile(username)"> |
|
292 | 300 | ${base.gravatar_with_user(username, 16, tooltip=True)} |
|
293 | 301 | </%def> |
|
294 | 302 | |
|
295 | 303 | <%def name="user_group_name(user_group_name)"> |
|
296 | 304 | <div> |
|
297 | 305 | <i class="icon-user-group" title="${_('User group')}"></i> |
|
298 | 306 | ${h.link_to_group(user_group_name)} |
|
299 | 307 | </div> |
|
300 | 308 | </%def> |
|
301 | 309 | |
|
302 | 310 | |
|
303 | 311 | ## GISTS |
|
304 | 312 | |
|
305 | 313 | <%def name="gist_gravatar(full_contact)"> |
|
306 | 314 | <div class="gist_gravatar"> |
|
307 | 315 | ${base.gravatar(full_contact, 30)} |
|
308 | 316 | </div> |
|
309 | 317 | </%def> |
|
310 | 318 | |
|
311 | 319 | <%def name="gist_access_id(gist_access_id, full_contact)"> |
|
312 | 320 | <div> |
|
313 | 321 | <code> |
|
314 | 322 | <a href="${h.route_path('gist_show', gist_id=gist_access_id)}">${gist_access_id}</a> |
|
315 | 323 | </code> |
|
316 | 324 | </div> |
|
317 | 325 | </%def> |
|
318 | 326 | |
|
319 | 327 | <%def name="gist_author(full_contact, created_on, expires)"> |
|
320 | 328 | ${base.gravatar_with_user(full_contact, 16, tooltip=True)} |
|
321 | 329 | </%def> |
|
322 | 330 | |
|
323 | 331 | |
|
324 | 332 | <%def name="gist_created(created_on)"> |
|
325 | 333 | <div class="created"> |
|
326 | 334 | ${h.age_component(created_on, time_is_local=True)} |
|
327 | 335 | </div> |
|
328 | 336 | </%def> |
|
329 | 337 | |
|
330 | 338 | <%def name="gist_expires(expires)"> |
|
331 | 339 | <div class="created"> |
|
332 | 340 | %if expires == -1: |
|
333 | 341 | ${_('never')} |
|
334 | 342 | %else: |
|
335 | 343 | ${h.age_component(h.time_to_utcdatetime(expires))} |
|
336 | 344 | %endif |
|
337 | 345 | </div> |
|
338 | 346 | </%def> |
|
339 | 347 | |
|
340 | 348 | <%def name="gist_type(gist_type)"> |
|
341 | 349 | %if gist_type == 'public': |
|
342 | 350 | <span class="tag tag-gist-public disabled">${_('Public Gist')}</span> |
|
343 | 351 | %else: |
|
344 | 352 | <span class="tag tag-gist-private disabled">${_('Private Gist')}</span> |
|
345 | 353 | %endif |
|
346 | 354 | </%def> |
|
347 | 355 | |
|
348 | 356 | <%def name="gist_description(gist_description)"> |
|
349 | 357 | ${gist_description} |
|
350 | 358 | </%def> |
|
351 | 359 | |
|
352 | 360 | |
|
353 | 361 | ## PULL REQUESTS GRID RENDERERS |
|
354 | 362 | |
|
355 | 363 | <%def name="pullrequest_target_repo(repo_name)"> |
|
356 | 364 | <div class="truncate"> |
|
357 | 365 | ${h.link_to(repo_name,h.route_path('repo_summary',repo_name=repo_name))} |
|
358 | 366 | </div> |
|
359 | 367 | </%def> |
|
360 | 368 | |
|
361 | 369 | <%def name="pullrequest_status(status)"> |
|
362 | 370 | <i class="icon-circle review-status-${status}"></i> |
|
363 | 371 | </%def> |
|
364 | 372 | |
|
365 | 373 | <%def name="pullrequest_title(title, description)"> |
|
366 | 374 | ${title} |
|
367 | 375 | </%def> |
|
368 | 376 | |
|
369 | 377 | <%def name="pullrequest_comments(comments_nr)"> |
|
370 | 378 | <i class="icon-comment"></i> ${comments_nr} |
|
371 | 379 | </%def> |
|
372 | 380 | |
|
373 | 381 | <%def name="pullrequest_name(pull_request_id, state, is_wip, target_repo_name, short=False)"> |
|
374 | 382 | <a href="${h.route_path('pullrequest_show',repo_name=target_repo_name,pull_request_id=pull_request_id)}"> |
|
375 | 383 | |
|
376 | 384 | % if short: |
|
377 | 385 | !${pull_request_id} |
|
378 | 386 | % else: |
|
379 | 387 | ${_('Pull request !{}').format(pull_request_id)} |
|
380 | 388 | % endif |
|
381 | 389 | |
|
382 | 390 | % if state not in ['created']: |
|
383 | 391 | <span class="tag tag-merge-state-${state} tooltip" title="Pull request state is changing">${state}</span> |
|
384 | 392 | % endif |
|
385 | 393 | |
|
386 | 394 | % if is_wip: |
|
387 | 395 | <span class="tag tooltip" title="${_('Work in progress')}">wip</span> |
|
388 | 396 | % endif |
|
389 | 397 | </a> |
|
390 | 398 | </%def> |
|
391 | 399 | |
|
392 | 400 | <%def name="pullrequest_updated_on(updated_on)"> |
|
393 | 401 | ${h.age_component(h.time_to_utcdatetime(updated_on))} |
|
394 | 402 | </%def> |
|
395 | 403 | |
|
396 | 404 | <%def name="pullrequest_author(full_contact)"> |
|
397 | 405 | ${base.gravatar_with_user(full_contact, 16, tooltip=True)} |
|
398 | 406 | </%def> |
|
399 | 407 | |
|
400 | 408 | |
|
401 | 409 | ## ARTIFACT RENDERERS |
|
402 | 410 | <%def name="repo_artifact_name(repo_name, file_uid, artifact_display_name)"> |
|
403 | 411 | <a href="${h.route_path('repo_artifacts_get', repo_name=repo_name, uid=file_uid)}"> |
|
404 | 412 | ${artifact_display_name or '_EMPTY_NAME_'} |
|
405 | 413 | </a> |
|
406 | 414 | </%def> |
|
407 | 415 | |
|
408 | 416 | <%def name="repo_artifact_uid(repo_name, file_uid)"> |
|
409 | 417 | <code>${h.shorter(file_uid, size=24, prefix=True)}</code> |
|
410 | 418 | </%def> |
|
411 | 419 | |
|
412 | 420 | <%def name="repo_artifact_sha256(artifact_sha256)"> |
|
413 | 421 | <div class="code">${h.shorter(artifact_sha256, 12)}</div> |
|
414 | 422 | </%def> |
|
415 | 423 | |
|
416 | 424 | <%def name="repo_artifact_actions(repo_name, file_store_id, file_uid)"> |
|
417 | 425 | ## <div class="grid_edit"> |
|
418 | 426 | ## <a href="#Edit" title="${_('Edit')}">${_('Edit')}</a> |
|
419 | 427 | ## </div> |
|
420 | 428 | <div class="grid_edit"> |
|
421 | 429 | <a href="${h.route_path('repo_artifacts_info', repo_name=repo_name, uid=file_store_id)}" title="${_('Info')}">${_('Info')}</a> |
|
422 | 430 | </div> |
|
423 | 431 | % if h.HasRepoPermissionAny('repository.admin')(c.repo_name): |
|
424 | 432 | <div class="grid_delete"> |
|
425 | 433 | ${h.secure_form(h.route_path('repo_artifacts_delete', repo_name=repo_name, uid=file_store_id), request=request)} |
|
426 | ${h.submit('remove_',_('Delete'),id="remove_artifact_%s" % file_store_id, class_="btn btn-link btn-danger", | |
|
427 |
onclick=" |
|
|
434 | <input class="btn btn-link btn-danger" id="remove_artifact_${file_store_id}" name="remove_artifact_${file_store_id}" | |
|
435 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this artifact'), _gettext('Delete'), '${file_uid}')" | |
|
436 | type="submit" value="${_('Delete')}" | |
|
437 | > | |
|
428 | 438 | ${h.end_form()} |
|
429 | 439 | </div> |
|
430 | 440 | % endif |
|
431 | 441 | </%def> |
|
432 | 442 | |
|
433 | 443 | <%def name="markup_form(form_id, form_text='', help_text=None)"> |
|
434 | 444 | |
|
435 | 445 | <div class="markup-form"> |
|
436 | 446 | <div class="markup-form-area"> |
|
437 | 447 | <div class="markup-form-area-header"> |
|
438 | 448 | <ul class="nav-links clearfix"> |
|
439 | 449 | <li class="active"> |
|
440 | 450 | <a href="#edit-text" tabindex="-1" id="edit-btn_${form_id}">${_('Write')}</a> |
|
441 | 451 | </li> |
|
442 | 452 | <li class=""> |
|
443 | 453 | <a href="#preview-text" tabindex="-1" id="preview-btn_${form_id}">${_('Preview')}</a> |
|
444 | 454 | </li> |
|
445 | 455 | </ul> |
|
446 | 456 | </div> |
|
447 | 457 | |
|
448 | 458 | <div class="markup-form-area-write" style="display: block;"> |
|
449 | 459 | <div id="edit-container_${form_id}"> |
|
450 | 460 | <textarea id="${form_id}" name="${form_id}" class="comment-block-ta ac-input">${form_text if form_text else ''}</textarea> |
|
451 | 461 | </div> |
|
452 | 462 | <div id="preview-container_${form_id}" class="clearfix" style="display: none;"> |
|
453 | 463 | <div id="preview-box_${form_id}" class="preview-box"></div> |
|
454 | 464 | </div> |
|
455 | 465 | </div> |
|
456 | 466 | |
|
457 | 467 | <div class="markup-form-area-footer"> |
|
458 | 468 | <div class="toolbar"> |
|
459 | 469 | <div class="toolbar-text"> |
|
460 | 470 | ${(_('Parsed using %s syntax') % ( |
|
461 | 471 | ('<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())), |
|
462 | 472 | ) |
|
463 | 473 | )|n} |
|
464 | 474 | </div> |
|
465 | 475 | </div> |
|
466 | 476 | </div> |
|
467 | 477 | </div> |
|
468 | 478 | |
|
469 | 479 | <div class="markup-form-footer"> |
|
470 | 480 | % if help_text: |
|
471 | 481 | <span class="help-block">${help_text}</span> |
|
472 | 482 | % endif |
|
473 | 483 | </div> |
|
474 | 484 | </div> |
|
475 | 485 | <script type="text/javascript"> |
|
476 | 486 | new MarkupForm('${form_id}'); |
|
477 | 487 | </script> |
|
478 | 488 | |
|
479 | 489 | </%def> |
@@ -1,911 +1,912 b'' | |||
|
1 | 1 | <%inherit file="/base/base.mako"/> |
|
2 | 2 | <%namespace name="base" file="/base/base.mako"/> |
|
3 | 3 | <%namespace name="dt" file="/data_table/_dt_elements.mako"/> |
|
4 | 4 | |
|
5 | 5 | <%def name="title()"> |
|
6 | 6 | ${_('{} Pull Request !{}').format(c.repo_name, c.pull_request.pull_request_id)} |
|
7 | 7 | %if c.rhodecode_name: |
|
8 | 8 | · ${h.branding(c.rhodecode_name)} |
|
9 | 9 | %endif |
|
10 | 10 | </%def> |
|
11 | 11 | |
|
12 | 12 | <%def name="breadcrumbs_links()"> |
|
13 | 13 | |
|
14 | 14 | </%def> |
|
15 | 15 | |
|
16 | 16 | <%def name="menu_bar_nav()"> |
|
17 | 17 | ${self.menu_items(active='repositories')} |
|
18 | 18 | </%def> |
|
19 | 19 | |
|
20 | 20 | <%def name="menu_bar_subnav()"> |
|
21 | 21 | ${self.repo_menu(active='showpullrequest')} |
|
22 | 22 | </%def> |
|
23 | 23 | |
|
24 | 24 | <%def name="main()"> |
|
25 | 25 | |
|
26 | 26 | <script type="text/javascript"> |
|
27 | 27 | // TODO: marcink switch this to pyroutes |
|
28 | 28 | AJAX_COMMENT_DELETE_URL = "${h.route_path('pullrequest_comment_delete',repo_name=c.repo_name,pull_request_id=c.pull_request.pull_request_id,comment_id='__COMMENT_ID__')}"; |
|
29 | 29 | templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id}; |
|
30 | 30 | </script> |
|
31 | 31 | |
|
32 | 32 | <div class="box"> |
|
33 | 33 | |
|
34 | 34 | <div class="box pr-summary"> |
|
35 | 35 | |
|
36 | 36 | <div class="summary-details block-left"> |
|
37 | 37 | <div id="pr-title"> |
|
38 | 38 | % if c.pull_request.is_closed(): |
|
39 | 39 | <span class="pr-title-closed-tag tag">${_('Closed')}</span> |
|
40 | 40 | % endif |
|
41 | 41 | <input class="pr-title-input large disabled" disabled="disabled" name="pullrequest_title" type="text" value="${c.pull_request.title}"> |
|
42 | 42 | </div> |
|
43 | 43 | <div id="pr-title-edit" class="input" style="display: none;"> |
|
44 | 44 | <input class="pr-title-input large" id="pr-title-input" name="pullrequest_title" type="text" value="${c.pull_request.title}"> |
|
45 | 45 | </div> |
|
46 | 46 | |
|
47 | 47 | <% summary = lambda n:{False:'summary-short'}.get(n) %> |
|
48 | 48 | <div class="pr-details-title"> |
|
49 | 49 | <div class="pull-left"> |
|
50 | 50 | <a href="${h.route_path('pull_requests_global', pull_request_id=c.pull_request.pull_request_id)}">${_('Pull request !{}').format(c.pull_request.pull_request_id)}</a> |
|
51 | 51 | ${_('Created on')} |
|
52 | 52 | <span class="tooltip" title="${_('Last updated on')} ${h.format_date(c.pull_request.updated_on)}">${h.format_date(c.pull_request.created_on)},</span> |
|
53 | 53 | <span class="pr-details-title-author-pref">${_('by')}</span> |
|
54 | 54 | </div> |
|
55 | 55 | |
|
56 | 56 | <div class="pull-left"> |
|
57 | 57 | ${self.gravatar_with_user(c.pull_request.author.email, 16, tooltip=True)} |
|
58 | 58 | </div> |
|
59 | 59 | |
|
60 | 60 | %if c.allowed_to_update: |
|
61 | 61 | <div class="pull-right"> |
|
62 | 62 | <div id="edit_pull_request" class="action_button pr-save" style="display: none;">${_('Update title & description')}</div> |
|
63 | 63 | <div id="delete_pullrequest" class="action_button pr-save ${('' if c.allowed_to_delete else 'disabled' )}" style="display: none;"> |
|
64 | 64 | % if c.allowed_to_delete: |
|
65 | 65 | ${h.secure_form(h.route_path('pullrequest_delete', repo_name=c.pull_request.target_repo.repo_name, pull_request_id=c.pull_request.pull_request_id), request=request)} |
|
66 | ${h.submit('remove_%s' % c.pull_request.pull_request_id, _('Delete pull request'), | |
|
67 | class_="btn btn-link btn-danger no-margin",onclick="return confirm('"+_('Confirm to delete this pull request')+"');")} | |
|
66 | <input class="btn btn-link btn-danger no-margin" id="remove_${c.pull_request.pull_request_id}" name="remove_${c.pull_request.pull_request_id}" | |
|
67 | onclick="submitConfirm(event, this, _gettext('Confirm to delete this pull request'), _gettext('Delete'), '${'!{}'.format(c.pull_request.pull_request_id)}')" | |
|
68 | type="submit" value="${_('Delete pull request')}"> | |
|
68 | 69 | ${h.end_form()} |
|
69 | 70 | % else: |
|
70 | 71 | <span class="tooltip" title="${_('Not allowed to delete this pull request')}">${_('Delete pull request')}</span> |
|
71 | 72 | % endif |
|
72 | 73 | </div> |
|
73 | 74 | <div id="open_edit_pullrequest" class="action_button">${_('Edit')}</div> |
|
74 | 75 | <div id="close_edit_pullrequest" class="action_button" style="display: none;">${_('Cancel')}</div> |
|
75 | 76 | </div> |
|
76 | 77 | |
|
77 | 78 | %endif |
|
78 | 79 | </div> |
|
79 | 80 | |
|
80 | 81 | <div id="pr-desc" class="input" title="${_('Rendered using {} renderer').format(c.renderer)}"> |
|
81 | 82 | ${h.render(c.pull_request.description, renderer=c.renderer, repo_name=c.repo_name)} |
|
82 | 83 | </div> |
|
83 | 84 | |
|
84 | 85 | <div id="pr-desc-edit" class="input textarea" style="display: none;"> |
|
85 | 86 | <input id="pr-renderer-input" type="hidden" name="description_renderer" value="${c.visual.default_renderer}"> |
|
86 | 87 | ${dt.markup_form('pr-description-input', form_text=c.pull_request.description)} |
|
87 | 88 | </div> |
|
88 | 89 | |
|
89 | 90 | <div id="summary" class="fields pr-details-content"> |
|
90 | 91 | |
|
91 | 92 | ## review |
|
92 | 93 | <div class="field"> |
|
93 | 94 | <div class="label-pr-detail"> |
|
94 | 95 | <label>${_('Review status')}:</label> |
|
95 | 96 | </div> |
|
96 | 97 | <div class="input"> |
|
97 | 98 | %if c.pull_request_review_status: |
|
98 | 99 | <div class="tag status-tag-${c.pull_request_review_status}"> |
|
99 | 100 | <i class="icon-circle review-status-${c.pull_request_review_status}"></i> |
|
100 | 101 | <span class="changeset-status-lbl"> |
|
101 | 102 | %if c.pull_request.is_closed(): |
|
102 | 103 | ${_('Closed')}, |
|
103 | 104 | %endif |
|
104 | 105 | |
|
105 | 106 | ${h.commit_status_lbl(c.pull_request_review_status)} |
|
106 | 107 | |
|
107 | 108 | </span> |
|
108 | 109 | </div> |
|
109 | 110 | - ${_ungettext('calculated based on {} reviewer vote', 'calculated based on {} reviewers votes', len(c.pull_request_reviewers)).format(len(c.pull_request_reviewers))} |
|
110 | 111 | %endif |
|
111 | 112 | </div> |
|
112 | 113 | </div> |
|
113 | 114 | |
|
114 | 115 | ## source |
|
115 | 116 | <div class="field"> |
|
116 | 117 | <div class="label-pr-detail"> |
|
117 | 118 | <label>${_('Commit flow')}:</label> |
|
118 | 119 | </div> |
|
119 | 120 | <div class="input"> |
|
120 | 121 | <div class="pr-commit-flow"> |
|
121 | 122 | ## Source |
|
122 | 123 | %if c.pull_request.source_ref_parts.type == 'branch': |
|
123 | 124 | <a href="${h.route_path('repo_commits', repo_name=c.pull_request.source_repo.repo_name, _query=dict(branch=c.pull_request.source_ref_parts.name))}"><code class="pr-source-info">${c.pull_request.source_ref_parts.type}:${c.pull_request.source_ref_parts.name}</code></a> |
|
124 | 125 | %else: |
|
125 | 126 | <code class="pr-source-info">${'{}:{}'.format(c.pull_request.source_ref_parts.type, c.pull_request.source_ref_parts.name)}</code> |
|
126 | 127 | %endif |
|
127 | 128 | ${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.repo_name}</a> |
|
128 | 129 | → |
|
129 | 130 | ## Target |
|
130 | 131 | %if c.pull_request.target_ref_parts.type == 'branch': |
|
131 | 132 | <a href="${h.route_path('repo_commits', repo_name=c.pull_request.target_repo.repo_name, _query=dict(branch=c.pull_request.target_ref_parts.name))}"><code class="pr-target-info">${c.pull_request.target_ref_parts.type}:${c.pull_request.target_ref_parts.name}</code></a> |
|
132 | 133 | %else: |
|
133 | 134 | <code class="pr-target-info">${'{}:{}'.format(c.pull_request.target_ref_parts.type, c.pull_request.target_ref_parts.name)}</code> |
|
134 | 135 | %endif |
|
135 | 136 | |
|
136 | 137 | ${_('of')} <a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.repo_name}</a> |
|
137 | 138 | |
|
138 | 139 | <a class="source-details-action" href="#expand-source-details" onclick="return versionController.toggleElement(this, '.source-details')" data-toggle-on='<i class="icon-angle-down">more details</i>' data-toggle-off='<i class="icon-angle-up">less details</i>'> |
|
139 | 140 | <i class="icon-angle-down">more details</i> |
|
140 | 141 | </a> |
|
141 | 142 | |
|
142 | 143 | </div> |
|
143 | 144 | |
|
144 | 145 | <div class="source-details" style="display: none"> |
|
145 | 146 | |
|
146 | 147 | <ul> |
|
147 | 148 | |
|
148 | 149 | ## common ancestor |
|
149 | 150 | <li> |
|
150 | 151 | ${_('Common ancestor')}: |
|
151 | 152 | % if c.ancestor_commit: |
|
152 | 153 | <a href="${h.route_path('repo_commit', repo_name=c.target_repo.repo_name, commit_id=c.ancestor_commit.raw_id)}">${h.show_id(c.ancestor_commit)}</a> |
|
153 | 154 | % else: |
|
154 | 155 | ${_('not available')} |
|
155 | 156 | % endif |
|
156 | 157 | </li> |
|
157 | 158 | |
|
158 | 159 | ## pull url |
|
159 | 160 | <li> |
|
160 | 161 | %if h.is_hg(c.pull_request.source_repo): |
|
161 | 162 | <% clone_url = 'hg pull -r {} {}'.format(h.short_id(c.source_ref), c.pull_request.source_repo.clone_url()) %> |
|
162 | 163 | %elif h.is_git(c.pull_request.source_repo): |
|
163 | 164 | <% clone_url = 'git pull {} {}'.format(c.pull_request.source_repo.clone_url(), c.pull_request.source_ref_parts.name) %> |
|
164 | 165 | %endif |
|
165 | 166 | |
|
166 | 167 | <span>${_('Pull changes from source')}</span>: <input type="text" class="input-monospace pr-pullinfo" value="${clone_url}" readonly="readonly"> |
|
167 | 168 | <i class="tooltip icon-clipboard clipboard-action pull-right pr-pullinfo-copy" data-clipboard-text="${clone_url}" title="${_('Copy the pull url')}"></i> |
|
168 | 169 | </li> |
|
169 | 170 | |
|
170 | 171 | ## Shadow repo |
|
171 | 172 | <li> |
|
172 | 173 | % if not c.pull_request.is_closed() and c.pull_request.shadow_merge_ref: |
|
173 | 174 | %if h.is_hg(c.pull_request.target_repo): |
|
174 | 175 | <% clone_url = 'hg clone --update {} {} pull-request-{}'.format(c.pull_request.shadow_merge_ref.name, c.shadow_clone_url, c.pull_request.pull_request_id) %> |
|
175 | 176 | %elif h.is_git(c.pull_request.target_repo): |
|
176 | 177 | <% clone_url = 'git clone --branch {} {} pull-request-{}'.format(c.pull_request.shadow_merge_ref.name, c.shadow_clone_url, c.pull_request.pull_request_id) %> |
|
177 | 178 | %endif |
|
178 | 179 | |
|
179 | 180 | <span class="tooltip" title="${_('Clone repository in its merged state using shadow repository')}">${_('Clone from shadow repository')}</span>: <input type="text" class="input-monospace pr-mergeinfo" value="${clone_url}" readonly="readonly"> |
|
180 | 181 | <i class="tooltip icon-clipboard clipboard-action pull-right pr-mergeinfo-copy" data-clipboard-text="${clone_url}" title="${_('Copy the clone url')}"></i> |
|
181 | 182 | |
|
182 | 183 | % else: |
|
183 | 184 | <div class=""> |
|
184 | 185 | ${_('Shadow repository data not available')}. |
|
185 | 186 | </div> |
|
186 | 187 | % endif |
|
187 | 188 | </li> |
|
188 | 189 | |
|
189 | 190 | </ul> |
|
190 | 191 | |
|
191 | 192 | </div> |
|
192 | 193 | |
|
193 | 194 | </div> |
|
194 | 195 | |
|
195 | 196 | </div> |
|
196 | 197 | |
|
197 | 198 | ## versions |
|
198 | 199 | <div class="field"> |
|
199 | 200 | <div class="label-pr-detail"> |
|
200 | 201 | <label>${_('Versions')}:</label> |
|
201 | 202 | </div> |
|
202 | 203 | |
|
203 | 204 | <% outdated_comm_count_ver = len(c.inline_versions[None]['outdated']) %> |
|
204 | 205 | <% general_outdated_comm_count_ver = len(c.comment_versions[None]['outdated']) %> |
|
205 | 206 | |
|
206 | 207 | <div class="pr-versions"> |
|
207 | 208 | % if c.show_version_changes: |
|
208 | 209 | <% outdated_comm_count_ver = len(c.inline_versions[c.at_version_num]['outdated']) %> |
|
209 | 210 | <% general_outdated_comm_count_ver = len(c.comment_versions[c.at_version_num]['outdated']) %> |
|
210 | 211 | ${_ungettext('{} version available for this pull request, ', '{} versions available for this pull request, ', len(c.versions)).format(len(c.versions))} |
|
211 | 212 | <a id="show-pr-versions" onclick="return versionController.toggleVersionView(this)" href="#show-pr-versions" |
|
212 | 213 | data-toggle-on="${_('show versions')}." |
|
213 | 214 | data-toggle-off="${_('hide versions')}."> |
|
214 | 215 | ${_('show versions')}. |
|
215 | 216 | </a> |
|
216 | 217 | <table> |
|
217 | 218 | ## SHOW ALL VERSIONS OF PR |
|
218 | 219 | <% ver_pr = None %> |
|
219 | 220 | |
|
220 | 221 | % for data in reversed(list(enumerate(c.versions, 1))): |
|
221 | 222 | <% ver_pos = data[0] %> |
|
222 | 223 | <% ver = data[1] %> |
|
223 | 224 | <% ver_pr = ver.pull_request_version_id %> |
|
224 | 225 | <% display_row = '' if c.at_version and (c.at_version_num == ver_pr or c.from_version_num == ver_pr) else 'none' %> |
|
225 | 226 | |
|
226 | 227 | <tr class="version-pr" style="display: ${display_row}"> |
|
227 | 228 | <td> |
|
228 | 229 | <code> |
|
229 | 230 | <a href="${request.current_route_path(_query=dict(version=ver_pr or 'latest'))}">v${ver_pos}</a> |
|
230 | 231 | </code> |
|
231 | 232 | </td> |
|
232 | 233 | <td> |
|
233 | 234 | <input ${('checked="checked"' if c.from_version_num == ver_pr else '')} class="compare-radio-button" type="radio" name="ver_source" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/> |
|
234 | 235 | <input ${('checked="checked"' if c.at_version_num == ver_pr else '')} class="compare-radio-button" type="radio" name="ver_target" value="${ver_pr or 'latest'}" data-ver-pos="${ver_pos}"/> |
|
235 | 236 | </td> |
|
236 | 237 | <td> |
|
237 | 238 | <% review_status = c.review_versions[ver_pr].status if ver_pr in c.review_versions else 'not_reviewed' %> |
|
238 | 239 | <i class="tooltip icon-circle review-status-${review_status}" title="${_('Your review status at this version')}"></i> |
|
239 | 240 | |
|
240 | 241 | </td> |
|
241 | 242 | <td> |
|
242 | 243 | % if c.at_version_num != ver_pr: |
|
243 | 244 | <i class="tooltip icon-comment" title="${_('Comments from pull request version v{0}').format(ver_pos)}"></i> |
|
244 | 245 | <code> |
|
245 | 246 | General:${len(c.comment_versions[ver_pr]['at'])} / Inline:${len(c.inline_versions[ver_pr]['at'])} |
|
246 | 247 | </code> |
|
247 | 248 | % endif |
|
248 | 249 | </td> |
|
249 | 250 | <td> |
|
250 | 251 | ##<code>${ver.source_ref_parts.commit_id[:6]}</code> |
|
251 | 252 | </td> |
|
252 | 253 | <td> |
|
253 | 254 | <code>${h.age_component(ver.updated_on, time_is_local=True, tooltip=False)}</code> |
|
254 | 255 | </td> |
|
255 | 256 | </tr> |
|
256 | 257 | % endfor |
|
257 | 258 | |
|
258 | 259 | <tr> |
|
259 | 260 | <td colspan="6"> |
|
260 | 261 | <button id="show-version-diff" onclick="return versionController.showVersionDiff()" class="btn btn-sm" style="display: none" |
|
261 | 262 | data-label-text-locked="${_('select versions to show changes')}" |
|
262 | 263 | data-label-text-diff="${_('show changes between versions')}" |
|
263 | 264 | data-label-text-show="${_('show pull request for this version')}" |
|
264 | 265 | > |
|
265 | 266 | ${_('select versions to show changes')} |
|
266 | 267 | </button> |
|
267 | 268 | </td> |
|
268 | 269 | </tr> |
|
269 | 270 | </table> |
|
270 | 271 | % else: |
|
271 | 272 | <div> |
|
272 | 273 | ${_('Pull request versions not available')}. |
|
273 | 274 | </div> |
|
274 | 275 | % endif |
|
275 | 276 | </div> |
|
276 | 277 | </div> |
|
277 | 278 | |
|
278 | 279 | </div> |
|
279 | 280 | |
|
280 | 281 | </div> |
|
281 | 282 | |
|
282 | 283 | ## REVIEW RULES |
|
283 | 284 | <div id="review_rules" style="display: none" class="reviewers-title block-right"> |
|
284 | 285 | <div class="pr-details-title"> |
|
285 | 286 | ${_('Reviewer rules')} |
|
286 | 287 | %if c.allowed_to_update: |
|
287 | 288 | <span id="close_edit_reviewers" class="block-right action_button last-item" style="display: none;">${_('Close')}</span> |
|
288 | 289 | %endif |
|
289 | 290 | </div> |
|
290 | 291 | <div class="pr-reviewer-rules"> |
|
291 | 292 | ## review rules will be appended here, by default reviewers logic |
|
292 | 293 | </div> |
|
293 | 294 | <input id="review_data" type="hidden" name="review_data" value=""> |
|
294 | 295 | </div> |
|
295 | 296 | |
|
296 | 297 | ## REVIEWERS |
|
297 | 298 | <div class="reviewers-title first-panel block-right"> |
|
298 | 299 | <div class="pr-details-title"> |
|
299 | 300 | ${_('Pull request reviewers')} |
|
300 | 301 | %if c.allowed_to_update: |
|
301 | 302 | <span id="open_edit_reviewers" class="block-right action_button last-item">${_('Edit')}</span> |
|
302 | 303 | %endif |
|
303 | 304 | </div> |
|
304 | 305 | </div> |
|
305 | 306 | <div id="reviewers" class="block-right pr-details-content reviewers"> |
|
306 | 307 | |
|
307 | 308 | ## members redering block |
|
308 | 309 | <input type="hidden" name="__start__" value="review_members:sequence"> |
|
309 | 310 | <ul id="review_members" class="group_members"> |
|
310 | 311 | |
|
311 | 312 | % for review_obj, member, reasons, mandatory, status in c.pull_request_reviewers: |
|
312 | 313 | <script> |
|
313 | 314 | var member = ${h.json.dumps(h.reviewer_as_json(member, reasons=reasons, mandatory=mandatory, user_group=review_obj.rule_user_group_data()))|n}; |
|
314 | 315 | var status = "${(status[0][1].status if status else 'not_reviewed')}"; |
|
315 | 316 | var status_lbl = "${h.commit_status_lbl(status[0][1].status if status else 'not_reviewed')}"; |
|
316 | 317 | var allowed_to_update = ${h.json.dumps(c.allowed_to_update)}; |
|
317 | 318 | |
|
318 | 319 | var entry = renderTemplate('reviewMemberEntry', { |
|
319 | 320 | 'member': member, |
|
320 | 321 | 'mandatory': member.mandatory, |
|
321 | 322 | 'reasons': member.reasons, |
|
322 | 323 | 'allowed_to_update': allowed_to_update, |
|
323 | 324 | 'review_status': status, |
|
324 | 325 | 'review_status_label': status_lbl, |
|
325 | 326 | 'user_group': member.user_group, |
|
326 | 327 | 'create': false |
|
327 | 328 | }); |
|
328 | 329 | $('#review_members').append(entry) |
|
329 | 330 | </script> |
|
330 | 331 | |
|
331 | 332 | % endfor |
|
332 | 333 | |
|
333 | 334 | </ul> |
|
334 | 335 | |
|
335 | 336 | <input type="hidden" name="__end__" value="review_members:sequence"> |
|
336 | 337 | ## end members redering block |
|
337 | 338 | |
|
338 | 339 | %if not c.pull_request.is_closed(): |
|
339 | 340 | <div id="add_reviewer" class="ac" style="display: none;"> |
|
340 | 341 | %if c.allowed_to_update: |
|
341 | 342 | % if not c.forbid_adding_reviewers: |
|
342 | 343 | <div id="add_reviewer_input" class="reviewer_ac"> |
|
343 | 344 | ${h.text('user', class_='ac-input', placeholder=_('Add reviewer or reviewer group'))} |
|
344 | 345 | <div id="reviewers_container"></div> |
|
345 | 346 | </div> |
|
346 | 347 | % endif |
|
347 | 348 | <div class="pull-right"> |
|
348 | 349 | <button id="update_pull_request" class="btn btn-small no-margin">${_('Save Changes')}</button> |
|
349 | 350 | </div> |
|
350 | 351 | %endif |
|
351 | 352 | </div> |
|
352 | 353 | %endif |
|
353 | 354 | </div> |
|
354 | 355 | |
|
355 | 356 | ## TODOs will be listed here |
|
356 | 357 | <div class="reviewers-title block-right"> |
|
357 | 358 | <div class="pr-details-title"> |
|
358 | 359 | ## Only show unresolved, that is only what matters |
|
359 | 360 | TODO Comments - ${len(c.unresolved_comments)} / ${(len(c.unresolved_comments) + len(c.resolved_comments))} |
|
360 | 361 | |
|
361 | 362 | % if not c.at_version: |
|
362 | 363 | % if c.resolved_comments: |
|
363 | 364 | <span class="block-right action_button last-item noselect" onclick="$('.unresolved-todo-text').toggle(); return versionController.toggleElement(this, '.unresolved-todo');" data-toggle-on="Show resolved" data-toggle-off="Hide resolved">Show resolved</span> |
|
364 | 365 | % else: |
|
365 | 366 | <span class="block-right last-item noselect">Show resolved</span> |
|
366 | 367 | % endif |
|
367 | 368 | % endif |
|
368 | 369 | </div> |
|
369 | 370 | </div> |
|
370 | 371 | <div class="block-right pr-details-content reviewers"> |
|
371 | 372 | |
|
372 | 373 | <table class="todo-table"> |
|
373 | 374 | <% |
|
374 | 375 | def sorter(entry): |
|
375 | 376 | user_id = entry.author.user_id |
|
376 | 377 | resolved = '1' if entry.resolved else '0' |
|
377 | 378 | if user_id == c.rhodecode_user.user_id: |
|
378 | 379 | # own comments first |
|
379 | 380 | user_id = 0 |
|
380 | 381 | return '{}_{}_{}'.format(resolved, user_id, str(entry.comment_id).zfill(100)) |
|
381 | 382 | %> |
|
382 | 383 | |
|
383 | 384 | % if c.at_version: |
|
384 | 385 | <tr> |
|
385 | 386 | <td class="unresolved-todo-text">${_('unresolved TODOs unavailable in this view')}.</td> |
|
386 | 387 | </tr> |
|
387 | 388 | % else: |
|
388 | 389 | % for todo_comment in sorted(c.unresolved_comments + c.resolved_comments, key=sorter): |
|
389 | 390 | <% resolved = todo_comment.resolved %> |
|
390 | 391 | % if inline: |
|
391 | 392 | <% outdated_at_ver = todo_comment.outdated_at_version(getattr(c, 'at_version_num', None)) %> |
|
392 | 393 | % else: |
|
393 | 394 | <% outdated_at_ver = todo_comment.older_than_version(getattr(c, 'at_version_num', None)) %> |
|
394 | 395 | % endif |
|
395 | 396 | |
|
396 | 397 | <tr ${('class="unresolved-todo" style="display: none"' if resolved else '') |n}> |
|
397 | 398 | |
|
398 | 399 | <td class="td-todo-number"> |
|
399 | 400 | % if resolved: |
|
400 | 401 | <a class="permalink todo-resolved tooltip" title="${_('Resolved by comment #{}').format(todo_comment.resolved.comment_id)}" href="#comment-${todo_comment.comment_id}" onclick="return Rhodecode.comments.scrollToComment($('#comment-${todo_comment.comment_id}'), 0, ${h.json.dumps(outdated_at_ver)})"> |
|
401 | 402 | <i class="icon-flag-filled"></i> ${todo_comment.comment_id}</a> |
|
402 | 403 | % else: |
|
403 | 404 | <a class="permalink" href="#comment-${todo_comment.comment_id}" onclick="return Rhodecode.comments.scrollToComment($('#comment-${todo_comment.comment_id}'), 0, ${h.json.dumps(outdated_at_ver)})"> |
|
404 | 405 | <i class="icon-flag-filled"></i> ${todo_comment.comment_id}</a> |
|
405 | 406 | % endif |
|
406 | 407 | </td> |
|
407 | 408 | <td class="td-todo-gravatar"> |
|
408 | 409 | ${base.gravatar(todo_comment.author.email, 16, user=todo_comment.author, tooltip=True, extra_class=['no-margin'])} |
|
409 | 410 | </td> |
|
410 | 411 | <td class="todo-comment-text-wrapper"> |
|
411 | 412 | <div class="todo-comment-text"> |
|
412 | 413 | <code>${h.chop_at_smart(todo_comment.text, '\n', suffix_if_chopped='...')}</code> |
|
413 | 414 | </div> |
|
414 | 415 | </td> |
|
415 | 416 | |
|
416 | 417 | </tr> |
|
417 | 418 | % endfor |
|
418 | 419 | |
|
419 | 420 | % if len(c.unresolved_comments) == 0: |
|
420 | 421 | <tr> |
|
421 | 422 | <td class="unresolved-todo-text">${_('No unresolved TODOs')}.</td> |
|
422 | 423 | </tr> |
|
423 | 424 | % endif |
|
424 | 425 | |
|
425 | 426 | % endif |
|
426 | 427 | |
|
427 | 428 | </table> |
|
428 | 429 | |
|
429 | 430 | </div> |
|
430 | 431 | </div> |
|
431 | 432 | |
|
432 | 433 | </div> |
|
433 | 434 | |
|
434 | 435 | <div class="box"> |
|
435 | 436 | |
|
436 | 437 | % if c.state_progressing: |
|
437 | 438 | |
|
438 | 439 | <h2 style="text-align: center"> |
|
439 | 440 | ${_('Cannot show diff when pull request state is changing. Current progress state')}: <span class="tag tag-merge-state-${c.pull_request.state}">${c.pull_request.state}</span> |
|
440 | 441 | |
|
441 | 442 | % if c.is_super_admin: |
|
442 | 443 | <br/> |
|
443 | 444 | If you think this is an error try <a href="${h.current_route_path(request, force_state='created')}">forced state reset</a> to <span class="tag tag-merge-state-created">created</span> state. |
|
444 | 445 | % endif |
|
445 | 446 | </h2> |
|
446 | 447 | |
|
447 | 448 | % else: |
|
448 | 449 | |
|
449 | 450 | ## Diffs rendered here |
|
450 | 451 | <div class="table" > |
|
451 | 452 | <div id="changeset_compare_view_content"> |
|
452 | 453 | ##CS |
|
453 | 454 | % if c.missing_requirements: |
|
454 | 455 | <div class="box"> |
|
455 | 456 | <div class="alert alert-warning"> |
|
456 | 457 | <div> |
|
457 | 458 | <strong>${_('Missing requirements:')}</strong> |
|
458 | 459 | ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')} |
|
459 | 460 | </div> |
|
460 | 461 | </div> |
|
461 | 462 | </div> |
|
462 | 463 | % elif c.missing_commits: |
|
463 | 464 | <div class="box"> |
|
464 | 465 | <div class="alert alert-warning"> |
|
465 | 466 | <div> |
|
466 | 467 | <strong>${_('Missing commits')}:</strong> |
|
467 | 468 | ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')} |
|
468 | 469 | ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')} |
|
469 | 470 | ${_('Consider doing a {force_refresh_url} in case you think this is an error.').format(force_refresh_url=h.link_to('force refresh', h.current_route_path(request, force_refresh='1')))|n} |
|
470 | 471 | </div> |
|
471 | 472 | </div> |
|
472 | 473 | </div> |
|
473 | 474 | % endif |
|
474 | 475 | |
|
475 | 476 | <div class="compare_view_commits_title"> |
|
476 | 477 | % if not c.compare_mode: |
|
477 | 478 | |
|
478 | 479 | % if c.at_version_pos: |
|
479 | 480 | <h4> |
|
480 | 481 | ${_('Showing changes at v%d, commenting is disabled.') % c.at_version_pos} |
|
481 | 482 | </h4> |
|
482 | 483 | % endif |
|
483 | 484 | |
|
484 | 485 | <div class="pull-left"> |
|
485 | 486 | <div class="btn-group"> |
|
486 | 487 | <a class="${('collapsed' if c.collapse_all_commits else '')}" href="#expand-commits" onclick="toggleCommitExpand(this); return false" data-toggle-commits-cnt=${len(c.commit_ranges)} > |
|
487 | 488 | % if c.collapse_all_commits: |
|
488 | 489 | <i class="icon-plus-squared-alt icon-no-margin"></i> |
|
489 | 490 | ${_ungettext('Expand {} commit', 'Expand {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))} |
|
490 | 491 | % else: |
|
491 | 492 | <i class="icon-minus-squared-alt icon-no-margin"></i> |
|
492 | 493 | ${_ungettext('Collapse {} commit', 'Collapse {} commits', len(c.commit_ranges)).format(len(c.commit_ranges))} |
|
493 | 494 | % endif |
|
494 | 495 | </a> |
|
495 | 496 | </div> |
|
496 | 497 | </div> |
|
497 | 498 | |
|
498 | 499 | <div class="pull-right"> |
|
499 | 500 | % if c.allowed_to_update and not c.pull_request.is_closed(): |
|
500 | 501 | |
|
501 | 502 | <div class="btn-group btn-group-actions"> |
|
502 | 503 | <a id="update_commits" class="btn btn-primary no-margin" onclick="updateController.updateCommits(this); return false"> |
|
503 | 504 | ${_('Update commits')} |
|
504 | 505 | </a> |
|
505 | 506 | |
|
506 | 507 | <a id="update_commits_switcher" class="tooltip btn btn-primary" style="margin-left: -1px" data-toggle="dropdown" aria-pressed="false" role="button" title="${_('more update options')}"> |
|
507 | 508 | <i class="icon-down"></i> |
|
508 | 509 | </a> |
|
509 | 510 | |
|
510 | 511 | <div class="btn-action-switcher-container" id="update-commits-switcher"> |
|
511 | 512 | <ul class="btn-action-switcher" role="menu"> |
|
512 | 513 | <li> |
|
513 | 514 | <a href="#forceUpdate" onclick="updateController.forceUpdateCommits(this); return false"> |
|
514 | 515 | ${_('Force update commits')} |
|
515 | 516 | </a> |
|
516 | 517 | <div class="action-help-block"> |
|
517 | 518 | ${_('Update commits and force refresh this pull request.')} |
|
518 | 519 | </div> |
|
519 | 520 | </li> |
|
520 | 521 | </ul> |
|
521 | 522 | </div> |
|
522 | 523 | </div> |
|
523 | 524 | |
|
524 | 525 | % else: |
|
525 | 526 | <a class="tooltip btn disabled pull-right" disabled="disabled" title="${_('Update is disabled for current view')}">${_('Update commits')}</a> |
|
526 | 527 | % endif |
|
527 | 528 | |
|
528 | 529 | </div> |
|
529 | 530 | % endif |
|
530 | 531 | </div> |
|
531 | 532 | |
|
532 | 533 | % if not c.missing_commits: |
|
533 | 534 | % if c.compare_mode: |
|
534 | 535 | % if c.at_version: |
|
535 | 536 | <h4> |
|
536 | 537 | ${_('Commits and changes between v{ver_from} and {ver_to} of this pull request, commenting is disabled').format(ver_from=c.from_version_pos, ver_to=c.at_version_pos if c.at_version_pos else 'latest')}: |
|
537 | 538 | </h4> |
|
538 | 539 | |
|
539 | 540 | <div class="subtitle-compare"> |
|
540 | 541 | ${_('commits added: {}, removed: {}').format(len(c.commit_changes_summary.added), len(c.commit_changes_summary.removed))} |
|
541 | 542 | </div> |
|
542 | 543 | |
|
543 | 544 | <div class="container"> |
|
544 | 545 | <table class="rctable compare_view_commits"> |
|
545 | 546 | <tr> |
|
546 | 547 | <th></th> |
|
547 | 548 | <th>${_('Time')}</th> |
|
548 | 549 | <th>${_('Author')}</th> |
|
549 | 550 | <th>${_('Commit')}</th> |
|
550 | 551 | <th></th> |
|
551 | 552 | <th>${_('Description')}</th> |
|
552 | 553 | </tr> |
|
553 | 554 | |
|
554 | 555 | % for c_type, commit in c.commit_changes: |
|
555 | 556 | % if c_type in ['a', 'r']: |
|
556 | 557 | <% |
|
557 | 558 | if c_type == 'a': |
|
558 | 559 | cc_title = _('Commit added in displayed changes') |
|
559 | 560 | elif c_type == 'r': |
|
560 | 561 | cc_title = _('Commit removed in displayed changes') |
|
561 | 562 | else: |
|
562 | 563 | cc_title = '' |
|
563 | 564 | %> |
|
564 | 565 | <tr id="row-${commit.raw_id}" commit_id="${commit.raw_id}" class="compare_select"> |
|
565 | 566 | <td> |
|
566 | 567 | <div class="commit-change-indicator color-${c_type}-border"> |
|
567 | 568 | <div class="commit-change-content color-${c_type} tooltip" title="${h.tooltip(cc_title)}"> |
|
568 | 569 | ${c_type.upper()} |
|
569 | 570 | </div> |
|
570 | 571 | </div> |
|
571 | 572 | </td> |
|
572 | 573 | <td class="td-time"> |
|
573 | 574 | ${h.age_component(commit.date)} |
|
574 | 575 | </td> |
|
575 | 576 | <td class="td-user"> |
|
576 | 577 | ${base.gravatar_with_user(commit.author, 16, tooltip=True)} |
|
577 | 578 | </td> |
|
578 | 579 | <td class="td-hash"> |
|
579 | 580 | <code> |
|
580 | 581 | <a href="${h.route_path('repo_commit', repo_name=c.target_repo.repo_name, commit_id=commit.raw_id)}"> |
|
581 | 582 | r${commit.idx}:${h.short_id(commit.raw_id)} |
|
582 | 583 | </a> |
|
583 | 584 | ${h.hidden('revisions', commit.raw_id)} |
|
584 | 585 | </code> |
|
585 | 586 | </td> |
|
586 | 587 | <td class="td-message expand_commit" data-commit-id="${commit.raw_id}" title="${_( 'Expand commit message')}" onclick="commitsController.expandCommit(this); return false"> |
|
587 | 588 | <i class="icon-expand-linked"></i> |
|
588 | 589 | </td> |
|
589 | 590 | <td class="mid td-description"> |
|
590 | 591 | <div class="log-container truncate-wrap"> |
|
591 | 592 | <div class="message truncate" id="c-${commit.raw_id}" data-message-raw="${commit.message}">${h.urlify_commit_message(commit.message, c.repo_name)}</div> |
|
592 | 593 | </div> |
|
593 | 594 | </td> |
|
594 | 595 | </tr> |
|
595 | 596 | % endif |
|
596 | 597 | % endfor |
|
597 | 598 | </table> |
|
598 | 599 | </div> |
|
599 | 600 | |
|
600 | 601 | % endif |
|
601 | 602 | |
|
602 | 603 | % else: |
|
603 | 604 | <%include file="/compare/compare_commits.mako" /> |
|
604 | 605 | % endif |
|
605 | 606 | |
|
606 | 607 | <div class="cs_files"> |
|
607 | 608 | <%namespace name="cbdiffs" file="/codeblocks/diffs.mako"/> |
|
608 | 609 | % if c.at_version: |
|
609 | 610 | <% c.inline_cnt = len(c.inline_versions[c.at_version_num]['display']) %> |
|
610 | 611 | <% c.comments = c.comment_versions[c.at_version_num]['display'] %> |
|
611 | 612 | % else: |
|
612 | 613 | <% c.inline_cnt = len(c.inline_versions[c.at_version_num]['until']) %> |
|
613 | 614 | <% c.comments = c.comment_versions[c.at_version_num]['until'] %> |
|
614 | 615 | % endif |
|
615 | 616 | |
|
616 | 617 | <% |
|
617 | 618 | pr_menu_data = { |
|
618 | 619 | 'outdated_comm_count_ver': outdated_comm_count_ver |
|
619 | 620 | } |
|
620 | 621 | %> |
|
621 | 622 | |
|
622 | 623 | ${cbdiffs.render_diffset_menu(c.diffset, range_diff_on=c.range_diff_on)} |
|
623 | 624 | |
|
624 | 625 | % if c.range_diff_on: |
|
625 | 626 | % for commit in c.commit_ranges: |
|
626 | 627 | ${cbdiffs.render_diffset( |
|
627 | 628 | c.changes[commit.raw_id], |
|
628 | 629 | commit=commit, use_comments=True, |
|
629 | 630 | collapse_when_files_over=5, |
|
630 | 631 | disable_new_comments=True, |
|
631 | 632 | deleted_files_comments=c.deleted_files_comments, |
|
632 | 633 | inline_comments=c.inline_comments, |
|
633 | 634 | pull_request_menu=pr_menu_data, show_todos=False)} |
|
634 | 635 | % endfor |
|
635 | 636 | % else: |
|
636 | 637 | ${cbdiffs.render_diffset( |
|
637 | 638 | c.diffset, use_comments=True, |
|
638 | 639 | collapse_when_files_over=30, |
|
639 | 640 | disable_new_comments=not c.allowed_to_comment, |
|
640 | 641 | deleted_files_comments=c.deleted_files_comments, |
|
641 | 642 | inline_comments=c.inline_comments, |
|
642 | 643 | pull_request_menu=pr_menu_data, show_todos=False)} |
|
643 | 644 | % endif |
|
644 | 645 | |
|
645 | 646 | </div> |
|
646 | 647 | % else: |
|
647 | 648 | ## skipping commits we need to clear the view for missing commits |
|
648 | 649 | <div style="clear:both;"></div> |
|
649 | 650 | % endif |
|
650 | 651 | |
|
651 | 652 | </div> |
|
652 | 653 | </div> |
|
653 | 654 | |
|
654 | 655 | ## template for inline comment form |
|
655 | 656 | <%namespace name="comment" file="/changeset/changeset_file_comment.mako"/> |
|
656 | 657 | |
|
657 | 658 | ## comments heading with count |
|
658 | 659 | <div class="comments-heading"> |
|
659 | 660 | <i class="icon-comment"></i> |
|
660 | 661 | ${_('Comments')} ${len(c.comments)} |
|
661 | 662 | </div> |
|
662 | 663 | |
|
663 | 664 | ## render general comments |
|
664 | 665 | <div id="comment-tr-show"> |
|
665 | 666 | % if general_outdated_comm_count_ver: |
|
666 | 667 | <div class="info-box"> |
|
667 | 668 | % if general_outdated_comm_count_ver == 1: |
|
668 | 669 | ${_('there is {num} general comment from older versions').format(num=general_outdated_comm_count_ver)}, |
|
669 | 670 | <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show it')}</a> |
|
670 | 671 | % else: |
|
671 | 672 | ${_('there are {num} general comments from older versions').format(num=general_outdated_comm_count_ver)}, |
|
672 | 673 | <a href="#show-hidden-comments" onclick="$('.comment-general.comment-outdated').show(); $(this).parent().hide(); return false;">${_('show them')}</a> |
|
673 | 674 | % endif |
|
674 | 675 | </div> |
|
675 | 676 | % endif |
|
676 | 677 | </div> |
|
677 | 678 | |
|
678 | 679 | ${comment.generate_comments(c.comments, include_pull_request=True, is_pull_request=True)} |
|
679 | 680 | |
|
680 | 681 | % if not c.pull_request.is_closed(): |
|
681 | 682 | ## main comment form and it status |
|
682 | 683 | ${comment.comments(h.route_path('pullrequest_comment_create', repo_name=c.repo_name, |
|
683 | 684 | pull_request_id=c.pull_request.pull_request_id), |
|
684 | 685 | c.pull_request_review_status, |
|
685 | 686 | is_pull_request=True, change_status=c.allowed_to_change_status)} |
|
686 | 687 | |
|
687 | 688 | ## merge status, and merge action |
|
688 | 689 | <div class="pull-request-merge"> |
|
689 | 690 | <%include file="/pullrequests/pullrequest_merge_checks.mako"/> |
|
690 | 691 | </div> |
|
691 | 692 | |
|
692 | 693 | %endif |
|
693 | 694 | |
|
694 | 695 | % endif |
|
695 | 696 | </div> |
|
696 | 697 | |
|
697 | 698 | <script type="text/javascript"> |
|
698 | 699 | |
|
699 | 700 | versionController = new VersionController(); |
|
700 | 701 | versionController.init(); |
|
701 | 702 | |
|
702 | 703 | reviewersController = new ReviewersController(); |
|
703 | 704 | commitsController = new CommitsController(); |
|
704 | 705 | |
|
705 | 706 | updateController = new UpdatePrController(); |
|
706 | 707 | |
|
707 | 708 | $(function () { |
|
708 | 709 | |
|
709 | 710 | // custom code mirror |
|
710 | 711 | var codeMirrorInstance = $('#pr-description-input').get(0).MarkupForm.cm; |
|
711 | 712 | |
|
712 | 713 | var PRDetails = { |
|
713 | 714 | editButton: $('#open_edit_pullrequest'), |
|
714 | 715 | closeButton: $('#close_edit_pullrequest'), |
|
715 | 716 | deleteButton: $('#delete_pullrequest'), |
|
716 | 717 | viewFields: $('#pr-desc, #pr-title'), |
|
717 | 718 | editFields: $('#pr-desc-edit, #pr-title-edit, .pr-save'), |
|
718 | 719 | |
|
719 | 720 | init: function () { |
|
720 | 721 | var that = this; |
|
721 | 722 | this.editButton.on('click', function (e) { |
|
722 | 723 | that.edit(); |
|
723 | 724 | }); |
|
724 | 725 | this.closeButton.on('click', function (e) { |
|
725 | 726 | that.view(); |
|
726 | 727 | }); |
|
727 | 728 | }, |
|
728 | 729 | |
|
729 | 730 | edit: function (event) { |
|
730 | 731 | this.viewFields.hide(); |
|
731 | 732 | this.editButton.hide(); |
|
732 | 733 | this.deleteButton.hide(); |
|
733 | 734 | this.closeButton.show(); |
|
734 | 735 | this.editFields.show(); |
|
735 | 736 | codeMirrorInstance.refresh(); |
|
736 | 737 | }, |
|
737 | 738 | |
|
738 | 739 | view: function (event) { |
|
739 | 740 | this.editButton.show(); |
|
740 | 741 | this.deleteButton.show(); |
|
741 | 742 | this.editFields.hide(); |
|
742 | 743 | this.closeButton.hide(); |
|
743 | 744 | this.viewFields.show(); |
|
744 | 745 | } |
|
745 | 746 | }; |
|
746 | 747 | |
|
747 | 748 | var ReviewersPanel = { |
|
748 | 749 | editButton: $('#open_edit_reviewers'), |
|
749 | 750 | closeButton: $('#close_edit_reviewers'), |
|
750 | 751 | addButton: $('#add_reviewer'), |
|
751 | 752 | removeButtons: $('.reviewer_member_remove,.reviewer_member_mandatory_remove'), |
|
752 | 753 | |
|
753 | 754 | init: function () { |
|
754 | 755 | var self = this; |
|
755 | 756 | this.editButton.on('click', function (e) { |
|
756 | 757 | self.edit(); |
|
757 | 758 | }); |
|
758 | 759 | this.closeButton.on('click', function (e) { |
|
759 | 760 | self.close(); |
|
760 | 761 | }); |
|
761 | 762 | }, |
|
762 | 763 | |
|
763 | 764 | edit: function (event) { |
|
764 | 765 | this.editButton.hide(); |
|
765 | 766 | this.closeButton.show(); |
|
766 | 767 | this.addButton.show(); |
|
767 | 768 | this.removeButtons.css('visibility', 'visible'); |
|
768 | 769 | // review rules |
|
769 | 770 | reviewersController.loadReviewRules( |
|
770 | 771 | ${c.pull_request.reviewer_data_json | n}); |
|
771 | 772 | }, |
|
772 | 773 | |
|
773 | 774 | close: function (event) { |
|
774 | 775 | this.editButton.show(); |
|
775 | 776 | this.closeButton.hide(); |
|
776 | 777 | this.addButton.hide(); |
|
777 | 778 | this.removeButtons.css('visibility', 'hidden'); |
|
778 | 779 | // hide review rules |
|
779 | 780 | reviewersController.hideReviewRules() |
|
780 | 781 | } |
|
781 | 782 | }; |
|
782 | 783 | |
|
783 | 784 | PRDetails.init(); |
|
784 | 785 | ReviewersPanel.init(); |
|
785 | 786 | |
|
786 | 787 | showOutdated = function (self) { |
|
787 | 788 | $('.comment-inline.comment-outdated').show(); |
|
788 | 789 | $('.filediff-outdated').show(); |
|
789 | 790 | $('.showOutdatedComments').hide(); |
|
790 | 791 | $('.hideOutdatedComments').show(); |
|
791 | 792 | }; |
|
792 | 793 | |
|
793 | 794 | hideOutdated = function (self) { |
|
794 | 795 | $('.comment-inline.comment-outdated').hide(); |
|
795 | 796 | $('.filediff-outdated').hide(); |
|
796 | 797 | $('.hideOutdatedComments').hide(); |
|
797 | 798 | $('.showOutdatedComments').show(); |
|
798 | 799 | }; |
|
799 | 800 | |
|
800 | 801 | refreshMergeChecks = function () { |
|
801 | 802 | var loadUrl = "${request.current_route_path(_query=dict(merge_checks=1))}"; |
|
802 | 803 | $('.pull-request-merge').css('opacity', 0.3); |
|
803 | 804 | $('.action-buttons-extra').css('opacity', 0.3); |
|
804 | 805 | |
|
805 | 806 | $('.pull-request-merge').load( |
|
806 | 807 | loadUrl, function () { |
|
807 | 808 | $('.pull-request-merge').css('opacity', 1); |
|
808 | 809 | |
|
809 | 810 | $('.action-buttons-extra').css('opacity', 1); |
|
810 | 811 | } |
|
811 | 812 | ); |
|
812 | 813 | }; |
|
813 | 814 | |
|
814 | 815 | closePullRequest = function (status) { |
|
815 | 816 | if (!confirm(_gettext('Are you sure to close this pull request without merging?'))) { |
|
816 | 817 | return false; |
|
817 | 818 | } |
|
818 | 819 | // inject closing flag |
|
819 | 820 | $('.action-buttons-extra').append('<input type="hidden" class="close-pr-input" id="close_pull_request" value="1">'); |
|
820 | 821 | $(generalCommentForm.statusChange).select2("val", status).trigger('change'); |
|
821 | 822 | $(generalCommentForm.submitForm).submit(); |
|
822 | 823 | }; |
|
823 | 824 | |
|
824 | 825 | $('#show-outdated-comments').on('click', function (e) { |
|
825 | 826 | var button = $(this); |
|
826 | 827 | var outdated = $('.comment-outdated'); |
|
827 | 828 | |
|
828 | 829 | if (button.html() === "(Show)") { |
|
829 | 830 | button.html("(Hide)"); |
|
830 | 831 | outdated.show(); |
|
831 | 832 | } else { |
|
832 | 833 | button.html("(Show)"); |
|
833 | 834 | outdated.hide(); |
|
834 | 835 | } |
|
835 | 836 | }); |
|
836 | 837 | |
|
837 | 838 | $('.show-inline-comments').on('change', function (e) { |
|
838 | 839 | var show = 'none'; |
|
839 | 840 | var target = e.currentTarget; |
|
840 | 841 | if (target.checked) { |
|
841 | 842 | show = '' |
|
842 | 843 | } |
|
843 | 844 | var boxid = $(target).attr('id_for'); |
|
844 | 845 | var comments = $('#{0} .inline-comments'.format(boxid)); |
|
845 | 846 | var fn_display = function (idx) { |
|
846 | 847 | $(this).css('display', show); |
|
847 | 848 | }; |
|
848 | 849 | $(comments).each(fn_display); |
|
849 | 850 | var btns = $('#{0} .inline-comments-button'.format(boxid)); |
|
850 | 851 | $(btns).each(fn_display); |
|
851 | 852 | }); |
|
852 | 853 | |
|
853 | 854 | $('#merge_pull_request_form').submit(function () { |
|
854 | 855 | if (!$('#merge_pull_request').attr('disabled')) { |
|
855 | 856 | $('#merge_pull_request').attr('disabled', 'disabled'); |
|
856 | 857 | } |
|
857 | 858 | return true; |
|
858 | 859 | }); |
|
859 | 860 | |
|
860 | 861 | $('#edit_pull_request').on('click', function (e) { |
|
861 | 862 | var title = $('#pr-title-input').val(); |
|
862 | 863 | var description = codeMirrorInstance.getValue(); |
|
863 | 864 | var renderer = $('#pr-renderer-input').val(); |
|
864 | 865 | editPullRequest( |
|
865 | 866 | "${c.repo_name}", "${c.pull_request.pull_request_id}", |
|
866 | 867 | title, description, renderer); |
|
867 | 868 | }); |
|
868 | 869 | |
|
869 | 870 | $('#update_pull_request').on('click', function (e) { |
|
870 | 871 | $(this).attr('disabled', 'disabled'); |
|
871 | 872 | $(this).addClass('disabled'); |
|
872 | 873 | $(this).html(_gettext('Saving...')); |
|
873 | 874 | reviewersController.updateReviewers( |
|
874 | 875 | "${c.repo_name}", "${c.pull_request.pull_request_id}"); |
|
875 | 876 | }); |
|
876 | 877 | |
|
877 | 878 | |
|
878 | 879 | // fixing issue with caches on firefox |
|
879 | 880 | $('#update_commits').removeAttr("disabled"); |
|
880 | 881 | |
|
881 | 882 | $('.show-inline-comments').on('click', function (e) { |
|
882 | 883 | var boxid = $(this).attr('data-comment-id'); |
|
883 | 884 | var button = $(this); |
|
884 | 885 | |
|
885 | 886 | if (button.hasClass("comments-visible")) { |
|
886 | 887 | $('#{0} .inline-comments'.format(boxid)).each(function (index) { |
|
887 | 888 | $(this).hide(); |
|
888 | 889 | }); |
|
889 | 890 | button.removeClass("comments-visible"); |
|
890 | 891 | } else { |
|
891 | 892 | $('#{0} .inline-comments'.format(boxid)).each(function (index) { |
|
892 | 893 | $(this).show(); |
|
893 | 894 | }); |
|
894 | 895 | button.addClass("comments-visible"); |
|
895 | 896 | } |
|
896 | 897 | }); |
|
897 | 898 | |
|
898 | 899 | // register submit callback on commentForm form to track TODOs |
|
899 | 900 | window.commentFormGlobalSubmitSuccessCallback = function () { |
|
900 | 901 | refreshMergeChecks(); |
|
901 | 902 | }; |
|
902 | 903 | |
|
903 | 904 | ReviewerAutoComplete('#user'); |
|
904 | 905 | |
|
905 | 906 | }) |
|
906 | 907 | |
|
907 | 908 | </script> |
|
908 | 909 | |
|
909 | 910 | </div> |
|
910 | 911 | |
|
911 | 912 | </%def> |
General Comments 0
You need to be logged in to leave comments.
Login now