Skip to content

Commit 736b999

Browse files
authored
Merge pull request #139 from biothings/validation
Validation Feature
2 parents 51b638c + b314d92 commit 736b999

File tree

8 files changed

+1000
-486
lines changed

8 files changed

+1000
-486
lines changed

webapp/src/BaseDataSource.vue

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,22 @@
55
import axios from 'axios'
66
import bus from './bus.js'
77
8-
export default {
8+
export default {
99
name: 'base-data-source',
1010
// Note: we don't declare "source", it must be defined in subclass/mixed
1111
// (sometimes it's a prop, sometimes it's a data field
12-
created () {
12+
created() {
1313
bus.$on('change_source', this.onSourceChanged)
1414
},
15-
beforeDestroy () {
15+
beforeDestroy() {
1616
bus.$off('change_source', this.onSourceChanged)
1717
$('.ui.basic.unregister.modal').remove()
1818
},
19-
data () {
19+
data() {
2020
return {
2121
limit_error: null,
22-
sample_error: null
22+
sample_error: null,
23+
validations: {}
2324
}
2425
},
2526
computed: {
@@ -29,6 +30,9 @@ export default {
2930
upload_status: function () {
3031
return this.getStatus('upload')
3132
},
33+
validate_status: function () {
34+
return this.getStatus('validate')
35+
},
3236
download_status: function () {
3337
if (this.source.download && this.source.download.status) { return this.source.download.status } else { return 'unknown status' }
3438
},
@@ -52,6 +56,9 @@ export default {
5256
upload_error: function () {
5357
return this.getError('upload')
5458
},
59+
validate_error: function () {
60+
return this.getError('validate')
61+
},
5562
download_error: function () {
5663
if (this.source.download && this.source.download.error) { return this.source.download.error }
5764
},
@@ -74,7 +81,7 @@ export default {
7481
var status = 'unknown'
7582
if (this.source.hasOwnProperty(subkey)) {
7683
for (var subsrc in this.source[subkey].sources) {
77-
if (['failed', 'inspecting', 'uploading'].indexOf(this.source[subkey].sources[subsrc].status) != -1) {
84+
if (['failed', 'inspecting', 'uploading', 'validating'].indexOf(this.source[subkey].sources[subsrc].status) != -1) {
7885
status = this.source[subkey].sources[subsrc].status
7986
// precedence to these statuses
8087
break
@@ -97,6 +104,7 @@ export default {
97104
if (this.download_error) { errs.push('Dump') }
98105
if (this.upload_error.length) { errs.push('Upload') }
99106
if (this.inspect_error.length) { errs.push('Inspect') }
107+
if (this.validate_error.length) { errs.push('Validate') }
100108
return errs.join(' - ') + ' error'
101109
},
102110
dump: function (release = null, force = null) {
@@ -111,13 +119,16 @@ export default {
111119
console.log('Error getting job manager information: ' + err)
112120
})
113121
},
114-
upload: function (subsrc = null, release = null){
122+
upload: function (subsrc = null, release = null, validate = false) {
115123
var srcname = this.source.name
116124
if (subsrc != null) { srcname += '.' + subsrc } // upload a sub-source only
117125
let payload = {};
118126
if (release && release.trim() !== '') {
119127
payload.release = release;
120128
}
129+
if (validate) {
130+
payload.validate = true;
131+
}
121132
axios.put(axios.defaults.baseURL + `/source/${srcname}/upload`, payload)
122133
.then(response => {
123134
console.log(response.data.result)
@@ -126,6 +137,51 @@ export default {
126137
console.log('Error getting job manager information: ' + err)
127138
})
128139
},
140+
createValidation(subsrc = null) {
141+
var srcname = this.source.name
142+
if (subsrc != null) srcname += '.' + subsrc
143+
return axios.put(axios.defaults.baseURL + `/source/${srcname}/create_validation`)
144+
.then(response => {
145+
// Step 1: The create request finished
146+
// Step 2: Now fetch the updated validations
147+
return this.getValidations(subsrc)
148+
})
149+
.catch(err => {
150+
console.error('Error creating validation:', err)
151+
throw err
152+
})
153+
},
154+
validate: function (subsrc = null, model_file = null) {
155+
var srcname = this.source.name
156+
if (subsrc != null) { srcname += '.' + subsrc } // validate a sub-source only
157+
let payload = {};
158+
if (model_file && model_file.trim() !== '') {
159+
payload.model_file = model_file;
160+
}
161+
axios.post(axios.defaults.baseURL + `/source/${srcname}/validate`, payload)
162+
.then(response => {
163+
// console.log(response.data.result)
164+
})
165+
.catch(err => {
166+
console.log('Error getting job manager information: ' + err)
167+
})
168+
},
169+
getValidations: function (subsrc = null) {
170+
var srcname = this.source.name
171+
if (subsrc != null) {
172+
srcname += '.' + subsrc
173+
}
174+
return axios.get(axios.defaults.baseURL + `/source/${srcname}/validations`)
175+
.then(response => {
176+
this.$set(this.validations, subsrc, response.data.result)
177+
// console.log(response.data.result)
178+
return response.data.result
179+
})
180+
.catch(err => {
181+
console.log('Error getting validations information:', err)
182+
throw err
183+
})
184+
},
129185
unregister: function () {
130186
$(`.${this.source.name}.ui.basic.unregister.modal`)
131187
.modal('setting', {
@@ -147,8 +203,8 @@ export default {
147203
inspect: function () {
148204
bus.$emit('do_inspect', ['src', this.source._id])
149205
},
150-
mark_dump_success (dry_run=false, dry_run_callback) {
151-
axios.put(axios.defaults.baseURL + `/source/${this.source.name}/mark_dump_success`, {dry_run: dry_run})
206+
mark_dump_success(dry_run = false, dry_run_callback) {
207+
axios.put(axios.defaults.baseURL + `/source/${this.source.name}/mark_dump_success`, { dry_run: dry_run })
152208
.then(response => {
153209
if (dry_run && dry_run_callback) {
154210
dry_run_callback(response.data.result)
@@ -159,7 +215,7 @@ export default {
159215
console.log('Error getting job manager information: ' + err)
160216
})
161217
},
162-
onSourceChanged (_id = null, op = null) {
218+
onSourceChanged(_id = null, op = null) {
163219
// this method acts as a dispatcher, reacting to change_source events, filtering
164220
// them for the proper source
165221
// _id null: event containing change about a source but we don't know which one

webapp/src/DataInspection.vue

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<div class="ui tab" :data-tab="source_name + '-type-stats'">
44
<p>
5-
This is the field type and stats for <b>{{page_type}}</b>.
5+
This is the field type and stats for <b>{{ page_type }}</b>.
66
</p>
77
<p>
88
It provides a summary of the data structure,
@@ -34,12 +34,8 @@
3434
<tbody>
3535
<tr v-for="row in inspection_data">
3636
<td>
37-
<div v-if="hasInspectionFieldValidationWarnings(row)"
38-
class="tooltip"
39-
data-position="top left"
40-
data-variation="very wide"
41-
:data-html="formatInspectionValidationTooltipMessage(row.warnings)"
42-
>
37+
<div v-if="hasInspectionFieldValidationWarnings(row)" class="tooltip" data-position="top left"
38+
data-variation="very wide" :data-html="formatInspectionValidationTooltipMessage(row.warnings)">
4339
<span class="ui text warning">{{ row.field_name }} <i class="exclamation circle icon"></i></span>
4440
</div>
4541
<div v-else>{{ row.field_name }}</div>
@@ -76,10 +72,10 @@ export default {
7672
'source_name',
7773
'source_data',
7874
],
79-
mounted () {
75+
mounted() {
8076
this.fetch_flatten_inspection_data()
8177
},
82-
data () {
78+
data() {
8379
return {
8480
inspection_data: [],
8581
}
@@ -103,29 +99,29 @@ export default {
10399
}
104100
105101
axios.put(axios.defaults.baseURL + '/flatten_inspection_data', data)
106-
.then(response => {
107-
console.log(response.data.result)
108-
if (response.data.result?.[self.source_name]) {
109-
const inspection_data_by_modes = response.data.result[self.source_name]
110-
self.inspection_data = inspection_data_by_modes.type || []
111-
if (Object.keys(inspection_data_by_modes.stats).length > 1) {
112-
self.inspection_data = inspection_data_by_modes.stats
102+
.then(response => {
103+
// console.log(response.data.result)
104+
if (response.data.result?.[self.source_name]) {
105+
const inspection_data_by_modes = response.data.result[self.source_name]
106+
self.inspection_data = inspection_data_by_modes.type || []
107+
if (Object.keys(inspection_data_by_modes.stats).length > 1) {
108+
self.inspection_data = inspection_data_by_modes.stats
109+
}
113110
}
114-
}
115-
else {
116-
self.inspection_data = []
117-
}
118-
setTimeout(() => {$('.tooltip').popup()}, 0)
119-
})
120-
.catch(err => {
121-
console.log('Error fetching flatten inspection data: ' + err)
122-
})
111+
else {
112+
self.inspection_data = []
113+
}
114+
setTimeout(() => { $('.tooltip').popup() }, 0)
115+
})
116+
.catch(err => {
117+
console.log('Error fetching flatten inspection data: ' + err)
118+
})
123119
},
124120
hasInspectionFieldValidationWarnings: function (field_inspection) {
125121
return field_inspection.warnings.length > 0
126122
},
127123
hasInspectionValidationWarnings: function (inspection_data) {
128-
for (const field_inspection of inspection_data) {
124+
for (const field_inspection of inspection_data) {
129125
if (this.hasInspectionFieldValidationWarnings(field_inspection)) {
130126
return true
131127
}
@@ -151,7 +147,7 @@ export default {
151147
.sortable .row {
152148
padding-top: 0.2rem;
153149
padding-bottom: 0.2rem;
154-
border: 1px solid rgba(34,36,38,.1);
150+
border: 1px solid rgba(34, 36, 38, .1);
155151
}
156152
157153
.sortable .column {

0 commit comments

Comments
 (0)