Skip to content

Commit 23be16b

Browse files
authored
Merge branch 'master' into update_dep_2
2 parents c8caee9 + 454ee97 commit 23be16b

File tree

2 files changed

+174
-20
lines changed

2 files changed

+174
-20
lines changed

apps/st2-actions/actions-details.component.js

Lines changed: 172 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ import { Link } from '@stackstorm/module-router';
2626
import ActionReporter from '@stackstorm/module-action-reporter';
2727
import AutoForm from '@stackstorm/module-auto-form';
2828
import StringField from '@stackstorm/module-auto-form/fields/string';
29+
import EnumField from '@stackstorm/module-auto-form/fields/enum';
30+
import get from 'lodash/fp/get';
31+
2932
import {
3033
FlexTable,
3134
FlexTableRow,
@@ -48,7 +51,6 @@ import {
4851
} from '@stackstorm/module-panel';
4952
import Time from '@stackstorm/module-time';
5053

51-
5254
@connect((state) => {
5355
const { action, executions, entrypoint } = state;
5456
return { action, executions, entrypoint };
@@ -64,14 +66,28 @@ export default class ActionsDetails extends React.Component {
6466
action: PropTypes.object,
6567
executions: PropTypes.array,
6668
entrypoint: PropTypes.string,
69+
groups: PropTypes.array,
70+
filter: PropTypes.string,
71+
match: PropTypes.shape({
72+
params: PropTypes.shape({
73+
ref: PropTypes.string,
74+
section: PropTypes.string,
75+
}),
76+
}),
6777
}
6878

6979
state = {
7080
runPreview: false,
7181
runValue: null,
7282
runTrace: null,
7383
executionsVisible: {},
74-
isChecked:false,
84+
openModel: false,
85+
isChecked: false,
86+
destinationPack:'',
87+
destinationAction:'',
88+
packs:[],
89+
isRemoveFiles : false,
90+
7591
}
7692

7793
componentDidMount() {
@@ -129,11 +145,29 @@ export default class ActionsDetails extends React.Component {
129145
}
130146
}
131147

132-
componentDidUpdate(prevProps) {
133-
const { id } = this.props;
148+
UNSAFE_componentWillReceiveProps(nextProps) {
149+
const {groups, filter} = nextProps;
150+
const packs = [];
151+
if(!filter) {
152+
groups && groups.map(data => {
153+
packs.push(data.pack);
154+
});
155+
156+
this.setState({packs : packs});
157+
}
158+
}
159+
160+
componentDidUpdate(prevProps, prevState) {
161+
const { id , filter} = this.props;
162+
163+
134164
if (id && id !== prevProps.id) {
135165
this.fetchAction(id);
136166
}
167+
168+
if(filter && filter !== prevProps.filter) {
169+
this.setState({packs: prevState.packs});
170+
}
137171
}
138172

139173
componentWillUnmount() {
@@ -254,6 +288,101 @@ export default class ActionsDetails extends React.Component {
254288
return this.props.handleRun(...args);
255289
}
256290

291+
handleClone(e, srcPack,srcAction, destAction,destPack, overwrite) {
292+
e.preventDefault();
293+
return store.dispatch({
294+
type: 'CLONE_ACTION',
295+
promise: api.request({
296+
method: 'post',
297+
path: `/actions/${srcPack}.${srcAction}/clone`,
298+
},{
299+
'dest_pack': destPack,
300+
'dest_action': destAction,
301+
'overwrite': overwrite,
302+
303+
})
304+
.then((execution) => {
305+
document.getElementById('overlay').style.display = 'none';
306+
notification.success(`Action "${srcAction}" has been cloned successfully.`);
307+
this.getActions();
308+
return execution;
309+
})
310+
.catch((err) => {
311+
if (err.response) {
312+
const error = document.getElementById('error');
313+
error.textContent = err.response.data.faultstring;
314+
error.style.color = 'red';
315+
}
316+
}),
317+
});
318+
}
319+
320+
getActions() {
321+
return store.dispatch({
322+
type: 'FETCH_GROUPS',
323+
promise: api.request({
324+
path: '/actions',
325+
query: {
326+
include_attributes: [
327+
'ref',
328+
'pack',
329+
'name',
330+
'description',
331+
'runner_type',
332+
],
333+
},
334+
})
335+
.catch((err) => {
336+
notification.error('Unable to retrieve actions.', { err });
337+
throw err;
338+
}),
339+
})
340+
.then(() => {
341+
const { id } = this.urlParams;
342+
const { groups } = this.props;
343+
344+
if (id && groups && !groups.some(({ actions }) => actions.some(({ ref }) => ref === id))) {
345+
this.navigate({ id: false });
346+
}
347+
})
348+
;
349+
}
350+
351+
get urlParams() {
352+
const {
353+
ref = get('groups[0].actions[0].ref', this.props),
354+
section = 'general',
355+
} = this.props.match.params;
356+
357+
return {
358+
id: ref,
359+
section,
360+
};
361+
}
362+
363+
openModel (e) {
364+
const {action} = this.props;
365+
const el = document.getElementById('overlay');
366+
el.style.display = 'block';
367+
this.setState({ destinationPack:action.pack, destinationAction:'', isChecked: false});
368+
}
369+
370+
closeModel() {
371+
document.getElementById('overlay').style.display = 'none';
372+
}
373+
374+
handleDropdown(e) {
375+
const error = document.getElementById('error');
376+
error.textContent = '';
377+
this.setState({destinationPack:e});
378+
}
379+
380+
handleInput(e) {
381+
const error = document.getElementById('error');
382+
error.textContent = '';
383+
this.setState({destinationAction:e});
384+
}
385+
257386
handleChange(e) {
258387
const isChecked = document.getElementById('checkbox').checked;
259388
if(isChecked) {
@@ -264,28 +393,37 @@ export default class ActionsDetails extends React.Component {
264393
}
265394
}
266395

267-
openModel (e) {
268-
this.setState({isChecked: false});
269-
const el = document.getElementById('overlay');
396+
handleDeleteChange(e) {
397+
const isChecked = document.getElementById('deletecheckbox').checked;
398+
if(isChecked) {
399+
this.setState({isRemoveFiles:true});
400+
}
401+
else {
402+
this.setState({isRemoveFiles:false});
403+
}
404+
}
405+
406+
openDeleteModel (e) {
407+
this.setState({isRemoveFiles: false});
408+
const el = document.getElementById('delete');
270409
el.style.display = 'block';
271410
}
272411

273412
handleDelete (e) {
274413
e.preventDefault();
275414
const { id } = this.props;
276-
const {isChecked} = this.state;
277-
document.getElementById('overlay').style.display = 'none';
278-
return this.props.handleDelete(id, isChecked);
415+
const {isRemoveFiles} = this.state;
416+
document.getElementById('delete').style.display = 'none';
417+
return this.props.handleDelete(id, isRemoveFiles);
279418
}
280419

281-
closeModel() {
282-
283-
document.getElementById('overlay').style.display = 'none';
420+
closeDeleteModel() {
421+
document.getElementById('delete').style.display = 'none';
284422
}
285-
286423

287424
render() {
288-
const { section, action, executions, entrypoint } = this.props;
425+
const { section, action, executions, entrypoint} = this.props;
426+
289427
if (!action) {
290428
return null;
291429
}
@@ -325,7 +463,8 @@ export default class ActionsDetails extends React.Component {
325463
/>
326464
<Button flat value="Preview" onClick={() => this.handleToggleRunPreview()} />
327465
<DetailsToolbarSeparator />
328-
<Button className="st2-forms__button st2-details__toolbar-button" value="Delete" onClick={(e) => this.openModel(e)} />
466+
<Button disabled={this.props.id !== action.ref} className="st2-forms__button st2-details__toolbar-button" value="Clone" onClick={(e) => this.openModel(e)} />
467+
<Button className="st2-forms__button st2-details__toolbar-button" value="Delete" onClick={(e) => this.openDeleteModel(e)} />
329468

330469
{ action.runner_type === 'mistral-v2' || action.runner_type === 'orquesta' ? (
331470
<Link
@@ -425,15 +564,29 @@ export default class ActionsDetails extends React.Component {
425564
</DetailsPanel>
426565
</DetailsBody>
427566
) : null }
567+
568+
{/* Written pop-up box code here */}
569+
<div id="overlay" className="web_dialog_overlay" style={{display: 'none', position: 'fixed', zIndex: '10', left: '0',top: '0',width: '100%', minHeight: '-webkit-fill-available', overflow: 'auto', backgroundColor: 'rgba(0,0,0,0.4)' }}>
570+
<div id="dialog" className="web_dialog" style={{backgroundColor: '#fefefe' ,margin: '15% auto',padding: '20px', border: '1px solid #888' ,width: '28%' ,height:'50%' }}>
571+
<EnumField name="Destination Pack Name *" value={this.state.destinationPack ? this.state.destinationPack : action.pack} spec={{enum: this.state.packs}} onChange={(e) => this.handleDropdown(e)} /><br /><br />
572+
<StringField style={{height:'30%'}} name="Destination Action Name *" value={this.state.destinationAction} onChange={(e) => this.handleInput(e)} required /><br /><br />
428573

574+
<input id="checkbox" name="checkbox" type="checkbox" checked={this.state.isChecked} value={this.state.isChecked} onChange={(e) => this.handleChange(e)} /> Overwrite <br /><br /><br />
575+
<span id="error" /><br /><br />
576+
<div style={{width:'100%', display:'inline-block'}}>
577+
<button onClick={(e) => this.handleClone(e, action.pack,action.name,this.state.destinationAction,this.state.destinationPack, this.state.isChecked )} type="submit" className="btn" style={{backgroundColor: '#04AA6D' , color: 'white',padding: '16px 20px' ,border: 'none', cursor: 'pointer', width: '45%' ,marginBottom:'10px' , opacity: '0.8',float:'left'}}>Submit</button>
578+
<button onClick={(e) => this.closeModel(e)} type="close" className="btn cancel" style={{backgroundColor: 'red' , color: 'white',padding: '16px 20px' ,border: 'none', cursor: 'pointer', width: '45%' ,marginBottom:'10px' , opacity: '0.8', float:'right'}}>Close</button>
579+
</div>
580+
</div>
581+
</div>
429582

430-
<div id="overlay" className="web_dialog_overlay" style={{display: 'none', position: 'fixed', zIndex: '10', left: '0',top: '0',width: '100%', minHeight: '-webkit-fill-available', overflow: 'auto', backgroundColor: 'rgba(0,0,0,0.4)' }}>
583+
<div id="delete" className="web_dialog_overlay" style={{display: 'none', position: 'fixed', zIndex: '10', left: '0',top: '0',width: '100%', minHeight: '-webkit-fill-available', overflow: 'auto', backgroundColor: 'rgba(0,0,0,0.4)' }}>
431584
<div id="dialog" className="web_dialog" style={{backgroundColor: '#fefefe' ,margin: '15% auto',padding: '20px', border: '1px solid #888' ,width: '24%' ,height:'20%' }}>
432585
<p> You are about to delete the action. Are you sure? </p>
433-
<input id="checkbox" name="checkbox" type="checkbox" checked={this.state.isChecked} value={this.state.isChecked} onChange={(e) => this.handleChange(e)} /> Remove Files (This operation is irreversible.) <br /><br /><br />
586+
<input id="deletecheckbox" name="checkbox" type="checkbox" checked={this.state.isRemoveFiles} value={this.state.isRemoveFiles} onChange={(e) => this.handleDeleteChange(e)} /> Remove Files (This operation is irreversible.) <br /><br /><br />
434587
<div style={{width:'100%', display:'inline-block'}}>
435588
<button onClick={(e) => this.handleDelete(e)} type="submit" className="btn" style={{backgroundColor: '#04AA6D' , color: 'white',padding: '16px 20px' ,border: 'none', cursor: 'pointer', width: '45%' ,marginBottom:'10px' , opacity: '0.8',float:'left'}}>Submit</button>
436-
<button onClick={(e) => this.closeModel(e)} type="close" className="btn cancel" style={{backgroundColor: 'red' , color: 'white',padding: '16px 20px' ,border: 'none', cursor: 'pointer', width: '45%' ,marginBottom:'10px' , opacity: '0.8', float:'right'}}>Close</button>
589+
<button onClick={(e) => this.closeDeleteModel(e)} type="close" className="btn cancel" style={{backgroundColor: 'red' , color: 'white',padding: '16px 20px' ,border: 'none', cursor: 'pointer', width: '45%' ,marginBottom:'10px' , opacity: '0.8', float:'right'}}>Close</button>
437590
</div>
438591
</div>
439592
</div>

apps/st2-actions/actions-panel.component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,6 @@ export default class ActionsPanel extends React.Component {
222222
.then((res) => {
223223
notification.success(`Action "${ref}" has been deleted successfully.`);
224224
this.navigate({ id: null });
225-
store.dispatch(flexActions.toggleAll());
226225
this.fetchGroups();
227226
return res;
228227
})
@@ -311,6 +310,8 @@ export default class ActionsPanel extends React.Component {
311310

312311
id={id}
313312
section={section}
313+
groups={groups}
314+
filter={filter}
314315
/>
315316
</Panel>
316317
);

0 commit comments

Comments
 (0)