Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Do not merge] Barcode enketo widget #9548

Draft
wants to merge 10 commits into
base: 4.9.0-FR-barcode-search-and-enketo-widget
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions api/resources/translations/messages-bm.properties
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ app.version.unknown =
associated.contact =
associated.contact.help = Ni nin labaarabaga ye baara k�masegin kunafoniw da u b� tengu a tigi t�g�la.
autoreply = Jaabili y�r�b�
barcode_scanner.error.cannot_read_barcode = K�r�f� k�m�ya la, i k�m�ya.
barcode_scanner.message.disable = Barcode scanner b� m�g� la m�g� k�n�.
birth_date = Wolo Don/Kalo/San
branding =
branding.favicon.field =
Expand Down
2 changes: 2 additions & 0 deletions api/resources/translations/messages-en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ app.version.unknown = Unknown - internet connection required.
associated.contact = Associated contact
associated.contact.help = When this user creates reports they will be assigned to this contact
autoreply = autoreply
barcode_scanner.error.cannot_read_barcode = Failed to read the barcode. Retry.
barcode_scanner.message.disable = The barcode scanner is not available on this device.
birth_date = Birth date
branding = Branding
branding.favicon.field = Small icon
Expand Down
4 changes: 3 additions & 1 deletion api/resources/translations/messages-es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ app.version.unknown = Desconocido - se requiere conexi籀n a Internet.
associated.contact = Contacto asociado
associated.contact.help = Cuando este usuario crea informes, ser獺n asignados a este contacto.
autoreply = respuesta autom獺tica
barcode_scanner.error.cannot_read_barcode = No se puede leer el c籀digo de barras. Vuelva a intentarlo.
barcode_scanner.message.disable = El esc獺ner de c籀digo de barras no est獺 disponible en este dispositivo.
birth_date = fecha de nacimiento
branding = marca
branding.favicon.field = Icono peque簽o
Expand Down Expand Up @@ -638,7 +640,7 @@ email.invalid = Direcci籀n de correo electr籀nico no v獺lida.
empty = El mensaje esta en blanco, por favor reenvielo. Si continua teniendo problemas, informe a su supervisor.
enketo.constraint.invalid = Valor no permitido
enketo.constraint.required = Este campo es obligatorio
enketo.drawwidget.annotation = anotaci鏮
enketo.drawwidget.annotation = anotaci嚙緯
enketo.drawwidget.drawing = dibujo
enketo.drawwidget.signature = firma
enketo.error.max_attachment_size = Los archivos subidos exceden el l穩mite de tama簽o total. Suba archivos m獺s peque簽os.
Expand Down
2 changes: 2 additions & 0 deletions api/resources/translations/messages-fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ app.version.unknown = Inconnu �� connexion Internet requise.
associated.contact = Contact associ矇
associated.contact.help = Lorsque cet utilisateur cr矇e des rapport, ils seront assign矇s � ce contact
autoreply = auto-r矇ponse
barcode_scanner.error.cannot_read_barcode = Impossible de lire le code barre. Veuillez r矇essayer.
barcode_scanner.message.disable = Le lecteur de code-barres n'est pas disponible sur cet appareil.
birth_date = Date de naissance
branding = Personnalisation
branding.favicon.field = Petite ic繫ne
Expand Down
2 changes: 2 additions & 0 deletions api/resources/translations/messages-hi.properties
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ app.version.unknown =
associated.contact = 鄐�鄐�鄍�鄍� 鄐詮� 鄐�鄐﹤兮鄐� 鄐嫩�鄐�
associated.contact.help = 鄐互 鄐能允 鄐能�鄐什 鄐啤凶鄐芹�鄐啤�鄐� 鄐眇尹鄐擒�鄐冗 鄐戈� 鄐菽� is 鄐�鄐兒�鄐�鄐�鄐� 鄐� 鄐詮冗鄐� 鄐�鄐﹤兮 鄐耜凶鄐� 鄐冗鄐�鄐� |
autoreply = 鄐詮�鄐菽�鄐擒仆鄐賴中 鄐今鄐擒互
barcode_scanner.error.cannot_read_barcode = 鄐眇冗鄐啤�鄍丑 鄐芹丐鄐潼尹鄍� 鄐桌�鄐� 鄐菽凶鄐徇仆鄍� 鄐芹�鄐兒� 鄐芹�鄐啤仁鄐擒元 鄐什鄍�鄍�
barcode_scanner.message.disable = 鄐眇冗鄐啤�鄍丑 鄐詮�鄐�鄐兒什 鄐元 鄐﹤凶鄐菽冗鄐元 鄐芹什 鄐云鄐耜互鄍之 鄐兒允鄍€鄐� 鄐嫩�鄍�
birth_date = 鄐尹鄍亢 鄐舟凶鄐�
branding =
branding.favicon.field =
Expand Down
2 changes: 2 additions & 0 deletions api/resources/translations/messages-id.properties
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ app.version.unknown =
associated.contact = Kontak yang berhubungan
associated.contact.help = Ketika pengguna ini membuat laporan, mereka akan dihubungkan kepada kontak ini
autoreply = jawab otomatis
barcode_scanner.error.cannot_read_barcode = Gagal membaca barcode. Mencoba kembali.
barcode_scanner.message.disable = Pemindai barcode tidak tersedia pada perangkat ini.
birth_date = Tanggal Lahir
branding =
branding.favicon.field =
Expand Down
2 changes: 2 additions & 0 deletions api/resources/translations/messages-ne.properties
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ app.version.unknown =
associated.contact = 鄐詮亢鄍互鄐舟�鄐� 鄐詮亢鄍云鄐啤�鄐�
associated.contact.help = 鄐互 鄐能� 鄐芹�鄐啤仁鄍�鄐什鄍中鄐擒仆鄍� 鄐啤凶鄐芹�鄐啤�鄐� 鄐兒凶鄐啤�鄐桌冗鄐� 鄐什鄍�, 鄐戈凶鄐兒凶鄐嫩什鄍� 鄐能� 鄐詮亢鄍云鄐啤�鄐亢鄐� 鄐兒凶鄐啤�鄐舟凶鄐獅�鄐� 鄐嫩�鄐兒�鄐尹鄍�
autoreply = 鄐詮�鄐菽�鄐擒仆鄐賴中 鄐今鄐擒井
barcode_scanner.error.cannot_read_barcode = 鄐眇冗鄐啤�鄍丑 鄐芹丐鄍尹 鄐詮�鄐賴�鄐兒奶 鄐芹�鄐�: 鄐芹�鄐啤仁鄐擒元 鄐什鄍尹鄍允鄍元鄍奶
barcode_scanner.message.disable = 鄐眇冗鄐啤�鄍丑 鄐詮�鄐�鄐能冗鄐兒什 鄐能元 鄐云鄐什鄐�亢鄐� 鄐云鄐耜互鄍之 鄐�鄐兒奶
birth_date = 鄐尹鄍亢 鄐桌凶鄐戈凶
branding =
branding.favicon.field =
Expand Down
2 changes: 2 additions & 0 deletions api/resources/translations/messages-sw.properties
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ app.version.unknown = Haijulikani - muunganisho wa mtandao unahitajika
associated.contact = Nambari za mawasiliano zinazohusika
associated.contact.help = Mhusika huyu akitoa ripoti, zitahusishwa na mwenzi huyu
autoreply = ujumbe wa moja kwa moja
barcode_scanner.error.cannot_read_barcode = Imeshindwa kusoma msimbo pau. Jaribu tena.
barcode_scanner.message.disable = Kisomaji cha barcode haipatikani kwenye kifaa hiki.
birth_date = Tarehe ya kuzaliwa
branding = Chapa
branding.favicon.field = Ikoni ndogo
Expand Down
3 changes: 2 additions & 1 deletion config/covid-19/app_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@
],
"can_aggregate_targets": [
"chw_supervisor"
]
],
"can_search_with_barcode_scanner": []
},
"place_hierarchy_types": [
"district_hospital",
Expand Down
3 changes: 2 additions & 1 deletion config/default/app_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@
"can_have_multiple_places": [],
"can_export_devices_details": [
"national_admin"
]
],
"can_search_with_barcode_scanner": []
},
"uhc": {
"contacts_default_sort": "",
Expand Down
3 changes: 2 additions & 1 deletion config/demo/app_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@
"program_officer"
],
"can_view_old_filter_and_search": [],
"can_view_old_action_bar": []
"can_view_old_action_bar": [],
"can_search_with_barcode_scanner": []
},
"uhc": {
"contacts_default_sort": "",
Expand Down
10 changes: 10 additions & 0 deletions webapp/src/css/enketo/medic.less
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,16 @@
.pages.or .or-repeat-info[role="page"] {
display: block;
}

.scan-barcode {
font-size: 2.5rem;
line-height: 2.5rem;
text-align: center;
vertical-align: middle;
.barcode-scanner-file {
display: none;
}
}
}

@media (max-width: @media-mobile) {
Expand Down
18 changes: 17 additions & 1 deletion webapp/src/css/inbox.less
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ mm-search-bar {

.search-bar-left-icon {
align-self: center;
width: 18px;
min-width: 18px;
height: 20px;
margin: 0 15px;
}
Expand Down Expand Up @@ -1265,11 +1265,27 @@ mm-search-bar {
.fa {
font-size: @font-extra-large;
color: @filter-icon-color;
vertical-align: top;
&.fa-qrcode {
font-size: @font-extra-extra-large;
}

&.fa-sliders {
vertical-align: baseline;
}

&:not(:first-child) {
margin-left: 15px;
}
}

&.disabled .search-bar-left-icon .fa {
color: @inactive-color;
}

.barcode-scanner-input {
display: none;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions webapp/src/js/enketo/widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
require( './widgets/bikram-sambat-datepicker' ),
require( './widgets/mrdt' ),
require( './widgets/android-app-launcher' ),
require( './widgets/barcode-scanner' ),
require( './widgets/display-base64-image' ),
require( './widgets/dynamic-url' ),
require( './widgets/draw' ),
Expand Down
54 changes: 54 additions & 0 deletions webapp/src/js/enketo/widgets/barcode-scanner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use strict';
const Widget = require( 'enketo-core/src/js/widget' ).default;
const $ = require('jquery');
require('enketo-core/src/js/plugins');

const APPEARANCES = {
widget: '.or-appearance-barcode-scanner',
input: '.or-appearance-barcode-input',
};

/**
* Barcode scanner
* @extends Widget
*/
class Barcodescannerwidget extends Widget {
static get selector() {
return APPEARANCES.widget;
}

async _init() {
const $widget = $(this.element);

const canScanBarcodes = await window.CHTCore.BarcodeScanner.canScanBarcodes();
if (!canScanBarcodes) {
window.CHTCore.Translate
.get('barcode_scanner.message.disable')
.then(label => $widget.append(`<label>${label}</label>`));
return;
}

const barcodeImageElement = await window.CHTCore.BarcodeScanner.initBarcodeScanner(barcodes => {
if (!barcodes || !barcodes.length) {
return;
}
$(`${APPEARANCES.input} input[type="text"]`)
.val(barcodes[0].rawValue)
.trigger('change');
});

$widget.append(
`<label class="scan-barcode fa fa-qrcode">
<input type="file" name="barcode-file" class="barcode-scanner-file" data-type-xml="binary" accept="image/*"/>
</label>`
);

$widget.on(
'change',
'.barcode-scanner-file',
event => window.CHTCore.BarcodeScanner.processBarcodeFile(event.target, barcodeImageElement)
);
}
}

module.exports = Barcodescannerwidget;
3 changes: 3 additions & 0 deletions webapp/src/ts/components/search-bar/search-bar.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<section class="mm-search-bar-container" [class.open-search]="openSearch" [class.disabled]="disabled">
<div class="search-bar-left-icon">
<label class="fa fa-qrcode" *ngIf="isBarcodeScannerAvailable && showSearchIcon()" (click)="onBarcodeOpen()">
<input type="file" class="barcode-scanner-input" data-type-xml="binary" accept="image/*" (change)="processBarcodeFile($event)"/>
</label>
<span class="fa fa-search" *ngIf="showSearchIcon()" (click)="toggleMobileSearch()"></span>
<a class="fa fa-chevron-left search-bar-clear" *ngIf="showClearIcon()" (click)="clear()"></a>
</div>
Expand Down
59 changes: 53 additions & 6 deletions webapp/src/ts/components/search-bar/search-bar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import { Selectors } from '@mm-selectors/index';
import { FreetextFilterComponent } from '@mm-components/filters/freetext-filter/freetext-filter.component';
import { ResponsiveService } from '@mm-services/responsive.service';
import { SearchFiltersService } from '@mm-services/search-filters.service';
import { AuthService } from '@mm-services/auth.service';
import { SessionService } from '@mm-services/session.service';
import { TelemetryService } from '@mm-services/telemetry.service';
import { BarcodeScannerService } from '@mm-services/barcode-scanner.service';

export const CAN_USE_BARCODE_SCANNER = 'can_search_with_barcode_scanner';

@Component({
selector: 'mm-search-bar',
Expand All @@ -24,31 +30,41 @@ export class SearchBarComponent implements AfterContentInit, AfterViewInit, OnDe
@Input() disabled;
@Input() showFilter;
@Input() showSort;
@Input() showBarcodeScanner;
@Input() sortDirection;
@Input() lastVisitedDateExtras;
@Output() sort: EventEmitter<any> = new EventEmitter();
@Output() toggleFilter: EventEmitter<any> = new EventEmitter();
@Output() search: EventEmitter<any> = new EventEmitter();

private readonly TELEMETRY_PREFIX = 'search_by_barcode';
private filters;
private barcodeImageElement;
subscription: Subscription = new Subscription();
activeFilters: number = 0;
openSearch = false;
isBarcodeScannerAvailable = false;

@ViewChild(FreetextFilterComponent) freetextFilter?: FreetextFilterComponent;

constructor(
private store: Store,
private responsiveService: ResponsiveService,
private searchFiltersService: SearchFiltersService,
) { }
private readonly store: Store,
private readonly responsiveService: ResponsiveService,
private readonly searchFiltersService: SearchFiltersService,
private readonly authService: AuthService,
private readonly sessionService: SessionService,
private readonly telemetryService: TelemetryService,
private readonly barcodeScannerService: BarcodeScannerService,
) {}

ngAfterContentInit() {
this.subscribeToStore();
}

ngAfterViewInit() {
async ngAfterViewInit() {
this.isBarcodeScannerAvailable = await this.canShowBarcodeScanner();
this.searchFiltersService.init(this.freetextFilter);
this.barcodeImageElement = await this.barcodeScannerService.initBarcodeScanner(codes => this.scanBarcode(codes));
}

private subscribeToStore() {
Expand All @@ -66,12 +82,21 @@ export class SearchBarComponent implements AfterContentInit, AfterViewInit, OnDe
this.subscription.add(subscription);
}

clear() {
onBarcodeOpen() {
this.telemetryService.record(`${this.TELEMETRY_PREFIX}:open`);
}

processBarcodeFile($event) {
this.barcodeScannerService.processBarcodeFile($event.target, this.barcodeImageElement);
}

async clear() {
if (this.disabled) {
return;
}
this.freetextFilter?.clear(true);
this.toggleMobileSearch(false);
this.barcodeImageElement = await this.barcodeScannerService.initBarcodeScanner(codes => this.scanBarcode(codes));
}

toggleMobileSearch(forcedValue?) {
Expand Down Expand Up @@ -99,6 +124,28 @@ export class SearchBarComponent implements AfterContentInit, AfterViewInit, OnDe
return this.openSearch || !!this.filters?.search;
}

private async canShowBarcodeScanner() {
if (!this.showBarcodeScanner) {
return false;
}

const canUseBarcodeScanner = !this.sessionService.isAdmin() && await this.authService.has(CAN_USE_BARCODE_SCANNER);
if (!canUseBarcodeScanner) {
return false;
}

return await this.barcodeScannerService.canScanBarcodes();
}

private async scanBarcode(barcodes) {
if (!barcodes.length) {
return;
}

this.searchFiltersService.freetextSearch(barcodes[0].rawValue);
await this.telemetryService.record(`${this.TELEMETRY_PREFIX}:trigger_search`);
}

ngOnDestroy() {
this.subscription.unsubscribe();
}
Expand Down
1 change: 1 addition & 0 deletions webapp/src/ts/modules/contacts/contacts.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
[showSort]="isAllowedToSort"
[sortDirection]="sortDirection"
[lastVisitedDateExtras]="lastVisitedDateExtras"
[showBarcodeScanner]="true"
(sort)="sort($event)"
(search)="search()">
</mm-search-bar>
Expand Down
Loading
Loading