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
12 changes: 12 additions & 0 deletions structures-frontend-next/src/components/CrudTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ConfirmDialog from "primevue/confirmdialog";
import Card from "primevue/card";
import Paginator, { type PageState } from "primevue/paginator";
import SelectButton from "primevue/selectbutton";
import { useToast } from "primevue/usetoast";

import {
type IDataSource,
Expand Down Expand Up @@ -63,6 +64,8 @@ class CrudTable extends Vue {
@Prop({ default: true }) enableRowHover!: boolean
@Prop({ default: 10 }) defaultPageSize!: number

private toast = useToast()

getRowClass() {
return {
"dynamic-hover": this.enableRowHover,
Expand Down Expand Up @@ -250,6 +253,15 @@ class CrudTable extends Vue {
this.initialSearchCompleted = true;
});
}

displayAlert(text: string) {
this.toast.add({
severity: 'error',
summary: 'Error',
detail: text,
life: 3000
});
}
}

export default toNative(CrudTable);
Expand Down
57 changes: 55 additions & 2 deletions structures-frontend-next/src/components/ProjectStructuresTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,65 @@ export default class ProjectStructuresTable extends Vue {
this.markProjectAsActive()
}

@Watch('applicationId', { immediate: true })
onApplicationIdChange(newApplicationId: string, oldApplicationId: string) {
console.log('ProjectStructuresTable: applicationId changed from', oldApplicationId, 'to', newApplicationId)
this.refreshTable()
this.markProjectAsActive()
}

@Watch('APPLICATION_STATE.currentApplication', { immediate: true })
async onGlobalApplicationChange(newApp: any, oldApp: any) {
console.log('ProjectStructuresTable: Global APPLICATION_STATE.currentApplication changed from', oldApp?.id, 'to', newApp?.id)

if (this.isProjectStructuresPage && newApp && newApp.id !== oldApp?.id) {
await this.handleApplicationChangeForProjectStructures(newApp)
} else {
this.refreshTable()
this.markProjectAsActive()
}
}

get isProjectStructuresPage(): boolean {
return /^\/application\/[^/]+\/project\/[^/]+\/structures$/.test(this.$route.path)
}

async handleApplicationChangeForProjectStructures(newApp: any) {
try {
console.log('ProjectStructuresTable: Handling application change for ProjectStructures page')

const pageable = { pageNumber: 0, pageSize: 1 } as any
const result = await Structures.getProjectService().findAllForApplication(newApp.id, pageable)
const firstProject = result.content?.[0]

if (firstProject) {
console.log('ProjectStructuresTable: Found first project:', firstProject.name, 'navigating to it')

const applicationId = newApp.id
const projectId = firstProject.id ?? ''
await this.$router.push(`/application/${encodeURIComponent(applicationId)}/project/${encodeURIComponent(projectId)}/structures`)
} else {
console.log('ProjectStructuresTable: No projects found for application:', newApp.id)
this.refreshTable()
this.markProjectAsActive()
}
} catch (error) {
console.error('ProjectStructuresTable: Error handling application change:', error)
this.refreshTable()
this.markProjectAsActive()
}
}

get dataSource() {
return {
findAll: async (pageable: Pageable): Promise<IterablePage<Structure>> => {
console.log('ProjectStructuresTable: dataSource.findAll called with projectId:', this.projectId, 'and currentApplication:', APPLICATION_STATE.currentApplication?.id)
const result = await Structures.getStructureService().findAllForProject(this.projectId, pageable)
APPLICATION_STATE.structuresCount = result.totalElements ?? 0
return result
},
search: async (_searchText: string, pageable: Pageable): Promise<IterablePage<Structure>> => {
console.log('ProjectStructuresTable: dataSource.search called with projectId:', this.projectId, 'and currentApplication:', APPLICATION_STATE.currentApplication?.id)
const search = `projectId:${this.projectId} && ${this.searchText}`
return Structures.getStructureService().search(search, pageable)
}
Expand Down Expand Up @@ -122,8 +173,10 @@ export default class ProjectStructuresTable extends Vue {
}

openPublishModal(item: Structure) {
console.log('ProjectStructuresTable: openPublishModal called for item:', item.name);
this.selectedStructure = item
this.showPublishModal = true
console.log('ProjectStructuresTable: showPublishModal set to:', this.showPublishModal);
}

closePublishModal() {
Expand Down Expand Up @@ -151,8 +204,10 @@ export default class ProjectStructuresTable extends Vue {

handleRowClick(item: Structure) {
if (item.published) {
console.log('ProjectStructuresTable: Opening data modal for published structure');
this.openModal(item)
} else {
console.log('ProjectStructuresTable: Opening publish modal for unpublished structure');
this.openPublishModal(item)
}
}
Expand Down Expand Up @@ -331,7 +386,6 @@ export default class ProjectStructuresTable extends Vue {
@close="closeModal"
/>

<!-- Publish Modal -->
<Dialog
v-model:visible="showPublishModal"
modal
Expand Down Expand Up @@ -373,7 +427,6 @@ export default class ProjectStructuresTable extends Vue {
</template>
</Dialog>

<!-- Unpublish Modal -->
<Dialog
v-model:visible="showUnpublishModal"
modal
Expand Down
2 changes: 0 additions & 2 deletions structures-frontend-next/src/components/StructuresList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ export default class StructuresList extends Vue {
} catch (error: any) {
delete item["publishing"];
console.error('Error unpublishing structure:', error);
// You could add a toast notification here if needed
}
}

Expand Down Expand Up @@ -332,7 +331,6 @@ export default class StructuresList extends Vue {
@close="closeItemModal"
/>

<!-- Publish Modal -->
<Dialog
v-model:visible="showPublishModal"
modal
Expand Down
6 changes: 6 additions & 0 deletions structures-frontend-next/src/layouts/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ export default class Header extends Vue {

await this.loadProjectsForCurrentApp();

if (this.isProjectStructuresPage && this.projectsForCurrentApp.length > 0) {
const firstProject = this.projectsForCurrentApp[0];
console.log('Header: Auto-selecting first project for ProjectStructures page:', firstProject.name);
this.selectProject(firstProject);
}

this.$emit('application-changed', app);
}

Expand Down
3 changes: 2 additions & 1 deletion structures-frontend-next/src/pages/EntityList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ if (!id) {
}

displayAlert(text: string) {
alert(text)
console.log(text)
// alert(text)
}

find() {
Expand Down
14 changes: 12 additions & 2 deletions structures-frontend-next/src/pages/ProjectStructuresPage.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
<script lang="ts" setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
import { computed, watch } from 'vue'
import ProjectStructuresTable from '@/components/ProjectStructuresTable.vue'
import { APPLICATION_STATE } from '@/states/IApplicationState'

const route = useRoute()
const projectId = computed(() => route.params.projectId as string)
const applicationId = computed(() => APPLICATION_STATE.currentApplication?.id || '')

watch(() => APPLICATION_STATE.currentApplication, (newApp) => {
console.log('ProjectStructuresPage: APPLICATION_STATE.currentApplication changed to:', newApp?.id)
}, { deep: true })

watch(applicationId, (newId) => {
console.log('ProjectStructuresPage: applicationId computed changed to:', newId)
})
</script>

<template>
<div class="p-6">
<h1 class="text-2xl font-semibold mb-4 text-surface-950">
{{ projectId }}
</h1>
<ProjectStructuresTable :projectId="projectId" />
<ProjectStructuresTable :key="`${applicationId}-${projectId}`" :applicationId="applicationId" />
</div>
</template>
87 changes: 13 additions & 74 deletions structures-frontend-next/src/pages/login/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,7 @@
<img src="@/assets/login-page-logo-new.svg" class="absolute left-[75px] bottom-[56px] max-w-[300px] h-[63px] w-auto xl:max-w-[300px] xl:h-[63px] lg:max-w-[250px] lg:h-[52px] md:max-w-[200px] md:h-[42px] sm:max-w-[150px] sm:h-[32px]"/>
</div>
<div class="w-1/2 h-full flex flex-col justify-center items-center bg-center bg-cover relative">
<div v-if="showSuccessMessage" class="w-full h-full flex flex-col justify-center items-center text-center">
<div class="mb-6">
<div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
</div>
<h2 class="text-4xl font-semibold text-surface-900 mb-4">Authentication successful</h2>
<p class="text-surface-900 text-base font-normal">You can close this tab and return to your command line</p>
</div>
</div>

<div v-if="!showSuccessMessage" class="w-[320px] flex flex-col items-center">
<div class="w-[320px] flex flex-col items-center">
<img src="@/assets/login-page-logo.svg" class="w-[218px] h-[45px] mb-[53px]" />

<div v-if="isInitialized && shouldShowLoginForm">
Expand Down Expand Up @@ -254,10 +242,6 @@ export default class Login extends Vue {

private _isConfigLoaded: boolean = false;
private _isBasicAuthEnabled: boolean = true;

private showSuccessMessage: boolean = false;
private countdown: number = 2;
private countdownInterval: NodeJS.Timeout | null = null;

get isConfigLoaded() { return this._isConfigLoaded; }
get isBasicAuthEnabled() { return this._isBasicAuthEnabled; }
Expand Down Expand Up @@ -375,12 +359,8 @@ export default class Login extends Vue {

await this.userState.handleOidcLogin(user);

if (referer) {
this.$route.query.referer = referer;
}

this.showSuccessMessage = true;
this.startCountdown();
const redirectPath = referer || '/applications';
await CONTINUUM_UI.navigate(redirectPath);
} catch (error: unknown) {
console.error('OIDC callback error:', error);
if (error instanceof Error) {
Expand All @@ -406,8 +386,16 @@ export default class Login extends Vue {
try {
await this.userState.authenticate(this.login, this.password);

this.showSuccessMessage = true;
this.startCountdown();
if (this.referer) {
await CONTINUUM_UI.navigate(this.referer);
} else {
const redirectPath = this.$route.redirectedFrom?.fullPath;
if (redirectPath && redirectPath !== "/") {
await CONTINUUM_UI.navigate(redirectPath);
} else {
await CONTINUUM_UI.navigate('/applications');
}
}
} catch (error: unknown) {
console.error('Authentication error:', error);
if (error instanceof Error) {
Expand Down Expand Up @@ -577,54 +565,5 @@ export default class Login extends Vue {
}
}

private startCountdown() {
this.countdown = 2;

this.countdownInterval = setInterval(() => {
this.countdown--;

if (this.countdown <= 0) {
this.clearCountdown();
this.redirectAfterSuccess();
}
}, 1000);
}

private clearCountdown() {
if (this.countdownInterval) {
clearInterval(this.countdownInterval);
this.countdownInterval = null;
}
}

private async redirectAfterSuccess() {
try {
const refererFromQuery = this.$route.query.referer as string;
if (refererFromQuery) {
await CONTINUUM_UI.navigate(refererFromQuery);
return;
}

if (this.referer) {
await CONTINUUM_UI.navigate(this.referer);
return;
}

const redirectPath = this.$route.redirectedFrom?.fullPath;
if (redirectPath && redirectPath !== "/") {
await CONTINUUM_UI.navigate(redirectPath);
return;
}

await CONTINUUM_UI.navigate('/applications');
} catch (error) {
console.error('Redirect error:', error);
await CONTINUUM_UI.navigate('/applications');
}
}

beforeUnmount() {
this.clearCountdown();
}
}
</script>