Skip to content

Commit f3e50e3

Browse files
committed
OPSMN-7008: Added "repeat job" button on the import jobs list view/page to repeat the import job.
Users are navigated to the import page with all the details filled using the selected job. Users are required only to upload the CSV file.
1 parent 35a3603 commit f3e50e3

File tree

9 files changed

+120
-38
lines changed

9 files changed

+120
-38
lines changed

WEB-INF/src/com/krishagni/catissueplus/core/importer/events/ImportJobDetail.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.Date;
55
import java.util.List;
66
import java.util.Map;
7+
import java.util.stream.Collectors;
78

89
import com.krishagni.catissueplus.core.common.events.UserSummary;
910
import com.krishagni.catissueplus.core.importer.domain.ImportJob;
@@ -31,6 +32,12 @@ public class ImportJobDetail {
3132

3233
private String displayName;
3334

35+
private String dateFormat;
36+
37+
private String timeFormat;
38+
39+
private String fieldSeparator;
40+
3441
public Long getId() {
3542
return id;
3643
}
@@ -119,6 +126,30 @@ public void setDisplayName(String displayName) {
119126
this.displayName = displayName;
120127
}
121128

129+
public String getDateFormat() {
130+
return dateFormat;
131+
}
132+
133+
public void setDateFormat(String dateFormat) {
134+
this.dateFormat = dateFormat;
135+
}
136+
137+
public String getTimeFormat() {
138+
return timeFormat;
139+
}
140+
141+
public void setTimeFormat(String timeFormat) {
142+
this.timeFormat = timeFormat;
143+
}
144+
145+
public String getFieldSeparator() {
146+
return fieldSeparator;
147+
}
148+
149+
public void setFieldSeparator(String fieldSeparator) {
150+
this.fieldSeparator = fieldSeparator;
151+
}
152+
122153
public static ImportJobDetail from(ImportJob job) {
123154
ImportJobDetail detail = new ImportJobDetail();
124155
detail.setId(job.getId());
@@ -132,16 +163,14 @@ public static ImportJobDetail from(ImportJob job) {
132163
detail.setFailedRecords(job.getFailedRecords());
133164
detail.setParams(job.getParams());
134165
detail.setDisplayName(job.getDisplayName());
166+
detail.setDateFormat(job.getDateFormat());
167+
detail.setTimeFormat(job.getTimeFormat());
168+
detail.setFieldSeparator(job.getFieldSeparator());
135169
return detail;
136170
}
137171

138172
public static List<ImportJobDetail> from(List<ImportJob> jobs) {
139-
List<ImportJobDetail> result = new ArrayList<ImportJobDetail>();
140-
for (ImportJob job : jobs) {
141-
result.add(ImportJobDetail.from(job));
142-
}
143-
144-
return result;
173+
return jobs.stream().map(ImportJobDetail::from).collect(Collectors.toList());
145174
}
146175

147176
public static ImportJobDetail txnSizeExceeded(int inputRecordsCnt) {

ui/src/biospecimen/participants/ImportJobsList.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<os-page-body>
1212
<os-grid>
1313
<os-grid-column :width="12">
14-
<os-import-jobs :object-types="objectTypes" :object-params="objectParams" />
14+
<os-import-jobs :object-types="objectTypes" :object-params="objectParams"
15+
:create-job="createJobRoute" />
1516
</os-grid-column>
1617
</os-grid>
1718
</os-page-body>
@@ -68,6 +69,11 @@ export default {
6869
6970
objectParams: function() {
7071
return {cpId: +this.cpId > 0 ? +this.cpId : -1};
72+
},
73+
74+
createJobRoute: function() {
75+
const name = +this.cpId > 0 ? 'CpImportRecords' : 'MultiCpImportRecords';
76+
return {name, params: {cpId: this.cpId}};
7177
}
7278
}
7379
}

ui/src/biospecimen/participants/ImportRecords.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
<os-grid-column :width="12">
1414
<os-import-records ref="impRecsForm" :object-type="objectType" :object-params="objectParams"
1515
:hide-ops="hideOps" :show-upsert="showUpsert" :csv-type="csvType" :record-types="getRecordTypes"
16-
:field-separator="fieldSeparator" @record-type-selected="onRecordTypeSelection">
16+
:field-separator="fieldSeparator" :repeat-job-id="repeatJobId"
17+
@record-type-selected="onRecordTypeSelection">
1718
<os-button primary :label="$t('import.validate_n_import')" @click="submitJob" />
1819

1920
<os-button text :label="$t('common.buttons.cancel')" @click="cancel" />
@@ -35,7 +36,7 @@ import util from '@/common/services/Util.js';
3536
import CpViewContext from './CpViewContext.js';
3637
3738
export default {
38-
props: ['cpId'],
39+
props: ['cpId', 'repeatJobId'],
3940
4041
inject: ['cpViewCtx'],
4142

ui/src/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,7 @@
12991299
"UPSERT": "Upsert"
13001300
},
13011301
"record_type_req": "Record Type is mandatory",
1302+
"repeat_job": "Repeat Job",
13021303
"update": "Update",
13031304
"upsert": "Upsert",
13041305
"view_past_imports": "View Past Imports",

ui/src/importer/components/CreateJob.vue

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import addJobSchema from '../schemas/create-job.js';
2929
import alertsSvc from '@/common/services/Alerts.js';
3030
import http from '@/common/services/HttpClient.js';
3131
import jobSvc from '@/importer/services/ImportJob.js';
32+
import routerSvc from '@/common/services/Router.js';
3233
import settingsSvc from '@/common/services/Setting.js';
3334
import util from '@/common/services/Util.js';
3435
@@ -65,7 +66,28 @@ export default {
6566
},
6667
6768
async created() {
68-
this._setupRecordTypes();
69+
await this._setupRecordTypes();
70+
71+
const route = routerSvc.getCurrentRoute();
72+
if (route.query && +route.query.repeatJobId > 0) {
73+
const dbJob = this.ctx.dbJob = await jobSvc.getJob(route.query.repeatJobId);
74+
const {job} = this.ctx;
75+
if (dbJob.name != 'extensions' && dbJob.name != 'userExtensions') {
76+
job.recordType = this.ctx.recordTypes.find(rt => rt.id == dbJob.name);
77+
} else if (dbJob.name == 'extensions') {
78+
const {entityType, cpId, formName} = dbJob.params || {};
79+
job.recordType = this.ctx.recordTypes.find(rt => rt.type == 'extensions' && rt.params.entityType == entityType && rt.params.cpId == cpId && rt.params.formName == formName);
80+
} else if (dbJob.name == 'userExtensions') {
81+
const {entityType, entityId, formName} = dbJob.params || {};
82+
job.recordType = this.ctx.recordTypes.find(rt => rt.type == 'userExtensions' && rt.params.entityType == entityType && rt.params.entityId == entityId && rt.params.formName == formName);
83+
}
84+
85+
job.importType = dbJob.type;
86+
job.dateFormat = dbJob.dateFormat;
87+
job.timeFormat = dbJob.timeFormat;
88+
job.fieldSeparator = dbJob.fieldSeparator;
89+
this.$emit('record-type-selected', job.recordType);
90+
}
6991
},
7092
7193
computed: {

ui/src/importer/components/JobsList.vue

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
v-os-tooltip.bottom="$t('import.download_status')" v-if="job.status != 'QUEUED'" />
1414
<os-button size="small" left-icon="ban" @click="stopJob(job)"
1515
v-os-tooltip.bottom="$t('import.stop_job')" v-if="job.status == 'QUEUED' || job.status == 'IN_PROGRESS'" />
16+
<os-button size="small" left-icon="redo" @click="repeatJob(job)"
17+
v-os-tooltip.bottom="$t('import.repeat_job')"
18+
v-if="createJob && job.status != 'QUEUED' && job.status != 'IN_PROGRESS'" />
1619
</os-button-group>
1720
</template>
1821

@@ -38,11 +41,12 @@ import listSchema from '@/importer/schemas/jobs-list.js';
3841
3942
import alertsSvc from '@/common/services/Alerts.js';
4043
import importSvc from '@/importer/services/ImportJob.js';
44+
import routerSvc from '@/common/services/Router.js';
4145
4246
const MAX_JOBS = 25;
4347
4448
export default {
45-
props: ['objectTypes', 'objectParams'],
49+
props: ['objectTypes', 'objectParams', 'createJob'],
4650
4751
data() {
4852
return {
@@ -116,6 +120,13 @@ export default {
116120
} else {
117121
alertsSvc.info({code: 'import.job_stop_in_progress', args: job});
118122
}
123+
},
124+
125+
repeatJob: function(job) {
126+
const {name, params, query} = (typeof this.createJob == 'function' ? this.createJob(job) : this.createJob) || {};
127+
if (name) {
128+
routerSvc.goto(name, params, {...(query || {}), repeatJobId: job.id});
129+
}
119130
}
120131
}
121132
}

ui/src/importer/services/ImportJob.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ class ImportJob {
66
return http.get('import-jobs', crit);
77
}
88

9+
getJob(jobId) {
10+
return http.get('import-jobs/' + jobId);
11+
}
12+
913
getJobDescription(job) {
1014
return '#' + job.id + ' ' + i18n.msg('import.ops.' + job.type) + ' ' + i18n.msg('import.object_types.' + job.name, job.params);
1115
}

ui/src/importer/views/JobsList.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<os-page-body>
1212
<os-grid>
1313
<os-grid-column :width="12">
14-
<os-import-jobs :object-types="objectTypes" :object-params="objectParams" />
14+
<os-import-jobs :object-types="objectTypes" :object-params="objectParams" :create-job="createJob" />
1515
</os-grid-column>
1616
</os-grid>
1717
</os-page-body>
@@ -20,7 +20,7 @@
2020

2121
<script>
2222
export default {
23-
props: ['bcrumb', 'title', 'object-types', 'object-params']
23+
props: ['bcrumb', 'title', 'object-types', 'object-params', 'create-job']
2424
}
2525
</script>
2626

0 commit comments

Comments
 (0)