Skip to content

Commit 3bd516e

Browse files
committed
ZENKO-2487 create replication workflow
1 parent dc0343f commit 3bd516e

6 files changed

Lines changed: 4267 additions & 158 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"dependencies": {
4040
"@fortawesome/fontawesome-free": "5.7.2",
4141
"@scality/core-ui": "github:scality/core-ui.git#add-dist-folder",
42+
"@scality/pensieve-front": "file:../pensieve-front",
4243
"async": "^3.2.0",
4344
"aws-sdk": "^2.616.0",
4445
"connected-react-router": "^6.7.0",

src/react/ui-elements/CreateContainer.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ const CreateContainer = styled.div`
2222
.input{
2323
display: flex;
2424
flex-direction: column;
25+
margin-bottom: 20px;
2526
.sc-input-wrapper{ width:100%; }
27+
.name {
28+
margin-bottom: 10px;
29+
}
2630
input{
27-
margin-top: 10px;
31+
margin-bottom: 10px;
2832
width:90%;
2933
}
3034
}

src/react/workflow/replication/ReplicationCreate.jsx

Lines changed: 122 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,132 @@
1-
import { Button, Input, Select } from '@scality/core-ui';
1+
import { Button, Input, MultiSelect, Select } from '@scality/core-ui';
22
import React, { useState } from 'react';
3+
import { convertToReplicationStream, generateStreamName, newReplicationForm } from './utils';
34
import CreateContainer from '../../ui-elements/CreateContainer';
45
// import ReplicationCreateForm from './ReplicationCreateForm';
56
import { connect } from 'react-redux';
67
import { push } from 'connected-react-router';
78
import { saveReplication } from '../../actions/replication';
89

9-
function newReplicationForm() {
10-
return {
11-
streamName: '',
12-
streamVersion: 1,
13-
streamId: '',
14-
enabled: true,
15-
sourceBucket: '',
16-
sourcePrefix: '',
17-
destinationLocations: [],
18-
preferredReadLocation: null,
19-
};
20-
}
21-
2210
function ReplicationCreate(props){
2311

2412
const [stream, setStream] = useState(newReplicationForm());
2513

26-
const onChange = (r) => {
27-
setStream(r);
28-
}
29-
3014
const save = (e) => {
3115
if (e) {
3216
e.preventDefault();
3317
}
34-
props.saveReplicationStream(stream);
18+
let streamName = stream.streamName;
19+
if (!streamName && stream.sourceBucket && stream.destinationLocations && stream.destinationLocations.length) {
20+
streamName = generateStreamName(stream.sourceBucket, stream.destinationLocations);
21+
}
22+
const s = { ...stream, streamName};
23+
console.log('FINAL FORM stream s!!!', s);
24+
// props.saveReplicationStream(convertToReplicationStream(s));
3525
}
3626

3727
const cancel = () => {
3828
props.redirect('/workflow');
3929
}
4030

31+
const handleInputChange = (e) => {
32+
const s = {
33+
...stream,
34+
[e.target.name]: e.target.value,
35+
};
36+
setStream(s);
37+
}
38+
39+
// BUCKET SOURCE
40+
const handleSelectChange = (e) => {
41+
if (!e) {
42+
return;
43+
}
44+
setStream({ ...stream, sourceBucket: e.value });
45+
};
46+
4147
const selectSourceOptions = () => {
42-
console.log('props.bucketLis!!!', props.bucketList);
48+
const bucketsUsedForReplication = props.streams.map(
49+
stream => stream.source.bucketName);
50+
console.log('bucketsUsedForReplication!!!', bucketsUsedForReplication);
4351
const buckets = props.bucketList.map(b => {
4452
return {
4553
label: b.name,
4654
title: b.name,
4755
value: b.name,
4856
location: b.location,
57+
// TODO: DISABLE IF NOT SUPPORT REPLICATION SOURCE
58+
isDisabled: bucketsUsedForReplication.indexOf(b.name) > -1,
59+
// isDisabled: false,
4960
};
5061
});
62+
console.log('buckets!!!', buckets);
63+
return buckets;
64+
};
5165

52-
// return buckets;
66+
// DESTINATION LOCATION
67+
68+
const multipleSelectOptions = () => {
69+
// return Object.keys(this.props.locations)
70+
// .filter(n => {
71+
// const locationType = this.props.locations[n].locationType;
72+
// return storageOptions[locationType].supportsReplicationTarget &&
73+
// this.props.destinationLocations.every((location => location.name !== n));
74+
// }).map(n => {
75+
// return {
76+
// value: n,
77+
// label: n,
78+
// };
79+
// });
80+
return Object.keys(props.locations)
81+
.filter(n => {
82+
return stream.destinationLocations.every((location => location.name !== n));
83+
})
84+
.map(n => {
85+
return {
86+
value: n,
87+
label: n,
88+
};
89+
});
90+
};
5391

54-
return buckets;
92+
const addDestinationLocation = (l) => {
93+
const destinationLocations = [
94+
...stream.destinationLocations,
95+
{ name: l.label, storageClass: 'standard'},
96+
];
97+
const s = {
98+
...stream,
99+
destinationLocations,
100+
};
101+
setStream(s);
102+
};
55103

56-
// [{
57-
// 'data-cy': 'Item_0',
58-
// label: 'Item 0',
59-
// title: 'Item 0',
60-
// value: 0,
61-
// }]
62-
}
104+
const onItemRemove = label => {
105+
const destinationLocations = stream.destinationLocations.filter(d => d.name !== label);
106+
setStream({...stream, destinationLocations});
107+
};
108+
109+
const onFavoriteClick = label => {
110+
setStream({...stream, preferredReadLocation: label});
111+
};
112+
113+
const isFavorite = locationName => {
114+
return stream.preferredReadLocation === locationName;
115+
};
116+
117+
const destinationLocationsItems = () => {
118+
return stream.destinationLocations.map(d => {
119+
return {
120+
// description: d.label,
121+
isFavorite: isFavorite(d.name),
122+
label: d.name,
123+
onFavoriteClick: onFavoriteClick,
124+
onItemRemove: onItemRemove,
125+
// onSelect: function noRefCheck(){},
126+
// selected: true,
127+
};
128+
});
129+
};
63130

64131

65132
return <CreateContainer>
@@ -70,11 +137,36 @@ function ReplicationCreate(props){
70137
<Select
71138
name="default_select"
72139
noOptionsMessage={function noRefCheck(){}}
73-
onChange={function noRefCheck(){}}
140+
onChange={handleSelectChange}
74141
options={selectSourceOptions()}
75142
placeholder="Select a bucket"
143+
isOptionDisabled={(option) => { console.log('option!!!', option); return option.isDisabled === true }}
144+
/>
145+
</div>
146+
<div className='input'>
147+
<div className='name'> destination location: </div>
148+
<MultiSelect
149+
items={destinationLocationsItems()}
150+
onItemRemove={function noRefCheck(){}}
151+
search={{
152+
// onAdd: (e) => { console.log('onAdd e=> ', e) },
153+
onSelect: addDestinationLocation,
154+
options: multipleSelectOptions(),
155+
placeholder: 'Select location to add',
156+
selectedOption: null,
157+
}}
76158
/>
77159
</div>
160+
<div className='input'>
161+
<div className='name'> Only apply to objects with prefix (optional)</div>
162+
<Input
163+
type='text'
164+
name='sourcePrefix'
165+
placeholder='assets/images/'
166+
onChange={handleInputChange}
167+
value={stream.prefix}
168+
autoComplete='off' />
169+
</div>
78170
</div>
79171
<div className='footer'>
80172
<Button outlined onClick={cancel} text='Cancel'/>
@@ -85,7 +177,6 @@ function ReplicationCreate(props){
85177

86178

87179
function mapStateToProps(state) {
88-
console.log('state!!!', state);
89180
return {
90181
bucketList: state.stats.bucketList,
91182
streams: state.configuration.latest.replicationStreams,

src/react/workflow/replication/ReplicationCreateForm.jsx

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
export function generateStreamName(bucketName, destinationLocations) {
2+
const destinations = destinationLocations.length <= 1 ?
3+
destinationLocations[0].name :
4+
`${destinationLocations[0].name} and ${destinationLocations.length - 1} more`;
5+
return `${bucketName}${destinations}`;
6+
}
7+
8+
export function newReplicationForm() {
9+
return {
10+
streamName: '',
11+
streamVersion: 1,
12+
streamId: '',
13+
enabled: true,
14+
sourceBucket: '',
15+
sourcePrefix: '',
16+
destinationLocations: [],
17+
preferredReadLocation: null,
18+
};
19+
}
20+
21+
function newReplicationStream() {
22+
return {
23+
streamId: '',
24+
name: '',
25+
version: 1,
26+
enabled: true,
27+
source: {
28+
prefix: null,
29+
bucketName: '',
30+
},
31+
destination: {
32+
locations: [],
33+
preferredReadLocation: null,
34+
},
35+
};
36+
}
37+
38+
export function convertToReplicationStream(r) {
39+
if (!r) {
40+
return newReplicationStream();
41+
}
42+
return {
43+
streamId: r.streamId || '',
44+
name: r.streamName || '',
45+
version: r.streamVersion || 1,
46+
enabled: true,
47+
source: {
48+
prefix: r.sourcePrefix || '',
49+
bucketName: r.sourceBucket || '',
50+
},
51+
destination: {
52+
locations: r.destinationLocations || [],
53+
preferredReadLocation: r.preferredReadLocation,
54+
},
55+
};
56+
}

0 commit comments

Comments
 (0)