Skip to content

Commit

Permalink
feat: duplicates in portalicious
Browse files Browse the repository at this point in the history
AB#33536 AB#33535
  • Loading branch information
aberonni committed Feb 18, 2025
1 parent d4388ae commit 48a5ec9
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 21 deletions.
14 changes: 14 additions & 0 deletions interfaces/Portalicious/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions interfaces/Portalicious/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@primeng/themes": "^19.0.2",
"@tanstack/angular-query-experimental": "^5.62.16",
"angular-mentions": "^1.5.0",
"angular-svg-icon": "^19.1.1",
"chart.js": "^4.4.7",
"chartjs-plugin-datalabels": "^2.2.0",
"filesize": "^9.0.11",
Expand Down
2 changes: 2 additions & 0 deletions interfaces/Portalicious/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
provideTanStackQuery,
QueryClient,
} from '@tanstack/angular-query-experimental';
import { provideAngularSvgIcon } from 'angular-svg-icon';
import { providePrimeNG } from 'primeng/config';

import { routes } from '~/app.routes';
Expand All @@ -33,6 +34,7 @@ export const getAppConfig = (locale: Locale): ApplicationConfig => ({
provideExperimentalZonelessChangeDetection(),
provideAnimationsAsync(),
provideHttpClient(withInterceptorsFromDi()),
provideAngularSvgIcon(),
providePrimeNG({
theme: {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- AppTheme is typed as any in primeng
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { VisaCard121Status } from '@121-service/src/payments/fsp-integration/intersolve-visa/enums/wallet-status-121.enum';
import { TransactionStatusEnum } from '@121-service/src/payments/transactions/enums/transaction-status.enum';
import { DuplicateStatus } from '@121-service/src/registration/enum/duplicate-status.enum';
import { RegistrationStatusEnum } from '@121-service/src/registration/enum/registration-status.enum';

import { ChipVariant } from '~/components/colored-chip/colored-chip.component';
Expand All @@ -9,6 +10,7 @@ import {
MessageStatus,
} from '~/domains/message/message.helper';
import {
DUPLICATE_STATUS_LABELS,
REGISTRATION_STATUS_LABELS,
VISA_CARD_STATUS_LABELS,
} from '~/domains/registration/registration.helper';
Expand Down Expand Up @@ -85,3 +87,11 @@ export const getChipDataByVisaCardStatus = (
[VisaCard121Status.CardDataMissing]: 'orange',
[VisaCard121Status.Paused]: 'orange',
});

export const getChipDataByDuplicateStatus = (
status?: DuplicateStatus | null,
): ChipData =>
mapValueToChipData(status, DUPLICATE_STATUS_LABELS, {
[DuplicateStatus.unique]: 'green',
[DuplicateStatus.duplicate]: 'red',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<div
class="mb-6 flex w-full items-start rounded-2xl border border-red-500 bg-red-100 p-4"
>
<svg-icon
src="assets/duplicates.svg"
class="h-7 w-7 text-red-700"
></svg-icon>
<strong
i18n
class="mx-2 text-red-700"
>Duplicated with:</strong
>
<ul class="me-auto">
@for (duplicate of duplicates(); track $index) {
<li class="ms-6 list-disc">
<a
[routerLink]="['/registration', duplicate.id]"
class="underline hover:no-underline focus:no-underline"
>
{{ duplicate.name }}
<span class="pi pi-external-link ms-1"></span>
</a>
<span
i18n
class="ms-1"
>
(matching fields: phoneNumber)</span
>
</li>
}
</ul>
<i
class="pi pi-info-circle cursor-help self-center text-xl"
pTooltip="To handle duplications you can edit the personal information or decline the registration."
i18n-pTooltip
></i>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { RouterLink } from '@angular/router';

import { SvgIconComponent } from 'angular-svg-icon';
import { TooltipModule } from 'primeng/tooltip';

@Component({
selector: 'app-registration-duplicates-banner',
imports: [SvgIconComponent, RouterLink, TooltipModule],
templateUrl: './registration-duplicates-banner.component.html',
styles: ``,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RegistrationDuplicatesBannerComponent {
readonly duplicates = input.required<
{
id: number;
name: string;
}[]
>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,40 @@
[pageTitle]="registrationTitle()"
[isPending]="registration.isPending()"
>
<app-registration-duplicates-banner [duplicates]="duplicates()" />
<p-card
styleClass="[&_.p-card-content]:flex-end group relative h-full [&_.p-card-title]:flex-grow"
>
<div class="flex items-center space-x-4 border-b border-grey-300 pb-4">
<h1 class="me-auto">
<div
class="flex w-full items-center space-x-4 border-b border-grey-300 pb-4"
>
<h1>
{{ registrationTitle() }}
</h1>
@if (canUpdatePersonalData() && !registration.isError()) {
<p-button
label="Add note"
i18n-label="@@add-note"
rounded
outlined
[loading]="registration.isPending()"
icon="pi pi-pen-to-square"
(click)="addNoteFormVisible.set(true)"
/>
@if (registration.isSuccess()) {
<app-add-note-form
[(formVisible)]="addNoteFormVisible"
[projectId]="projectId()"
[registrationId]="registrationId()"
<app-colored-chip
[variant]="'red'"
[label]="'Duplicate'"
/>
<div class="!ms-auto">
@if (canUpdatePersonalData() && !registration.isError()) {
<p-button
label="Add note"
i18n-label="@@add-note"
rounded
outlined
[loading]="registration.isPending()"
icon="pi pi-pen-to-square"
(click)="addNoteFormVisible.set(true)"
/>
@if (registration.isSuccess()) {
<app-add-note-form
[(formVisible)]="addNoteFormVisible"
[projectId]="projectId()"
[registrationId]="registrationId()"
/>
}
}
}
</div>
</div>
<app-data-list [data]="registrationData()" />
<div class="mt-4 text-end">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import { CardModule } from 'primeng/card';
import { PermissionEnum } from '@121-service/src/user/enum/permission.enum';

import { AppRoutes } from '~/app.routes';
import { ColoredChipComponent } from '~/components/colored-chip/colored-chip.component';
import { getChipDataByRegistrationStatus } from '~/components/colored-chip/colored-chip.helper';
import {
DataListComponent,
DataListItem,
} from '~/components/data-list/data-list.component';
import { PageLayoutComponent } from '~/components/page-layout/page-layout.component';
import { AddNoteFormComponent } from '~/components/registration-page-layout/components/add-note-form/add-note-form.component';
import { RegistrationDuplicatesBannerComponent } from '~/components/registration-page-layout/components/registration-duplicates-banner/registration-duplicates-banner.component';
import { RegistrationMenuComponent } from '~/components/registration-page-layout/components/registration-menu/registration-menu.component';
import { SkeletonInlineComponent } from '~/components/skeleton-inline/skeleton-inline.component';
import { ProjectApiService } from '~/domains/project/project.api.service';
Expand All @@ -41,6 +43,8 @@ import { TranslatableStringService } from '~/services/translatable-string.servic
SkeletonInlineComponent,
AddNoteFormComponent,
RegistrationMenuComponent,
RegistrationDuplicatesBannerComponent,
ColoredChipComponent,
],
templateUrl: './registration-page-layout.component.html',
styles: ``,
Expand All @@ -64,6 +68,8 @@ export class RegistrationPageLayoutComponent {
),
);

readonly addNoteFormVisible = signal(false);

readonly registrationData = computed(() => {
const registrationRawData = this.registration.data();
const { chipLabel, chipVariant } = getChipDataByRegistrationStatus(
Expand Down Expand Up @@ -129,14 +135,24 @@ export class RegistrationPageLayoutComponent {
return `${localized}${this.registration.data()?.registrationProgramId.toString() ?? ''} - ${this.registration.data()?.name ?? ''}`;
});

readonly addNoteFormVisible = signal(false);

readonly canUpdatePersonalData = computed(() =>
this.authService.hasPermission({
projectId: this.projectId(),
requiredPermission: PermissionEnum.RegistrationPersonalUPDATE,
}),
);

readonly duplicates = computed(() => [
{
id: 1,
name: 'Duplicate 1',
},
{
id: 2,
name: 'Duplicate 2',
},
]);

private getPaymentCountString(
paymentCount?: null | number,
maxPayments?: null | number,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ActivityTypeEnum } from '@121-service/src/activities/enum/activity-type.enum';
import { VisaCard121Status } from '@121-service/src/payments/fsp-integration/intersolve-visa/enums/wallet-status-121.enum';
import { DuplicateStatus } from '@121-service/src/registration/enum/duplicate-status.enum';
import { RegistrationStatusEnum } from '@121-service/src/registration/enum/registration-status.enum';
import { LanguageEnum } from '@121-service/src/shared/enum/language.enums';

Expand Down Expand Up @@ -53,6 +54,11 @@ export const REGISTRATION_STATUS_VERB_PROGRESSIVE: Record<
[RegistrationStatusEnum.deleted]: $localize`Deleting`,
};

export const DUPLICATE_STATUS_LABELS: Record<DuplicateStatus, string> = {
[DuplicateStatus.duplicate]: $localize`:@@duplicate-status-duplicate:Duplicate`,
[DuplicateStatus.unique]: $localize`:@@duplicate-status-unique:Unique`,
};

export const LANGUAGE_ENUM_LABEL: Record<LanguageEnum, string> = {
ar: $localize`Arabic`,
en: $localize`English`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ import {
queryOptions,
} from '@tanstack/angular-query-experimental';

import { DuplicateStatus } from '@121-service/src/registration/enum/duplicate-status.enum';
import { RegistrationAttributeTypes } from '@121-service/src/registration/enum/registration-attribute.enum';
import { RegistrationStatusEnum } from '@121-service/src/registration/enum/registration-status.enum';

import { getChipDataByRegistrationStatus } from '~/components/colored-chip/colored-chip.helper';
import {
getChipDataByDuplicateStatus,
getChipDataByRegistrationStatus,
} from '~/components/colored-chip/colored-chip.helper';
import {
QueryTableColumn,
QueryTableColumnType,
} from '~/components/query-table/query-table.component';
import { ProjectApiService } from '~/domains/project/project.api.service';
import {
DUPLICATE_STATUS_LABELS,
REGISTRATION_STATUS_LABELS,
registrationLink,
} from '~/domains/registration/registration.helper';
Expand All @@ -30,12 +35,14 @@ export const FILTERABLE_ATTRIBUTES_LABELS: Record<string, string> = {
paymentCountRemaining: $localize`:@@payment-count-remaining:Remaining payments`,
maxPayments: $localize`:@@max-payments:Max payments`,
lastMessageStatus: $localize`:@@last-message-status:Last message status`,
duplicateStatus: $localize`:@@duplicate-status:Duplicates`,
};

export const DEFAULT_VISIBLE_FIELDS_SORTED: string[] = [
'registrationProgramId',
'name',
'status',
'duplicateStatus',
'phoneNumber',
'paymentCount',
'maxPayments',
Expand Down Expand Up @@ -113,6 +120,17 @@ export class RegistrationsTableColumnService {
getCellChipData: (registration) =>
getChipDataByRegistrationStatus(registration.status),
},
{
field: 'duplicateStatus',
header: $localize`:@@registration-status:Duplicates`,
type: QueryTableColumnType.MULTISELECT,
options: Object.values(DuplicateStatus).map((status) => ({
label: DUPLICATE_STATUS_LABELS[status],
value: status,
})),
getCellChipData: (registration) =>
getChipDataByDuplicateStatus(registration.duplicateStatus),
},
{
field: 'programFinancialServiceProviderConfigurationName',
header: $localize`FSP`,
Expand Down
15 changes: 15 additions & 0 deletions interfaces/Portalicious/src/assets/duplicates.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions interfaces/Portalicious/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ body {
--font-family: theme(fontFamily.body);
}

svg-icon svg {
fill: currentColor;
}

@layer tailwind-base {
h1 {
@apply font-bold txt-h-1;
Expand Down

0 comments on commit 48a5ec9

Please sign in to comment.