Skip to content
Open
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
41 changes: 8 additions & 33 deletions frontend/__tests__/components/GLogin.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ describe('components', () => {
let loginStore // eslint-disable-line no-unused-vars
let localStorageStore
let mockRoute
let mockRouter
let mockNext

function mountLogin () {
return mount(GLogin, {
Expand All @@ -49,7 +47,6 @@ describe('components', () => {
],
mocks: {
$route: mockRoute,
$router: mockRouter,
},
},
})
Expand All @@ -73,10 +70,6 @@ describe('components', () => {
redirectPath: '/namespace/garden/shoots',
},
}
mockRouter = {
push: vi.fn(),
replace: vi.fn(),
}
pinia = createTestingPinia({
stubActions: false,
initialState: {
Expand Down Expand Up @@ -120,25 +113,17 @@ describe('components', () => {
title: error.title,
}),
}
mockNext = vi.fn().mockImplementation(fn => {
if (typeof fn === 'function') {
fn(wrapper.vm)
}
})
await GLogin.beforeRouteEnter.call(wrapper.vm, to, undefined, mockNext)
expect(wrapper.vm.error.message).toBe(error.message)
await GLogin.beforeRouteUpdate.call(wrapper.vm, undefined, undefined, () => {})
expect(mockNext).toBeCalledTimes(1)
expect(mockNext.mock.calls[0]).toEqual([expect.any(Function)])

await GLogin.beforeRouteEnter.call(wrapper.vm, to, undefined)
expect(wrapper.vm.loginError.message).toBe(error.message)
await GLogin.mounted.call(wrapper.vm)
expect(appStore.setError).toBeCalledTimes(1)
expect(appStore.setError.mock.calls[0]).toEqual([
expect.objectContaining({
message: 'error',
title: 'title',
}),
])
expect(mockRouter.replace).toBeCalledTimes(1)
expect(mockRouter.replace.mock.calls[0]).toEqual(['/login'])
})

it('should not show a login error', async () => {
Expand All @@ -150,17 +135,10 @@ describe('components', () => {
title: error.title,
}),
}
mockNext = vi.fn().mockImplementation(fn => {
if (typeof fn === 'function') {
fn(wrapper.vm)
}
})
await GLogin.beforeRouteEnter.call(wrapper.vm, to, undefined, mockNext)
expect(mockNext).toBeCalledTimes(1)
expect(mockNext.mock.calls[0]).toEqual([expect.any(Function)])

await GLogin.beforeRouteEnter.call(wrapper.vm, to, undefined)
await GLogin.mounted.call(wrapper.vm)
expect(appStore.setError).not.toBeCalled()
expect(mockRouter.replace).toBeCalledTimes(1)
expect(mockRouter.replace.mock.calls[0]).toEqual(['/login'])
})

it('should automatically login', async () => {
Expand All @@ -171,10 +149,7 @@ describe('components', () => {
redirectPath: '/namespace/garden-foo/shoots',
},
}
mockNext = vi.fn()
await GLogin.beforeRouteEnter.call(wrapper.vm, to, undefined, mockNext)
expect(mockNext).toBeCalledTimes(1)
expect(mockNext.mock.calls[0]).toEqual([false])
await GLogin.beforeRouteEnter.call(wrapper.vm, to, undefined)
expect(authnStore.signinWithOidc).toBeCalledTimes(1)
expect(authnStore.signinWithOidc.mock.calls[0]).toEqual([to.query.redirectPath])
})
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/layouts/GDefault.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ function onClick () {
}

// hooks
onBeforeRouteUpdate((to, from, next) => {
onBeforeRouteUpdate(() => {
mainContent.value?.setScrollTop(0)
next()
})

onMounted(() => {
Expand Down
31 changes: 13 additions & 18 deletions frontend/src/layouts/GLogin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default {
GNotify,
},
inject: ['api'],
async beforeRouteEnter (to, from, next) {
async beforeRouteEnter (to) {
let err
if (/^#.+/.test(to.hash)) {
const searchParams = new URLSearchParams(to.hash.substring(1))
Expand All @@ -168,31 +168,18 @@ export default {
const redirectPath = get(to.query, ['redirectPath'], '/')
const authnStore = useAuthnStore()
authnStore.signinWithOidc(redirectPath)
return next(false)
return false
}

next(vm => {
if (err) {
if (err.message !== 'NoAutoLogin') {
vm.error = err
}
vm.$router.replace('/login')
}
})
},
beforeRouteUpdate (to, from, next) {
if (this.error) {
const err = this.error
this.error = null
this.setError(err)
if (err && err.message !== 'NoAutoLogin') {
loginStore.loginError = err
return { path: '/login', replace: true }
}
next()
},
data () {
return {
showToken: false,
token: '',
error: null,
}
},
computed: {
Expand All @@ -203,6 +190,7 @@ export default {
]),
...mapWritableState(useLoginStore, [
'loginType',
'loginError',
]),
breakpointName () {
return this.$vuetify.display.name
Expand Down Expand Up @@ -281,6 +269,13 @@ export default {
immediate: true,
},
},
mounted () {
if (this.loginError) {
const err = this.loginError
this.loginError = null
this.setError(err)
}
},
methods: {
...mapActions(useAppStore, [
'setError',
Expand Down
18 changes: 8 additions & 10 deletions frontend/src/views/GNewShoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -174,30 +174,28 @@ export default {
GToolbar,
},
inject: ['api', 'logger'],
async beforeRouteLeave (to, from, next) {
async beforeRouteLeave (to) {
if (!this.sortedInfraProviderTypeList.length) {
return next()
return true
}

if (to.name === 'NewShootEditor') {
if (this.v$.$invalid && !await this.confirmNavigateToYamlIfInvalid()) {
return next(false)
return false
}
return next()
return true
}

if (!this.isShootCreated && this.isShootDirty && !await this.confirmNavigation()) {
return next(false)
return false
}

return next()
},
async beforeRouteUpdate (to, from, next) {
async beforeRouteUpdate () {
if (!this.isShootCreated && this.isShootDirty && !await this.confirmNavigation()) {
return next(false)
return false
}

return next()
return true
},
setup () {
const {
Expand Down
18 changes: 9 additions & 9 deletions frontend/src/views/GNewShootEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,35 +123,35 @@ async function save () {
}
}

onBeforeRouteLeave(async (to, from, next) => {
onBeforeRouteLeave(async to => {
if (to.name === 'NewShoot') {
try {
setShootManifest(getEditorValue())
return next()
return true
} catch (err) {
errorMessage.value = err.message
return next(false)
return false
}
}
if (isShootCreated.value) {
return next()
return true
}
if (!clean.value || isShootDirty.value) {
if (!await confirmEditorNavigation()) {
focusEditor()
return next(false)
return false
}
}
return next()
return true
})

onBeforeRouteUpdate(async (to, from, next) => {
onBeforeRouteUpdate(async () => {
if (!clean.value || isShootDirty.value) {
if (!await confirmEditorNavigation()) {
focusEditor()
return next(false)
return false
}
}
return next()
return true
})
</script>
18 changes: 7 additions & 11 deletions frontend/src/views/GShootItemEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,15 @@ function confirmOverwrite () {
})
}

onBeforeRouteLeave(async (to, from, next) => {
onBeforeRouteLeave(async () => {
if (clean.value) {
return next()
return true
}
try {
if (await confirmEditorNavigation()) {
next()
} else {
focusEditor()
next(false)
}
} catch (err) {
next(err)
if (await confirmEditorNavigation()) {
return true
} else {
focusEditor()
return false
}
})
</script>
11 changes: 5 additions & 6 deletions frontend/src/views/GShootList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export default {
GTableSearch,
},
inject: ['logger'],
beforeRouteUpdate (to, from, next) {
beforeRouteUpdate (to, from) {
if (to.path !== from.path) {
this.setShootSearch('')
}
Expand All @@ -191,14 +191,10 @@ export default {
// Reset expanded state in case project changes
this.resetState(this.expandedWorkerGroups, { default: false })
this.resetState(this.expandedAccessRestrictions, { default: false })

next()
},
beforeRouteLeave (to, from, next) {
beforeRouteLeave () {
this.setShootSearch('')
this.focusModeInternal = false

next()
},
setup () {
const projectStore = useProjectStore()
Expand Down Expand Up @@ -692,6 +688,9 @@ export default {
}
},
},
mounted () {
this.updateTableSettings()
},
methods: {
...mapActions(useShootStore, [
'toogleShootListFilter',
Expand Down
Loading