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 frontend/src/app/modules/common/common-components.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { StatusDropdown } from './status-dropdown/status-dropdown.component';
import { CustomConfirmDialogComponent } from './custom-confirm-dialog/custom-confirm-dialog.component';
import { TreeGraphComponent } from './tree-graph/tree-graph.component';
import { GuardianSwitchButton } from './guardian-switch-button/guardian-switch-button.component';
import { GuardianTabsSwitch } from './guardian-tabs-switch/guardian-tabs-switch.component';
import { ImportEntityDialog } from './import-entity-dialog/import-entity-dialog.component';
import { DialogService, DynamicDialogModule } from 'primeng/dynamicdialog';
import { GuardianDialogService } from '../../services/guardian-dialog.service';
Expand All @@ -53,6 +54,8 @@ import { PluralizePipe } from './pipes/pluralize.pipe';
import { PagesControl } from './pages-control/pages-control.component';
import { GridDialogComponent } from './grid-dialog/grid-dialog.component';
import { ContentSearchComponent } from './content-search/content-search.component';
import { CommonDialogComponent, DialogHeaderDirective, DialogFooterDirective } from './common-dialog/common-dialog.component';
import { ProgressSpinnerModule } from 'primeng/progressspinner';

@NgModule({
declarations: [
Expand All @@ -79,6 +82,7 @@ import { ContentSearchComponent } from './content-search/content-search.componen
CustomConfirmDialogComponent,
TreeGraphComponent,
GuardianSwitchButton,
GuardianTabsSwitch,
ImportEntityDialog,
MathLiveComponent,
MenuButton,
Expand All @@ -93,6 +97,9 @@ import { ContentSearchComponent } from './content-search/content-search.componen
PagesControl,
GridDialogComponent,
ContentSearchComponent,
CommonDialogComponent,
DialogHeaderDirective,
DialogFooterDirective,
],
imports: [
CommonModule,
Expand All @@ -112,6 +119,7 @@ import { ContentSearchComponent } from './content-search/content-search.componen
TooltipModule,
DynamicDialogModule,
AgGridModule,
ProgressSpinnerModule,
],
providers: [
provideNgxMask(),
Expand Down Expand Up @@ -141,6 +149,7 @@ import { ContentSearchComponent } from './content-search/content-search.componen
CustomConfirmDialogComponent,
TreeGraphComponent,
GuardianSwitchButton,
GuardianTabsSwitch,
ImportEntityDialog,
MathLiveComponent,
MenuButton,
Expand All @@ -155,6 +164,9 @@ import { ContentSearchComponent } from './content-search/content-search.componen
PagesControl,
GridDialogComponent,
ContentSearchComponent,
CommonDialogComponent,
DialogHeaderDirective,
DialogFooterDirective,
]
})
export class CommonComponentsModule {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<div class="guardian-common-dialog" [style.width]="width" [style.height]="height">
@if (showHeader) {
<div class="dialog-header">
<div class="header-container">
<ng-content select="[appDialogHeader]"></ng-content>
@if (!hasCustomHeader && title) {
<div class="header-text">{{ title }}</div>
}
</div>
<div class="header-icon" (click)="close.emit()">
<svg-icon src="/assets/images/icons/close.svg" svgClass="icon-color-close"></svg-icon>
</div>
</div>
}

<div class="dialog-body" [style.max-height]="bodyMaxHeight">
@if (!loading) {
<ng-content></ng-content>
} @else {
<div class="loading">
<p-progressSpinner></p-progressSpinner>
</div>
}
</div>

@if (showFooter) {
<div class="dialog-footer">
<ng-content select="[appDialogFooter]"></ng-content>
@if (!hasCustomFooter) {
<div class="action-buttons">
@if (cancelVisible) {
<div class="dialog-button">
<button (click)="cancel.emit()"
class="guardian-button guardian-button-secondary">{{ cancelLabel }}</button>
</div>
}
@if (confirmVisible) {
<div class="dialog-button">
<button [disabled]="confirmDisabled" (click)="confirm.emit()"
class="guardian-button guardian-button-primary">{{ confirmLabel }}</button>
</div>
}
</div>
}
</div>
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
:host {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}

.guardian-common-dialog {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;

.dialog-body {
flex: 1 1 auto;
min-height: 0;
margin-top: 16px;
}

.dialog-footer {
flex-shrink: 0;
}
}

.loading {
display: flex;
align-items: center;
justify-content: center;
align-content: center;
min-height: 120px;
background: var(--guardian-background, #fff);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {
AfterContentInit,
Component,
ContentChild,
Directive,
EventEmitter,
Input,
Output,
} from '@angular/core';

@Directive({
selector: '[appDialogHeader]',
standalone: false,
})
export class DialogHeaderDirective {}

@Directive({
selector: '[appDialogFooter]',
standalone: false,
})
export class DialogFooterDirective {}

@Component({
selector: 'app-common-dialog',
templateUrl: './common-dialog.component.html',
styleUrls: ['./common-dialog.component.scss'],
standalone: false,
})
export class CommonDialogComponent implements AfterContentInit {
@Input() title: string;
@Input() confirmLabel: string = 'Confirm';
@Input() cancelLabel: string = 'Close';
@Input() confirmDisabled: boolean = false;
@Input() confirmVisible: boolean = true;
@Input() cancelVisible: boolean = true;
@Input() showHeader: boolean = true;
@Input() showFooter: boolean = true;
@Input() loading: boolean = false;
@Input() width: string;
@Input() height: string;
@Input() bodyMaxHeight: string;

@Output() confirm: EventEmitter<void> = new EventEmitter<void>();
@Output() cancel: EventEmitter<void> = new EventEmitter<void>();
@Output() close: EventEmitter<void> = new EventEmitter<void>();

@ContentChild(DialogHeaderDirective) private headerContent?: DialogHeaderDirective;
@ContentChild(DialogFooterDirective) private footerContent?: DialogFooterDirective;

public hasCustomHeader: boolean = false;
public hasCustomFooter: boolean = false;

public ngAfterContentInit(): void {
this.hasCustomHeader = !!this.headerContent;
this.hasCustomFooter = !!this.footerContent;
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<div class="dialog-header">
<div class="header-container">
<div class="header-text">{{ title }}</div>
</div>
<div class="header-icon" (click)="onNoClick()">
<svg-icon src="/assets/images/icons/close.svg" svgClass="icon-color-close"></svg-icon>
</div>
</div>

<div class="dialog-body">
<app-common-dialog
[title]="title"
cancelLabel="Close"
[confirmLabel]="button"
[confirmDisabled]="!dataForm.valid"
(cancel)="onNoClick()"
(close)="onNoClick()"
(confirm)="dialogRef.close(dataForm.value)">
<form [formGroup]="dataForm">
@for (field of fieldsConfig; track field) {
<div class="guardian-input-container">
Expand All @@ -21,20 +19,4 @@
</div>
}
</form>
</div>

<div class="dialog-footer">
<div class="action-buttons">
<div class="dialog-button">
<button
(click)="onNoClick()"
class="guardian-button guardian-button-secondary">Close</button>
</div>
<div class="dialog-button">
<button
[disabled]="!dataForm.valid"
(click)="dialogRef.close(dataForm.value)"
class="guardian-button guardian-button-primary">{{button}}</button>
</div>
</div>
</div>
</app-common-dialog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="tabs-nav">
<p-tabs [value]="value">
<p-tablist>
@for (tab of options; track tab.value) {
<p-tab [value]="tab.value" (click)="onSelect(tab.value)">
<div class="tabview-label">{{ tab.label }}</div>
</p-tab>
}
</p-tablist>
</p-tabs>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
:host ::ng-deep {
.p-tab {
padding: 0 !important;
color: var(--color-grey-5) !important;
}

.p-tabs,
.p-tablist,
.p-tablist-content,
.p-tablist-tab-list {
background: transparent;
}

.p-tabpanels {
background: transparent;
}

.p-tabs .p-tab.p-tab-active,
.p-tabs .p-tab[data-p-active='true'] {
color: var(--color-primary) !important;
border-color: var(--color-primary);
}
}

.tabview-label {
padding: 10px 25px 10px 25px;
background: var(--guardian-grey-background, #f9fafc);
text-align: center;
font-family: Inter, sans-serif;
font-size: 14px;
font-style: normal;
font-weight: 600;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';

/**
* Reusable tab-style switcher matching the Schemas page tabs.
* Renders a list of options as PrimeNG tabs and emits the selected value.
*/
@Component({
selector: 'guardian-tabs-switch',
templateUrl: './guardian-tabs-switch.component.html',
styleUrls: ['./guardian-tabs-switch.component.scss'],
standalone: false
})
export class GuardianTabsSwitch {
@Input('options') options: { label: string; value: any }[] = [];
@Input('value') value: any;

@Output('valueChange') valueChange = new EventEmitter<any>();
@Output('onChange') change = new EventEmitter<any>();

onSelect(value: any): void {
if (value === this.value) {
return;
}
this.value = value;
this.valueChange.emit(value);
this.change.emit(value);
}
}
Original file line number Diff line number Diff line change
@@ -1,54 +1,6 @@
.actions__tabs {
position: relative;
margin-bottom: 40px;

&::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: var(--color-grey-3);
z-index: 0;
}

::ng-deep .p-selectbutton .p-button {
background: transparent !important;
border: none !important;
color: #848FA9 !important;
position: relative;
padding: 0.75rem 2rem 0.5rem 0 !important;
margin: 0 0.5rem 0 0 !important;
border-radius: 0 !important;
}

::ng-deep .p-selectbutton .p-button.p-highlight {
color: var(--color-primary, #0b73f8) !important;
pointer-events: none !important;
cursor: default !important;
}

::ng-deep .p-selectbutton .p-button.p-highlight::after {
display: none !important;
}

::ng-deep .p-selectbutton .p-button .p-button-label {
position: relative;
padding: 0 !important;
margin: 0 !important;
}

::ng-deep .p-selectbutton .p-button.p-highlight .p-button-label::after {
content: "";
position: absolute;
bottom: -8px;
left: 0;
width: 100%;
height: 3px;
background: var(--color-primary, #0b73f8);
z-index: 2;
}
margin-bottom: 28px;
}

.button-group {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@
<div class="guardian-user-page-header">Retirement</div>
<div class="actions actions--top">
<div class="actions__tabs">
<p-selectButton
[(ngModel)]="type"
<guardian-tabs-switch
[value]="type"
[options]="contractTypeOptions"
(valueChange)="type = $event"
(onChange)="onChangeType($event)"
[options]="[
{ label: 'Token Wiping Contracts', value: 'WIPE' },
{ label: 'Token Retirement Contracts', value: 'RETIRE' }
]"
></p-selectButton>
></guardian-tabs-switch>
</div>
<div class="actions__cta button-group">
<button
Expand Down
Loading
Loading