Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion web-app/packages/app/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default defineComponent({
})
},
async created() {
this.init()
await this.fetchConfig()
if (this.loggedUser) {
// here is loaded current workspace on startup (and reloaded in watcher when user has changed)
Expand Down Expand Up @@ -161,7 +162,8 @@ export default defineComponent({
...mapActions(useAppStore, ['setServerError']),
...mapActions(useInstanceStore, ['fetchPing', 'fetchConfig', 'initApp']),
...mapActions(useNotificationStore, { notificationError: 'error' }),
...mapActions(useUserStore, ['checkCurrentWorkspace', 'updateLoggedUser'])
...mapActions(useUserStore, ['checkCurrentWorkspace', 'updateLoggedUser']),
...mapActions(useLayoutStore, ['init'])
}
})
</script>
Expand Down
91 changes: 64 additions & 27 deletions web-app/packages/app/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
FileBrowserView,
FileVersionDetailView,
ProjectVersionsView,
VersionDetailView,
NotFoundView,
VerifyEmailView,
routeUtils,
Expand Down Expand Up @@ -84,7 +83,7 @@ export const createRouter = (pinia: Pinia) => {
sidebar: SideBar
},
meta: {
title: 'Dashboard'
breadcrump: [{ title: 'Dashboard', path: '/dashboard' }]
},
props: {
default: true
Expand Down Expand Up @@ -112,7 +111,11 @@ export const createRouter = (pinia: Pinia) => {
props: {
default: true
},
meta: { public: true, title: 'Projects' },
meta: {
public: true,
title: 'Projects',
breadcrump: [{ title: 'Projects', path: '/projects' }]
},
children: [
{
path: 'explore',
Expand Down Expand Up @@ -146,6 +149,21 @@ export const createRouter = (pinia: Pinia) => {
return
}
},
/** Redirect of unused /history/:version_id path to /history?version_id */
Comment thread
MarcelGeo marked this conversation as resolved.
{
path: '/projects/:namespace/:projectName/history/:version_id',
name: 'project-versions-detail',
component: NotFoundView,
props: true,
meta: { public: true },
beforeEnter: (to, from, next) => {
next({
path: `/projects/${to.params.namespace}/${to.params.projectName}/history`,
query: { version_id: to.params.version_id }
})
return
}
},
{
path: '/projects/:namespace/:projectName',
name: 'project',
Expand All @@ -158,7 +176,7 @@ export const createRouter = (pinia: Pinia) => {
default: true
},
meta: {
title: 'Projects'
breadcrump: [{ title: 'Projects', path: '/projects' }]
},
redirect: { name: 'project-tree' },

Expand All @@ -182,36 +200,55 @@ export const createRouter = (pinia: Pinia) => {
component: ProjectVersionsView,
props: true
},
{
path: 'history/:version_id',
name: 'project-versions-detail',
component: VersionDetailView,
props: true
},
{
path: 'history/:version_id/:path',
name: 'file-version-detail',
component: FileVersionDetailView,
props: true,
meta: { public: true }
}
].map((child) => ({
...child,
beforeEnter: (to, from, next) => {
// added project name to matched route
to.matched = to.matched.map((route) => ({
...route,
meta: {
...route.meta,
title:
route.name === to.name
? (to.params.projectName as string)
: route.meta.title
meta: { public: true },
// TODO: refactor to function in utils
beforeEnter(to, from, next) {
to.meta = {
...to.meta,
breadcrump: [
{
title: String(to.params.projectName),
path: `/projects/${to.params.namespace}/${to.params.projectName}/history`
},
{
title: String(to.params.version_id),
path: `/projects/${to.params.namespace}/${to.params.projectName}/history/${to.params.version_id}`
},
{
title: String(to.params.path),
path: to.fullPath
}
]
}
}))
next()
next()
}
}
}))
]
// Not apply for project version detail , which have own breadcrump
.map((child) =>
child.name === 'file-version-detail'
? child
: {
...child,
beforeEnter: (to, from, next) => {
to.meta = {
...to.meta,
breadcrump: [
{
title: String(to.params.projectName),
path: to.fullPath
}
]
}
next()
}
}
)
},
{
path: '/:pathMatch(.*)*',
Expand Down
2 changes: 1 addition & 1 deletion web-app/packages/app/src/shims-vue-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ declare module 'vue-router' {
interface RouteMeta {
public?: boolean
allowedForNoWorkspace?: boolean
title?: string
breadcrump?: { title: string; path: string }[]
}
}
5 changes: 3 additions & 2 deletions web-app/packages/lib/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ export {}

declare module 'vue' {
export interface GlobalComponents {
PAccordion: typeof import('primevue/accordion')['default']
PAccordionTab: typeof import('primevue/accordiontab')['default']
PAvatar: typeof import('primevue/avatar')['default']
PBreadcrumb: typeof import('primevue/breadcrumb')['default']
PButton: typeof import('primevue/button')['default']
PColumn: typeof import('primevue/column')['default']
PDataTable: typeof import('primevue/datatable')['default']
PDataView: typeof import('primevue/dataview')['default']
PDialog: typeof import('primevue/dialog')['default']
PDivider: typeof import('primevue/divider')['default']
PDropdown: typeof import('primevue/dropdown')['default']
PImage: typeof import('primevue/image')['default']
PInlineMessage: typeof import('primevue/inlinemessage')['default']
Expand Down Expand Up @@ -47,8 +50,6 @@ declare module 'vue' {
VIcon: typeof import('vuetify/components')['VIcon']
VImg: typeof import('vuetify/components')['VImg']
VLayout: typeof import('vuetify/components')['VLayout']
VList: typeof import('vuetify/components')['VList']
VListGroup: typeof import('vuetify/components')['VListGroup']
VListItem: typeof import('vuetify/components')['VListItem']
VListItemSubtitle: typeof import('vuetify/components')['VListItemSubtitle']
VListItemTitle: typeof import('vuetify/components')['VListItemTitle']
Expand Down
2 changes: 1 addition & 1 deletion web-app/packages/lib/src/common/components/AppSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-MerginMaps-Commercial
:class="[
ground
? 'surface-ground'
: 'surface-section border-round-2xl overflow-hidden'
: 'surface-section border-round-xl overflow-hidden'
]"
>
<header
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const model = computed({
get() {
return props.modelValue
},
set(value) {
set() {
return emitModelValue('update:modelValue')
}
})
Expand Down
1 change: 1 addition & 0 deletions web-app/packages/lib/src/modules/dashboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
export * from './components'
export * from './module'
export * from './views'
export * from './routes'
12 changes: 12 additions & 0 deletions web-app/packages/lib/src/modules/dashboard/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (C) Lutra Consulting Limited
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-MerginMaps-Commercial

/**
* Enum for route names in the app's router.
* Defines string constants for each route path used by project module.
* Feel free to use it in application router as name attribute and in redirects from lib or app
*/
export enum DashboardRouteName {
Dashboard = 'dashboard'
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-MerginMaps-Commercial
>
<template #item="{ item, props }">
<router-link
v-if="item.route"
v-if="item.path"
v-slot="{ href, navigate }"
:to="{
params: item.params,
name: item.route
path: item.path
}"
custom
>
Expand All @@ -46,14 +45,32 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-MerginMaps-Commercial
import { MenuItem } from 'primevue/menuitem'
import { useRoute } from 'vue-router'

type EnhancedMenuItem = MenuItem & { path: string; active?: boolean }

const route = useRoute()
const items: MenuItem[] = route.matched
.filter((item) => item.meta.title)
.map<MenuItem>((item) => ({
label: item.meta.title,
active: route.name === item.name,
route: item.name,
params: route.params
// Merge all matched meta.breadcrumps with current route breadcrumps
const items = [
...route.matched.reduce<EnhancedMenuItem[]>((acc, curr) => {
if (curr.name === route.name) return acc

return [
...acc,
...(curr.meta?.breadcrump ?? []).map((item) => ({
label: item.title,
path: item.path
}))
]
}, []),
// adding current route wich is not in matched meta
...(route.meta.breadcrump ?? []).map((item) => ({
label: item.title,
path: item.path
}))
]
// last will be active
.map((item, index, items) => ({
...item,
active: index === items.length - 1
}))
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ export default defineComponent({
</script>

<template>
<li>
<li class="p-2">
<router-link
:class="[
'sidebar-item__link p-4 flex align-items-center transition-color transition-duration-200 no-underline',
'sidebar-item__link px-3 py-2 flex align-items-center transition-color transition-duration-200 no-underline border-round-lg text-sm',
item.active && 'sidebar-item__link--active'
]"
:to="item.to"
><div class="mr-2"><i :class="['text-2xl', item.icon]"></i></div>
><div class="mr-2"><i :class="['text-xl', item.icon]"></i></div>
<span>{{ item.title }}</span></router-link
>
</li>
Expand All @@ -41,8 +41,8 @@ export default defineComponent({
}

&--active {
color: var(--surface-a);
background-color: var(--forest-color);
color: var(--forest-color);
background-color: var(--light-green-color);
font-weight: 600;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,30 @@ import { useRoute } from 'vue-router'

import { SideBarItemModel } from '../types'

import { DashboardRouteName } from '@/main'
import SideBarItem from '@/modules/layout/components/SideBarItem.vue'
import { useLayoutStore } from '@/modules/layout/store'
import { ProjectRouteName } from '@/modules/project'

const route = useRoute()
const layoutStore = useLayoutStore()
layoutStore.init()

const currentPage = computed(() => route.name)

const initialSidebarItems = computed<SideBarItemModel[]>(() => {
return [
{
active: currentPage.value === 'dashboard',
active: route.matched.some(
(item) => item.name === DashboardRouteName.Dashboard
),
title: 'Dashboard',
to: '/dashboard',
icon: 'ti ti-home'
},
{
active: currentPage.value === 'projects',
active: route.matched.some(
(item) =>
item.name === ProjectRouteName.Projects ||
item.name === ProjectRouteName.Project
),
title: 'Projects',
to: '/projects',
icon: 'ti ti-article'
Expand Down
14 changes: 9 additions & 5 deletions web-app/packages/lib/src/modules/project/components/DropArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ import { useInstanceStore } from '@/modules/instance/store'
import { useNotificationStore } from '@/modules/notification/store'
import { useProjectStore } from '@/modules/project/store'

type ExtendedFile = File & { isFile: boolean }

export default defineComponent({
props: ['location'],
data() {
Expand Down Expand Up @@ -114,9 +116,9 @@ export default defineComponent({
})
}
// prepare all entries because they will be not accessible after this callback ends (after 'await')
const entries = Array.from(evt.dataTransfer.items).map(
(i: DataTransferItem) => i.webkitGetAsEntry()
)
const entries = Array.from(
evt.dataTransfer.items as DataTransferItem[]
).map((i) => i.webkitGetAsEntry())
if (entries.some((e) => e === null)) {
return this.error({
text: 'Drop only files or folders'
Expand All @@ -129,9 +131,11 @@ export default defineComponent({
this.$refs.selectFilesInput.click()
}
},
onFileSelected(evt) {
onFileSelected(evt: Event) {
// prepare all entries because they will be not accessible after this callback ends (after 'await')
const entries = Array.from(evt.target.files).map((i: any) => {
const entries = Array.from(
(evt.target as HTMLInputElement).files as unknown as ExtendedFile[]
).map((i) => {
i.isFile = true
return i
})
Expand Down
Loading