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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
-->

<div class="container-fluid p-0 page-container">
<!-- Header -->
<div class="w-100 text-white text-center py-2 page-header">
(HEADER)
</div>
@if (loading()) {
<div class="container py-5">
<div class="d-flex justify-content-center align-items-center loading-container">
Expand Down Expand Up @@ -514,13 +518,6 @@ <h3 class="h5 mb-0">
}
</div>

<!-- Back Button -->
<div class="mt-4 ps-4">
<button class="btn btn-back d-flex align-items-center" (click)="goBack()">
<i class="fa-solid fa-arrow-left icon-md me-2"></i>
Back to Integration Catalog
</button>
</div>
</div>

<!-- Right Panel - Sidebar -->
Expand Down Expand Up @@ -596,6 +593,14 @@ <h6 class="text-muted small mb-1">Installations</h6>
</div>
</div>
</div>

<!-- Back Button -->
<div class="mt-4 ps-4">
<button class="btn btn-back d-flex align-items-center" (click)="goBack()">
<i class="fa-solid fa-arrow-left icon-md me-2"></i>
Back to Integration Catalog
</button>
</div>
</div>

<!-- Fixed Position Filter Dropdowns -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
.text-title {
color: #1a202c;
font-weight: 600;
font-size: 2rem;
}

.text-body {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
-->

<div class="container-fluid p-0 position-relative page-bg">
<!-- Header -->
<div class="w-100 text-white text-center py-2 page-header">
(HEADER)
</div>
<!-- Login Required Toast Notification -->
@if (showLoginRequiredMessage()) {
<div class="position-fixed top-0 end-0 p-3 toast-container">
Expand All @@ -27,7 +31,7 @@

<div class="container-fluid p-0 page-bg">
<!-- Hero Banner -->
<div class="bg-primary text-white py-5 hero-gradient">
<div class="bg-primary text-white py-5 hero-gradient position-relative">
<!-- Login/Logout Button (Top Right) -->
<div class="position-absolute top-0 end-0 p-3 z-index-10">
@if (currentUser()) {
Expand All @@ -40,7 +44,7 @@
}
</div>

<div class="container">
<div class="mx-auto content-width position-relative">
<!-- title -->
<div class="row">
<div class="col-12 text-center">
Expand All @@ -57,9 +61,9 @@ <h1 class="display-6 fw-bold mb-3 hero-title">Integration Catalog</h1>
</div>
</div>

<!-- Row 3: 2 columns (left numbers, right image) -->
<!-- Row 3: 2 columns (left numbers, right image overlapping into gray below) -->
<div class="row mt-4">
<div class="col-lg-6 d-flex justify-content-center">
<div class="col-6 d-flex justify-content-center">
<div class="d-flex gap-5">
<div class="text-center">
<div class="display-4 fw-bold mb-2 hero-stat-value">{{ activeIntegrationsCount() }}</div>
Expand All @@ -71,30 +75,29 @@ <h1 class="display-6 fw-bold mb-3 hero-title">Integration Catalog</h1>
</div>
</div>
</div>
<div class="col-lg-6"><!-- empty, reserved for overlay image alignment --></div>
<div class="col-6 position-relative">
<div class="overlay-image-container">
<img
src="installation-nobg.png"
alt="Integration illustration"
class="overlay-image" />
</div>
</div>
</div>
</div>
</div>

<!-- Overlay image across blue + gray -->
<div class="d-none d-md-block overlay-image-container">
<img
src="installation-nobg.png"
alt="Integration illustration"
class="img-fluid overlay-image" />
</div>

<!-- Description + filter section (gray background) -->
<div class="pt-5 pb-4">
<div class="row mb-3 mx-auto content-width">
<div class="col-lg-6">
<div class="col-6">
<p class="mb-0 description-text">
Explore available integrations to jump-start your workflow, build your own with AI-guided assistance,
or upload an existing configuration to get started in just minutes. The process is fast, flexible, and
user-friendly.
</p>
</div>
<div class="col-lg-6"></div>
<div class="col-6"></div>
</div>
</div>

Expand Down Expand Up @@ -254,7 +257,7 @@ <h1 class="display-6 fw-bold mb-3 hero-title">Integration Catalog</h1>
}

@if (!loading() && !error() && featuredApplications().length > 0) {
<h2 class="h3 mb-4 text-center">Featured integration apps</h2>
<h2 class="h3 mb-4 text-center section-title">Featured integration apps</h2>

<div class="position-relative mb-5 mx-auto content-width">
<button class="btn rounded-circle position-absolute top-50 start-0 translate-middle-y d-flex align-items-center justify-content-center scroll-btn"
Expand Down Expand Up @@ -364,7 +367,7 @@ <h5 class="card-title card-title-truncate">{{ app.displayName }}</h5>
@if (!(filterState().trending || filterState().categories.length > 0 || filterState().capabilities.length > 0 || filterState().appStatus.length > 0 || filterState().midpointVersions.length > 0 || filterState().integrationMethods.length > 0 || filterState().maintainers.length > 0)) {
<div class="position-relative mb-5">
<div class="text-center">
<h2 class="h3 mb-0">More apps</h2>
<h2 class="h3 mb-0 section-title">More apps</h2>
</div>
</div>

Expand All @@ -388,7 +391,7 @@ <h2 class="h3 mb-0">More apps</h2>
}
</div>

<div class="d-flex flex-wrap gap-4 mb-4 mx-auto content-width">
<div class="apps-grid mb-4 mx-auto content-width">
@for (app of moreApplications(); track app.id) {
<div>
<div class="card shadow-sm position-relative app-card">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
======================================== */
.page-bg {
background-color: #e9ecef;
min-width: 1080px;
}

.content-width {
width: 1080px;
max-width: 1080px;
width: 100%;
}

/* ========================================
Expand All @@ -32,6 +34,7 @@

.hero-stat-value {
color: #A3CDCC;
font-size: 3.5rem;
}

.hero-stat-label {
Expand Down Expand Up @@ -67,16 +70,24 @@
======================================== */
.overlay-image-container {
position: absolute;
right: 28%;
top: 150px;
top: -35px;
left: 45%;
transform: translateX(-50%);
z-index: 5;
}

.overlay-image {
max-width: 450px;
width: 450px;
height: auto;
}

/* ========================================
SECTION TITLES
======================================== */
.section-title {
font-size: 1.75rem;
}

/* ========================================
DESCRIPTION TEXT
======================================== */
Expand Down Expand Up @@ -235,6 +246,20 @@
transition: opacity 0.3s ease;
}

/* ========================================
MORE APPS RESPONSIVE GRID
======================================== */
.apps-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(252px, 1fr));
gap: 1.5rem;
}

.apps-grid .app-card {
width: 100%;
min-width: unset;
}

/* ========================================
STATUS BADGES
======================================== */
Expand Down Expand Up @@ -410,7 +435,8 @@
border: 0;
border-top: 1px solid #6c757d;
margin: 3rem auto;
width: 1080px;
max-width: 1080px;
width: 100%;
}

/* ========================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Licensed under the EUPL-1.2 or later.
*/

import { Component, OnInit, signal, computed, ViewChild, ViewChildren, ElementRef, AfterViewInit, QueryList } from '@angular/core';
import { Component, OnInit, OnDestroy, signal, computed, ViewChild, ViewChildren, ElementRef, AfterViewInit, QueryList } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
Expand All @@ -23,7 +23,7 @@ import { AuthService } from '../../services/auth.service';
templateUrl: './applications-list.html',
styleUrls: ['./applications-list.scss']
})
export class ApplicationsList implements OnInit, AfterViewInit {
export class ApplicationsList implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('scrollContainer') scrollContainer!: ElementRef<HTMLDivElement>;
@ViewChild('scrollContainerMore') scrollContainerMore!: ElementRef<HTMLDivElement>;
@ViewChildren('featuredCard') featuredCards!: QueryList<ElementRef<HTMLDivElement>>;
Expand Down Expand Up @@ -75,6 +75,9 @@ export class ApplicationsList implements OnInit, AfterViewInit {
protected showLoginRequiredMessage = signal<boolean>(false);
protected dropdownPosition = signal<{ top: number; left: number } | null>(null);

private activeChipElement: HTMLElement | null = null;
private scrollListener: (() => void) | null = null;

protected filterState = signal<FilterState>({
trending: false,
categories: [],
Expand Down Expand Up @@ -255,17 +258,15 @@ export class ApplicationsList implements OnInit, AfterViewInit {

protected toggleDropdown(filterType: string, event: MouseEvent): void {
if (this.openDropdown() === filterType) {
this.openDropdown.set(null);
this.dropdownPosition.set(null);
this.closeDropdown();
} else {
const target = event.currentTarget as HTMLElement;
const rect = target.closest('.filter-chip')?.getBoundingClientRect();
const chip = target.closest('.filter-chip') as HTMLElement | null;

if (rect) {
this.dropdownPosition.set({
top: rect.bottom + 8,
left: rect.left
});
if (chip) {
this.activeChipElement = chip;
this.updateDropdownPosition();
this.attachScrollListener();
}
this.openDropdown.set(filterType);
}
Expand All @@ -274,6 +275,34 @@ export class ApplicationsList implements OnInit, AfterViewInit {
protected closeDropdown(): void {
this.openDropdown.set(null);
this.dropdownPosition.set(null);
this.activeChipElement = null;
this.detachScrollListener();
}

private updateDropdownPosition(): void {
if (!this.activeChipElement) return;
const rect = this.activeChipElement.getBoundingClientRect();
this.dropdownPosition.set({
top: rect.bottom + 8,
left: rect.left
});
}

private attachScrollListener(): void {
this.detachScrollListener();
this.scrollListener = () => this.updateDropdownPosition();
window.addEventListener('scroll', this.scrollListener, true);
}

private detachScrollListener(): void {
if (this.scrollListener) {
window.removeEventListener('scroll', this.scrollListener, true);
this.scrollListener = null;
}
}

ngOnDestroy(): void {
this.detachScrollListener();
}

protected clearTrendingFilter(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export class FilterModal implements OnInit {

protected toggleTrending(): void {
this.trending.set(!this.trending());
this.closeModal();
}

protected toggleCategory(categoryName: string): void {
Expand All @@ -133,6 +134,7 @@ export class FilterModal implements OnInit {
current.add(categoryName);
}
this.selectedCategories.set(current);
this.closeModal();
}

protected toggleCapability(capability: string): void {
Expand All @@ -143,6 +145,7 @@ export class FilterModal implements OnInit {
current.add(capability);
}
this.selectedCapabilities.set(current);
this.closeModal();
}

protected toggleAppStatus(status: string): void {
Expand All @@ -153,6 +156,7 @@ export class FilterModal implements OnInit {
current.add(status);
}
this.selectedAppStatus.set(current);
this.closeModal();
}

protected isCategorySelected(categoryName: string): boolean {
Expand All @@ -175,6 +179,7 @@ export class FilterModal implements OnInit {
current.add(version);
}
this.selectedMidpointVersions.set(current);
this.closeModal();
}

protected isMidpointVersionSelected(version: string): boolean {
Expand All @@ -189,6 +194,7 @@ export class FilterModal implements OnInit {
current.add(method);
}
this.selectedIntegrationMethods.set(current);
this.closeModal();
}

protected isIntegrationMethodSelected(method: string): boolean {
Expand All @@ -203,6 +209,7 @@ export class FilterModal implements OnInit {
current.add(maintainer);
}
this.selectedMaintainers.set(current);
this.closeModal();
}

protected isMaintainerSelected(maintainer: string): boolean {
Expand Down
Loading