feat(ui): rebuild all tools pages on Carbon Design System web components
- @carbon/web-components v2.50.0 via the IBM CDN (version-pinned); @carbon/styles CSS + IBM Plex Sans for tokens/typography - landing: Carbon header + cds-tile tool cards - fingerprint wizard: Carbon-styled form controls, cds-progress-bar scan progress, cds-tag badges, cds-inline-notification replacing swal - cropper: cds-toast replacing toastr, cds-checkbox review reasons, cds-tag process badge; vue-croppa pad kept in the Carbon layout - Bootstrap 4, swal, toastr and jQuery removed from all pages - behavior frozen: same flows, endpoints, validation and copy
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
/* Fingerprint Agent — enrollment wizard. Captures run through the local
|
||||
fpagent binary; artifacts are saved via the app's a2loft proxy. */
|
||||
/* global Vue, axios, swal, io */
|
||||
/* global Vue, axios, io, customElements */
|
||||
Vue.config.ignoredElements = [/^cds-/];
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
@@ -25,7 +27,8 @@
|
||||
staff: null,
|
||||
busy: { lookup: false, save: false },
|
||||
refreshing: false,
|
||||
pageError: '',
|
||||
notif: { show: false, kind: 'info', title: '', subtitle: '' },
|
||||
notifTimer: null,
|
||||
fingers: {
|
||||
'right-thumb': newFinger(),
|
||||
'right-index-finger': newFinger(),
|
||||
@@ -78,9 +81,26 @@
|
||||
})
|
||||
.catch(function () { /* loadSession redirects on 401 */ });
|
||||
setInterval(function () { self.tick = Date.now(); }, 1000);
|
||||
// web components upgrade after first render — re-apply reactive bindings
|
||||
Promise.all(
|
||||
['cds-button', 'cds-tag', 'cds-progress-bar', 'cds-inline-notification'].map(function (n) {
|
||||
return customElements.whenDefined(n).catch(function () {});
|
||||
})
|
||||
).then(function () {
|
||||
self.$forceUpdate();
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
showNotif: function (kind, title, subtitle, sticky) {
|
||||
var self = this;
|
||||
this.notif = { show: true, kind: kind, title: title, subtitle: subtitle || '' };
|
||||
if (this.notifTimer) clearTimeout(this.notifTimer);
|
||||
if (!sticky) {
|
||||
this.notifTimer = setTimeout(function () { self.notif.show = false; }, 6000);
|
||||
}
|
||||
},
|
||||
|
||||
loadSession: function () {
|
||||
var self = this;
|
||||
return axios.get('/auth/session').then(function (r) {
|
||||
@@ -93,7 +113,7 @@
|
||||
return;
|
||||
}
|
||||
self.loading = false;
|
||||
self.pageError = 'Could not load your session. Please refresh the page.';
|
||||
self.showNotif('error', 'Session error', 'Could not load your session. Please refresh the page.', true);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -108,12 +128,13 @@
|
||||
self.domain = self.session.domains[0].code;
|
||||
}
|
||||
if (!self.session.domains.length) {
|
||||
swal('No permitted domains', 'You are not permitted to capture fingerprints for any domain.', 'info');
|
||||
self.showNotif('warning', 'No permitted domains',
|
||||
'You are not permitted to capture fingerprints for any domain.', true);
|
||||
}
|
||||
}).catch(function (err) {
|
||||
var msg = (err.response && err.response.data && err.response.data.message) ||
|
||||
'Could not refresh domain permissions.';
|
||||
swal('Refresh failed', msg, 'error');
|
||||
self.showNotif('error', 'Refresh failed', msg);
|
||||
}).finally(function () {
|
||||
self.refreshing = false;
|
||||
});
|
||||
@@ -174,12 +195,13 @@
|
||||
f.status = 'failed';
|
||||
f.stage = 0;
|
||||
}
|
||||
swal(
|
||||
self.showNotif(
|
||||
wasCancelling ? 'info' : 'error',
|
||||
wasCancelling ? 'Capture cancelled' : 'Capture failed',
|
||||
wasCancelling
|
||||
? (restored ? 'The previous capture for the ' + self.fingerLabels[finger].toLowerCase() + ' was kept.' : 'No changes were saved for the ' + self.fingerLabels[finger].toLowerCase() + '.')
|
||||
: (data && data.message) || 'The capture did not complete.',
|
||||
wasCancelling ? 'info' : 'error'
|
||||
? (restored ? 'The previous capture for the ' + self.fingerLabels[finger].toLowerCase() + ' was kept.'
|
||||
: 'No changes were saved for the ' + self.fingerLabels[finger].toLowerCase() + '.')
|
||||
: ((data && data.message) || 'The capture did not complete.')
|
||||
);
|
||||
});
|
||||
},
|
||||
@@ -220,13 +242,13 @@
|
||||
{ params: { otp: this.otpLookup } }
|
||||
).then(function (r) {
|
||||
if (!r.data.ok) {
|
||||
swal('Not found', 'Operation failed. ' + (r.data.message || '') + ' (reference ' + self.reference + ')', 'error');
|
||||
self.showNotif('error', 'Not found', 'Operation failed. ' + (r.data.message || '') + ' (reference ' + self.reference + ')');
|
||||
return;
|
||||
}
|
||||
self.staff = r.data.data;
|
||||
}).catch(function (err) {
|
||||
var msg = (err.response && err.response.data && err.response.data.message) || 'Could not reach the identity service.';
|
||||
swal('Lookup failed', msg, 'error');
|
||||
self.showNotif('error', 'Lookup failed', msg);
|
||||
}).finally(function () {
|
||||
self.busy.lookup = false;
|
||||
});
|
||||
@@ -245,14 +267,15 @@
|
||||
{ params: { otp: this.otpSave } }
|
||||
).then(function (r) {
|
||||
if (r.data.ok) {
|
||||
swal('Saved', 'Fingerprints saved for ' + self.staff.name + ' (reference ' + self.staff.reference + ').', 'success');
|
||||
self.showNotif('success', 'Enrollment saved',
|
||||
'Fingerprints saved for ' + self.staff.name + ' (reference ' + self.staff.reference + ').');
|
||||
self.newEnrollment();
|
||||
} else {
|
||||
swal('Not saved', 'Operation failed. ' + (r.data.message || ''), 'error');
|
||||
self.showNotif('error', 'Not saved', 'Operation failed. ' + (r.data.message || ''));
|
||||
}
|
||||
}).catch(function (err) {
|
||||
var msg = (err.response && err.response.data && err.response.data.message) || 'Could not reach the identity service.';
|
||||
swal('Save failed', msg, 'error');
|
||||
self.showNotif('error', 'Save failed', msg);
|
||||
}).finally(function () {
|
||||
self.busy.save = false;
|
||||
});
|
||||
@@ -269,18 +292,14 @@
|
||||
this.prevCapture = null;
|
||||
},
|
||||
|
||||
fingerBadge: function (finger) {
|
||||
fingerTag: function (finger) {
|
||||
switch (this.fingers[finger].status) {
|
||||
case 'scanning': return { cls: 'badge-brand', text: 'Scanning' };
|
||||
case 'done': return { cls: 'badge-ok', text: 'Captured' };
|
||||
case 'failed': return { cls: 'badge-err', text: 'Failed' };
|
||||
default: return { cls: 'badge-idle', text: 'Pending' };
|
||||
case 'scanning': return { type: 'blue', text: 'Scanning' };
|
||||
case 'done': return { type: 'green', text: 'Captured' };
|
||||
case 'failed': return { type: 'red', text: 'Failed' };
|
||||
default: return { type: 'gray', text: 'Pending' };
|
||||
}
|
||||
},
|
||||
|
||||
progressPct: function (stage) {
|
||||
return Math.round((Math.min(stage, MAX_STAGE) / MAX_STAGE) * 100) + '%';
|
||||
},
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user