Skip to content
Snippets Groups Projects
Commit 065cf3ca authored by moon's avatar moon
Browse files

#41: Implemented DataTable interface for UpdateItems

parent 3e87eecf
No related branches found
No related tags found
No related merge requests found
......@@ -34,8 +34,19 @@ export default {
}
// console.log(vm.isExperimental)
const qs = require('qs');
const query = qs.stringify({
sort: ['id:asc'],
populate: ['submittedBy', 'reviewedBy'],
pagination: {
pageSize: 1000,
page: 1,
},
}, {
encodeValuesOnly: true,
});
let url = `${host}/api/update-items`;
let url = `${host}/api/update-items?${query}`;
const jwt = vm.jwt;
if(jwt === null) {
......
<template>
<div class="flex items-center justify-center panel w-full md:w-auto">
<table :id=id class="table table-striped table-bordered table-hover"></table>
</div>
</template>
<script>
const _ = require('lodash');
const $ = window.jQuery = require('jquery');
require('@/components/js/datatable');
let table;
export default {
name: 'update-item-table',
props: ['id', 'data'],
data() {
return {
};
},
methods: {
editUpdateItem(id) {
// eslint-disable-next-line
this.$router.push('/updateitem/' + id)
},
createTable(id, data) {
const vm = this;
_.forEach(data, (d) => {
d.DT_RowID = `${d.id}`;
});
const columns = [
{
title: 'ID',
data: 'id',
fnCreatedCell: (nTd, sData, oData) => {
$(nTd).html(`<a href="" class="edit-link"> ${sData}</a>`);
},
},
{
title: 'Resource Name',
data: 'attributes.ResourceName',
},
{
title: 'Resource ID',
data: 'attributes.ResourceID',
},
{
title: 'Attribute',
data: 'attributes.DataAttribute',
},
{
title: 'Value',
data: 'attributes.DataAttributeValue',
},
{
title: 'Change Operation',
data: 'attributes.ChangeOperation',
},
{
title: 'Review Operation',
data: 'attributes.ReviewOperation',
},
{
title: 'Submitted at',
data: 'attributes.SubmittedAt',
render: function ( data, type, row, meta ) {
return new Date(Date.parse(data)).toLocaleString();
},
},
{
title: 'Submitted by',
data: 'attributes.submittedBy',
render: function ( data, type, row, meta ) {
if(data.data) {
return data.data.attributes.username
} else {
return '';
}
},
},
{
title: 'Reviewer',
data: 'attributes.reviewedBy',
render: function ( data, type, row, meta ) {
if(data.data) {
return data.data.attributes.username
} else {
return '';
}
},
}];
const nTableOptions = {
columns,
// aaSorting: [[ 0, 'asc' ]],
lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
paging: true,
searching: true,
info: false,
data,
order: [], // order: [[0, 'asc']],
bDestroy: true, // Add this property to new setting,
oLanguage: {
sSearch: "Filter",
},
dom: '<"row"<"col-sm-2"l><"col-sm-2"f><"col-sm-8"p>><"row"t><"row"<"col-sm-4"i><"col-sm-8"p>>'
};
const tableId = `#${id}`;
if (table) {
table.destroy();
$(tableId).empty();
}
table = $(tableId).DataTable(nTableOptions);
const tableBody = `${tableId} tbody`;
$(tableBody).on('click', 'tr td a.edit-link', (e) => {
e.preventDefault()
const tr = $(e.target).parent().parent();
const row = table.row(tr);
vm.editUpdateItem(row.data().id);
});
},
exportTsv() {
// const vm = this;
},
},
mounted() {
const vm = this;
vm.createTable(vm.id, vm.data);
},
};
</script>
<style scoped>
@import url('~@/assets/datatable.css');
select.form-control {
font-size: 12px;
padding: 3px 12px;
}
ul.pagination {
font-size: 1rem;
}
.form-inline .form-control {
height: 25px;
line-height: 25px;
vertical-align: middle;
}
.edit-link {
font-weight: bold;
color: #0065b9;
}
.uniprot-link {
font-weight: bold;
color: #0065b9;
}
.pubmed-link {
font-weight: bold;
color: #0065b9;
}
.external-link {
font-weight: bold;
color: #0065b9;
}
.pagination {
font-size: 1.2rem;
}
</style>
......@@ -96,6 +96,11 @@ export default new Router({
name: 'resetPassword',
component: () => import('@/views/ResetPassword'),
},
{
path: '/updateitem/:item',
name: 'updateItem',
component: () => import('@/views/UpdateItem'),
},
// { path: '/user/:id', component: User },
// {
// path: '*',
......
......@@ -3,6 +3,7 @@ const namespaced = true
const state = {
jwt: null,
userData: null,
userRole: null,
}
const mutations = {
......@@ -12,15 +13,20 @@ const mutations = {
SET_USER_DATA (state, userData) {
state.userData = userData
},
SET_USER_ROLE (state, userRole) {
state.userRole = userRole
},
LOG_OUT (state) {
state.jwt = null
state.userData = null
state.userRole = null
},
}
const getters = {
jwt: state => state.jwt,
userData: state => state.userData,
userRole: state => state.userRole,
}
const actions = {
......@@ -30,6 +36,9 @@ const actions = {
setUserData ({ commit }, userData) {
commit('SET_USER_DATA', userData)
},
setUserRole ({ commit }, userRole) {
commit('SET_USER_ROLE', userRole)
},
logOut ({ commit }) {
commit('LOG_OUT')
},
......
......@@ -60,7 +60,7 @@ export default {
});
const { jwt, user } = res.data
// console.log(user.email)
// console.log(user)
window.localStorage.setItem('jwt', jwt)
window.localStorage.setItem('userData', JSON.stringify(user))
......
......@@ -26,7 +26,7 @@
<div class="row">
<div class="text col-sm-3">Role</div>
<div class="col-sm-9">
{{response.role.name}}
{{$store.dispatch('User/setUserRole', response.role.name) && response.role.name}}
</div>
</div>
<div class="row">
......@@ -58,21 +58,23 @@
</div>
</div>
<h4 class="round">Update Items</h4>
<div class="panel panel-default">
Table
</div>
<button class="btn btn-primary" @click="$router.push('/updateitem/new')">
Create new Update Item
</button>
</div>
</slot>
</template>
</fetch-profile>
<h4 class="round">Update Items</h4>
<fetch-update-items v-if="userData !== null">
<template slot-scope="{response, loading}">
<slot :response="response" :loading="loading">
<div v-if="loading || response === null"></div>
<div v-else>
{{response}}
<update-item-table id="update-item-table" :data="response.data">
</update-item-table>
</div>
</slot>
</template>
......@@ -83,13 +85,14 @@
<script>
import FetchProfile from "@/components/CMS/fetchProfile";
import FetchUpdateItems from "@/components/CMS/fetchUpdateItems";
import UpdateItemTable from "@/components/UpdateItemTable";
const _ = require('lodash')
export default {
name: 'ProfilePage',
components: {
FetchProfile, FetchUpdateItems
FetchProfile, FetchUpdateItems, UpdateItemTable
},
props: {
msg: String
......
<template>
<div>
<div class="flex items-center justify-center">
<div class="md:flex card p-2 mt-5">
<div class="p-5 mx-auto text-left font-raleway">
<h1 class="card-header font-bold text-left font-montserrat text-3xl sm:text-5xl mb-7">
{{ item === 'new'? 'Create new Update Item' : item }}
</h1>
<p v-show="error" class="text-lg text-red-500">{{ errorMsg }}</p>
<form @submit="update" class="w-full max-w-lg">
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-entity-type">
Entity Type
</label>
</div>
<div class="md:w-2/3">
<select v-model="entity" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-entity-type" >
<option disabled value="">Please select one</option>
<option>Protein</option>
<option>Condensate</option>
<option>Condensate_Protein</option>
</select>
</div>
</div>
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-entity-id">
Entity ID
</label>
</div>
<div class="md:w-2/3">
<input v-model="entityId" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-entity-id" type="text" placeholder="UNE6">
</div>
</div>
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-change-operation">
Change Operation
</label>
</div>
<div class="md:w-2/3">
<select v-model="changeOperation" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-change-operation" >
<option disabled value="">Please select one</option>
<option>Add</option>
<option>Remove</option>
<option>Update_Add</option>
<option>Update_Remove</option>
</select>
</div>
</div>
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-attribute-name">
Attribute Name
</label>
</div>
<div class="md:w-2/3">
<input v-model="attribute" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-attribute-name" type="text" placeholder="functional_type">
</div>
</div>
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-attribute-value">
Attribute Value
</label>
</div>
<div class="md:w-2/3">
<input v-model="attributeValue" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-attribute-value" type="text" placeholder="driver">
</div>
</div>
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-status">
Status
</label>
</div>
<div class="md:w-2/3">
<select v-model="status" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-status" >
<option disabled value="">Please select one</option>
<option>Requested</option>
<option>Accepted</option>
<option>Rejected</option>
<option>Partially_Accepted</option>
<option>Synced</option>
</select>
</div>
</div>
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-comment">
Comment
</label>
</div>
<div class="md:w-2/3">
<input v-model="comment" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-comment" type="text" placeholder="your comments here">
</div>
</div>
<div class="md:flex md:items-center -mx-3 mb-6">
<div class="md:w-1/3">
<label class="text-left font-bold md:text-right mb-1 md:mb-0 pr-4" for="inline-reviewer-comment">
Reviewer Comment
</label>
</div>
<div class="md:w-2/3">
<input v-if="userRole === 'Maintainer' || userRole === 'Administrator'" v-model="reviewComment" class="bg-white w-full py-2 text-gray-700 outline-none bg-transparent border-b hover:border-blue-700 focus:bg-gray-200 focus:border-blue-700" id="inline-reviewer-comment" type="text" placeholder="reviewer comments here">
<p v-if="userRole === 'Contributor' && itemId !== 'new'">
{{reviewComment}}
</p>
</div>
</div>
<button type="submit" :disabled="entityId.length < 3" class="bg-green-400 p-5 text-white">
{{ item === 'new'? 'Submit' : 'Update' }} <span class="fa fa-arrow-right"/>
</button>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'UpdateItem',
props: ['itemId'],
data() {
return {
item: this.$route.params.item ? this.$route.params.item : this.itemId,
entity: 'Protein', // [protein, condensate, condensate_protein]
entityId: '', // protein: <uniprot_id>, condensate: <canonical_id>, condensate_protein: <uniprot_id>==<canonical_id>
changeOperation: 'Add', // add/remove/update/update_add/update_remove
attribute: '', // protein: functional_type[driver/client/regulator], pubmed_ids[]
// condensate: description, proteins
// condensate_protein: confidence_score, pubmed_ids
attributeValue: '', // the value of the attribute to be updated. Could be "null" for add/remove operations. The data type is dynamic
status: 'Requested', // 1. Requested, 2. Accepted, 3. Rejected, 4. Patially_Accepted, 5. Synced
submittedBy: '',
submittedAt: '', // datetime
submissionComment: '',
reviewedBy: '',
reviewedAt: '', // datetime
reviewComment: '',
syncedAt: '', // datetime
syncResponse: '', // response from the sync process (errors if any)
comment: '', // user comment
error: false,
errorMsg: `An error occurred, please try again`
}
},
computed: {
jwt: function () {
return this.$store.getters['User/jwt']
},
userData: function () {
return this.$store.getters['User/userData']
},
userRole: function () {
return this.$store.getters['User/userRole']
},
},
methods: {
async update(e) {
const vm = this;
e.preventDefault()
const jwt = vm.jwt;
if(jwt === null) {
vm.loading = false;
vm.response = null;
return
}
// console.log(vm.userData)
let dat = {
ResourceName: this.entity,
ResourceID: this.entityId,
DataAttribute: this.attribute,
DataAttributeValue: this.attributeValue,
ChangeOperation: this.changeOperation,
UserComment: this.comment,
ReviewComment: this.reviewComment,
// ReviewedBy:
// ReviewedAt:
// ReviewComment:
// SyncedAt:
// SyncResponse:
};
try {
if(vm.item !== 'new') {
const res = await this.axios.put(`http://localhost:1337/api/update-items/` + vm.item, {
data: dat,
}, {
headers: {
Authorization: `Bearer ${jwt}`
}
});
} else {
const res = await this.axios.post(`http://localhost:1337/api/update-items`, {
data: dat,
}, {
headers: {
Authorization: `Bearer ${jwt}`
}
});
}
// console.log(res)
this.$router.push('/profile')
} catch(error) {
// console.log(error.response.data.error.message)
console.log(error.response)
this.error = true
this.errorMsg = error
}
},
async load(id) {
const vm = this;
const jwt = vm.jwt;
if(jwt === null) {
vm.loading = false;
vm.response = null;
return
}
// console.log(vm.userData)
try {
const res = await this.axios.get(`http://localhost:1337/api/update-items/` + id, {
headers: {
Authorization: `Bearer ${jwt}`
}
});
// console.log(res)
if(res.data.data) {
const d = res.data.data.attributes;
vm.item = res.data.data.id;
vm.entity = d.ResourceName;
vm.entityId = d.ResourceID;
vm.attribute = d.DataAttribute;
vm.attributeValue = d.DataAttributeValue;
vm.changeOperation = d.ChangeOperation;
vm.comment = d.UserComment;
vm.reviewComment = d.reviewComment;
// ReviewedBy:
// ReviewedAt:
// ReviewComment:
// SyncedAt:
// SyncResponse:
}
} catch(error) {
console.log(error)
this.error = true
this.errorMsg = error
}
}
},
mounted: function () {
const vm = this
vm.load(vm.item)
}
}
</script>
<style>
@import url('~@/assets/bootstrap.css');
a {
color: #42b983;
}
</style>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment