39 changed files with 1535 additions and 355 deletions
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
<template> |
||||
<v-card link :to="{ name: `researchStudies.study.apps.${app.component.slug}`, params: {studyId: studyId, appId: app.id } }"> |
||||
<v-img |
||||
:src="app.avatar" |
||||
height="50" |
||||
width="50" |
||||
/> |
||||
<v-card-title>{{app.name}}</v-card-title> |
||||
<v-card-subtitle v-text="app.description"></v-card-subtitle> |
||||
</v-card> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
props: { |
||||
studyId: { |
||||
type: [String, Number], |
||||
default: 0 |
||||
}, |
||||
app: { |
||||
type: Object, |
||||
default() { |
||||
return {} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,118 @@
@@ -0,0 +1,118 @@
|
||||
<template> |
||||
<v-card> |
||||
<v-card-title> |
||||
Apps |
||||
<v-spacer></v-spacer> |
||||
<v-text-field |
||||
v-model="search" |
||||
append-icon="mdi-magnify" |
||||
label="Search" |
||||
single-line |
||||
hide-details |
||||
></v-text-field> |
||||
</v-card-title> |
||||
<v-data-table |
||||
multi-sort |
||||
hide-default-footer |
||||
:headers="headers" |
||||
:items="apps" |
||||
:search="search" |
||||
@click:row="navigateToRow" |
||||
> |
||||
</v-data-table> |
||||
</v-card> |
||||
</template> |
||||
|
||||
provider |
||||
cpu |
||||
gpu |
||||
ram |
||||
storage |
||||
user |
||||
action |
||||
|
||||
|
||||
app |
||||
access: [] |
||||
additional_gpu_amount: 1 |
||||
additional_gpu_type: 1 |
||||
additional_memory_amount: 0 |
||||
additional_memory_type: null |
||||
additional_storage_amount: 0 |
||||
additional_storage_type: null |
||||
base_memory_amount: 12 |
||||
base_memory_type: 2 |
||||
base_storage_amount: 100 |
||||
base_storage_type: 2 |
||||
created_at: "2021-10-05T10:47:01.186516+02:00" |
||||
id: 19 |
||||
name: "VM_a" |
||||
networks: [1, 2] |
||||
operating_system: 2 |
||||
operating_system_name: "Windows 10 standaard" |
||||
profile: 2 |
||||
profile_name: "Premium" |
||||
researcher: 7 |
||||
study: 10 |
||||
total_memory: 12884901888 |
||||
total_storage: 107374182400 |
||||
updated_at: "2021-10-05T10:47:01.186640+02:00" |
||||
|
||||
<script> |
||||
export default { |
||||
props: { |
||||
studies: { |
||||
type: Array, |
||||
default() { |
||||
return [] |
||||
}, |
||||
}, |
||||
}, |
||||
data () { |
||||
return { |
||||
search: '', |
||||
headers: [ |
||||
{ |
||||
text: 'provider', |
||||
value: 'provider', |
||||
}, |
||||
{ |
||||
text: 'CPU', |
||||
value: 'cpu' |
||||
}, |
||||
{ |
||||
text: 'GPU', |
||||
value: 'gpu', |
||||
}, |
||||
{ |
||||
text: 'RAM', |
||||
value: 'ram' |
||||
}, |
||||
{ |
||||
text: 'Storage', |
||||
value: 'storage' |
||||
}, |
||||
{ |
||||
text: 'Researcher', |
||||
value: 'user' |
||||
}, |
||||
{ |
||||
text: '', |
||||
sortable: false, |
||||
value: 'isShared' |
||||
} |
||||
], |
||||
} |
||||
}, |
||||
methods: { |
||||
navigateToRow(row) { |
||||
this.$router.push({ |
||||
name: 'researchStudies.study.overview', |
||||
params: { |
||||
studyId: row.id |
||||
} |
||||
}); |
||||
} |
||||
}, |
||||
} |
||||
</script> |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
<template> |
||||
<v-row justify="center"> |
||||
<v-dialog |
||||
v-model="dialog" |
||||
persistent |
||||
max-width="290" |
||||
> |
||||
|
||||
<template #activator="{ on, attrs }"> |
||||
<v-icon |
||||
v-if="!contributor.isOwner" |
||||
small |
||||
v-bind="attrs" |
||||
v-on="on" |
||||
> |
||||
mdi-delete |
||||
</v-icon> |
||||
</template> |
||||
|
||||
<v-card> |
||||
<v-card-title>Remove contributor</v-card-title> |
||||
<v-card-text>Are you sure you want to remove this contributor?</v-card-text> |
||||
<v-card-actions> |
||||
<v-spacer></v-spacer> |
||||
<v-btn |
||||
text |
||||
@click="dialog = false" |
||||
> |
||||
No |
||||
</v-btn> |
||||
<v-btn |
||||
text |
||||
@click="clickDelete(contributor)" |
||||
> |
||||
Yes |
||||
</v-btn> |
||||
</v-card-actions> |
||||
</v-card> |
||||
</v-dialog> |
||||
</v-row> |
||||
</template> |
||||
|
||||
|
||||
<script> |
||||
import { mapActions } from 'vuex'; |
||||
|
||||
export default { |
||||
props: { |
||||
studyId: { |
||||
type: [Number, String], |
||||
default: 0, |
||||
}, |
||||
contributor: { |
||||
type: Object, |
||||
default() { return {} } |
||||
} |
||||
}, |
||||
data () { |
||||
return { |
||||
dialog: false, |
||||
} |
||||
}, |
||||
methods: { |
||||
...mapActions(['studies/deleteContributorFromStudy']), |
||||
clickDelete(contributor) { |
||||
this['studies/deleteContributorFromStudy']({ |
||||
studyId: this.studyId, |
||||
contributorId: contributor.researcher.id |
||||
}).then(() => { |
||||
this.$nuxt.refresh(); |
||||
this.dialog = false; |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
<template> |
||||
<v-btn @click="goToInviteContributor"> |
||||
Invite contributor |
||||
</v-btn> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
props: { |
||||
studyId: { |
||||
type: [Number, String], |
||||
default: 0, |
||||
} |
||||
}, |
||||
methods: { |
||||
goToInviteContributor() { |
||||
this.$router.push({ |
||||
name: 'researchStudies.study.contributors.invite', |
||||
params: { |
||||
studyId: this.studyId, |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,143 @@
@@ -0,0 +1,143 @@
|
||||
<template> |
||||
<v-card> |
||||
<v-card-title> |
||||
Contributors |
||||
<v-spacer></v-spacer> |
||||
<v-text-field |
||||
v-model="search" |
||||
append-icon="mdi-magnify" |
||||
label="Search" |
||||
single-line |
||||
hide-details |
||||
></v-text-field> |
||||
</v-card-title> |
||||
<v-data-table |
||||
multi-sort |
||||
hide-default-footer |
||||
:headers="headers" |
||||
:items="contributors" |
||||
:search="search" |
||||
:custom-filter="customFilter" |
||||
@click:row="navigateToRow" |
||||
> |
||||
<template #item.image="{ item }"> |
||||
<v-avatar> |
||||
<v-img |
||||
:src="`https://randomuser.me/api/portraits/men/${item.researcher.id+6}.jpg`" |
||||
:alt="`${item.researcher.first_name} ${item.researcher.last_name}`" |
||||
/> |
||||
</v-avatar> |
||||
</template> |
||||
|
||||
<template #item.name="{item}"> |
||||
{{item.researcher.first_name}} {{item.researcher.last_name}} |
||||
</template> |
||||
|
||||
<template #item.email="{item}"> |
||||
{{item.researcher.email_address}} |
||||
</template> |
||||
|
||||
<template #item.faculty="{item}"> |
||||
{{item.researcher.faculty.name}} |
||||
</template> |
||||
<template #item.university="{item}"> |
||||
{{item.researcher.faculty.university.name}} |
||||
</template> |
||||
|
||||
<template #item.isOwner="{item}"> |
||||
{{owner.id === item.researcher.id}} |
||||
</template> |
||||
|
||||
<template #item.actions="{item}"> |
||||
<contributors-delete-button :contributor="item" :study-id="studyId" /> |
||||
</template> |
||||
|
||||
</v-data-table> |
||||
</v-card> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
props: { |
||||
contributors: { |
||||
type: Array, |
||||
default() { |
||||
return [] |
||||
}, |
||||
}, |
||||
owner: { |
||||
type: Object, |
||||
default() { |
||||
return {} |
||||
} |
||||
}, |
||||
studyId: { |
||||
type: [String, Number], |
||||
default: 0, |
||||
}, |
||||
}, |
||||
data () { |
||||
return { |
||||
search: '', |
||||
headers: [ |
||||
{ |
||||
text: '', |
||||
align: 'start', |
||||
value: 'image', |
||||
}, |
||||
{ |
||||
text: 'Name', |
||||
value: 'name', |
||||
}, |
||||
{ |
||||
text: 'Email', |
||||
value: 'email', |
||||
}, |
||||
{ |
||||
text: 'Faculty', |
||||
value: 'faculty', |
||||
}, |
||||
{ |
||||
text: 'University', |
||||
value: 'university', |
||||
}, |
||||
{ |
||||
text: 'Role', |
||||
value: 'role' |
||||
}, |
||||
{ |
||||
text: 'Owner', |
||||
value: 'isOwner' |
||||
}, |
||||
{ |
||||
text: '', |
||||
value: 'actions' |
||||
} |
||||
], |
||||
} |
||||
}, |
||||
methods: { |
||||
navigateToRow(row) { |
||||
this.$router.push({ |
||||
name: 'researchStudies.study.contributors.edit', |
||||
params: { |
||||
studyId: this.studyId, |
||||
contributorId: row.id |
||||
} |
||||
}); |
||||
}, |
||||
customFilter(_, search, item) { |
||||
search = search.toString().toLowerCase(); |
||||
return ( |
||||
item.role.toLowerCase().includes(search) |
||||
|| item.researcher.email_address.toLowerCase().includes(search) |
||||
|| String(item.researcher.faculty).toLowerCase().includes(search) |
||||
|| item.researcher.first_name.toLowerCase().includes(search) |
||||
|| item.researcher.last_name.toLowerCase().includes(search) |
||||
|| item.researcher.faculty.name.toLowerCase().includes(search) |
||||
|| item.researcher.faculty.university.name.toLowerCase().includes(search) |
||||
) |
||||
} |
||||
}, |
||||
} |
||||
</script> |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
<template> |
||||
<v-row justify="center"> |
||||
<v-dialog |
||||
v-model="dialog" |
||||
persistent |
||||
max-width="290" |
||||
> |
||||
|
||||
<template #activator="{ on, attrs }"> |
||||
<v-btn |
||||
small |
||||
v-bind="attrs" |
||||
v-on="on" |
||||
> |
||||
delete study |
||||
</v-btn> |
||||
</template> |
||||
|
||||
<ui-rug-card-form |
||||
:form="form" |
||||
> |
||||
<v-card-title>Remove research study</v-card-title> |
||||
<v-card-text>Are you sure you want to remove this research study?</v-card-text> |
||||
|
||||
<span slot="actions"> |
||||
<v-btn |
||||
text |
||||
@click="dialog = false" |
||||
> |
||||
No |
||||
</v-btn> |
||||
<v-btn |
||||
text |
||||
type="submit" |
||||
> |
||||
Yes |
||||
</v-btn> |
||||
</span> |
||||
</ui-rug-card-form> |
||||
|
||||
</v-dialog> |
||||
</v-row> |
||||
</template> |
||||
|
||||
<script> |
||||
import { mapActions } from 'vuex'; |
||||
import Form from '@/lib/form'; |
||||
|
||||
export default { |
||||
props: { |
||||
studyId: { |
||||
type: [Number, String], |
||||
default: 0, |
||||
}, |
||||
}, |
||||
data () { |
||||
return { |
||||
dialog: false, |
||||
formData: { |
||||
studyId: this.studyId, |
||||
}, |
||||
form: new Form({ |
||||
vm: this, |
||||
action: this['studies/deleteStudy'], |
||||
onResponse() { |
||||
this.dialog = false; |
||||
this.$router.push({ name: 'researchStudies' }); |
||||
} |
||||
}), |
||||
} |
||||
}, |
||||
methods: { |
||||
...mapActions(['studies/deleteStudy']), |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
<template> |
||||
<div> |
||||
<apps-list :apps="apps" :studyId="studyId" /> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
async asyncData({ store, route }) { |
||||
const studyId = route.params.studyId; |
||||
await store.dispatch('apps/getApps'); |
||||
return { |
||||
studyId, |
||||
apps: store.getters['apps/getApps'], |
||||
} |
||||
// return { |
||||
// // apps: store.getters['apps/getAppsForStudy'](studyId), |
||||
// studyId, |
||||
// }; |
||||
}, |
||||
} |
||||
</script> |
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
<template> |
||||
<div> |
||||
app detail edit page |
||||
</div> |
||||
</template> |
@ -0,0 +1,177 @@
@@ -0,0 +1,177 @@
|
||||
<template> |
||||
<v-card> |
||||
<v-card-title> |
||||
Virtual machines |
||||
<v-spacer></v-spacer> |
||||
<!-- <v-data-table |
||||
multi-sort |
||||
hide-default-footer |
||||
:headers="headers" |
||||
:items="profiles" |
||||
:search="search" |
||||
:custom-filter="customFilter" |
||||
@click:row="navigateToRow" |
||||
/> --> |
||||
<!-- <windows-vdi-edit-button :studyId="studyId" :virtualMachineId="item.id" /> |
||||
<windows-vdi-delete-button :virtualMachineId="item.id" /> --> |
||||
|
||||
|
||||
data-table: current vm's (name, os, ram, storage, researcher) |
||||
edit button |
||||
add vm page in edit modus |
||||
delete button |
||||
delete action => re-render |
||||
button: add vm |
||||
page: |
||||
pick-profile-input: |
||||
data-table: vm profiles choice |
||||
returns profile-id |
||||
dropdown: researcher |
||||
button: create workspace |
||||
|
||||