mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-10 15:47:32 +00:00
added possibility to select an application and navigate the route
This commit is contained in:
parent
b866e8f156
commit
15ba3dd043
17 changed files with 377 additions and 20 deletions
backend
src/baserow/api/v0/applications
tests/baserow/api/v0/applications
web-frontend
assets/scss/components
components/sidebar
config
core
mixins
modules/database
pages/app
services
store
|
@ -1,15 +1,17 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from baserow.api.v0.groups.serializers import GroupSerializer
|
||||||
from baserow.core.applications import registry
|
from baserow.core.applications import registry
|
||||||
from baserow.core.models import Application
|
from baserow.core.models import Application
|
||||||
|
|
||||||
|
|
||||||
class ApplicationSerializer(serializers.ModelSerializer):
|
class ApplicationSerializer(serializers.ModelSerializer):
|
||||||
type = serializers.SerializerMethodField()
|
type = serializers.SerializerMethodField()
|
||||||
|
group = GroupSerializer()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Application
|
model = Application
|
||||||
fields = ('id', 'name', 'order', 'type')
|
fields = ('id', 'name', 'order', 'type', 'group')
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'id': {
|
'id': {
|
||||||
'read_only': True
|
'read_only': True
|
||||||
|
|
|
@ -56,6 +56,18 @@ class ApplicationView(APIView):
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
core_handler = CoreHandler()
|
core_handler = CoreHandler()
|
||||||
|
|
||||||
|
@map_exceptions({
|
||||||
|
UserNotIngroupError: ERROR_USER_NOT_IN_GROUP
|
||||||
|
})
|
||||||
|
def get(self, request, application_id):
|
||||||
|
"""Selects a single application and responds with a serialized version."""
|
||||||
|
application = get_object_or_404(
|
||||||
|
Application.objects.select_related('group'),
|
||||||
|
pk=application_id, group__users__in=[request.user]
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response(ApplicationSerializer(application).data)
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
@validate_body(ApplicationUpdateSerializer)
|
@validate_body(ApplicationUpdateSerializer)
|
||||||
@map_exceptions({
|
@map_exceptions({
|
||||||
|
|
|
@ -94,6 +94,46 @@ def test_create_application(api_client, data_fixture):
|
||||||
assert response_json['order'] == database.order
|
assert response_json['order'] == database.order
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_get_application(api_client, data_fixture):
|
||||||
|
user, token = data_fixture.create_user_and_token()
|
||||||
|
user_2, token_2 = data_fixture.create_user_and_token()
|
||||||
|
group = data_fixture.create_group(user=user)
|
||||||
|
group_2 = data_fixture.create_group(user=user_2)
|
||||||
|
application = data_fixture.create_database_application(group=group)
|
||||||
|
application_2 = data_fixture.create_database_application(group=group_2)
|
||||||
|
|
||||||
|
url = reverse('api_v0:applications:item',
|
||||||
|
kwargs={'application_id': application_2.id})
|
||||||
|
response = api_client.get(
|
||||||
|
url,
|
||||||
|
format='json',
|
||||||
|
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
url = reverse('api_v0:applications:item',
|
||||||
|
kwargs={'application_id': 99999})
|
||||||
|
response = api_client.get(
|
||||||
|
url,
|
||||||
|
format='json',
|
||||||
|
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
url = reverse('api_v0:applications:item',
|
||||||
|
kwargs={'application_id': application.id})
|
||||||
|
response = api_client.get(
|
||||||
|
url,
|
||||||
|
format='json',
|
||||||
|
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||||
|
)
|
||||||
|
response_json = response.json()
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response_json['id'] == application.id
|
||||||
|
assert response_json['group']['id'] == group.id
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_update_application(api_client, data_fixture):
|
def test_update_application(api_client, data_fixture):
|
||||||
user, token = data_fixture.create_user_and_token()
|
user, token = data_fixture.create_user_and_token()
|
||||||
|
|
|
@ -129,6 +129,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tree-sub-add {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 0 10px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: $color-neutral-300;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: $color-neutral-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tree-options {
|
.tree-options {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
<li
|
<li
|
||||||
class="tree-item"
|
class="tree-item"
|
||||||
:class="{
|
:class="{
|
||||||
|
active: application._.selected,
|
||||||
'tree-item-loading': application._.loading
|
'tree-item-loading': application._.loading
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="tree-action">
|
<div class="tree-action">
|
||||||
<a class="tree-link">
|
<a class="tree-link" @click="selectApplication(application)">
|
||||||
<i
|
<i
|
||||||
class="tree-type fas"
|
class="tree-type fas"
|
||||||
:class="'fa-' + application._.type.iconClass"
|
:class="'fa-' + application._.type.iconClass"
|
||||||
|
@ -42,6 +43,16 @@
|
||||||
</ul>
|
</ul>
|
||||||
</Context>
|
</Context>
|
||||||
</div>
|
</div>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
application._.selected && application._.type.hasSelectedSidebarComponent
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="getSelectedApplicationComponent(application)"
|
||||||
|
:application="application"
|
||||||
|
></component>
|
||||||
|
</template>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -83,6 +94,24 @@ export default {
|
||||||
this.setLoading(application, false)
|
this.setLoading(application, false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
selectApplication(application) {
|
||||||
|
this.setLoading(application, true)
|
||||||
|
|
||||||
|
this.$nuxt.$router.push(
|
||||||
|
{
|
||||||
|
name: application._.type.routeName,
|
||||||
|
params: {
|
||||||
|
id: application.id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.setLoading(application, false)
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.setLoading(application, false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
deleteApplication(application) {
|
deleteApplication(application) {
|
||||||
this.$refs.context.hide()
|
this.$refs.context.hide()
|
||||||
this.setLoading(application, true)
|
this.setLoading(application, true)
|
||||||
|
@ -90,6 +119,12 @@ export default {
|
||||||
this.$store.dispatch('application/delete', application).then(() => {
|
this.$store.dispatch('application/delete', application).then(() => {
|
||||||
this.setLoading(application, false)
|
this.setLoading(application, false)
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
getSelectedApplicationComponent(application) {
|
||||||
|
const type = this.$store.getters['application/getApplicationByType'](
|
||||||
|
application.type
|
||||||
|
)
|
||||||
|
return type.getSelectedSidebarComponent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
export default {
|
export default {
|
||||||
mode: 'universal',
|
mode: 'universal',
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Headers of the page
|
* Headers of the page
|
||||||
*/
|
*/
|
||||||
head: {
|
head: {
|
||||||
title: 'Baserow',
|
title: 'Baserow',
|
||||||
|
@ -12,18 +12,18 @@ export default {
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Customize the progress-bar color
|
* Customize the progress-bar color
|
||||||
*/
|
*/
|
||||||
loading: { color: '#fff' },
|
loading: { color: '#fff' },
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Global CSS
|
* Global CSS
|
||||||
*/
|
*/
|
||||||
css: ['@/assets/scss/default.scss'],
|
css: ['@/assets/scss/default.scss'],
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Plugins to load before mounting the App
|
* Plugins to load before mounting the App
|
||||||
*/
|
*/
|
||||||
plugins: [
|
plugins: [
|
||||||
{ src: '@/plugins/global.js' },
|
{ src: '@/plugins/global.js' },
|
||||||
|
@ -32,8 +32,8 @@ export default {
|
||||||
{ src: '@/plugins/vuelidate.js' }
|
{ src: '@/plugins/vuelidate.js' }
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Nuxt.js modules
|
* Nuxt.js modules
|
||||||
*/
|
*/
|
||||||
modules: [
|
modules: [
|
||||||
'@nuxtjs/axios',
|
'@nuxtjs/axios',
|
||||||
|
|
|
@ -30,6 +30,14 @@ export class Application {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must return the route name where the application can navigate to when the
|
||||||
|
* application is selected.
|
||||||
|
*/
|
||||||
|
getRouteName() {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The form component that will be rendered when creating a new instance of
|
* The form component that will be rendered when creating a new instance of
|
||||||
* this application. By default the ApplicationForm component is returned, but
|
* this application. By default the ApplicationForm component is returned, but
|
||||||
|
@ -40,19 +48,32 @@ export class Application {
|
||||||
return ApplicationForm
|
return ApplicationForm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sidebar component that will be rendered when an application instance
|
||||||
|
* is selected. By default no component will rendered. This could be used for
|
||||||
|
* example to render a list of tables that belong to a database.
|
||||||
|
*/
|
||||||
|
getSelectedSidebarComponent() {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.type = this.getType()
|
this.type = this.getType()
|
||||||
this.iconClass = this.getIconClass()
|
this.iconClass = this.getIconClass()
|
||||||
this.name = this.getName()
|
this.name = this.getName()
|
||||||
|
this.routeName = this.getRouteName()
|
||||||
|
|
||||||
if (this.type === null) {
|
if (this.type === null) {
|
||||||
throw Error('The type name of an application must be set.')
|
throw new Error('The type name of an application must be set.')
|
||||||
}
|
}
|
||||||
if (this.iconClass === null) {
|
if (this.iconClass === null) {
|
||||||
throw Error('The icon class of an application must be set.')
|
throw new Error('The icon class of an application must be set.')
|
||||||
}
|
}
|
||||||
if (this.name === null) {
|
if (this.name === null) {
|
||||||
throw Error('The name of an application must be set.')
|
throw new Error('The name of an application must be set.')
|
||||||
|
}
|
||||||
|
if (this.routeName === null) {
|
||||||
|
throw new Error('The route name of an application must be set.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +84,9 @@ export class Application {
|
||||||
return {
|
return {
|
||||||
type: this.type,
|
type: this.type,
|
||||||
iconClass: this.iconClass,
|
iconClass: this.iconClass,
|
||||||
name: this.name
|
name: this.name,
|
||||||
|
routeName: this.routeName,
|
||||||
|
hasSelectedSidebarComponent: this.getSelectedSidebarComponent() !== null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
web-frontend/mixins/application.js
Normal file
29
web-frontend/mixins/application.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { notify404 } from '@/utils/error'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This mixin can be used in combination with the page an application routes to
|
||||||
|
* when selected. It will make sure that the application preSelect action is
|
||||||
|
* called so that the all the depending information is loaded. If something
|
||||||
|
* goes wrong while loading this information it will show a standard error.
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.dispatch('application/preSelect', this.id).catch(error => {
|
||||||
|
notify404(
|
||||||
|
this.$store.dispatch,
|
||||||
|
error,
|
||||||
|
'Application not found.',
|
||||||
|
"The application with the provided id doesn't exist or you " +
|
||||||
|
"don't have access to it."
|
||||||
|
)
|
||||||
|
|
||||||
|
this.$nuxt.$router.push({ name: 'app' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { Application } from '@/core/applications'
|
import { Application } from '@/core/applications'
|
||||||
|
import Sidebar from '@/modules/database/components/Sidebar'
|
||||||
|
|
||||||
export class DatabaseApplication extends Application {
|
export class DatabaseApplication extends Application {
|
||||||
getType() {
|
getType() {
|
||||||
|
@ -12,4 +13,12 @@ export class DatabaseApplication extends Application {
|
||||||
getName() {
|
getName() {
|
||||||
return 'Database'
|
return 'Database'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRouteName() {
|
||||||
|
return 'application-database'
|
||||||
|
}
|
||||||
|
|
||||||
|
getSelectedSidebarComponent() {
|
||||||
|
return Sidebar
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
38
web-frontend/modules/database/components/Sidebar.vue
Normal file
38
web-frontend/modules/database/components/Sidebar.vue
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ul class="tree-subs">
|
||||||
|
<li class="tree-sub active">
|
||||||
|
<a href="#" class="tree-sub-link">@TODO</a>
|
||||||
|
<a
|
||||||
|
class="tree-options"
|
||||||
|
@click="
|
||||||
|
$refs.context.toggle($event.currentTarget, 'bottom', 'right', 0)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<i class="fas fa-ellipsis-v"></i>
|
||||||
|
</a>
|
||||||
|
<Context ref="context">
|
||||||
|
<div class="context-menu-title">@TODO</div>
|
||||||
|
<ul class="context-menu">
|
||||||
|
<li>
|
||||||
|
<a>
|
||||||
|
<i class="context-menu-icon fas fa-fw fa-pen"></i>
|
||||||
|
Rename
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a>
|
||||||
|
<i class="context-menu-icon fas fa-fw fa-trash"></i>
|
||||||
|
Delete
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</Context>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<a href="#" class="tree-sub-add">
|
||||||
|
<i class="fas fa-plus"></i>
|
||||||
|
Create table
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,9 +1,15 @@
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
|
import { databaseRoutes } from './routes'
|
||||||
|
|
||||||
export default function DatabaseModule(options) {
|
export default function DatabaseModule(options) {
|
||||||
// Add the plugin to register the database application.
|
// Add the plugin to register the database application.
|
||||||
this.addPlugin({
|
this.addPlugin({
|
||||||
src: path.resolve(__dirname, 'plugin.js'),
|
src: path.resolve(__dirname, 'plugin.js'),
|
||||||
filename: 'plugin.js'
|
filename: 'plugin.js'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.extendRoutes(routes => {
|
||||||
|
routes.push(...databaseRoutes)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
29
web-frontend/modules/database/pages/Database.vue
Normal file
29
web-frontend/modules/database/pages/Database.vue
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<header class="layout-col-3-1 header">
|
||||||
|
<ul class="header-filter">
|
||||||
|
<li class="header-filter-item"> </li>
|
||||||
|
</ul>
|
||||||
|
<ul class="header-info">
|
||||||
|
<li>{{ selectedApplication.name }}</li>
|
||||||
|
<li>@TODO table name</li>
|
||||||
|
</ul>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
|
import application from '@/mixins/application'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
layout: 'app',
|
||||||
|
mixins: [application],
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
selectedApplication: state => state.application.selected
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
14
web-frontend/modules/database/routes.js
Normal file
14
web-frontend/modules/database/routes.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
export const databaseRoutes = [
|
||||||
|
{
|
||||||
|
name: 'application-database',
|
||||||
|
path: '/database/:id',
|
||||||
|
component: path.resolve(__dirname, 'pages/Database.vue'),
|
||||||
|
props(route) {
|
||||||
|
const props = { ...route.params }
|
||||||
|
props.id = parseInt(props.id)
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
|
@ -9,6 +9,11 @@
|
||||||
{{ applications }}
|
{{ applications }}
|
||||||
<br /><br />
|
<br /><br />
|
||||||
{{ groupApplications }}
|
{{ groupApplications }}
|
||||||
|
<br /><br />
|
||||||
|
<nuxt-link :to="{ name: 'application-database', params: { id: 1 } }">
|
||||||
|
<i class="fas fa-arrow-left"></i>
|
||||||
|
App
|
||||||
|
</nuxt-link>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -7,6 +7,9 @@ export default {
|
||||||
create(groupId, values) {
|
create(groupId, values) {
|
||||||
return client.post(`/applications/group/${groupId}/`, values)
|
return client.post(`/applications/group/${groupId}/`, values)
|
||||||
},
|
},
|
||||||
|
get(applicationId) {
|
||||||
|
return client.get(`/applications/${applicationId}/`)
|
||||||
|
},
|
||||||
update(applicationId, values) {
|
update(applicationId, values) {
|
||||||
return client.patch(`/applications/${applicationId}/`, values)
|
return client.patch(`/applications/${applicationId}/`, values)
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,9 +3,12 @@ import ApplicationService from '@/services/application'
|
||||||
import { notify404, notifyError } from '@/utils/error'
|
import { notify404, notifyError } from '@/utils/error'
|
||||||
|
|
||||||
function populateApplication(application, getters) {
|
function populateApplication(application, getters) {
|
||||||
|
const type = getters.getApplicationByType(application.type)
|
||||||
|
|
||||||
application._ = {
|
application._ = {
|
||||||
type: getters.getApplicationByType(application.type).serialize(),
|
type: type.serialize(),
|
||||||
loading: false
|
loading: false,
|
||||||
|
selected: false
|
||||||
}
|
}
|
||||||
return application
|
return application
|
||||||
}
|
}
|
||||||
|
@ -13,7 +16,8 @@ function populateApplication(application, getters) {
|
||||||
export const state = () => ({
|
export const state = () => ({
|
||||||
applications: {},
|
applications: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
items: []
|
items: [],
|
||||||
|
selected: {}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
|
@ -39,6 +43,19 @@ export const mutations = {
|
||||||
DELETE_ITEM(state, id) {
|
DELETE_ITEM(state, id) {
|
||||||
const index = state.items.findIndex(item => item.id === id)
|
const index = state.items.findIndex(item => item.id === id)
|
||||||
state.items.splice(index, 1)
|
state.items.splice(index, 1)
|
||||||
|
},
|
||||||
|
SET_SELECTED(state, group) {
|
||||||
|
Object.values(state.items).forEach(item => {
|
||||||
|
item._.selected = false
|
||||||
|
})
|
||||||
|
group._.selected = true
|
||||||
|
state.selected = group
|
||||||
|
},
|
||||||
|
UNSELECT(state) {
|
||||||
|
Object.values(state.items).forEach(item => {
|
||||||
|
item._.selected = false
|
||||||
|
})
|
||||||
|
state.selected = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +182,77 @@ export const actions = {
|
||||||
' not part of the group where the application is in.'
|
' not part of the group where the application is in.'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Select an application.
|
||||||
|
*/
|
||||||
|
select({ commit }, application) {
|
||||||
|
commit('SET_SELECTED', application)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Select an application by a given application id.
|
||||||
|
*/
|
||||||
|
selectById({ dispatch, getters }, id) {
|
||||||
|
const application = getters.get(id)
|
||||||
|
if (application === undefined) {
|
||||||
|
throw new Error(`Application with id ${id} is not found.`)
|
||||||
|
}
|
||||||
|
return dispatch('select', application)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Unselect the
|
||||||
|
*/
|
||||||
|
unselect({ commit }) {
|
||||||
|
commit('UNSELECT', {})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* The preSelect action will eventually select an application, but it will
|
||||||
|
* first check which information still needs to be loaded. For example if
|
||||||
|
* no group or not the group where the application is in loaded it will then
|
||||||
|
* first fetch that group and related application so that the sidebar is up
|
||||||
|
* to date. In short it will make sure that the depending state of the given
|
||||||
|
* application will be there.
|
||||||
|
*/
|
||||||
|
preSelect({ dispatch, getters, rootGetters }, id) {
|
||||||
|
// First we will check if the application is already in the items.
|
||||||
|
const application = getters.get(id)
|
||||||
|
|
||||||
|
// If the application is already selected we don't have to do anything.
|
||||||
|
if (application !== undefined && application._.selected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function will select a group by its id which will then automatically
|
||||||
|
// fetch the applications related to that group. When done it will select
|
||||||
|
// the provided application id.
|
||||||
|
const selectGroupAndApplication = (groupId, applicationId) => {
|
||||||
|
return dispatch('group/selectById', groupId, {
|
||||||
|
root: true
|
||||||
|
}).then(() => {
|
||||||
|
return dispatch('selectById', applicationId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (application !== undefined) {
|
||||||
|
// If the application is already in the selected groups, which means that
|
||||||
|
// the groups and applications are already loaded, we can just select that
|
||||||
|
// application.
|
||||||
|
dispatch('select', application)
|
||||||
|
} else {
|
||||||
|
// The application is not in the selected group so we need to figure out
|
||||||
|
// in which he is by fetching the application.
|
||||||
|
return ApplicationService.get(id).then(data => {
|
||||||
|
if (!rootGetters['group/isLoaded']) {
|
||||||
|
// If the groups are not already loaded we need to load them first.
|
||||||
|
return dispatch('group/fetchAll', {}, { root: true }).then(() => {
|
||||||
|
return selectGroupAndApplication(data.data.group.id, id)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// The groups are already loaded so we
|
||||||
|
return selectGroupAndApplication(data.data.group.id, id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +260,9 @@ export const getters = {
|
||||||
isLoading(state) {
|
isLoading(state) {
|
||||||
return state.loading
|
return state.loading
|
||||||
},
|
},
|
||||||
|
get: state => id => {
|
||||||
|
return state.items.find(item => item.id === id)
|
||||||
|
},
|
||||||
applicationTypeExists: state => type => {
|
applicationTypeExists: state => type => {
|
||||||
return state.applications.hasOwnProperty(type)
|
return state.applications.hasOwnProperty(type)
|
||||||
},
|
},
|
||||||
|
|
|
@ -135,7 +135,6 @@ export const actions = {
|
||||||
return GroupService.delete(group.id)
|
return GroupService.delete(group.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (group._.selected) {
|
if (group._.selected) {
|
||||||
console.log('calling unselect')
|
|
||||||
dispatch('unselect', group)
|
dispatch('unselect', group)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +158,16 @@ export const actions = {
|
||||||
setGroupCookie(group.id, this.app.$cookies)
|
setGroupCookie(group.id, this.app.$cookies)
|
||||||
return dispatch('application/fetchAll', group, { root: true })
|
return dispatch('application/fetchAll', group, { root: true })
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Select a group by a given group id.
|
||||||
|
*/
|
||||||
|
selectById({ dispatch, getters }, id) {
|
||||||
|
const group = getters.get(id)
|
||||||
|
if (group === undefined) {
|
||||||
|
throw new Error(`Group with id ${id} is not found.`)
|
||||||
|
}
|
||||||
|
return dispatch('select', group)
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Unselect a group if selected and clears all the fetched applications.
|
* Unselect a group if selected and clears all the fetched applications.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue