Browse Source

Make the apps working??

master
Joshua Rubingh 5 months ago
parent
commit
670b23774f
  1. 21
      components/app/list/item.vue
  2. 73
      components/apps/deleteButton.vue
  3. 11
      locales/en.js
  4. 199
      pages/researchStudies/_studyId/apps/windows-vdi/index.vue
  5. 4
      pages/researchStudies/_studyId/index.vue
  6. 28
      store/apps.js

21
components/app/list/item.vue

@ -1,9 +1,14 @@ @@ -1,9 +1,14 @@
<template>
<!-- This is STUPID!!! Why do I have to make 2 complete HTML blocks with the same code, just to DISABLE a a-href..... -->
<v-card
v-if="app.available"
link
:to="localePath(`/researchStudies/${studyId}/apps/${app.slug}/`)"
:to="
!app.login
? localePath(`/researchStudies/${studyId}/apps/${app.slug}/`)
: false
"
:href="app.login ? app.login : false"
:target="app.login ? '_blank' : false"
:disabled="!app.available"
>
<v-avatar>
<v-img :src="app.src" :alt="`${app.name}`" height="100" width="100" />
@ -13,16 +18,6 @@ @@ -13,16 +18,6 @@
<v-card-subtitle v-text="app.description"></v-card-subtitle>
</div>
</v-card>
<v-card v-else outlined class="grey lighten-1">
<v-avatar>
<v-img :src="app.src" :alt="`${app.name}`" height="100" width="100" />
</v-avatar>
<div style="padding-left: 5rem">
<v-card-title>{{ app.name }}</v-card-title>
<v-card-subtitle v-text="app.description"></v-card-subtitle>
</div>
</v-card>
</template>
<script>

73
components/apps/deleteButton.vue

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
<template>
<v-row justify="center">
<v-dialog v-model="dialog" persistent max-width="290">
<template #activator="{ on, attrs }">
<v-icon small v-bind="attrs" v-on="on"> mdi-delete </v-icon>
</template>
<ui-rug-card-form :form="form">
<v-card-title>{{
$t('page.researchStudies.studyId.apps.index.delete_modal.title')
}}</v-card-title>
<v-card-text>{{
$t('page.researchStudies.studyId.apps.index.delete_modal.text', {
app_name: app.name,
researcher_name: app.contributor.researcher.display_name,
})
}}</v-card-text>
<span slot="actions">
<v-spacer></v-spacer>
<v-btn text @click="dialog = false">
{{
$t('page.researchStudies.studyId.apps.index.delete_modal.cancel')
}}
</v-btn>
<v-btn text type="submit">
{{ $t('page.researchStudies.studyId.apps.index.delete_modal.ok') }}
</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,
},
app: {
type: Object,
default() {
return {}
},
},
},
data() {
return {
dialog: false,
formData: {
studyId: this.studyId,
appId: this.app.id,
},
form: new Form({
vm: this,
action: this['apps/removeStudyApp'],
onResponse() {
this.vm.dialog = false
this.vm.$nuxt.refresh()
},
}),
}
},
methods: {
...mapActions(['apps/removeStudyApp']),
},
}
</script>

11
locales/en.js

@ -85,7 +85,15 @@ export default { @@ -85,7 +85,15 @@ export default {
},
},
apps: {
title: 'Apps for study {study_name}',
index: {
title: 'Apps for study {study_name}',
delete_modal: {
title: 'Delete app',
text: 'Are you sure you want to remove the {app_name} app for researcher {researcher_name}?',
ok: 'Yes',
cancel: 'No'
}
}
}
}
},
@ -176,6 +184,7 @@ export default { @@ -176,6 +184,7 @@ export default {
},
},
apps: {
header: 'Create a new app',
version: {
label: 'Version'
},

199
pages/researchStudies/_studyId/apps/windows-vdi/index.vue

@ -1,8 +1,9 @@ @@ -1,8 +1,9 @@
<template>
<v-card>
<ui-rug-card-title>
{{ study.name }} ({{ study.code }})
<!--
<v-container>
<ui-rug-card-form :form="form">
<ui-rug-card-title>
{{ study.name }} ({{ study.code }})
<!--
<v-spacer></v-spacer>
<v-text-field
v-model="search"
@ -12,69 +13,74 @@ @@ -12,69 +13,74 @@
hide-details
></v-text-field>
-->
</ui-rug-card-title>
</ui-rug-card-title>
<v-card-text class="flex-row mb-6">
<v-data-table
multi-sort
hide-default-footer
:headers="headers"
:items="test"
:search="search"
:custom-filter="customFilter"
>
<template #item.version="{ item }">
<v-select
:items="versions"
:item-text="
(row) => {
return `${row.os} ${row.name} (${row.memory}, ${row.disk})`
}
"
:value="item.version"
dense
>
</v-select>
</template>
<v-card-text class="flex-row mb-6">
<v-data-table
multi-sort
hide-default-footer
:headers="headers"
:items="apps"
:search="search"
:custom-filter="customFilter"
>
<template #item.version="{ item }">
{{ item.name }}
</template>
<template #item.contributor="{ item }">
{{ item.contributor.researcher.display_name }}
</template>
<template #item.actions="{ item }">
<div style="float: right">
<apps-delete-button
v-if="isAdmin"
:app="item"
:study-id="studyId"
/>
</div>
</template>
</v-data-table>
<template #item.contributor="{ item }">
<!-- TODO: Ad some kind of realtime filter to filter out the already selected researchers -->
<v-select
:items="active_contributors"
:item-text="
(row) => {
return `${row.researcher.display_name} (${row.researcher.email_address})`
}
"
:value="item.contributor"
dense
></v-select>
</template>
<br /><br />
<h1>{{ $t('form.apps.header') }}</h1>
<template #item.actions="{}">
<v-icon v-if="test.length > 1" @click="deleteRow(index)"
>mdi-minus-circle</v-icon
>
</template>
<v-select
id="formData.version"
v-model="formData.version"
:error-messages="form.getError('formData.version')"
:items="versions"
:item-text="
(row) => {
return `${row.os} ${row.name} (${row.memory}, ${row.disk})`
}
"
item-value="id"
:value="formData.version"
:label="$t('form.apps.version.label')"
></v-select>
<template slot="body.append">
<tr v-if="test.length < active_contributors.length">
<td colspan="2"></td>
<td>
<v-icon style="margin-right: 1rem" @click="addRow"
>mdi-plus-circle</v-icon
>
</td>
</tr>
</template>
</v-data-table>
</v-card-text>
</v-card>
<v-select
id="formData.contributor"
v-model="formData.contributor"
:error-messages="form.getError('formData.contributor')"
:items="availableContributors"
:item-text="
(row) => {
return `${row.researcher.display_name} (${row.researcher.email_address})`
}
"
item-value="id"
:value="formData.contributor"
:label="$t('form.apps.contributor.label')"
></v-select>
</v-card-text>
</ui-rug-card-form>
</v-container>
</template>
<script>
/* import { mapActions } from 'vuex' */
/* import Form from '@/lib/form' */
import { mapActions } from 'vuex'
import Form from '@/lib/form'
/* TODO: Make this function system wide available in a general include ?? https://stackoverflow.com/a/55641743 */
const trim = (str, chars) => str.split(chars).filter(Boolean).join(chars)
@ -97,18 +103,31 @@ export default { @@ -97,18 +103,31 @@ export default {
}),
])
const isAdmin = store.getters['authorisation/isAdminOfStudy']({
study: store.getters['studies/getActiveStudy'],
})
const availableContributors = store.getters[
'studies/getActiveStudy'
].contributors.filter((contributor) => {
return (
contributor.active &&
!store.getters['apps/getStudyApps']
.map((app) => {
return app.contributor.id
})
.includes(contributor.id)
)
})
return {
studyId,
appType,
isAdmin,
study: store.getters['studies/getActiveStudy'],
active_contributors: store.getters[
'studies/getActiveStudy'
].contributors.filter((contributor) => {
return contributor.active
}),
profiles: store.getters['apps/getAppTypeProfiles'],
availableContributors,
apps: store.getters['apps/getStudyApps'],
versions: store.getters['apps/getAppTypeProfiles'],
test: [{ version: '', contributor: '' }],
}
},
data() {
@ -121,7 +140,7 @@ export default { @@ -121,7 +140,7 @@ export default {
value: 'version',
},
{
text: $t('form.apps.version.label'),
text: $t('form.apps.contributor.label'),
value: 'contributor',
},
{
@ -129,12 +148,40 @@ export default { @@ -129,12 +148,40 @@ export default {
value: 'actions',
},
],
formData: {
version: null,
contributor: null,
studyId: this.$route.params.studyId,
appType: trim(this.$route.path, '/').split('/').pop(),
},
form: new Form({
vm: this,
action: this['apps/createNewStudyApp'],
schema: {
type: 'object',
properties: {
version: {
type: 'integer',
},
contributor: {
type: 'integer',
},
},
required: ['version', 'contributor'],
},
onResponse(response) {
this.vm.$nuxt.refresh()
},
}),
}
},
head() {
const $t = this.$t.bind(this)
return {
title: $t('page.researchStudies.studyId.apps.title', {
title: $t('page.researchStudies.studyId.apps.index.title', {
study_name: this.study.name,
}),
}
@ -148,20 +195,8 @@ export default { @@ -148,20 +195,8 @@ export default {
item.contributor.toLowerCase().includes(search)
)
},
addRow() {
if (this.test.length < this.active_contributors.length) {
this.test.push({ version: '', contributor: '' })
}
},
deleteRow(index) {
if (this.test.length > 1) {
this.test.splice(index, 1)
}
},
/*
...mapActions(['studies/createStudy']),
*/
...mapActions(['apps/createNewStudyApp']),
},
}
</script>

4
pages/researchStudies/_studyId/index.vue

@ -3,7 +3,9 @@ @@ -3,7 +3,9 @@
<ui-rug-card-title> {{ study.name }} ({{ study.code }}) </ui-rug-card-title>
<v-card-text class="d-flex flex-row mb-6">
<apps-list :apps="apps" :study-id="studyId" />
<v-list v-for="app in apps" :key="app">
<app-list-item :app="app" :study-id="studyId" />
</v-list>
<v-list
v-for="contributor in study.contributors"

28
store/apps.js

@ -34,7 +34,22 @@ export const actions = { @@ -34,7 +34,22 @@ export const actions = {
}
}),
createNewStudyApp: actionCreator({
name: 'createNewStudyApp',
method(data) {
return this.$axios.post(`/api/v1/studies/${data.studyId}/app-types/${data.appType}/`, data)
}
}),
removeStudyApp: actionCreator({
commit: {
success: false,
},
name: 'removeStudyApp',
method(data) {
return this.$axios.delete(`/api/v1/studies/${data.studyId}/apps/${data.appId}/`)
}
}),
}
export const mutations = {
@ -58,7 +73,8 @@ export const mutations = { @@ -58,7 +73,8 @@ export const mutations = {
id: app.id,
src: app.avatar,
name: app.display_name,
login: app.login_url
login: app.login_url,
available: true,
}
})
},
@ -69,12 +85,12 @@ export const mutations = { @@ -69,12 +85,12 @@ export const mutations = {
id: app.id,
src: app.avatar,
name: app.display_name,
login: app.login_url
login: app.login_url,
contributor: app.contributor
}
})
},
getAppTypeProfilesSuccess(state, { result }) {
state.app_profiles = result.map((profile) => {
return {
@ -85,7 +101,11 @@ export const mutations = { @@ -85,7 +101,11 @@ export const mutations = {
memory: profile.memory
}
});
}
},
createNewStudyAppSuccess(state, { result }) {
},
}
export const getters = {

Loading…
Cancel
Save