Fix/mask generic inputs (#1570)

* add masking to generic input component

* clear inputs after submission

* adjust convenience FE make steps

* cleaner masking

* remove mask pipe from module

* switch to redacted font
This commit is contained in:
Lucy C
2022-06-27 13:51:35 -06:00
committed by GitHub
parent 22af45fb6e
commit 123f71cb86
8 changed files with 48 additions and 11 deletions

View File

@@ -83,4 +83,7 @@ patch-db/client/dist: $(PATCH_DB_CLIENT_SRC) patch-db/client/node_modules
npm --prefix patch-db/client run build npm --prefix patch-db/client run build
# this is a convenience step to build all frontends - it is not referenced elsewhere in this file # this is a convenience step to build all frontends - it is not referenced elsewhere in this file
frontend: frontend/node_modules frontend/config.json $(EMBASSY_UIS) frontends: frontend/node_modules frontend/config.json $(EMBASSY_UIS)
# this is a convenience step to build the UI
ui: frontend/node_modules frontend/config.json frontend/dist/ui

Binary file not shown.

View File

@@ -72,6 +72,12 @@
<ion-input <ion-input
type="text" type="text"
[inputmode]="spec.type === 'number' ? 'tel' : 'text'" [inputmode]="spec.type === 'number' ? 'tel' : 'text'"
[class.redacted]="
spec.type === 'string' &&
entry.value.value &&
spec.masked &&
!unmasked[entry.key]
"
[placeholder]="spec.placeholder || 'Enter ' + spec.name" [placeholder]="spec.placeholder || 'Enter ' + spec.name"
[formControlName]="entry.key" [formControlName]="entry.key"
(ionFocus)="presentAlertChangeWarning(entry.key, spec)" (ionFocus)="presentAlertChangeWarning(entry.key, spec)"
@@ -80,7 +86,7 @@
</ion-input> </ion-input>
</ng-template> </ng-template>
<!-- removing mask button until proper solution implemented --> <!-- removing mask button until proper solution implemented -->
<!-- <ion-button <ion-button
*ngIf="spec.type === 'string' && spec.masked" *ngIf="spec.type === 'string' && spec.masked"
slot="end" slot="end"
fill="clear" fill="clear"
@@ -92,7 +98,7 @@
[name]="unmasked[entry.key] ? 'eye-off-outline' : 'eye-outline'" [name]="unmasked[entry.key] ? 'eye-off-outline' : 'eye-outline'"
size="small" size="small"
></ion-icon> ></ion-icon>
</ion-button> --> </ion-button>
<ion-note <ion-note
*ngIf="spec.type === 'number' && spec.units" *ngIf="spec.type === 'number' && spec.units"
slot="end" slot="end"

View File

@@ -10,6 +10,10 @@
--border-color: var(--ion-color-danger-shade); --border-color: var(--ion-color-danger-shade);
} }
.redacted {
font-family: 'Redacted'
}
ion-input { ion-input {
font-family: 'Courier New'; font-family: 'Courier New';
font-weight: bold; font-weight: bold;

View File

@@ -23,13 +23,13 @@
<ion-input <ion-input
#mainInput #mainInput
type="text" type="text"
[(ngModel)]="value"
name="value" name="value"
[ngModel]="masked ? maskedValue : value"
(ngModelChange)="transformInput($event)"
[placeholder]="options.placeholder" [placeholder]="options.placeholder"
(ionChange)="error = ''" (ionChange)="error = ''"
></ion-input> ></ion-input>
<!-- removing mask button until proper solution implemented --> <ion-button
<!-- <ion-button
slot="end" slot="end"
*ngIf="options.useMask" *ngIf="options.useMask"
fill="clear" fill="clear"
@@ -38,10 +38,10 @@
> >
<ion-icon <ion-icon
slot="icon-only" slot="icon-only"
[name]="unmasked ? 'eye-off-outline' : 'eye-outline'" [name]="!masked ? 'eye-off-outline' : 'eye-outline'"
size="small" size="small"
></ion-icon> ></ion-icon>
</ion-button> --> </ion-button>
</ion-item> </ion-item>
<!-- error --> <!-- error -->
<p *ngIf="error"> <p *ngIf="error">

View File

@@ -5,6 +5,7 @@ import { IonicModule } from '@ionic/angular'
import { RouterModule } from '@angular/router' import { RouterModule } from '@angular/router'
import { SharedPipesModule } from '@start9labs/shared' import { SharedPipesModule } from '@start9labs/shared'
import { FormsModule } from '@angular/forms' import { FormsModule } from '@angular/forms'
import { MaskPipeModule } from 'src/app/pipes/mask/mask.module'
@NgModule({ @NgModule({
declarations: [GenericInputComponent], declarations: [GenericInputComponent],

View File

@@ -1,20 +1,26 @@
import { Component, Input, ViewChild } from '@angular/core' import { Component, Input, ViewChild } from '@angular/core'
import { ModalController, IonicSafeString, IonInput } from '@ionic/angular' import { ModalController, IonicSafeString, IonInput } from '@ionic/angular'
import { getErrorMessage } from '@start9labs/shared' import { getErrorMessage } from '@start9labs/shared'
import { MaskPipe } from 'src/app/pipes/mask/mask.pipe'
@Component({ @Component({
selector: 'generic-input', selector: 'generic-input',
templateUrl: './generic-input.component.html', templateUrl: './generic-input.component.html',
styleUrls: ['./generic-input.component.scss'], styleUrls: ['./generic-input.component.scss'],
providers: [MaskPipe],
}) })
export class GenericInputComponent { export class GenericInputComponent {
@ViewChild('mainInput') elem: IonInput @ViewChild('mainInput') elem: IonInput
@Input() options: GenericInputOptions @Input() options: GenericInputOptions
value: string value: string
unmasked = false maskedValue: string
masked: boolean
error: string | IonicSafeString error: string | IonicSafeString
constructor(private readonly modalCtrl: ModalController) {} constructor(
private readonly modalCtrl: ModalController,
private readonly mask: MaskPipe,
) {}
ngOnInit() { ngOnInit() {
const defaultOptions: Partial<GenericInputOptions> = { const defaultOptions: Partial<GenericInputOptions> = {
@@ -29,6 +35,7 @@ export class GenericInputComponent {
...this.options, ...this.options,
} }
this.masked = !!this.options.useMask
this.value = this.options.initialValue || '' this.value = this.options.initialValue || ''
} }
@@ -37,13 +44,22 @@ export class GenericInputComponent {
} }
toggleMask() { toggleMask() {
this.unmasked = !this.unmasked this.masked = !this.masked
} }
cancel() { cancel() {
this.modalCtrl.dismiss() this.modalCtrl.dismiss()
} }
transformInput(newValue: string) {
let i = 0
this.value = newValue
.split('')
.map(x => (x === '●' ? this.value[i++] : x))
.join('')
this.maskedValue = this.mask.transform(this.value)
}
async submit() { async submit() {
const value = this.value.trim() const value = this.value.trim()

View File

@@ -43,6 +43,13 @@
src: url('/assets/fonts/Open_Sans/OpenSans-Light.ttf'); src: url('/assets/fonts/Open_Sans/OpenSans-Light.ttf');
} }
@font-face {
font-family: 'Redacted';
font-style: normal;
font-weight: normal;
src: url('/assets/fonts/Redacted/redacted.regular.ttf');
}
/** Ionic CSS Variables overrides **/ /** Ionic CSS Variables overrides **/
:root { :root {
--ion-font-family: 'Open Sans'; --ion-font-family: 'Open Sans';