Skip to content

Commit

Permalink
(feat) : Adapt data sources to new schema specification and add `remo…
Browse files Browse the repository at this point in the history
…te-select` Question
  • Loading branch information
donaldkibet committed Jan 13, 2025
1 parent 6187fe1 commit 81507c6
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,22 @@ export class RemoteSelectComponent implements OnInit, ControlValueAccessor {

private loadOptions() {
this.remoteOptions$ = concat(
of([]), // default items
this.dataSource.searchOptions(
'',
this.dataSource?.dataSourceOptions ?? {}
) ?? of([]), // default items
this.remoteOptionInput$.pipe(
distinctUntilChanged(),
tap(() => {
this.loading = true;
}),
switchMap((term) =>
this.dataSource.searchOptions(term).pipe(
catchError(() => of([])), // empty list on error
tap(() => (this.loading = false))
)
this.dataSource
.searchOptions(term, this.dataSource?.dataSourceOptions ?? {})
.pipe(
catchError(() => of([])), // empty list on error
tap(() => (this.loading = false))
)
)
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { MinLengthValidationModel } from '../question-models/min-length-validati
import { WorkspaceLauncherQuestion } from '../question-models';
import { DecimalValidationModel } from '../question-models/decimal-validation.model';
import { DisallowDecimalsValidationModel } from '../question-models/disallow-decimals-validation.model';
import { RemoteSelectQuestion } from '../question-models/remote-select-question';
@Injectable()
export class QuestionFactory {
dataSources: any = {};
Expand Down Expand Up @@ -745,6 +746,38 @@ export class QuestionFactory {
return question;
}

toRemoteSelectQuestion(schemaQuestion: any): RemoteSelectQuestion {
const dataSource = this.getDataSourceConfig(schemaQuestion);
const question = new RemoteSelectQuestion({
dataSource: dataSource.name,
dataSourceOptions: dataSource.options,
type: '',
key: ''
});
question.questionIndex = this.quetionIndex;
question.label = schemaQuestion.label;
question.prefix = schemaQuestion.prefix;
question.key = schemaQuestion.id;
question.renderingType = 'remote-select';
question.validators = this.addValidators(schemaQuestion);
question.extras = schemaQuestion;
return question;
}

private getDataSourceConfig(
schemaQuestion: any
): { name: string; options: any } {
const dataSourceName = schemaQuestion.questionOptions?.dataSource;
const dataSourceOptions = schemaQuestion.questionOptions?.dataSourceOptions;
// See https://github.com/openmrs/openmrs-contrib-json-schemas/blob/main/form.schema.json
const legacyDataSource = schemaQuestion.questionOptions?.datasource;

return {
name: dataSourceName ?? legacyDataSource?.name ?? '',
options: dataSourceOptions ?? legacyDataSource?.config ?? {}
};
}

toDecimalQuestion(schemaQuestion: any): TextInputQuestion {
const question = new TextInputQuestion({
placeholder: '',
Expand Down Expand Up @@ -938,6 +971,8 @@ export class QuestionFactory {
return this.toFileUploadQuestion(schema);
case 'workspace-launcher':
return this.toWorkspaceLauncher(schema);
case 'remote-select':
return this.toRemoteSelectQuestion(schema);
default:
console.warn('New Schema Question Type found.........' + renderType);
return this.toTextQuestion(schema);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { SelectOption } from './select-option';
import { Observable } from 'rxjs';

export interface DataSource {
dataSourceOptions?: any;
dataSourceOptions?: Record<string, unknown>;
dataFromSourceChanged?: Observable<SelectOption[]>;
resolveSelectedValue(value): Observable<SelectOption>;
searchOptions(searchText): Observable<SelectOption[]>;
searchOptions(
searchText,
dataSourceOptions?: Record<string, unknown>
): Observable<SelectOption[]>;
fileUpload(data): Observable<any>;
fetchFile(url: string, fileType?: string): Observable<any>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { BaseOptions } from '../interfaces/base-options';

export interface RemoteSelectQuestionOptions extends BaseOptions {
dataSource: string;
dataSourceOptions?: Record<string, unknown>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class QuestionBase implements BaseOptions {
historicalDataValue?: any;
extras?: any;
dataSource?: string;
dataSourceOptions?: any;
dataSourceOptions?: Record<string, unknown>;

controlType?: AfeControlType;
validators?: Array<ValidationModel>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { QuestionBase } from './question-base';
import { AfeControlType } from '../../abstract-controls-extension/afe-control-type';
import { RemoteSelectQuestionOptions } from './interfaces/remote-select-question-options';

export class RemoteSelectQuestion extends QuestionBase {
rendering: string;
options: any[];

constructor(options: RemoteSelectQuestionOptions) {
super(options);
this.renderingType = 'select';
this.controlType = AfeControlType.AfeFormControl;
this.dataSource = options.dataSource || '';
this.dataSourceOptions = options.dataSourceOptions || {};
}
}
50 changes: 45 additions & 5 deletions src/app/adult-1.6.json
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,23 @@
"rendering": "ui-select-extended"
}
},
{
"id": "admitToLocation",
"type": "obs",
"required": true,
"label": "Admit to location",
"questionOptions": {
"rendering": "remote-select",
"required": true,
"concept": "CIEL:169403",
"datasource": {
"name": "location_datasource",
"config": {
"tag": "Admission Location"
}
}
}
},
{
"type": "encounterLocation",
"label": "Facility name (site/satellite clinic required):",
Expand Down Expand Up @@ -3362,7 +3379,9 @@
"type": "obs",
"hide": {
"field": "tb_current",
"value": ["b8aa06ca-93c6-40ea-b144-c74f841926f4"]
"value": [
"b8aa06ca-93c6-40ea-b144-c74f841926f4"
]
},
"id": "__ptxCzFD2s"
}
Expand Down Expand Up @@ -6991,7 +7010,9 @@
"type": "obs",
"hide": {
"field": "q26f",
"value": ["b8aa06ca-93c6-40ea-b144-c74f841926f4"]
"value": [
"b8aa06ca-93c6-40ea-b144-c74f841926f4"
]
},
"id": "__Jywyp94Lw"
}
Expand Down Expand Up @@ -8012,7 +8033,16 @@
"questionOptions": {
"concept": "318a5e8b-218c-4f66-9106-cd581dec1f95",
"rendering": "date",
"weeksList": [2, 4, 6, 8, 12, 16, 24, 36]
"weeksList": [
2,
4,
6,
8,
12,
16,
24,
36
]
},
"validators": [
{
Expand Down Expand Up @@ -8042,7 +8072,17 @@
"questionOptions": {
"concept": "a8a666ba-1350-11df-a1f1-0026b9348838",
"rendering": "date",
"weeksList": [2, 4, 6, 8, 12, 16, 20, 24, 36]
"weeksList": [
2,
4,
6,
8,
12,
16,
20,
24,
36
]
},
"validators": [
{
Expand Down Expand Up @@ -8178,4 +8218,4 @@
]
}
]
}
}
31 changes: 30 additions & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export class AppComponent implements OnInit {
searchOptions: this.sampleSearch,
resolveSelectedValue: this.sampleResolve
});
this.dataSources.registerDataSource('location_datasource', {
searchOptions: this.sampleLocationSearch,
resolveSelectedValue: this.sampleResolve
});
this.dataSources.registerDataSource('provider', {
searchOptions: this.sampleSearch,
resolveSelectedValue: this.sampleResolve
Expand Down Expand Up @@ -350,7 +354,32 @@ export class AppComponent implements OnInit {
});
}

public sampleSearch(): Observable<any> {
public sampleLocationSearch(): Observable<Array<Record<string, string>>> {
return of([
{
value: 'ba685651-ed3b-4e63-9b35-78893060758a',
label: 'Inpatient Ward'
},
{
value: '184ac7d9-225a-41f8-bac7-c87b1327e1b0',
label: 'Ward 1'
},
{
value: '5a7f3c53-6bb4-448b-a966-5e65b397b9f3',
label: 'Ward 2'
},
{
value: '2272b8cd-b690-4878-a50c-40d22235b3f3',
label: 'Ward 3'
},
{
value: 'db0253bb-8e2e-4b2c-b60c-6c88110e3c2e',
label: 'Duplix'
}
]);
}

public sampleSearch(searchText: string): Observable<any> {
const items: Array<any> = [
{ value: '0', label: 'Aech' },
{ value: '5b6e58ea-1359-11df-a1f1-0026b9348838', label: 'Art3mis' },
Expand Down
25 changes: 17 additions & 8 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import {
provideHttpClient,
withInterceptorsFromDi
} from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormEntryModule } from '@openmrs/ngx-formentry';
import { AppComponent } from './app.component';
import { NgxTranslateModule } from './translate/translate.module';

@NgModule({ declarations: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent], imports: [BrowserModule,
BrowserAnimationsModule,
FormEntryModule,
ReactiveFormsModule,
NgxTranslateModule], providers: [provideHttpClient(withInterceptorsFromDi())] })
@NgModule({
declarations: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormEntryModule,
ReactiveFormsModule,
NgxTranslateModule
],
providers: [provideHttpClient(withInterceptorsFromDi())]
})
export class AppModule {}

0 comments on commit 81507c6

Please sign in to comment.