diff --git a/.eslintrc.js b/.eslintrc.js
index 130e66a..6984915 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -30,6 +30,11 @@ module.exports = {
"semi": [
"error",
"never"
+ ],
+ "key-spacing": [
+ "error", {
+ "beforeColon": false
+ }
]
}
}
diff --git a/oidc_mock/config/clients.json b/oidc_mock/config/clients.json
index cccb0f4..cc7832d 100644
--- a/oidc_mock/config/clients.json
+++ b/oidc_mock/config/clients.json
@@ -7,7 +7,7 @@
"AllowAccessTokensViaBrowser": true,
"RedirectUris": ["http://localhost:8080/logged-in"],
"AllowedScopes": ["openid", "profile", "email", "permissions"],
- "IdentityTokenLifetime": 3600,
+ "IdentityTokenLifetime": 36000,
"AccessTokenLifetime": 3600,
"ClientClaimsPrefix": ""
}
diff --git a/src/assets/scss/bbmri.scss b/src/assets/scss/bbmri.scss
index bcf15a3..b00362d 100644
--- a/src/assets/scss/bbmri.scss
+++ b/src/assets/scss/bbmri.scss
@@ -15,4 +15,8 @@ $default-text-color: white;
.btn-primary {
color: white;
+}
+
+.cursor-pointer {
+ cursor: pointer;
}
\ No newline at end of file
diff --git a/src/components/NegotiationForm.vue b/src/components/NegotiationForm.vue
index 8b3f524..49262ec 100644
--- a/src/components/NegotiationForm.vue
+++ b/src/components/NegotiationForm.vue
@@ -38,7 +38,7 @@
v-for="section in accessCriteria.sections"
:key="section.name"
:title="section.label"
- class="form-step border rounded px-2 py-3 mb-2"
+ class="form-step border rounded-2 px-2 py-3 mb-2"
>
+
- {{ section.label }}
+ {{ section.label.toUpperCase() }}
- {{ negotiationCriteria[section.name][criteria.name] }}
+
+ {{ negotiationCriteria[section.name][criteria.name].name }}
+
+
+ {{ negotiationCriteria[section.name][criteria.name] }}
+
@@ -170,7 +183,7 @@ export default {
await this.createNegotiation({
data: {
requests: [this.requestId],
- payload: this.negotiationCriteria
+ payload: this.negotiationCriteria,
}
}).then((negotiationId) => {
if (negotiationId) {
@@ -180,6 +193,12 @@ export default {
}
})
},
+ isAttachment(value) {
+ return value instanceof File || value instanceof Object
+ },
+ handleFileUpload(event, section, criteria) {
+ this.negotiationCriteria[section][criteria] = event.target.files[0]
+ },
showNotification(variant, header, body) {
this.notificationVariant = variant
this.notificationHeader = header
diff --git a/src/config/consts.js b/src/config/consts.js
index 0aa83c8..907cc9a 100644
--- a/src/config/consts.js
+++ b/src/config/consts.js
@@ -12,4 +12,4 @@ const MESSAGE_STATUS = {
}
-export { dateFormat, ROLES, MESSAGE_STATUS }
\ No newline at end of file
+export { MESSAGE_STATUS, ROLES, dateFormat }
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index e93ec6d..e297429 100644
--- a/src/main.js
+++ b/src/main.js
@@ -4,7 +4,7 @@ import router from "./router"
import store from "./store"
import { sync } from "vuex-router-sync"
import { library } from "@fortawesome/fontawesome-svg-core"
-import { faPencil, faSpinner, faTrash } from "@fortawesome/free-solid-svg-icons"
+import { faDownload, faPencil, faSpinner, faTrash } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"
import "bootstrap/dist/css/bootstrap.css"
import "bootstrap-vue-next/dist/bootstrap-vue-next.css"
@@ -13,6 +13,7 @@ import "bootstrap"
library.add(faSpinner)
library.add(faPencil)
library.add(faTrash)
+library.add(faDownload)
const app = createApp(App)
diff --git a/src/store/actions.js b/src/store/actions.js
index 7a36b62..d694a16 100644
--- a/src/store/actions.js
+++ b/src/store/actions.js
@@ -1,11 +1,12 @@
-import axios from "axios"
import { ROLES } from "@/config/consts"
+import axios from "axios"
let BASE_API_PATH = "/api/v3"
const ACCESS_CRITERIA_PATH = `${BASE_API_PATH}/access-criteria/`
const REQUESTS_PATH = `${BASE_API_PATH}/requests`
const NEGOTIATION_PATH = `${BASE_API_PATH}/negotiations`
const USER_PATH = `${BASE_API_PATH}/users/roles`
+const ATTACHMENTS_PATH = `${BASE_API_PATH}/attachments`
function getBearerHeaders(token) {
return {
@@ -34,7 +35,7 @@ export default {
})
},
retrieveAccessCriteriaByResourceId({ state, commit }, { resourceId }) {
- return axios.get(`${ACCESS_CRITERIA_PATH}`, {headers : getBearerHeaders(state.oidc.access_token), params : {resourceId : resourceId}})
+ return axios.get(`${ACCESS_CRITERIA_PATH}`, {headers: getBearerHeaders(state.oidc.access_token), params: {resourceId: resourceId}})
.then((response) => {
return response.data
})
@@ -44,17 +45,41 @@ export default {
})
},
- createNegotiation({ state }, { data }) {
- return axios.post(NEGOTIATION_PATH, data, {headers : getBearerHeaders(state.oidc.access_token)})
+ async createNegotiation({ state, commit }, { data }) {
+ data.attachments = []
+ for (const [sectionName, criteriaList] of Object.entries(data.payload)) {
+ for (const [criteriaName, criteriaValue] of Object.entries(criteriaList)) {
+ if (criteriaValue instanceof File) {
+ const formData = new FormData()
+ formData.append("file", criteriaValue)
+ const uploadFileHeaders = { headers: getBearerHeaders(state.oidc.access_token) }
+
+ uploadFileHeaders["Content-type"] = "multipart/form-data"
+
+ const attachmentsIds = await axios.post("/api/v3/attachments", formData, uploadFileHeaders)
+ .then((response) => {
+ return response.data
+ })
+ .catch(() => {
+ commit("setNotification", "There was an error saving the attachment")
+ return null
+ })
+ data.payload[sectionName][criteriaName] = attachmentsIds
+ data.attachments.push(attachmentsIds)
+ }
+ }
+ }
+ return axios.post(NEGOTIATION_PATH, data, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data.id
})
.catch(() => {
- return null
+ commit("setNotification", "There was an error saving the Negotiation")
})
+
},
retrieveNegotiationsByRole({ state, commit }, { userRole }) {
- return axios.get(`${NEGOTIATION_PATH}`, {headers : getBearerHeaders(state.oidc.access_token), params : {userRole : userRole}})
+ return axios.get(`${NEGOTIATION_PATH}`, {headers: getBearerHeaders(state.oidc.access_token), params: {userRole: userRole}})
.then((response) => {
return response.data
})
@@ -64,7 +89,7 @@ export default {
})
},
updateNegotiationStatus({ state, commit }, { negotiationId , event }) {
- return axios.put(`${NEGOTIATION_PATH}/${negotiationId}/lifecycle/${event}`, {}, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.put(`${NEGOTIATION_PATH}/${negotiationId}/lifecycle/${event}`, {}, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
commit("setNotification", `Negotiation updated correctly with data ${response.data.id}`)
return response.data
@@ -75,7 +100,7 @@ export default {
})
},
retrievePossibleEvents({ state, commit }, { negotiationId }) {
- return axios.get(`${NEGOTIATION_PATH}/${negotiationId}/lifecycle`, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.get(`${NEGOTIATION_PATH}/${negotiationId}/lifecycle`, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data
})
@@ -84,7 +109,7 @@ export default {
})
},
retrievePossibleEventsForResource({ state, commit }, { negotiationId, resourceId }) {
- return axios.get(`${NEGOTIATION_PATH}/${negotiationId}/resources/${resourceId}/lifecycle`, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.get(`${NEGOTIATION_PATH}/${negotiationId}/resources/${resourceId}/lifecycle`, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data
})
@@ -93,7 +118,7 @@ export default {
})
},
updateResourceStatus({ state, commit }, { negotiationId , resourceId, event }) {
- return axios.put(`${NEGOTIATION_PATH}/${negotiationId}/resources/${resourceId}/lifecycle/${event}`, {}, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.put(`${NEGOTIATION_PATH}/${negotiationId}/resources/${resourceId}/lifecycle/${event}`, {}, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
commit("setNotification", `Negotiation updated correctly with data ${response.data.id}`)
return response.data
@@ -103,8 +128,8 @@ export default {
return null
})
},
- retrieveNegotiationById({ state, commit }, { negotiationId }) {
- return axios.get(`${NEGOTIATION_PATH}/${negotiationId}`, {headers : getBearerHeaders(state.oidc.access_token)})
+ async retrieveNegotiationById({ state, commit }, { negotiationId }) {
+ return axios.get(`${NEGOTIATION_PATH}/${negotiationId}`, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data
})
@@ -114,8 +139,8 @@ export default {
},
retrievePostsByNegotiationId({ state, commit }, { negotiationId, type, resourceId }) {
let url = `${NEGOTIATION_PATH}/${negotiationId}/posts`
- let params = resourceId ? {type: type, resource: resourceId} : {type : type}
- return axios.get(url, {headers : getBearerHeaders(state.oidc.access_token), params: params})
+ let params = resourceId ? {type: type, resource: resourceId} : {type: type}
+ return axios.get(url, {headers: getBearerHeaders(state.oidc.access_token), params: params})
.then((response) => {
return response.data
})
@@ -124,7 +149,7 @@ export default {
})
},
addMessageToNegotiation({ state, commit }, { data }) {
- return axios.post(`${NEGOTIATION_PATH}/${data.negotiationId}/posts`, data, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.post(`${NEGOTIATION_PATH}/${data.negotiationId}/posts`, data, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data
})
@@ -133,7 +158,7 @@ export default {
})
},
markMessageAsRead({ state }, { data }) {
- return axios.put(`${NEGOTIATION_PATH}/${data.negotiationId}/posts/${data.postId}`, data, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.put(`${NEGOTIATION_PATH}/${data.negotiationId}/posts/${data.postId}`, data, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data.id
})
@@ -144,7 +169,7 @@ export default {
getUnreadMessagesByRole({ state }, { data }) {
//the role shoud be complementary in relation of the one from the user
let complementaryRole = data.Rolename == ROLES.RESEARCHER ? ROLES.REPRESENTATIVE : ROLES.RESEARCHER
- return axios.get(`${NEGOTIATION_PATH}/${data.negotiationId}/${complementaryRole}/posts`, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.get(`${NEGOTIATION_PATH}/${data.negotiationId}/${complementaryRole}/posts`, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data
})
@@ -153,13 +178,28 @@ export default {
})
},
retrieveUserRoles({ state, commit }) {
- return axios.get(USER_PATH, {headers : getBearerHeaders(state.oidc.access_token)})
+ return axios.get(USER_PATH, {headers: getBearerHeaders(state.oidc.access_token)})
.then((response) => {
return response.data
})
.catch(() => {
commit("setNotification", "Error sending message")
})
-
+ },
+ downloadAttachment({ state }, { id, name }) {
+ axios.get(`${ATTACHMENTS_PATH}/${id}`, { headers: getBearerHeaders(state.oidc.access_token), responseType: "blob" })
+ .then((response) => {
+ const href = window.URL.createObjectURL(response.data)
+
+ const anchorElement = document.createElement("a")
+ anchorElement.href = href
+ anchorElement.download = name
+
+ document.body.appendChild(anchorElement)
+ anchorElement.click()
+
+ document.body.removeChild(anchorElement)
+ window.URL.revokeObjectURL(href)
+ })
}
}
\ No newline at end of file
diff --git a/src/views/NegotiationPage.vue b/src/views/NegotiationPage.vue
index 44d0b7f..c158e0d 100644
--- a/src/views/NegotiationPage.vue
+++ b/src/views/NegotiationPage.vue
@@ -46,21 +46,33 @@
RESOURCE STATUS
@@ -78,13 +90,9 @@
@@ -155,7 +159,7 @@
@@ -200,10 +204,10 @@
@@ -368,20 +367,4 @@ export default {
border: 1px solid gray;
width: 80%;
}
-
-.close {
- color: gray;
- float: right;
- font-size: 28px;
- font-weight: bold;
-}
-.close:hover,
-.close:focus {
- color: "$black";
- text-decoration: none;
- cursor: pointer;
-}
-.negotiation-list-table tbody tr:hover > td {
- cursor: pointer;
-}
\ No newline at end of file