Skip to content

Commit

Permalink
Allow non-required properties in the portal & change import registrat…
Browse files Browse the repository at this point in the history
…ions url
  • Loading branch information
Ruben committed Nov 5, 2024
1 parent f49f058 commit 5e6fefe
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ node_modules
# TS Build output logs
*.tsbuildinfo

**/.DS_Store
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
[multiple]="type === registrationAttributeType.MultiSelect"
>
<ion-select-option
*ngFor="let option of translatedOptions()"
*ngFor="let option of getTranslatedOptions()"
value="{{ option.option }}"
>
{{ option.label }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import {
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
} from '@angular/core';
import { NgModel } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
import { ProgramRegistrationAttributeOption } from 'src/app/models/program.model';
Expand All @@ -15,7 +22,7 @@ import { CheckAttributeInputUtils } from '../../shared/utils/check-attribute-inp
templateUrl: './update-property-item.component.html',
styleUrls: ['./update-property-item.component.scss'],
})
export class UpdatePropertyItemComponent implements OnInit {
export class UpdatePropertyItemComponent implements OnInit, OnChanges {
@Input()
public label: string;

Expand All @@ -28,6 +35,9 @@ export class UpdatePropertyItemComponent implements OnInit {
@Input()
public pattern: string;

@Input()
public isRequired: boolean;

@Input()
public value: string | string[];

Expand Down Expand Up @@ -66,11 +76,7 @@ export class UpdatePropertyItemComponent implements OnInit {
) {}

ngOnInit() {
if (this.type === RegistrationAttributeType.MultiSelect) {
this.value = this.value.toString().split(',');
}
this.propertyModel = this.value;

this.setValue();
this.reasonInputProps = {
promptType: PromptType.reason,
provideInput: true,
Expand All @@ -90,6 +96,39 @@ export class UpdatePropertyItemComponent implements OnInit {
};
}

ngOnChanges() {
this.setValue();
}

private setValue() {
if (this.type === RegistrationAttributeType.Enum && this.value == null) {
this.value = '_null_'; // Ionic select does not support null properly so using '_null_' instead as a workaround
}
this.propertyModel = this.value;
}

public getTranslatedOptions() {
let options = [...(this.options ?? [])];
if (!this.isRequired && this.type === RegistrationAttributeType.Enum) {
options = this.addEmptyOption(options);
}
const translatedOptions = options.map(({ option, label }) => ({
option,
label: this.translate.get(label),
}));
return translatedOptions;
}

private addEmptyOption(options: ProgramRegistrationAttributeOption[]) {
if (options.length > 0 && options[0].option !== '_null_') {
options.unshift({
option: '_null_', // Ionic select does not support null properly so using '_null_' instead as a workaround
label: { en: '-' }, // Add an string '-' for every language
});
}
return options;
}

public doUpdate(reasonInput?: string) {
if (this.type === 'date') {
if (!this.isValidDate()) {
Expand All @@ -101,18 +140,25 @@ export class UpdatePropertyItemComponent implements OnInit {
return;
}
}
let updatedValue = this.propertyModel;

this.updated.emit({ value: this.propertyModel, reason: reasonInput });
}
if (
this.type === RegistrationAttributeType.Enum &&
this.propertyModel === '_null_'
) {
updatedValue = null;
}

public translatedOptions() {
return this.options.map(({ option, label }) => ({
option,
label: this.translate.get(label),
}));
this.updated.emit({ value: updatedValue, reason: reasonInput });
}

private isValidDate(): boolean {
if (
!this.isRequired &&
(this.propertyModel === '' || this.propertyModel == null)
) {
return true;
}
const dateInput = this.propertyModel;

const regex = /^\d{2}-\d{2}-\d{4}$/;
Expand Down Expand Up @@ -144,6 +190,7 @@ export class UpdatePropertyItemComponent implements OnInit {
this.type,
this.pattern,
this.propertyModel,
this.isRequired,
)
);
}
Expand Down
1 change: 1 addition & 0 deletions interfaces/Portal/src/app/models/attribute.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export class Attribute {
name: string;
type: RegistrationAttributeType;
label: TranslatableString;
isRequired: boolean;
pattern?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ <h2>{{ person?.name }}</h2>
| translate
"
[value]="attributeValues?.paymentAmountMultiplier"
[isRequired]="true"
(updated)="
updatePaAttribute(
'paymentAmountMultiplier',
Expand Down Expand Up @@ -99,6 +100,7 @@ <h2>{{ person?.name }}</h2>
| translate
"
[value]="attributeValues?.maxPayments"
[isRequired]="false"
(updated)="
updatePaAttribute(
'maxPayments',
Expand Down Expand Up @@ -129,6 +131,7 @@ <h2>{{ person?.name }}</h2>
| translate
"
[value]="attributeValues?.phoneNumber"
[isRequired]="!program.allowEmptyPhoneNumber"
(updated)="
updatePaAttribute(
'phoneNumber',
Expand Down Expand Up @@ -156,6 +159,7 @@ <h2>{{ person?.name }}</h2>
| translate
"
[value]="attributeValues?.scope"
[isRequired]="false"
(updated)="
updatePaAttribute(
'scope',
Expand All @@ -180,6 +184,7 @@ <h2>{{ person?.name }}</h2>
| translate
"
[value]="attributeValues.preferredLanguage"
[isRequired]="true"
[options]="availableLanguages"
(updated)="
updatePaAttribute(
Expand Down Expand Up @@ -242,6 +247,7 @@ <h2>{{ person?.name }}</h2>
[showSubmit]="canUpdatePaData && canUpdatePersonalData"
[options]="paTableAttribute.options"
[pattern]="paTableAttribute.pattern"
[isRequired]="paTableAttribute.isRequired"
[explanation]="paTableAttribute.explanation"
(updated)="
updatePaAttribute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,16 @@ export class EditPersonAffectedPopupComponent implements OnInit {
attribute: string,
value: string | number | string[],
reason: string,
isPaTableAttribute: boolean,
isProgramRegistrationAttribute: boolean,
): Promise<void> {
let valueToStore: string | number | string[];

valueToStore = value;

if (isPaTableAttribute && !Array.isArray(value)) {
valueToStore = String(value);
if (isProgramRegistrationAttribute && value === '') {
valueToStore = null;
}

this.inProgress[attribute] = true;

if (attribute === PersonDefaultAttributes.paymentAmountMultiplier) {
Expand Down Expand Up @@ -272,6 +273,7 @@ export class EditPersonAffectedPopupComponent implements OnInit {
return {
name: paTableAttribute.name,
type: paTableAttribute.type,
isRequired: paTableAttribute.isRequired,
label,
value: this.person[paTableAttribute.name],
options,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ export class ProgramsServiceApiService {
import(programId: number, file: File): Promise<ImportResult> {
const formData = new FormData();
formData.append('file', file);
const path = `/programs/${programId}/registrations/import-csv`;
const path = `/programs/${programId}/registrations/import`;

return new Promise<ImportResult>((resolve, reject) => {
this.apiService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ export class CheckAttributeInputUtils {
type: RegistrationAttributeType,
pattern: string,
value: string,
isRequired: boolean,
): boolean {
if (value == null || value === '') {
if (isRequired) {
return false;
}
return true;
}

if (type === RegistrationAttributeType.Text) {
if (pattern) {
if (new RegExp(pattern).test(value || '')) {
Expand Down
2 changes: 1 addition & 1 deletion k6/models/registrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class RegistrationsModel {
}

importRegistrationsCsv(programId, csvFile) {
const url = `${baseUrl}api/programs/${programId}/registrations/import-csv`;
const url = `${baseUrl}api/programs/${programId}/registrations/import`;
const formData = {
file: http.file(csvFile, 'registrations.csv'),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export class ProgramAttributesService {
name: c.name,
type: c.type,
label: c.label,
isRequired: c.isRequired,
};
});
return programRegistrationAttributes;
Expand All @@ -205,6 +206,7 @@ export class ProgramAttributesService {
name: c.name,
type: c.type,
label: c.label,
isRequired: c.isRequired,
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class RegistrationsController {
summary: 'Import set of registered PAs, from CSV',
})
@ApiParam({ name: 'programId', required: true, type: 'integer' })
@Post('programs/:programId/registrations/import-csv')
@Post('programs/:programId/registrations/import')
@ApiConsumes('multipart/form-data')
@ApiBody(FILE_UPLOAD_API_FORMAT)
@UseInterceptors(FileInterceptor('file'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,16 @@ export class RegistrationsInputValidator {
) {
return;
}
if (!att.isRequired && row[att.name] === undefined) {
return;

// If attribute is not required skip in case of undefined and on null add to validatedRegistrationInput so it will be removed later on
if (!att.isRequired) {
if (row[att.name] === undefined) {
return;
}
if (row[att.name] == null) {
validatedRegistrationInput.data[att.name] = null;
return;
}
}

if (att.type === RegistrationAttributeTypes.tel) {
Expand Down Expand Up @@ -288,15 +296,6 @@ export class RegistrationsInputValidator {
}

if (att.type === RegistrationAttributeTypes.dropdown) {
if (!att.isRequired) {
if (row[att.name] == null) {
return (validatedRegistrationInput.data[att.name] = null);
} else {
// Skip validation if the attribute is not present in the row and it is not required
return;
}
}

const optionNames = att.options
? att.options?.map((option) => option.option)
: [];
Expand Down
2 changes: 1 addition & 1 deletion services/121-service/test/helpers/registration.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function importRegistrationsCSV(
accessToken: string,
): Promise<request.Response> {
return getServer()
.post(`/programs/${programId}/registrations/import-csv`)
.post(`/programs/${programId}/registrations/import`)
.set('Cookie', [accessToken])
.attach('file', filePath);
}
Expand Down

0 comments on commit 5e6fefe

Please sign in to comment.