Skip to content

Commit 8931253

Browse files
committed
DM-11387: fix several issue related to backgrounding
- added a checkbox to enable email notification - sync the checkbox and email field between download dialog and background monitor - remove 'resend email' feature which is confusing - when email notification is enabled, an email will be sent for each job when it's completed.
1 parent c767d51 commit 8931253

File tree

6 files changed

+104
-111
lines changed

6 files changed

+104
-111
lines changed

src/firefly/java/edu/caltech/ipac/firefly/server/packagedata/BackgroundInfoCacher.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -171,21 +171,9 @@ private void updateInfo(BackgroundInfo info) {
171171
*/
172172
private static void mergeInfoIntoStatus(BackgroundInfo info, BackgroundStatus bgStatus) {
173173
if (info != null && bgStatus != null) {
174-
if (bgStatus.getParam(ServerParams.TITLE) == null) {
175-
bgStatus.setParam(ServerParams.TITLE, info.getTitle());
176-
} else {
177-
info.setTitle(bgStatus.getParam(ServerParams.TITLE));
178-
}
179-
if (bgStatus.getParam(ServerParams.EMAIL) == null) {
180-
bgStatus.setParam(ServerParams.EMAIL, info.getEmailAddress());
181-
} else {
182-
info.setEmail(bgStatus.getParam(ServerParams.EMAIL));
183-
}
184-
if (bgStatus.getParam(BackgroundStatus.DATA_TAG) == null) {
185-
bgStatus.setParam(BackgroundStatus.DATA_TAG, info.getDataTag());
186-
} else {
187-
info.setDataTag(bgStatus.getParam(BackgroundStatus.DATA_TAG));
188-
}
174+
bgStatus.setParam(ServerParams.TITLE, info.getTitle());
175+
bgStatus.setParam(ServerParams.EMAIL, info.getEmailAddress());
176+
bgStatus.setParam(BackgroundStatus.DATA_TAG, info.getDataTag());
189177
}
190178
}
191179

src/firefly/java/edu/caltech/ipac/firefly/server/query/SearchManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public FileInfo getFileInfo(TableServerRequest request) throws DataAccessExcepti
206206
public BackgroundStatus getRawDataSetBackground(TableServerRequest request, Request clientRequest, int waitMillis) throws RPCException {
207207

208208
Logger.briefDebug("Backgrounded search started:" + waitMillis + " wait, req:" + request);
209-
String email= request.getMeta(ServerParams.EMAIL) == null ? "" : request.getMeta(ServerParams.EMAIL);
209+
String email= request.getMeta(ServerParams.EMAIL);
210210
SearchWorker worker= new SearchWorker(request, clientRequest);
211211
String title = request.getTblTitle() == null ? request.getRequestId() : request.getTblTitle();
212212
BackgroundEnv.BackgroundProcessor processor=

src/firefly/js/core/background/BackgroundCntlr.js

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44

55
import {take} from 'redux-saga/effects';
6-
import {set, get, has, pick} from 'lodash';
6+
import {set, get, has, pick, isNil} from 'lodash';
77

88
import {flux} from '../../Firefly.js';
99
import {smartMerge} from '../../tables/TableUtil.js';
@@ -72,8 +72,8 @@ export function dispatchBgStatus(bgStatus) {
7272
* set the email used for background status notification
7373
* @param {string} email
7474
*/
75-
export function dispatchBgSetEmail(email) {
76-
flux.process({ type : BG_SET_EMAIL, payload: {email} });
75+
export function dispatchBgSetEmailInfo({email, enableEmail}) {
76+
flux.process({ type : BG_SET_EMAIL, payload: {email, enableEmail} });
7777
}
7878

7979
/**
@@ -176,12 +176,11 @@ function bgJobCancel(action) {
176176

177177
function bgSetEmail(action) {
178178
return (dispatch) => {
179-
const {email=''} = action.payload;
180-
SearchServices.setEmail(email);
181-
dispatch(action);
182-
if (email) {
183-
SearchServices.resendEmail(email);
179+
const {email, enableEmail} = action.payload;
180+
if (!isNil(email)) {
181+
SearchServices.setEmail(email);
184182
}
183+
dispatch(action);
185184
};
186185
}
187186

@@ -211,10 +210,14 @@ function reducer(state={}, action={}) {
211210
case BG_STATUS :
212211
return handleBgStatusUpdate(state, action);
213212
break;
214-
case BG_SET_EMAIL :
215-
const {email} = action.payload;
216-
return updateSet(state, 'email', email);
213+
case BG_SET_EMAIL : {
214+
const {email, enableEmail} = action.payload;
215+
let nstate = state;
216+
if (!isNil(email)) nstate = updateSet(state, 'email', email);
217+
if (!isNil(enableEmail)) nstate = updateSet(state, 'enableEmail', enableEmail);
218+
return nstate;
217219
break;
220+
}
218221
case BG_ALLOW_DATA_TAG :
219222
const {patterns} = action.payload;
220223
return updateSet(state, 'allowDataTag', patterns);
@@ -243,7 +246,7 @@ function handleBgJobAdd(state, action) {
243246
var bgstats = action.payload;
244247
bgstats = transform(bgstats);
245248
const nState = set({}, ['jobs', bgstats.ID], bgstats);
246-
if (bgstats.email) nState.email = bgstats.email;
249+
if (!nState.email && !isNil(bgstats.email)) nState.email = bgstats.email; // use email from server if one is not set
247250
return smartMerge(state, nState);
248251
}
249252

src/firefly/js/core/background/BackgroundMonitor.jsx

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44

55
import React, {PureComponent} from 'react';
6-
import {get, set, isEmpty, unset} from 'lodash';
6+
import {get, set, isEmpty, unset, isNil} from 'lodash';
77

88
import DialogRootContainer from '../../ui/DialogRootContainer.jsx';
99
import {PopupPanel} from '../../ui/PopupPanel.jsx';
@@ -13,7 +13,7 @@ import Validate from '../../util/Validate.js';
1313
import {HelpIcon} from '../../ui/HelpIcon.jsx';
1414
import {dispatchShowDialog, dispatchHideDialog} from '../../core/ComponentCntlr.js';
1515
import {getBackgroundInfo, BG_STATE, isActive, isDone, isSuccess, emailSent, canCreateScript} from './BackgroundUtil.js';
16-
import {dispatchBgStatus, dispatchJobRemove, dispatchBgSetEmail, dispatchJobCancel} from './BackgroundCntlr.js';
16+
import {dispatchBgStatus, dispatchJobRemove, dispatchBgSetEmailInfo, dispatchJobCancel} from './BackgroundCntlr.js';
1717
import {downloadWithProgress} from '../../util/WebUtil.js';
1818
import {DownloadProgress} from '../../rpc/SearchServicesJson.js';
1919
import {showScriptDownloadDialog} from '../../ui/ScriptDownloadDialog.jsx';
@@ -48,7 +48,7 @@ class BackgroundMonitor extends SimpleComponent {
4848
}
4949

5050
render() {
51-
const {jobs={}, email='', help_id} = this.state || {};
51+
const {jobs={}, email='', help_id, enableEmail} = this.state || {};
5252
const packages = Object.entries(jobs)
5353
.filter(([id, job]) => get(job, 'TYPE') === 'PACKAGE')
5454
.map( ([id, job]) => {
@@ -71,7 +71,7 @@ class BackgroundMonitor extends SimpleComponent {
7171
{!isEmpty(searches) && searches}
7272
{!isEmpty(unknown) && unknown}
7373
</div>
74-
<BgFooter {...{help_id, email}}/>
74+
<BgFooter {...{help_id, email, enableEmail}}/>
7575
</div>
7676
);
7777
}
@@ -86,27 +86,38 @@ class BgFooter extends PureComponent {
8686
onEmailChanged(v) {
8787
if (get(v, 'valid')) {
8888
const {email} = this.props;
89-
if (email !== v.value) dispatchBgSetEmail(v.value);
89+
if (email !== v.value) dispatchBgSetEmailInfo({email: v.value});
9090
}
9191
}
9292

9393
render() {
94-
const {help_id = 'basics.bgmon', email} = this.props;
94+
const {help_id = 'basics.bgmon', email=''} = this.props;
95+
const enableEmail = isNil(this.props.enableEmail) ? !!email : this.props.enableEmail;
96+
const toggleEnableEmail = (e) => {
97+
const enableEmail = e.target.checked;
98+
const email = enableEmail ? email : '';
99+
dispatchBgSetEmailInfo({email, enableEmail});
100+
};
95101
return (
96102
<div className='BGMon__footer' key='bgMonFooter'>
97103
<button className='button std hl' onClick={this.onHide}
98104
title='Hide Background Monitor'>Hide</button>
99-
<InputField
100-
validator={Validate.validateEmail.bind(null, 'an email field')}
101-
tooltip='Enter an email to be notified when a process completes.'
102-
label='Email:'
103-
labelStyle={{display: 'inline-block', width: 40, fontWeight: 'bold'}}
104-
value={email}
105-
placeholder='Enter an email to get notification'
106-
size={27}
107-
onChange={this.onEmailChanged.bind(this)}
108-
actOn={['blur','enter']}
109-
/>
105+
<div>
106+
<div style={{width: 235}}><input type='checkbox' checked={enableEmail} value='' onChange={toggleEnableEmail}/>Enable email notification</div>
107+
{enableEmail &&
108+
<InputField
109+
validator={Validate.validateEmail.bind(null, 'an email field')}
110+
tooltip='Enter an email to be notified when a process completes.'
111+
label='Email:'
112+
labelStyle={{display: 'inline-block', marginLeft: 18, width: 32, fontWeight: 'bold'}}
113+
value={email}
114+
placeholder='Enter an email to get notification'
115+
size={27}
116+
onChange={this.onEmailChanged.bind(this)}
117+
actOn={['blur','enter']}
118+
/>
119+
}
120+
</div>
110121
<div>
111122
<HelpIcon helpId={help_id} />
112123
</div>

src/firefly/js/core/background/BackgroundUtil.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
33
*/
44

5-
import {get, omit} from 'lodash';
5+
import {get, omit, isNil} from 'lodash';
66
import Enum from 'enum';
77

88
import {flux} from '../../Firefly.js';
@@ -42,6 +42,15 @@ export function getBgEmail() {
4242
return get(flux.getState(), [BACKGROUND_PATH, 'email']);
4343
}
4444

45+
/**
46+
* returns the email related info. Currently, it's email and enableEmail.
47+
* @returns {object.<string, }
48+
*/
49+
export function getBgEmailInfo() {
50+
let {email, enableEmail} = get(flux.getState(), BACKGROUND_PATH) || {};
51+
enableEmail = isNil(enableEmail) ? !!email : enableEmail;
52+
return {email, enableEmail};
53+
}
4554

4655
export function emailSent(bgStatus) {
4756
return get(bgStatus, 'ATTRIBUTES', '').includes('EmailSent');

src/firefly/js/ui/DownloadDialog.jsx

Lines changed: 47 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import React, {PureComponent} from 'react';
66
import PropTypes from 'prop-types';
7-
import {set, cloneDeep} from 'lodash';
7+
import {set, cloneDeep, get} from 'lodash';
88

99
import {flux} from '../Firefly.js';
1010
import DialogRootContainer from './DialogRootContainer.jsx';
@@ -13,16 +13,17 @@ import {dispatchShowDialog, dispatchHideDialog} from '../core/ComponentCntlr.js'
1313
import {FormPanel} from './FormPanel.jsx';
1414
import {FieldGroup} from './FieldGroup.jsx';
1515
import Validate from '../util/Validate.js';
16+
import {InputField} from './InputField.jsx';
1617
import {ListBoxInputField} from './ListBoxInputField.jsx';
1718
import {CheckboxGroupInputField} from './CheckboxGroupInputField.jsx';
18-
import FieldGroupUtils from '../fieldGroup/FieldGroupUtils.js';
1919
import {ValidationField} from './ValidationField.jsx';
2020
import {showInfoPopup} from './PopupUtil.jsx';
21+
import {SimpleComponent} from './SimpleComponent.jsx';
2122

2223
import {makeTblRequest, getTblInfoById, getActiveTableId} from '../tables/TableUtil.js';
23-
import {dispatchPackage, doOnPackage} from '../core/background/BackgroundCntlr.js';
24+
import {dispatchPackage, dispatchBgSetEmailInfo} from '../core/background/BackgroundCntlr.js';
25+
import {getBgEmailInfo} from '../core/background/BackgroundUtil.js';
2426
import {SelectInfo} from '../tables/SelectInfo.js';
25-
import {dispatchAddSaga} from '../core/MasterSaga.js';
2627
import {DataTagMeta} from '../tables/TableUtil.js';
2728

2829
const DOWNLOAD_DIALOG_ID = 'Download Options';
@@ -124,59 +125,49 @@ DownloadButton.propTypes = {
124125
};
125126

126127

127-
export class DownloadOptionPanel extends PureComponent {
128+
export class DownloadOptionPanel extends SimpleComponent {
128129

129-
constructor(props) {
130-
super(props);
131-
const sendEmail = FieldGroupUtils.getFldValue(FieldGroupUtils.getGroupFields(props.groupKey), 'sendEmail');
132-
this.state = {sendEmail, mask: false};
133-
this.onSubmit = this.onSubmit.bind(this);
134-
}
135-
136-
componentDidMount() {
137-
this.removeListener= flux.addListener(() => this.storeUpdate());
138-
}
139-
140-
componentWillUnmount() {
141-
this.removeListener && this.removeListener();
142-
this.isUnmounted = true;
130+
getNextState() {
131+
const {email, enableEmail} = getBgEmailInfo();
132+
return {mask:false, email, enableEmail};
143133
}
144134

145-
storeUpdate() {
146-
const {groupKey} = this.props;
147-
if (!this.isUnmounted) {
148-
const sendEmail = FieldGroupUtils.getFldValue(FieldGroupUtils.getGroupFields(groupKey), 'sendEmail');
149-
this.setState({sendEmail});
135+
onEmailChanged(v) {
136+
if (get(v, 'valid')) {
137+
const {email} = this.state;
138+
if (email !== v.value) dispatchBgSetEmailInfo({email: v.value});
150139
}
151140
}
152141

153-
onSubmit(options) {
154-
const {tbl_id, dlParams, dataTag, cutoutSize} = this.props;
155-
var {request, selectInfo} = getTblInfoById(tbl_id);
156-
const {FileGroupProcessor} = dlParams;
157-
const Title = dlParams.Title || options.Title;
158-
const dreq = makeTblRequest(FileGroupProcessor, Title, Object.assign(dlParams, {cutoutSize}, options));
159-
this.setState({mask: true});
160-
request = set(cloneDeep(request), DataTagMeta, dataTag);
161-
dispatchAddSaga(doOnPackage, {title: Title, callback:() => {
162-
this.setState({mask: false});
163-
showDownloadDialog(this, false);
164-
}});
165-
dispatchPackage(dreq, request, SelectInfo.newInstance(selectInfo).toString());
166-
}
167-
168142
render() {
169-
const {groupKey, cutoutSize, help_id, children, style, title} = this.props;
170-
const {mask, sendEmail} = this.state;
143+
const {groupKey, cutoutSize, help_id, children, style, title, tbl_id, dlParams, dataTag} = this.props;
144+
const {mask, email, enableEmail} = this.state;
171145
const labelWidth = 110;
172146
const ttl = title || DOWNLOAD_DIALOG_ID;
147+
148+
const onSubmit = (options) => {
149+
var {request, selectInfo} = getTblInfoById(tbl_id);
150+
const {FileGroupProcessor} = dlParams;
151+
const Title = dlParams.Title || options.Title;
152+
const dreq = makeTblRequest(FileGroupProcessor, Title, Object.assign(dlParams, {cutoutSize}, options));
153+
request = set(cloneDeep(request), DataTagMeta, dataTag);
154+
dispatchPackage(dreq, request, SelectInfo.newInstance(selectInfo).toString());
155+
showDownloadDialog(this, false);
156+
};
157+
158+
const toggleEnableEmail = (e) => {
159+
const enableEmail = e.target.checked;
160+
const email = enableEmail ? email : '';
161+
dispatchBgSetEmailInfo({email, enableEmail});
162+
};
163+
173164
return (
174165
<div style = {Object.assign({margin: '4px', position: 'relative', minWidth: 350}, style)}>
175166
{mask && <div style={{width: '100%', height: '100%'}} className='loading-mask'/>}
176167
<FormPanel
177168
submitText = 'Prepare Download'
178169
groupKey = {groupKey}
179-
onSubmit = {this.onSubmit}
170+
onSubmit = {onSubmit}
180171
onCancel = {() => dispatchHideDialog(ttl)}
181172
help_id = {help_id}>
182173
<FieldGroup groupKey={'DownloadDialog'} keepState={true}>
@@ -211,29 +202,20 @@ export class DownloadOptionPanel extends PureComponent {
211202
]}
212203
labelWidth = {labelWidth}
213204
/>
214-
<CheckboxGroupInputField
215-
wrapperStyle={{marginTop: 20}}
216-
fieldKey='sendEmail'
217-
initialState= {{label : ' '}}
218-
options={[
219-
{label: 'Also send me email with URLs to download', value: 'true'}
220-
]}
221-
labelWidth = {0}
205+
206+
<div style={{width: 235, marginTop: 10}}><input type='checkbox' checked={enableEmail} onChange={toggleEnableEmail}/>Enable email notification</div>
207+
{enableEmail &&
208+
<InputField
209+
validator={Validate.validateEmail.bind(null, 'an email field')}
210+
tooltip='Enter an email to be notified when a process completes.'
211+
label='Email:'
212+
labelStyle={{display: 'inline-block', marginLeft: 18, width: 32, fontWeight: 'bold'}}
213+
value={email}
214+
placeholder='Enter an email to get notification'
215+
size={27}
216+
onChange={this.onEmailChanged.bind(this)}
217+
actOn={['blur','enter']}
222218
/>
223-
{sendEmail &&
224-
<div>
225-
<ValidationField
226-
wrapperStyle={{marginTop: 5, marginLeft: 80}}
227-
initialState = {{
228-
value: '',
229-
validator: Validate.validateEmail.bind(null, 'Email'),
230-
label : 'Email:',
231-
tooltip: 'Enter or modify your email address',
232-
}}
233-
fieldKey = 'Email'
234-
size = {30}
235-
labelWidth = {30}/>
236-
</div>
237219
}
238220
</FieldGroup>
239221
</FormPanel>
@@ -275,7 +257,7 @@ DownloadOptionPanel.defaultProps= {
275257
* @param {boolean} [show=true] show or hide this dialog
276258
*/
277259
function showDownloadDialog(panel, show=true) {
278-
let ttl = panel.props.title || DOWNLOAD_DIALOG_ID;
260+
const ttl = panel.props.title || DOWNLOAD_DIALOG_ID;
279261
if (show) {
280262
const content= (
281263
<PopupPanel title={ttl} >

0 commit comments

Comments
 (0)