Add a Project Group Detail view
This commit is contained in:
parent
d08c39d7d0
commit
9816c566e9
52
src/components/ProjectGroupTabProjects.vue
Normal file
52
src/components/ProjectGroupTabProjects.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<div class="project-group-project-list">
|
||||||
|
<Spinner v-if="loading" :fullScreen="true" />
|
||||||
|
<ProjectFilters @filter-change="getProjects" />
|
||||||
|
<ProjectListItem v-for="project in projects" :key="project.id" :project="project" />
|
||||||
|
<div v-if="!projects.length">
|
||||||
|
No matching stories found.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import project from '@/api/project.js'
|
||||||
|
|
||||||
|
import ProjectFilters from '@/components/ProjectFilters.vue'
|
||||||
|
import ProjectListItem from '@/components/ProjectListItem.vue'
|
||||||
|
import Spinner from '@/components/Spinner.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ProjectGroupTabStories',
|
||||||
|
props: ['projectGroup'],
|
||||||
|
components: {
|
||||||
|
ProjectFilters,
|
||||||
|
ProjectListItem,
|
||||||
|
Spinner
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
projects: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.getProjects(this.$route.query)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getProjects (filters = {}) {
|
||||||
|
this.$router.push({ query: filters })
|
||||||
|
const params = {
|
||||||
|
...filters,
|
||||||
|
project_group_id: this.projectGroup.id,
|
||||||
|
limit: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
this.projects = []
|
||||||
|
this.loading = true
|
||||||
|
this.projects = await project.browse(params)
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
52
src/components/ProjectGroupTabStories.vue
Normal file
52
src/components/ProjectGroupTabStories.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<div class="project-story-list">
|
||||||
|
<StoryFilters @filter-change="getStories" />
|
||||||
|
<Spinner v-if="loading" :fullScreen="true" />
|
||||||
|
<StoryListItem v-for="story in stories" :key="story.id" :story="story" />
|
||||||
|
<div v-if="!stories.length">
|
||||||
|
No matching stories found.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import story from '@/api/story.js'
|
||||||
|
|
||||||
|
import Spinner from '@/components/Spinner.vue'
|
||||||
|
import StoryFilters from '@/components/StoryFilters.vue'
|
||||||
|
import StoryListItem from '@/components/StoryListItem.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ProjectGroupTabStories',
|
||||||
|
props: ['projectGroup'],
|
||||||
|
components: {
|
||||||
|
Spinner,
|
||||||
|
StoryFilters,
|
||||||
|
StoryListItem
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
stories: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.getStories(this.$route.query)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getStories (filters = {}) {
|
||||||
|
this.$router.push({ query: filters })
|
||||||
|
const params = {
|
||||||
|
...filters,
|
||||||
|
project_group_id: this.projectGroup.id,
|
||||||
|
limit: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stories = []
|
||||||
|
this.loading = true
|
||||||
|
this.stories = await story.browse(params)
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -51,6 +51,10 @@ const routes = [
|
|||||||
name: 'Project Groups',
|
name: 'Project Groups',
|
||||||
component: () => import(/* webpackChunkName: "projectgroup" */ '../views/ProjectGroupList.vue')
|
component: () => import(/* webpackChunkName: "projectgroup" */ '../views/ProjectGroupList.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/project-group/:id',
|
||||||
|
component: () => import(/* webpackChunkName: "projectgroup-detail" */ '../views/ProjectGroupDetail.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/user',
|
path: '/user',
|
||||||
name: 'Users',
|
name: 'Users',
|
||||||
|
95
src/views/ProjectGroupDetail.vue
Normal file
95
src/views/ProjectGroupDetail.vue
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div class="project-detail">
|
||||||
|
<div class="header-row">
|
||||||
|
<h1>{{ projectGroup.title }}</h1>
|
||||||
|
</div>
|
||||||
|
<ul class="tabs">
|
||||||
|
<li class="tab" :class="{ active: currentTab === tab }" v-for="tab in tabs" :key="tab.name" @click="switchToTab(tab)">
|
||||||
|
{{ tab.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<component :is="currentTab.component" :projectGroup="projectGroup"></component>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import projectGroup from '@/api/project_group.js'
|
||||||
|
|
||||||
|
import ProjectGroupTabProjects from '@/components/ProjectGroupTabProjects.vue'
|
||||||
|
import ProjectGroupTabStories from '@/components/ProjectGroupTabStories.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ProjectGroupDetailView',
|
||||||
|
components: {
|
||||||
|
ProjectGroupTabProjects,
|
||||||
|
ProjectGroupTabStories
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
currentTab: {},
|
||||||
|
projectGroup: {},
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
name: 'Projects in this Group',
|
||||||
|
component: ProjectGroupTabProjects
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Stories related to this Group',
|
||||||
|
component: ProjectGroupTabStories
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.getProject(this.$route.params.id)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getProject (projectGroupId) {
|
||||||
|
this.projectGroup = await projectGroup.get(projectGroupId)
|
||||||
|
if (Object.keys(this.$route.query).length !== 0) {
|
||||||
|
this.currentTab = this.tabs[1]
|
||||||
|
} else {
|
||||||
|
this.currentTab = this.tabs[0]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
switchToTab (tab) {
|
||||||
|
if (tab !== this.tabs[1]) {
|
||||||
|
// If we're navigating away from the Stories tab, clear
|
||||||
|
// the query string to keep the URL intuitive when shared.
|
||||||
|
this.$router.replace({ query: {} })
|
||||||
|
}
|
||||||
|
this.currentTab = tab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.project-detail {
|
||||||
|
.tabs {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
//margin: 20px 15% 10px 15%;
|
||||||
|
padding: 0;
|
||||||
|
border-bottom: solid 1px #ddd;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 100ms ease-in-out all;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 -1px 0 inset #c43422;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #c43422;
|
||||||
|
box-shadow: 0 -2px 0 inset #c43422;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
x
Reference in New Issue
Block a user