@retalia/pos-components 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +491 -489
- package/fesm2022/retalia-pos-components.mjs +144 -45
- package/fesm2022/retalia-pos-components.mjs.map +1 -1
- package/package.json +1 -1
- package/types/retalia-pos-components.d.ts +25 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Directive, input, output, signal, computed, ChangeDetectionStrategy, Component, viewChild, linkedSignal, afterRenderEffect,
|
|
2
|
+
import { Directive, input, output, signal, computed, inject, DestroyRef, afterNextRender, ChangeDetectionStrategy, Component, viewChild, linkedSignal, afterRenderEffect, Injector, InjectionToken, booleanAttribute, ElementRef, contentChildren, effect, untracked, forwardRef } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
/** Projects partner content into the login shop column, after the date and POS number. */
|
|
5
5
|
class PosLoginAside {
|
|
@@ -50,6 +50,13 @@ class PosLogin {
|
|
|
50
50
|
/** Shop line. Empty hides it. */
|
|
51
51
|
shopName = input('shop 1', ...(ngDevMode ? [{ debugName: "shopName" }] : /* istanbul ignore next */ []));
|
|
52
52
|
dateLabel = input('Date', ...(ngDevMode ? [{ debugName: "dateLabel" }] : /* istanbul ignore next */ []));
|
|
53
|
+
/**
|
|
54
|
+
* Date to show, e.g. the trading date from the host. Null shows the device's current date,
|
|
55
|
+
* which updates at midnight.
|
|
56
|
+
*/
|
|
57
|
+
date = input(null, ...(ngDevMode ? [{ debugName: "date" }] : /* istanbul ignore next */ []));
|
|
58
|
+
/** Locale for the date, e.g. `en-GB`. Undefined uses the browser's locale. */
|
|
59
|
+
locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
53
60
|
posNumberLabel = input('POS No', ...(ngDevMode ? [{ debugName: "posNumberLabel" }] : /* istanbul ignore next */ []));
|
|
54
61
|
/** Empty hides the POS number tile. */
|
|
55
62
|
posNumber = input('001', ...(ngDevMode ? [{ debugName: "posNumber" }] : /* istanbul ignore next */ []));
|
|
@@ -76,11 +83,31 @@ class PosLogin {
|
|
|
76
83
|
const status = this.session().status;
|
|
77
84
|
return status === 'busy' || status === 'signedIn';
|
|
78
85
|
}, ...(ngDevMode ? [{ debugName: "interactionLocked" }] : /* istanbul ignore next */ []));
|
|
79
|
-
|
|
86
|
+
/** Device date, used when the host does not pass `date`. Refreshed at midnight. */
|
|
87
|
+
today = signal(new Date(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
|
|
88
|
+
destroyRef = inject(DestroyRef);
|
|
89
|
+
shownDate = computed(() => new Intl.DateTimeFormat(this.locale(), {
|
|
80
90
|
weekday: 'long',
|
|
81
91
|
day: 'numeric',
|
|
82
92
|
month: 'long',
|
|
83
|
-
}).format(
|
|
93
|
+
}).format(this.date() ?? this.today()), ...(ngDevMode ? [{ debugName: "shownDate" }] : /* istanbul ignore next */ []));
|
|
94
|
+
constructor() {
|
|
95
|
+
// Browser only: keep the fallback date current on a till left on the login screen overnight.
|
|
96
|
+
afterNextRender(() => {
|
|
97
|
+
let timer;
|
|
98
|
+
const scheduleMidnightRefresh = () => {
|
|
99
|
+
const now = new Date();
|
|
100
|
+
const nextMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
|
|
101
|
+
timer = setTimeout(() => {
|
|
102
|
+
this.today.set(new Date());
|
|
103
|
+
scheduleMidnightRefresh();
|
|
104
|
+
}, nextMidnight.getTime() - now.getTime());
|
|
105
|
+
};
|
|
106
|
+
this.today.set(new Date());
|
|
107
|
+
scheduleMidnightRefresh();
|
|
108
|
+
this.destroyRef.onDestroy(() => clearTimeout(timer));
|
|
109
|
+
});
|
|
110
|
+
}
|
|
84
111
|
sessionStatusText = computed(() => {
|
|
85
112
|
const current = this.session();
|
|
86
113
|
if (current.status === 'busy') {
|
|
@@ -138,14 +165,14 @@ class PosLogin {
|
|
|
138
165
|
this.action.emit({ type: 'login.back' });
|
|
139
166
|
}
|
|
140
167
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosLogin, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
141
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosLogin, isStandalone: true, selector: "pos-login", inputs: { errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, session: { classPropertyName: "session", publicName: "session", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, titleClerkNumber: { classPropertyName: "titleClerkNumber", publicName: "titleClerkNumber", isSignal: true, isRequired: false, transformFunction: null }, titleClerkPassword: { classPropertyName: "titleClerkPassword", publicName: "titleClerkPassword", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, loginLabel: { classPropertyName: "loginLabel", publicName: "loginLabel", isSignal: true, isRequired: false, transformFunction: null }, showAside: { classPropertyName: "showAside", publicName: "showAside", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, showBrandImage: { classPropertyName: "showBrandImage", publicName: "showBrandImage", isSignal: true, isRequired: false, transformFunction: null }, brandImage: { classPropertyName: "brandImage", publicName: "brandImage", isSignal: true, isRequired: false, transformFunction: null }, brandLabel: { classPropertyName: "brandLabel", publicName: "brandLabel", isSignal: true, isRequired: false, transformFunction: null }, locationName: { classPropertyName: "locationName", publicName: "locationName", isSignal: true, isRequired: false, transformFunction: null }, terminalLine: { classPropertyName: "terminalLine", publicName: "terminalLine", isSignal: true, isRequired: false, transformFunction: null }, shopName: { classPropertyName: "shopName", publicName: "shopName", isSignal: true, isRequired: false, transformFunction: null }, dateLabel: { classPropertyName: "dateLabel", publicName: "dateLabel", isSignal: true, isRequired: false, transformFunction: null }, posNumberLabel: { classPropertyName: "posNumberLabel", publicName: "posNumberLabel", isSignal: true, isRequired: false, transformFunction: null }, posNumber: { classPropertyName: "posNumber", publicName: "posNumber", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { classAttribute: "pos-login" }, ngImport: i0, template: "<div\r\n class=\"pos-login__shell\"\r\n [class.pos-login__shell--aside]=\"showAside()\"\r\n [class.pos-login__shell--bordered]=\"bordered()\"\r\n>\r\n @if (showAside()) {\r\n <aside class=\"pos-login__aside\">\r\n @if (showBrandImage() || brandLabel()) {\r\n <div class=\"pos-login__brand\">\r\n @if (showBrandImage()) {\r\n @if (brandImage()) {\r\n <img\r\n class=\"pos-login__brand-image\"\r\n [src]=\"brandImage()\"\r\n [alt]=\"brandLabel() ? '' : 'Brand'\"\r\n />\r\n } @else {\r\n <svg\r\n class=\"pos-login__brand-image\"\r\n viewBox=\"492.40 241.70 51.34 54.94\"\r\n [attr.aria-hidden]=\"brandLabel() ? true : null\"\r\n [attr.aria-label]=\"brandLabel() ? null : 'Retalia'\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 522.628906 291.910156 C 522.636719 293.0625 523.441406 293.511719 524.425781 292.914062 L 540.464844 283.207031 C 541.449219 282.613281 542.246094 281.195312 542.246094 280.046875 L 542.246094 261.132812 C 542.246094 259.980469 541.441406 259.523438 540.453125 260.113281 L 524.292969 269.691406 C 523.300781 270.277344 522.503906 271.683594 522.511719 272.835938 Z M 522.628906 291.910156\"\r\n />\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 539.097656 253.351562 L 517.101562 243.664062 C 516.066406 243.203125 514.417969 243.265625 513.421875 243.804688 L 495.835938 253.308594 C 494.839844 253.847656 494.027344 255.214844 494.023438 256.367188 L 493.910156 280.140625 C 493.902344 281.292969 494.699219 282.679688 495.683594 283.234375 L 501.734375 286.640625 C 502.71875 287.199219 503.503906 286.71875 503.480469 285.566406 L 503.214844 271.488281 C 503.207031 271.082031 503.492188 270.894531 503.855469 271.066406 L 506.128906 272.148438 C 507.152344 272.636719 507.980469 273.960938 507.980469 275.113281 L 507.980469 287.839844 C 507.980469 288.992188 508.773438 290.394531 509.746094 290.972656 L 515.777344 294.5625 C 516.753906 295.140625 517.554688 294.679688 517.566406 293.527344 L 517.800781 273.300781 C 517.808594 272.488281 517.539062 271.238281 517.195312 270.503906 L 515.460938 266.789062 C 515.292969 266.421875 515.476562 266.109375 515.871094 266.089844 L 518.925781 265.941406 C 520.050781 265.886719 521.761719 265.378906 522.738281 264.808594 L 539.195312 255.21875 C 540.175781 254.648438 540.132812 253.8125 539.097656 253.351562 M 520.609375 255.050781 L 518.019531 256.585938 C 516.914062 257.125 515.734375 257.289062 514.710938 256.804688 L 511.078125 255.101562 C 510.054688 254.621094 510.023438 253.773438 511.003906 253.210938 L 513.835938 251.597656 C 514.53125 251.203125 515.691406 251.132812 516.425781 251.445312 L 520.449219 253.128906 C 521.488281 253.570312 521.5625 254.429688 520.609375 255.050781\"\r\n />\r\n </svg>\r\n }\r\n }\r\n @if (brandLabel()) {\r\n <span class=\"pos-login__brand-label\">{{ brandLabel() }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (locationName() || terminalLine()) {\r\n <div class=\"pos-login__place\">\r\n @if (locationName()) {\r\n <p class=\"pos-login__location\">{{ locationName() }}</p>\r\n }\r\n @if (terminalLine()) {\r\n <p class=\"pos-login__terminal\">{{ terminalLine() }}</p>\r\n }\r\n @if (shopName()) {\r\n <p class=\"pos-login__terminal\">{{ shopName() }}</p>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"pos-login__facts\">\r\n <div class=\"pos-login__fact\">\r\n <p class=\"pos-login__fact-label\">{{ dateLabel() }}</p>\r\n <p class=\"pos-login__fact-value\">{{ shownDate() }}</p>\r\n </div>\r\n @if (posNumber()) {\r\n <div class=\"pos-login__fact\">\r\n <p class=\"pos-login__fact-label\">{{ posNumberLabel() }}</p>\r\n <p class=\"pos-login__fact-value\">{{ posNumber() }}</p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Custom content slot -->\r\n <div class=\"pos-login__slot\">\r\n <ng-content select=\"[posLoginAside]\" />\r\n </div>\r\n </aside>\r\n }\r\n\r\n<section class=\"pos-login__panel\" [attr.aria-busy]=\"session().status === 'busy' ? true : null\">\r\n <div class=\"pos-login__main\">\r\n <header class=\"pos-login__header\">\r\n <h1 class=\"pos-login__heading\">{{ heading() }}</h1>\r\n @if (showBack()) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__back\"\r\n aria-label=\"Back\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onBack()\"\r\n >\r\n Back\r\n </button>\r\n }\r\n </header>\r\n\r\n <div class=\"pos-login__display\">\r\n <p class=\"pos-login__title\" [class.pos-login__title--entry]=\"hasEntry()\">{{ displayText() }}</p>\r\n <input\r\n class=\"pos-login__input\"\r\n [attr.type]=\"maskInput() ? 'password' : 'text'\"\r\n [value]=\"inputValue()\"\r\n maxlength=\"12\"\r\n readonly\r\n tabindex=\"-1\"\r\n (keydown)=\"$event.preventDefault()\"\r\n aria-label=\"Login code\"\r\n />\r\n </div>\r\n\r\n <div class=\"pos-login__keypad\" role=\"group\" aria-label=\"Keypad\">\r\n @for (key of digitKeys; track key) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad(key)\"\r\n >\r\n {{ key }}\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key pos-login__key--delete\"\r\n aria-label=\"Delete\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad('\u2190')\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M8 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H8l-5-7 5-7Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"m14 10 4 4m0-4-4 4\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad('0')\"\r\n >\r\n 0\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__primary\"\r\n [attr.aria-label]=\"primaryLabel()\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onPrimary()\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M5 12.5 9.5 17 19 7.5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n @if (sessionStatusText() || errorMessage()) {\r\n <div class=\"pos-login__status\" aria-live=\"polite\">\r\n @if (sessionStatusText()) {\r\n <p>{{ sessionStatusText() }}</p>\r\n }\r\n @if (errorMessage()) {\r\n <p class=\"pos-login__error\" role=\"alert\">{{ errorMessage() }}</p>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- // Custom content slot -->\r\n <div class=\"pos-login__slot\">\r\n <ng-content select=\"[posLoginPanel]\" />\r\n </div>\r\n </div>\r\n</section>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%;height:100%;min-height:100vh;align-items:center;justify-content:center;padding:var(--pos-space-lg);color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md);background:transparent}*{box-sizing:border-box}.pos-login__shell{display:flex;flex-direction:column;width:min(22rem,100%);min-width:0}.pos-login__shell--aside{width:min(56rem,100%);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay);overflow:hidden}.pos-login__shell--bordered{border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg)}.pos-login__aside{display:flex;flex-direction:column;gap:var(--pos-space-xl);min-width:0;padding:var(--pos-space-xl);border-bottom:1px solid var(--pos-color-border)}.pos-login__brand{display:flex;align-items:center;gap:var(--pos-space-sm)}.pos-login__brand-image{flex:0 0 auto;width:auto;height:var(--pos-space-xl);color:var(--pos-color-ink)}.pos-login__brand-label{font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);letter-spacing:var(--pos-letter-spacing-brand)}.pos-login__place{display:flex;flex-direction:column;gap:var(--pos-space-xs)}.pos-login__location{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-login__terminal{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-login__facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--pos-space-md)}.pos-login__fact{min-width:0;padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg)}.pos-login__fact-label{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);letter-spacing:var(--pos-letter-spacing-brand);text-transform:uppercase}.pos-login__fact-value{margin:var(--pos-space-xs) 0 0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.25}.pos-login__slot{display:flex;flex-direction:column;gap:var(--pos-space-sm);min-width:0}.pos-login__slot:not(:has(*)){display:none}.pos-login__panel{display:flex;flex:1 1 auto;align-items:flex-start;justify-content:center;width:100%;min-width:0;padding:var(--pos-space-xl)}.pos-login__shell:not(.pos-login__shell--aside) .pos-login__panel{padding:0}.pos-login__main{display:flex;flex-direction:column;gap:var(--pos-space-md);width:min(22rem,100%)}.pos-login__header{display:flex;align-items:center;justify-content:space-between;gap:var(--pos-space-sm);min-height:var(--pos-space-xl)}.pos-login__heading{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-login__display{position:relative;display:flex;align-items:center;justify-content:center;width:100%;min-width:0;min-height:calc(var(--pos-button-min-height) + var(--pos-space-lg));padding:var(--pos-space-md) var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface-muted)}.pos-login__title{margin:0;max-width:100%;color:var(--pos-color-text);font-family:var(--pos-font-family-display);font-size:calc(var(--pos-font-size-xl) * 1.3);font-weight:var(--pos-font-weight-bold);line-height:1.2;text-align:center;overflow-wrap:anywhere}.pos-login__title--entry{letter-spacing:var(--pos-letter-spacing-display)}.pos-login__input{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.pos-login__keypad{display:grid;width:100%;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--pos-space-sm)}.pos-login__key,.pos-login__primary,.pos-login__back{font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-login__key,.pos-login__primary{display:inline-flex;align-items:center;justify-content:center;min-height:var(--pos-keypad-size);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-key);color:var(--pos-color-text);box-shadow:var(--pos-shadow-key);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-semibold);transition:background .12s ease,border-color .12s ease,color .12s ease,transform 80ms ease,filter .12s ease}.pos-login__key--delete{color:var(--pos-color-text-muted)}.pos-login__key:hover:not(:disabled){border-color:var(--pos-color-primary);background:color-mix(in srgb,var(--pos-color-primary) 22%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-login__key:active:not(:disabled),.pos-login__primary:active:not(:disabled),.pos-login__back:active:not(:disabled){transform:scale(.985)}.pos-login__key:disabled,.pos-login__back:disabled,.pos-login__primary:disabled{cursor:not-allowed;opacity:.45;transform:none;filter:none}.pos-login__key:focus-visible,.pos-login__primary:focus-visible,.pos-login__back:focus-visible{outline:3px solid var(--pos-color-primary);outline-offset:2px}.pos-login__primary{border-color:var(--pos-color-primary);background:var(--pos-color-primary);color:var(--pos-color-on-primary)}.pos-login__primary:hover:not(:disabled){filter:brightness(1.06)}.pos-login__back{border:0;background:transparent;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-login__back:hover:not(:disabled){color:var(--pos-color-text)}.pos-login__status{display:flex;flex-direction:column;gap:var(--pos-space-xs);text-align:center}.pos-login__status p{margin:0;font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-login__error{color:var(--pos-color-danger)}@media(min-width:768px){.pos-login__shell--aside{flex-direction:row;align-items:stretch}.pos-login__aside,.pos-login__panel{flex:1 1 50%}.pos-login__aside{border-bottom:0;border-right:1px solid var(--pos-color-border);padding:var(--pos-space-2xl)}.pos-login__key,.pos-login__primary{min-height:var(--pos-keypad-size-md)}}@media(prefers-reduced-motion:reduce){.pos-login__key,.pos-login__primary,.pos-login__back{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
168
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosLogin, isStandalone: true, selector: "pos-login", inputs: { errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, session: { classPropertyName: "session", publicName: "session", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, titleClerkNumber: { classPropertyName: "titleClerkNumber", publicName: "titleClerkNumber", isSignal: true, isRequired: false, transformFunction: null }, titleClerkPassword: { classPropertyName: "titleClerkPassword", publicName: "titleClerkPassword", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, loginLabel: { classPropertyName: "loginLabel", publicName: "loginLabel", isSignal: true, isRequired: false, transformFunction: null }, showAside: { classPropertyName: "showAside", publicName: "showAside", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, showBrandImage: { classPropertyName: "showBrandImage", publicName: "showBrandImage", isSignal: true, isRequired: false, transformFunction: null }, brandImage: { classPropertyName: "brandImage", publicName: "brandImage", isSignal: true, isRequired: false, transformFunction: null }, brandLabel: { classPropertyName: "brandLabel", publicName: "brandLabel", isSignal: true, isRequired: false, transformFunction: null }, locationName: { classPropertyName: "locationName", publicName: "locationName", isSignal: true, isRequired: false, transformFunction: null }, terminalLine: { classPropertyName: "terminalLine", publicName: "terminalLine", isSignal: true, isRequired: false, transformFunction: null }, shopName: { classPropertyName: "shopName", publicName: "shopName", isSignal: true, isRequired: false, transformFunction: null }, dateLabel: { classPropertyName: "dateLabel", publicName: "dateLabel", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, posNumberLabel: { classPropertyName: "posNumberLabel", publicName: "posNumberLabel", isSignal: true, isRequired: false, transformFunction: null }, posNumber: { classPropertyName: "posNumber", publicName: "posNumber", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { classAttribute: "pos-login" }, ngImport: i0, template: "<div\r\n class=\"pos-login__shell\"\r\n [class.pos-login__shell--aside]=\"showAside()\"\r\n [class.pos-login__shell--bordered]=\"bordered()\"\r\n>\r\n @if (showAside()) {\r\n <aside class=\"pos-login__aside\">\r\n @if (showBrandImage() || brandLabel()) {\r\n <div class=\"pos-login__brand\">\r\n @if (showBrandImage()) {\r\n @if (brandImage()) {\r\n <img\r\n class=\"pos-login__brand-image\"\r\n [src]=\"brandImage()\"\r\n [alt]=\"brandLabel() ? '' : 'Brand'\"\r\n />\r\n } @else {\r\n <svg\r\n class=\"pos-login__brand-image\"\r\n viewBox=\"492.40 241.70 51.34 54.94\"\r\n [attr.aria-hidden]=\"brandLabel() ? true : null\"\r\n [attr.aria-label]=\"brandLabel() ? null : 'Retalia'\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 522.628906 291.910156 C 522.636719 293.0625 523.441406 293.511719 524.425781 292.914062 L 540.464844 283.207031 C 541.449219 282.613281 542.246094 281.195312 542.246094 280.046875 L 542.246094 261.132812 C 542.246094 259.980469 541.441406 259.523438 540.453125 260.113281 L 524.292969 269.691406 C 523.300781 270.277344 522.503906 271.683594 522.511719 272.835938 Z M 522.628906 291.910156\"\r\n />\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 539.097656 253.351562 L 517.101562 243.664062 C 516.066406 243.203125 514.417969 243.265625 513.421875 243.804688 L 495.835938 253.308594 C 494.839844 253.847656 494.027344 255.214844 494.023438 256.367188 L 493.910156 280.140625 C 493.902344 281.292969 494.699219 282.679688 495.683594 283.234375 L 501.734375 286.640625 C 502.71875 287.199219 503.503906 286.71875 503.480469 285.566406 L 503.214844 271.488281 C 503.207031 271.082031 503.492188 270.894531 503.855469 271.066406 L 506.128906 272.148438 C 507.152344 272.636719 507.980469 273.960938 507.980469 275.113281 L 507.980469 287.839844 C 507.980469 288.992188 508.773438 290.394531 509.746094 290.972656 L 515.777344 294.5625 C 516.753906 295.140625 517.554688 294.679688 517.566406 293.527344 L 517.800781 273.300781 C 517.808594 272.488281 517.539062 271.238281 517.195312 270.503906 L 515.460938 266.789062 C 515.292969 266.421875 515.476562 266.109375 515.871094 266.089844 L 518.925781 265.941406 C 520.050781 265.886719 521.761719 265.378906 522.738281 264.808594 L 539.195312 255.21875 C 540.175781 254.648438 540.132812 253.8125 539.097656 253.351562 M 520.609375 255.050781 L 518.019531 256.585938 C 516.914062 257.125 515.734375 257.289062 514.710938 256.804688 L 511.078125 255.101562 C 510.054688 254.621094 510.023438 253.773438 511.003906 253.210938 L 513.835938 251.597656 C 514.53125 251.203125 515.691406 251.132812 516.425781 251.445312 L 520.449219 253.128906 C 521.488281 253.570312 521.5625 254.429688 520.609375 255.050781\"\r\n />\r\n </svg>\r\n }\r\n }\r\n @if (brandLabel()) {\r\n <span class=\"pos-login__brand-label\">{{ brandLabel() }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (locationName() || terminalLine()) {\r\n <div class=\"pos-login__place\">\r\n @if (locationName()) {\r\n <p class=\"pos-login__location\">{{ locationName() }}</p>\r\n }\r\n @if (terminalLine()) {\r\n <p class=\"pos-login__terminal\">{{ terminalLine() }}</p>\r\n }\r\n @if (shopName()) {\r\n <p class=\"pos-login__terminal\">{{ shopName() }}</p>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"pos-login__facts\">\r\n <div class=\"pos-login__fact\">\r\n <p class=\"pos-login__fact-label\">{{ dateLabel() }}</p>\r\n <p class=\"pos-login__fact-value\">{{ shownDate() }}</p>\r\n </div>\r\n @if (posNumber()) {\r\n <div class=\"pos-login__fact\">\r\n <p class=\"pos-login__fact-label\">{{ posNumberLabel() }}</p>\r\n <p class=\"pos-login__fact-value\">{{ posNumber() }}</p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Custom content slot -->\r\n <div class=\"pos-login__slot\">\r\n <ng-content select=\"[posLoginAside]\" />\r\n </div>\r\n </aside>\r\n }\r\n\r\n<section class=\"pos-login__panel\" [attr.aria-busy]=\"session().status === 'busy' ? true : null\">\r\n <div class=\"pos-login__main\">\r\n <header class=\"pos-login__header\">\r\n <h1 class=\"pos-login__heading\">{{ heading() }}</h1>\r\n @if (showBack()) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__back\"\r\n aria-label=\"Back\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onBack()\"\r\n >\r\n Back\r\n </button>\r\n }\r\n </header>\r\n\r\n <div class=\"pos-login__display\">\r\n <p class=\"pos-login__title\" [class.pos-login__title--entry]=\"hasEntry()\">{{ displayText() }}</p>\r\n <input\r\n class=\"pos-login__input\"\r\n [attr.type]=\"maskInput() ? 'password' : 'text'\"\r\n [value]=\"inputValue()\"\r\n maxlength=\"12\"\r\n readonly\r\n tabindex=\"-1\"\r\n (keydown)=\"$event.preventDefault()\"\r\n aria-label=\"Login code\"\r\n />\r\n </div>\r\n\r\n <div class=\"pos-login__keypad\" role=\"group\" aria-label=\"Keypad\">\r\n @for (key of digitKeys; track key) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad(key)\"\r\n >\r\n {{ key }}\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key pos-login__key--delete\"\r\n aria-label=\"Delete\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad('\u2190')\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M8 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H8l-5-7 5-7Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"m14 10 4 4m0-4-4 4\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad('0')\"\r\n >\r\n 0\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__primary\"\r\n [attr.aria-label]=\"primaryLabel()\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onPrimary()\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M5 12.5 9.5 17 19 7.5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n @if (sessionStatusText() || errorMessage()) {\r\n <div class=\"pos-login__status\" aria-live=\"polite\">\r\n @if (sessionStatusText()) {\r\n <p>{{ sessionStatusText() }}</p>\r\n }\r\n @if (errorMessage()) {\r\n <p class=\"pos-login__error\" role=\"alert\">{{ errorMessage() }}</p>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- // Custom content slot -->\r\n <div class=\"pos-login__slot\">\r\n <ng-content select=\"[posLoginPanel]\" />\r\n </div>\r\n </div>\r\n</section>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%;height:100%;min-height:100vh;align-items:center;justify-content:center;padding:var(--pos-space-lg);color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md);background:transparent}*{box-sizing:border-box}.pos-login__shell{display:flex;flex-direction:column;width:min(22rem,100%);min-width:0}.pos-login__shell--aside{width:min(56rem,100%);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay);overflow:hidden}.pos-login__shell--bordered{border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg)}.pos-login__aside{display:flex;flex-direction:column;gap:var(--pos-space-xl);min-width:0;padding:var(--pos-space-xl);border-bottom:1px solid var(--pos-color-border)}.pos-login__brand{display:flex;align-items:center;gap:var(--pos-space-sm)}.pos-login__brand-image{flex:0 0 auto;width:auto;height:var(--pos-space-xl);color:var(--pos-color-ink)}.pos-login__brand-label{font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);letter-spacing:var(--pos-letter-spacing-brand)}.pos-login__place{display:flex;flex-direction:column;gap:var(--pos-space-xs)}.pos-login__location{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-login__terminal{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-login__facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--pos-space-md)}.pos-login__fact{min-width:0;padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg)}.pos-login__fact-label{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);letter-spacing:var(--pos-letter-spacing-brand);text-transform:uppercase}.pos-login__fact-value{margin:var(--pos-space-xs) 0 0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.25}.pos-login__slot{display:flex;flex-direction:column;gap:var(--pos-space-sm);min-width:0}.pos-login__slot:not(:has(*)){display:none}.pos-login__panel{display:flex;flex:1 1 auto;align-items:flex-start;justify-content:center;width:100%;min-width:0;padding:var(--pos-space-xl)}.pos-login__shell:not(.pos-login__shell--aside) .pos-login__panel{padding:0}.pos-login__main{display:flex;flex-direction:column;gap:var(--pos-space-md);width:min(22rem,100%)}.pos-login__header{display:flex;align-items:center;justify-content:space-between;gap:var(--pos-space-sm);min-height:var(--pos-space-xl)}.pos-login__heading{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-login__display{position:relative;display:flex;align-items:center;justify-content:center;width:100%;min-width:0;min-height:calc(var(--pos-button-min-height) + var(--pos-space-lg));padding:var(--pos-space-md) var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface-muted)}.pos-login__title{margin:0;max-width:100%;color:var(--pos-color-text);font-family:var(--pos-font-family-display);font-size:calc(var(--pos-font-size-xl) * 1.3);font-weight:var(--pos-font-weight-bold);line-height:1.2;text-align:center;overflow-wrap:anywhere}.pos-login__title--entry{letter-spacing:var(--pos-letter-spacing-display)}.pos-login__input{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.pos-login__keypad{display:grid;width:100%;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--pos-space-sm)}.pos-login__key,.pos-login__primary,.pos-login__back{font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-login__key,.pos-login__primary{display:inline-flex;align-items:center;justify-content:center;min-height:var(--pos-keypad-size);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-key);color:var(--pos-color-text);box-shadow:var(--pos-shadow-key);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-semibold);transition:background .12s ease,border-color .12s ease,color .12s ease,transform 80ms ease,filter .12s ease}.pos-login__key--delete{color:var(--pos-color-text-muted)}.pos-login__key:hover:not(:disabled){border-color:var(--pos-color-primary);background:color-mix(in srgb,var(--pos-color-primary) 22%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-login__key:active:not(:disabled),.pos-login__primary:active:not(:disabled),.pos-login__back:active:not(:disabled){transform:scale(.985)}.pos-login__key:disabled,.pos-login__back:disabled,.pos-login__primary:disabled{cursor:not-allowed;opacity:.45;transform:none;filter:none}.pos-login__key:focus-visible,.pos-login__primary:focus-visible,.pos-login__back:focus-visible{outline:3px solid var(--pos-color-primary);outline-offset:2px}.pos-login__primary{border-color:var(--pos-color-primary);background:var(--pos-color-primary);color:var(--pos-color-on-primary)}.pos-login__primary:hover:not(:disabled){filter:brightness(1.06)}.pos-login__back{border:0;background:transparent;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-login__back:hover:not(:disabled){color:var(--pos-color-text)}.pos-login__status{display:flex;flex-direction:column;gap:var(--pos-space-xs);text-align:center}.pos-login__status p{margin:0;font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-login__error{color:var(--pos-color-danger)}@media(min-width:768px){.pos-login__shell--aside{flex-direction:row;align-items:stretch}.pos-login__aside,.pos-login__panel{flex:1 1 50%}.pos-login__aside{border-bottom:0;border-right:1px solid var(--pos-color-border);padding:var(--pos-space-2xl)}.pos-login__key,.pos-login__primary{min-height:var(--pos-keypad-size-md)}}@media(prefers-reduced-motion:reduce){.pos-login__key,.pos-login__primary,.pos-login__back{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
142
169
|
}
|
|
143
170
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosLogin, decorators: [{
|
|
144
171
|
type: Component,
|
|
145
172
|
args: [{ selector: 'pos-login', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
146
173
|
class: 'pos-login',
|
|
147
174
|
}, template: "<div\r\n class=\"pos-login__shell\"\r\n [class.pos-login__shell--aside]=\"showAside()\"\r\n [class.pos-login__shell--bordered]=\"bordered()\"\r\n>\r\n @if (showAside()) {\r\n <aside class=\"pos-login__aside\">\r\n @if (showBrandImage() || brandLabel()) {\r\n <div class=\"pos-login__brand\">\r\n @if (showBrandImage()) {\r\n @if (brandImage()) {\r\n <img\r\n class=\"pos-login__brand-image\"\r\n [src]=\"brandImage()\"\r\n [alt]=\"brandLabel() ? '' : 'Brand'\"\r\n />\r\n } @else {\r\n <svg\r\n class=\"pos-login__brand-image\"\r\n viewBox=\"492.40 241.70 51.34 54.94\"\r\n [attr.aria-hidden]=\"brandLabel() ? true : null\"\r\n [attr.aria-label]=\"brandLabel() ? null : 'Retalia'\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 522.628906 291.910156 C 522.636719 293.0625 523.441406 293.511719 524.425781 292.914062 L 540.464844 283.207031 C 541.449219 282.613281 542.246094 281.195312 542.246094 280.046875 L 542.246094 261.132812 C 542.246094 259.980469 541.441406 259.523438 540.453125 260.113281 L 524.292969 269.691406 C 523.300781 270.277344 522.503906 271.683594 522.511719 272.835938 Z M 522.628906 291.910156\"\r\n />\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 539.097656 253.351562 L 517.101562 243.664062 C 516.066406 243.203125 514.417969 243.265625 513.421875 243.804688 L 495.835938 253.308594 C 494.839844 253.847656 494.027344 255.214844 494.023438 256.367188 L 493.910156 280.140625 C 493.902344 281.292969 494.699219 282.679688 495.683594 283.234375 L 501.734375 286.640625 C 502.71875 287.199219 503.503906 286.71875 503.480469 285.566406 L 503.214844 271.488281 C 503.207031 271.082031 503.492188 270.894531 503.855469 271.066406 L 506.128906 272.148438 C 507.152344 272.636719 507.980469 273.960938 507.980469 275.113281 L 507.980469 287.839844 C 507.980469 288.992188 508.773438 290.394531 509.746094 290.972656 L 515.777344 294.5625 C 516.753906 295.140625 517.554688 294.679688 517.566406 293.527344 L 517.800781 273.300781 C 517.808594 272.488281 517.539062 271.238281 517.195312 270.503906 L 515.460938 266.789062 C 515.292969 266.421875 515.476562 266.109375 515.871094 266.089844 L 518.925781 265.941406 C 520.050781 265.886719 521.761719 265.378906 522.738281 264.808594 L 539.195312 255.21875 C 540.175781 254.648438 540.132812 253.8125 539.097656 253.351562 M 520.609375 255.050781 L 518.019531 256.585938 C 516.914062 257.125 515.734375 257.289062 514.710938 256.804688 L 511.078125 255.101562 C 510.054688 254.621094 510.023438 253.773438 511.003906 253.210938 L 513.835938 251.597656 C 514.53125 251.203125 515.691406 251.132812 516.425781 251.445312 L 520.449219 253.128906 C 521.488281 253.570312 521.5625 254.429688 520.609375 255.050781\"\r\n />\r\n </svg>\r\n }\r\n }\r\n @if (brandLabel()) {\r\n <span class=\"pos-login__brand-label\">{{ brandLabel() }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (locationName() || terminalLine()) {\r\n <div class=\"pos-login__place\">\r\n @if (locationName()) {\r\n <p class=\"pos-login__location\">{{ locationName() }}</p>\r\n }\r\n @if (terminalLine()) {\r\n <p class=\"pos-login__terminal\">{{ terminalLine() }}</p>\r\n }\r\n @if (shopName()) {\r\n <p class=\"pos-login__terminal\">{{ shopName() }}</p>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"pos-login__facts\">\r\n <div class=\"pos-login__fact\">\r\n <p class=\"pos-login__fact-label\">{{ dateLabel() }}</p>\r\n <p class=\"pos-login__fact-value\">{{ shownDate() }}</p>\r\n </div>\r\n @if (posNumber()) {\r\n <div class=\"pos-login__fact\">\r\n <p class=\"pos-login__fact-label\">{{ posNumberLabel() }}</p>\r\n <p class=\"pos-login__fact-value\">{{ posNumber() }}</p>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Custom content slot -->\r\n <div class=\"pos-login__slot\">\r\n <ng-content select=\"[posLoginAside]\" />\r\n </div>\r\n </aside>\r\n }\r\n\r\n<section class=\"pos-login__panel\" [attr.aria-busy]=\"session().status === 'busy' ? true : null\">\r\n <div class=\"pos-login__main\">\r\n <header class=\"pos-login__header\">\r\n <h1 class=\"pos-login__heading\">{{ heading() }}</h1>\r\n @if (showBack()) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__back\"\r\n aria-label=\"Back\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onBack()\"\r\n >\r\n Back\r\n </button>\r\n }\r\n </header>\r\n\r\n <div class=\"pos-login__display\">\r\n <p class=\"pos-login__title\" [class.pos-login__title--entry]=\"hasEntry()\">{{ displayText() }}</p>\r\n <input\r\n class=\"pos-login__input\"\r\n [attr.type]=\"maskInput() ? 'password' : 'text'\"\r\n [value]=\"inputValue()\"\r\n maxlength=\"12\"\r\n readonly\r\n tabindex=\"-1\"\r\n (keydown)=\"$event.preventDefault()\"\r\n aria-label=\"Login code\"\r\n />\r\n </div>\r\n\r\n <div class=\"pos-login__keypad\" role=\"group\" aria-label=\"Keypad\">\r\n @for (key of digitKeys; track key) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad(key)\"\r\n >\r\n {{ key }}\r\n </button>\r\n }\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key pos-login__key--delete\"\r\n aria-label=\"Delete\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad('\u2190')\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M8 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H8l-5-7 5-7Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"m14 10 4 4m0-4-4 4\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__key\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onKeypad('0')\"\r\n >\r\n 0\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-login__primary\"\r\n [attr.aria-label]=\"primaryLabel()\"\r\n [disabled]=\"interactionLocked()\"\r\n (click)=\"onPrimary()\"\r\n >\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <path\r\n d=\"M5 12.5 9.5 17 19 7.5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n @if (sessionStatusText() || errorMessage()) {\r\n <div class=\"pos-login__status\" aria-live=\"polite\">\r\n @if (sessionStatusText()) {\r\n <p>{{ sessionStatusText() }}</p>\r\n }\r\n @if (errorMessage()) {\r\n <p class=\"pos-login__error\" role=\"alert\">{{ errorMessage() }}</p>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- // Custom content slot -->\r\n <div class=\"pos-login__slot\">\r\n <ng-content select=\"[posLoginPanel]\" />\r\n </div>\r\n </div>\r\n</section>\r\n</div>\r\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%;height:100%;min-height:100vh;align-items:center;justify-content:center;padding:var(--pos-space-lg);color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md);background:transparent}*{box-sizing:border-box}.pos-login__shell{display:flex;flex-direction:column;width:min(22rem,100%);min-width:0}.pos-login__shell--aside{width:min(56rem,100%);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay);overflow:hidden}.pos-login__shell--bordered{border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg)}.pos-login__aside{display:flex;flex-direction:column;gap:var(--pos-space-xl);min-width:0;padding:var(--pos-space-xl);border-bottom:1px solid var(--pos-color-border)}.pos-login__brand{display:flex;align-items:center;gap:var(--pos-space-sm)}.pos-login__brand-image{flex:0 0 auto;width:auto;height:var(--pos-space-xl);color:var(--pos-color-ink)}.pos-login__brand-label{font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);letter-spacing:var(--pos-letter-spacing-brand)}.pos-login__place{display:flex;flex-direction:column;gap:var(--pos-space-xs)}.pos-login__location{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-login__terminal{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-login__facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--pos-space-md)}.pos-login__fact{min-width:0;padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg)}.pos-login__fact-label{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);letter-spacing:var(--pos-letter-spacing-brand);text-transform:uppercase}.pos-login__fact-value{margin:var(--pos-space-xs) 0 0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.25}.pos-login__slot{display:flex;flex-direction:column;gap:var(--pos-space-sm);min-width:0}.pos-login__slot:not(:has(*)){display:none}.pos-login__panel{display:flex;flex:1 1 auto;align-items:flex-start;justify-content:center;width:100%;min-width:0;padding:var(--pos-space-xl)}.pos-login__shell:not(.pos-login__shell--aside) .pos-login__panel{padding:0}.pos-login__main{display:flex;flex-direction:column;gap:var(--pos-space-md);width:min(22rem,100%)}.pos-login__header{display:flex;align-items:center;justify-content:space-between;gap:var(--pos-space-sm);min-height:var(--pos-space-xl)}.pos-login__heading{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-login__display{position:relative;display:flex;align-items:center;justify-content:center;width:100%;min-width:0;min-height:calc(var(--pos-button-min-height) + var(--pos-space-lg));padding:var(--pos-space-md) var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface-muted)}.pos-login__title{margin:0;max-width:100%;color:var(--pos-color-text);font-family:var(--pos-font-family-display);font-size:calc(var(--pos-font-size-xl) * 1.3);font-weight:var(--pos-font-weight-bold);line-height:1.2;text-align:center;overflow-wrap:anywhere}.pos-login__title--entry{letter-spacing:var(--pos-letter-spacing-display)}.pos-login__input{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.pos-login__keypad{display:grid;width:100%;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--pos-space-sm)}.pos-login__key,.pos-login__primary,.pos-login__back{font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-login__key,.pos-login__primary{display:inline-flex;align-items:center;justify-content:center;min-height:var(--pos-keypad-size);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-key);color:var(--pos-color-text);box-shadow:var(--pos-shadow-key);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-semibold);transition:background .12s ease,border-color .12s ease,color .12s ease,transform 80ms ease,filter .12s ease}.pos-login__key--delete{color:var(--pos-color-text-muted)}.pos-login__key:hover:not(:disabled){border-color:var(--pos-color-primary);background:color-mix(in srgb,var(--pos-color-primary) 22%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-login__key:active:not(:disabled),.pos-login__primary:active:not(:disabled),.pos-login__back:active:not(:disabled){transform:scale(.985)}.pos-login__key:disabled,.pos-login__back:disabled,.pos-login__primary:disabled{cursor:not-allowed;opacity:.45;transform:none;filter:none}.pos-login__key:focus-visible,.pos-login__primary:focus-visible,.pos-login__back:focus-visible{outline:3px solid var(--pos-color-primary);outline-offset:2px}.pos-login__primary{border-color:var(--pos-color-primary);background:var(--pos-color-primary);color:var(--pos-color-on-primary)}.pos-login__primary:hover:not(:disabled){filter:brightness(1.06)}.pos-login__back{border:0;background:transparent;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-login__back:hover:not(:disabled){color:var(--pos-color-text)}.pos-login__status{display:flex;flex-direction:column;gap:var(--pos-space-xs);text-align:center}.pos-login__status p{margin:0;font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-login__error{color:var(--pos-color-danger)}@media(min-width:768px){.pos-login__shell--aside{flex-direction:row;align-items:stretch}.pos-login__aside,.pos-login__panel{flex:1 1 50%}.pos-login__aside{border-bottom:0;border-right:1px solid var(--pos-color-border);padding:var(--pos-space-2xl)}.pos-login__key,.pos-login__primary{min-height:var(--pos-keypad-size-md)}}@media(prefers-reduced-motion:reduce){.pos-login__key,.pos-login__primary,.pos-login__back{transition:none}}\n"] }]
|
|
148
|
-
}], propDecorators: { errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], session: [{ type: i0.Input, args: [{ isSignal: true, alias: "session", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], titleClerkNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleClerkNumber", required: false }] }], titleClerkPassword: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleClerkPassword", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], loginLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "loginLabel", required: false }] }], showAside: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAside", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], showBrandImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBrandImage", required: false }] }], brandImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandImage", required: false }] }], brandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandLabel", required: false }] }], locationName: [{ type: i0.Input, args: [{ isSignal: true, alias: "locationName", required: false }] }], terminalLine: [{ type: i0.Input, args: [{ isSignal: true, alias: "terminalLine", required: false }] }], shopName: [{ type: i0.Input, args: [{ isSignal: true, alias: "shopName", required: false }] }], dateLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateLabel", required: false }] }], posNumberLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "posNumberLabel", required: false }] }], posNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "posNumber", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
175
|
+
}], ctorParameters: () => [], propDecorators: { errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], session: [{ type: i0.Input, args: [{ isSignal: true, alias: "session", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], titleClerkNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleClerkNumber", required: false }] }], titleClerkPassword: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleClerkPassword", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], loginLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "loginLabel", required: false }] }], showAside: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAside", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], showBrandImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBrandImage", required: false }] }], brandImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandImage", required: false }] }], brandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandLabel", required: false }] }], locationName: [{ type: i0.Input, args: [{ isSignal: true, alias: "locationName", required: false }] }], terminalLine: [{ type: i0.Input, args: [{ isSignal: true, alias: "terminalLine", required: false }] }], shopName: [{ type: i0.Input, args: [{ isSignal: true, alias: "shopName", required: false }] }], dateLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateLabel", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], posNumberLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "posNumberLabel", required: false }] }], posNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "posNumber", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
149
176
|
|
|
150
177
|
/** Id the host stores and passes back as `selectedId`. */
|
|
151
178
|
function posTillDeviceKey(device) {
|
|
@@ -251,7 +278,9 @@ class PosTillDevices {
|
|
|
251
278
|
}
|
|
252
279
|
event.preventDefault();
|
|
253
280
|
let next = index;
|
|
254
|
-
|
|
281
|
+
let remaining = cards.length;
|
|
282
|
+
while (remaining > 0) {
|
|
283
|
+
remaining -= 1;
|
|
255
284
|
next = (next + step + cards.length) % cards.length;
|
|
256
285
|
const card = cards[next];
|
|
257
286
|
if (!card.offline && !this.disabled()) {
|
|
@@ -384,7 +413,7 @@ class PosTillDevices {
|
|
|
384
413
|
return [host, identity].filter(Boolean).join(' · ');
|
|
385
414
|
}
|
|
386
415
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosTillDevices, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
387
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosTillDevices, isStandalone: true, selector: "pos-till-devices", inputs: { devices: { classPropertyName: "devices", publicName: "devices", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, listLabel: { classPropertyName: "listLabel", publicName: "listLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null }, selectLabel: { classPropertyName: "selectLabel", publicName: "selectLabel", isSignal: true, isRequired: false, transformFunction: null }, changeLabel: { classPropertyName: "changeLabel", publicName: "changeLabel", isSignal: true, isRequired: false, transformFunction: null }, setupLabel: { classPropertyName: "setupLabel", publicName: "setupLabel", isSignal: true, isRequired: false, transformFunction: null }, connectorLabel: { classPropertyName: "connectorLabel", publicName: "connectorLabel", isSignal: true, isRequired: false, transformFunction: null }, printerCaption: { classPropertyName: "printerCaption", publicName: "printerCaption", isSignal: true, isRequired: false, transformFunction: null }, paymentCaption: { classPropertyName: "paymentCaption", publicName: "paymentCaption", isSignal: true, isRequired: false, transformFunction: null }, noPaymentLabel: { classPropertyName: "noPaymentLabel", publicName: "noPaymentLabel", isSignal: true, isRequired: false, transformFunction: null }, paymentFallbackLabel: { classPropertyName: "paymentFallbackLabel", publicName: "paymentFallbackLabel", isSignal: true, isRequired: false, transformFunction: null }, hardwareLabel: { classPropertyName: "hardwareLabel", publicName: "hardwareLabel", isSignal: true, isRequired: false, transformFunction: null }, softwareLabel: { classPropertyName: "softwareLabel", publicName: "softwareLabel", isSignal: true, isRequired: false, transformFunction: null }, virtualLabel: { classPropertyName: "virtualLabel", publicName: "virtualLabel", isSignal: true, isRequired: false, transformFunction: null }, offlineLabel: { classPropertyName: "offlineLabel", publicName: "offlineLabel", isSignal: true, isRequired: false, transformFunction: null }, nothingToInstallLabel: { classPropertyName: "nothingToInstallLabel", publicName: "nothingToInstallLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { properties: { "class.pos-till-devices--dialog": "variant() === \"dialog\"", "class.pos-till-devices--summary": "variant() === \"summary\"", "class.pos-till-devices--link": "variant() === \"link\"" }, classAttribute: "pos-till-devices" }, viewQueries: [{ propertyName: "dialogRef", first: true, predicate: ["dialog"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (variant() === 'summary') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__summary\"\r\n [class.pos-till-devices__summary--attention]=\"!selectedCard()\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n <span class=\"pos-till-devices__eyebrow\">\r\n {{ connectorLabel() }}\r\n @if (selectedCard(); as card) {\r\n <span> \u00B7 {{ card.kindText }}</span>\r\n }\r\n </span>\r\n <span\r\n class=\"pos-till-devices__summary-title\"\r\n [class.pos-till-devices__summary-title--attention]=\"!selectedCard()\"\r\n >\r\n @if (selectedCard(); as card) {\r\n {{ card.device.name }}\r\n } @else {\r\n {{ setupLabel() }}\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </span>\r\n @if (selectedCard(); as card) {\r\n @if (card.printer || card.payment) {\r\n <span class=\"pos-till-devices__summary-meta\">\r\n @if (card.printer) {\r\n <span>{{ printerCaption() }}: {{ card.printer }}</span>\r\n }\r\n @if (card.printer && card.payment) {\r\n <span aria-hidden=\"true\"> \u00B7 </span>\r\n }\r\n @if (card.payment) {\r\n <span>{{ paymentCaption() }}: {{ card.payment }}</span>\r\n }\r\n </span>\r\n }\r\n }\r\n </button>\r\n}\r\n\r\n@if (variant() === 'link') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__link\"\r\n [class.pos-till-devices__link--attention]=\"icon() === 'none' && !selectedCard()\"\r\n [class.pos-till-devices__link--button]=\"icon() === 'plug'\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n @if (icon() === 'plug') {\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n }\r\n {{ linkText() }}\r\n @if (icon() === 'none') {\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </button>\r\n}\r\n\r\n@if (showDialog()) {\r\n <div class=\"pos-till-devices__overlay\" (click)=\"dismiss()\">\r\n <div\r\n #dialog\r\n class=\"pos-till-devices__dialog\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabindex=\"-1\"\r\n [attr.aria-labelledby]=\"titleId\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (click)=\"$event.stopPropagation()\"\r\n (keydown)=\"onDialogKeydown($event)\"\r\n >\r\n <header class=\"pos-till-devices__header\">\r\n <h2 [id]=\"titleId\" class=\"pos-till-devices__title\">{{ title() }}</h2>\r\n @if (description()) {\r\n <p [id]=\"descriptionId\" class=\"pos-till-devices__description\">{{ description() }}</p>\r\n }\r\n </header>\r\n\r\n @if (cards().length === 0) {\r\n <p class=\"pos-till-devices__empty\">{{ emptyLabel() }}</p>\r\n } @else {\r\n <div class=\"pos-till-devices__grid\" role=\"radiogroup\" [attr.aria-label]=\"listLabel()\">\r\n @for (card of cards(); track card.key) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__card\"\r\n [class.pos-till-devices__card--selected]=\"card.selected\"\r\n [class.pos-till-devices__card--offline]=\"card.offline\"\r\n role=\"radio\"\r\n [attr.data-card-index]=\"card.index\"\r\n [attr.aria-checked]=\"card.selected\"\r\n [disabled]=\"disabled() || card.offline\"\r\n (click)=\"pick(card)\"\r\n (keydown.arrowRight)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowDown)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowLeft)=\"moveSelection(card.index, -1, $event)\"\r\n (keydown.arrowUp)=\"moveSelection(card.index, -1, $event)\"\r\n >\r\n <span class=\"pos-till-devices__card-head\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n @if (card.kind === 'virtual') {\r\n <path\r\n d=\"M13 2 4 14h7l-1 8 10-14h-7l0-6Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n } @else {\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n }\r\n </svg>\r\n <span class=\"pos-till-devices__name\">{{ card.device.name }}</span>\r\n <span\r\n class=\"pos-till-devices__badge\"\r\n [class.pos-till-devices__badge--virtual]=\"card.kind === 'virtual'\"\r\n [class.pos-till-devices__badge--software]=\"card.kind === 'software'\"\r\n >\r\n {{ card.kindText }}\r\n </span>\r\n </span>\r\n\r\n @if (card.printer) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M7 8V4h10v4M7 17H5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M7 14h10v6H7z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ printerCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.printer }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.payment) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <rect\r\n x=\"3\"\r\n y=\"6\"\r\n width=\"18\"\r\n height=\"12\"\r\n rx=\"2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n />\r\n <path d=\"M3 10h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ paymentCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.payment }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.detail) {\r\n <span\r\n class=\"pos-till-devices__presence\"\r\n [class.pos-till-devices__presence--online]=\"card.presence === 'online'\"\r\n [class.pos-till-devices__presence--offline]=\"card.presence === 'offline'\"\r\n >\r\n <span class=\"pos-till-devices__dot\" aria-hidden=\"true\"></span>\r\n <span>{{ card.detail }}</span>\r\n </span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"pos-till-devices__actions\">\r\n <button type=\"button\" class=\"pos-till-devices__button\" (click)=\"dismiss()\">\r\n {{ cancelLabel() }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__button pos-till-devices__button--primary\"\r\n [disabled]=\"!canConfirm()\"\r\n (click)=\"confirm()\"\r\n >\r\n {{ confirmLabel() }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:block;box-sizing:border-box;min-width:0;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}:host(.pos-till-devices--link){display:flex;justify-content:center}*{box-sizing:border-box}.pos-till-devices__summary,.pos-till-devices__link,.pos-till-devices__card,.pos-till-devices__button{font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-till-devices__summary{display:flex;flex-direction:column;align-items:flex-start;gap:var(--pos-space-xs);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);text-align:left}.pos-till-devices__summary--attention{border-style:dashed;border-color:var(--pos-color-danger)}.pos-till-devices__eyebrow{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);letter-spacing:var(--pos-letter-spacing-brand);text-transform:uppercase}.pos-till-devices__summary-title{font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.25}.pos-till-devices__summary-title--attention{color:var(--pos-color-danger)}.pos-till-devices__summary-meta{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__link{display:inline-flex;align-items:center;justify-content:center;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-md);border:0;background:transparent;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__link--attention{color:var(--pos-color-danger);font-weight:var(--pos-font-weight-bold)}.pos-till-devices__link--button{width:100%;gap:var(--pos-space-sm);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);box-shadow:var(--pos-shadow-key)}.pos-till-devices__link--button .pos-till-devices__icon{width:1.15rem;height:1.15rem;margin-top:0;color:var(--pos-color-text)}.pos-till-devices__summary:hover:not(:disabled),.pos-till-devices__link:hover:not(:disabled),.pos-till-devices__card:hover:not(:disabled){border-color:var(--pos-color-primary)}.pos-till-devices__link:hover:not(:disabled){text-decoration:underline}.pos-till-devices__link--button:hover:not(:disabled){text-decoration:none}.pos-till-devices__summary:focus-visible,.pos-till-devices__link:focus-visible,.pos-till-devices__card:focus-visible,.pos-till-devices__button:focus-visible{outline:3px solid var(--pos-color-primary);outline-offset:2px}.pos-till-devices__summary:disabled,.pos-till-devices__link:disabled,.pos-till-devices__card:disabled,.pos-till-devices__button:disabled{cursor:not-allowed;opacity:.45}.pos-till-devices__overlay{position:fixed;inset:0;z-index:40;display:flex;align-items:flex-start;justify-content:center;padding:var(--pos-space-lg);overflow:auto;background:color-mix(in srgb,var(--pos-color-ink) 45%,transparent)}.pos-till-devices__dialog{display:flex;flex-direction:column;gap:var(--pos-space-lg);width:min(64rem,100%);max-height:calc(100vh - var(--pos-space-lg) * 2);margin-block:auto;padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay)}.pos-till-devices__header{display:flex;flex-direction:column;gap:var(--pos-space-xs)}.pos-till-devices__title{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-till-devices__description,.pos-till-devices__empty{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__empty{padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface-muted)}.pos-till-devices__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--pos-space-md);min-height:0;margin:0;padding:0;overflow:auto}.pos-till-devices__card{display:flex;flex-direction:column;align-items:stretch;gap:var(--pos-space-sm);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);box-shadow:var(--pos-shadow-key);text-align:left}.pos-till-devices__card--selected{border-color:var(--pos-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--pos-color-primary) 55%,transparent)}.pos-till-devices__card-head{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0}.pos-till-devices__icon{flex:0 0 auto;width:1.15rem;height:1.15rem;margin-top:.1rem;color:var(--pos-color-text-muted)}.pos-till-devices__name{flex:1 1 auto;min-width:0;font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);line-height:1.3;overflow-wrap:anywhere}.pos-till-devices__badge{flex:0 0 auto;padding:var(--pos-space-xs) var(--pos-space-sm);border-radius:var(--pos-radius-pill);background:var(--pos-color-surface-muted);color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);line-height:1.2}.pos-till-devices__badge--virtual{background:color-mix(in srgb,var(--pos-color-primary) 45%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__badge--software{background:color-mix(in srgb,var(--pos-color-warning) 40%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__row,.pos-till-devices__presence{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0;font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__row-label{color:var(--pos-color-text-muted)}.pos-till-devices__row-value{font-weight:var(--pos-font-weight-semibold);overflow-wrap:anywhere}.pos-till-devices__presence{align-items:center;color:var(--pos-color-text-muted)}.pos-till-devices__presence--online{color:color-mix(in srgb,var(--pos-color-success) 28%,var(--pos-color-text))}.pos-till-devices__presence--offline{color:var(--pos-color-danger)}.pos-till-devices__dot{flex:0 0 auto;width:var(--pos-space-sm);height:var(--pos-space-sm);margin-top:.15rem;border-radius:var(--pos-radius-pill);background:currentColor}.pos-till-devices__actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--pos-space-sm)}.pos-till-devices__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__button--primary{border-color:var(--pos-color-primary);background:var(--pos-color-primary);color:var(--pos-color-on-primary)}.pos-till-devices__button--primary:hover:not(:disabled){filter:brightness(1.06)}@media(min-width:768px){.pos-till-devices__dialog{padding:var(--pos-space-xl)}.pos-till-devices__grid{grid-template-columns:repeat(2,minmax(0,1fr))}.pos-till-devices__button{flex:0 1 auto;min-width:8rem}}@media(min-width:1024px){.pos-till-devices__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(prefers-reduced-motion:reduce){.pos-till-devices__button--primary{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
416
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosTillDevices, isStandalone: true, selector: "pos-till-devices", inputs: { devices: { classPropertyName: "devices", publicName: "devices", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, listLabel: { classPropertyName: "listLabel", publicName: "listLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null }, selectLabel: { classPropertyName: "selectLabel", publicName: "selectLabel", isSignal: true, isRequired: false, transformFunction: null }, changeLabel: { classPropertyName: "changeLabel", publicName: "changeLabel", isSignal: true, isRequired: false, transformFunction: null }, setupLabel: { classPropertyName: "setupLabel", publicName: "setupLabel", isSignal: true, isRequired: false, transformFunction: null }, connectorLabel: { classPropertyName: "connectorLabel", publicName: "connectorLabel", isSignal: true, isRequired: false, transformFunction: null }, printerCaption: { classPropertyName: "printerCaption", publicName: "printerCaption", isSignal: true, isRequired: false, transformFunction: null }, paymentCaption: { classPropertyName: "paymentCaption", publicName: "paymentCaption", isSignal: true, isRequired: false, transformFunction: null }, noPaymentLabel: { classPropertyName: "noPaymentLabel", publicName: "noPaymentLabel", isSignal: true, isRequired: false, transformFunction: null }, paymentFallbackLabel: { classPropertyName: "paymentFallbackLabel", publicName: "paymentFallbackLabel", isSignal: true, isRequired: false, transformFunction: null }, hardwareLabel: { classPropertyName: "hardwareLabel", publicName: "hardwareLabel", isSignal: true, isRequired: false, transformFunction: null }, softwareLabel: { classPropertyName: "softwareLabel", publicName: "softwareLabel", isSignal: true, isRequired: false, transformFunction: null }, virtualLabel: { classPropertyName: "virtualLabel", publicName: "virtualLabel", isSignal: true, isRequired: false, transformFunction: null }, offlineLabel: { classPropertyName: "offlineLabel", publicName: "offlineLabel", isSignal: true, isRequired: false, transformFunction: null }, nothingToInstallLabel: { classPropertyName: "nothingToInstallLabel", publicName: "nothingToInstallLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { properties: { "class.pos-till-devices--dialog": "variant() === \"dialog\"", "class.pos-till-devices--summary": "variant() === \"summary\"", "class.pos-till-devices--link": "variant() === \"link\"" }, classAttribute: "pos-till-devices" }, viewQueries: [{ propertyName: "dialogRef", first: true, predicate: ["dialog"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (variant() === 'summary') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__summary\"\r\n [class.pos-till-devices__summary--attention]=\"!selectedCard()\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n <span class=\"pos-till-devices__eyebrow\">\r\n {{ connectorLabel() }}\r\n @if (selectedCard(); as card) {\r\n <span> \u00B7 {{ card.kindText }}</span>\r\n }\r\n </span>\r\n <span\r\n class=\"pos-till-devices__summary-title\"\r\n [class.pos-till-devices__summary-title--attention]=\"!selectedCard()\"\r\n >\r\n @if (selectedCard(); as card) {\r\n {{ card.device.name }}\r\n } @else {\r\n {{ setupLabel() }}\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </span>\r\n @if (selectedCard(); as card) {\r\n @if (card.printer || card.payment) {\r\n <span class=\"pos-till-devices__summary-meta\">\r\n @if (card.printer) {\r\n <span>{{ printerCaption() }}: {{ card.printer }}</span>\r\n }\r\n @if (card.printer && card.payment) {\r\n <span aria-hidden=\"true\"> \u00B7 </span>\r\n }\r\n @if (card.payment) {\r\n <span>{{ paymentCaption() }}: {{ card.payment }}</span>\r\n }\r\n </span>\r\n }\r\n }\r\n </button>\r\n}\r\n\r\n@if (variant() === 'link') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__link\"\r\n [class.pos-till-devices__link--attention]=\"icon() === 'none' && !selectedCard()\"\r\n [class.pos-till-devices__link--button]=\"icon() === 'plug'\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n @if (icon() === 'plug') {\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n }\r\n {{ linkText() }}\r\n @if (icon() === 'none') {\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </button>\r\n}\r\n\r\n@if (showDialog()) {\r\n <div class=\"pos-till-devices__overlay\" role=\"presentation\" (click)=\"dismiss()\">\r\n <div\r\n #dialog\r\n class=\"pos-till-devices__dialog\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabindex=\"-1\"\r\n [attr.aria-labelledby]=\"titleId\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (click)=\"$event.stopPropagation()\"\r\n (keydown)=\"onDialogKeydown($event)\"\r\n >\r\n <header class=\"pos-till-devices__header\">\r\n <h2 [id]=\"titleId\" class=\"pos-till-devices__title\">{{ title() }}</h2>\r\n @if (description()) {\r\n <p [id]=\"descriptionId\" class=\"pos-till-devices__description\">{{ description() }}</p>\r\n }\r\n </header>\r\n\r\n @if (cards().length === 0) {\r\n <p class=\"pos-till-devices__empty\">{{ emptyLabel() }}</p>\r\n } @else {\r\n <div class=\"pos-till-devices__grid\" role=\"radiogroup\" [attr.aria-label]=\"listLabel()\">\r\n @for (card of cards(); track card.key) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__card\"\r\n [class.pos-till-devices__card--selected]=\"card.selected\"\r\n [class.pos-till-devices__card--offline]=\"card.offline\"\r\n role=\"radio\"\r\n [attr.data-card-index]=\"card.index\"\r\n [attr.aria-checked]=\"card.selected\"\r\n [disabled]=\"disabled() || card.offline\"\r\n (click)=\"pick(card)\"\r\n (keydown.arrowRight)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowDown)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowLeft)=\"moveSelection(card.index, -1, $event)\"\r\n (keydown.arrowUp)=\"moveSelection(card.index, -1, $event)\"\r\n >\r\n <span class=\"pos-till-devices__card-head\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n @if (card.kind === 'virtual') {\r\n <path\r\n d=\"M13 2 4 14h7l-1 8 10-14h-7l0-6Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n } @else {\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n }\r\n </svg>\r\n <span class=\"pos-till-devices__name\">{{ card.device.name }}</span>\r\n <span\r\n class=\"pos-till-devices__badge\"\r\n [class.pos-till-devices__badge--virtual]=\"card.kind === 'virtual'\"\r\n [class.pos-till-devices__badge--software]=\"card.kind === 'software'\"\r\n >\r\n {{ card.kindText }}\r\n </span>\r\n </span>\r\n\r\n @if (card.printer) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M7 8V4h10v4M7 17H5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M7 14h10v6H7z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ printerCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.printer }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.payment) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <rect\r\n x=\"3\"\r\n y=\"6\"\r\n width=\"18\"\r\n height=\"12\"\r\n rx=\"2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n />\r\n <path d=\"M3 10h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ paymentCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.payment }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.detail) {\r\n <span\r\n class=\"pos-till-devices__presence\"\r\n [class.pos-till-devices__presence--online]=\"card.presence === 'online'\"\r\n [class.pos-till-devices__presence--offline]=\"card.presence === 'offline'\"\r\n >\r\n <span class=\"pos-till-devices__dot\" aria-hidden=\"true\"></span>\r\n <span>{{ card.detail }}</span>\r\n </span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"pos-till-devices__actions\">\r\n <button type=\"button\" class=\"pos-till-devices__button\" (click)=\"dismiss()\">\r\n {{ cancelLabel() }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__button pos-till-devices__button--primary\"\r\n [disabled]=\"!canConfirm()\"\r\n (click)=\"confirm()\"\r\n >\r\n {{ confirmLabel() }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:block;box-sizing:border-box;min-width:0;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}:host(.pos-till-devices--link){display:flex;justify-content:center}*{box-sizing:border-box}.pos-till-devices__summary,.pos-till-devices__link,.pos-till-devices__card,.pos-till-devices__button{font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-till-devices__summary{display:flex;flex-direction:column;align-items:flex-start;gap:var(--pos-space-xs);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);text-align:left}.pos-till-devices__summary--attention{border-style:dashed;border-color:var(--pos-color-danger)}.pos-till-devices__eyebrow{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);letter-spacing:var(--pos-letter-spacing-brand);text-transform:uppercase}.pos-till-devices__summary-title{font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.25}.pos-till-devices__summary-title--attention{color:var(--pos-color-danger)}.pos-till-devices__summary-meta{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__link{display:inline-flex;align-items:center;justify-content:center;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-md);border:0;background:transparent;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__link--attention{color:var(--pos-color-danger);font-weight:var(--pos-font-weight-bold)}.pos-till-devices__link--button{width:100%;gap:var(--pos-space-sm);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);box-shadow:var(--pos-shadow-key)}.pos-till-devices__link--button .pos-till-devices__icon{width:1.15rem;height:1.15rem;margin-top:0;color:var(--pos-color-text)}.pos-till-devices__summary:hover:not(:disabled),.pos-till-devices__link:hover:not(:disabled),.pos-till-devices__card:hover:not(:disabled){border-color:var(--pos-color-primary)}.pos-till-devices__link:hover:not(:disabled){text-decoration:underline}.pos-till-devices__link--button:hover:not(:disabled){text-decoration:none}.pos-till-devices__summary:focus-visible,.pos-till-devices__link:focus-visible,.pos-till-devices__card:focus-visible,.pos-till-devices__button:focus-visible{outline:3px solid var(--pos-color-primary);outline-offset:2px}.pos-till-devices__summary:disabled,.pos-till-devices__link:disabled,.pos-till-devices__card:disabled,.pos-till-devices__button:disabled{cursor:not-allowed;opacity:.45}.pos-till-devices__overlay{position:fixed;inset:0;z-index:40;display:flex;align-items:flex-start;justify-content:center;padding:var(--pos-space-lg);overflow:auto;background:color-mix(in srgb,var(--pos-color-ink) 45%,transparent)}.pos-till-devices__dialog{display:flex;flex-direction:column;gap:var(--pos-space-lg);width:min(64rem,100%);max-height:calc(100vh - var(--pos-space-lg) * 2);margin-block:auto;padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay)}.pos-till-devices__header{display:flex;flex-direction:column;gap:var(--pos-space-xs)}.pos-till-devices__title{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-till-devices__description,.pos-till-devices__empty{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__empty{padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface-muted)}.pos-till-devices__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--pos-space-md);min-height:0;margin:0;padding:0;overflow:auto}.pos-till-devices__card{display:flex;flex-direction:column;align-items:stretch;gap:var(--pos-space-sm);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);box-shadow:var(--pos-shadow-key);text-align:left}.pos-till-devices__card--selected{border-color:var(--pos-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--pos-color-primary) 55%,transparent)}.pos-till-devices__card-head{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0}.pos-till-devices__icon{flex:0 0 auto;width:1.15rem;height:1.15rem;margin-top:.1rem;color:var(--pos-color-text-muted)}.pos-till-devices__name{flex:1 1 auto;min-width:0;font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);line-height:1.3;overflow-wrap:anywhere}.pos-till-devices__badge{flex:0 0 auto;padding:var(--pos-space-xs) var(--pos-space-sm);border-radius:var(--pos-radius-pill);background:var(--pos-color-surface-muted);color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);line-height:1.2}.pos-till-devices__badge--virtual{background:color-mix(in srgb,var(--pos-color-primary) 45%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__badge--software{background:color-mix(in srgb,var(--pos-color-warning) 40%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__row,.pos-till-devices__presence{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0;font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__row-label{color:var(--pos-color-text-muted)}.pos-till-devices__row-value{font-weight:var(--pos-font-weight-semibold);overflow-wrap:anywhere}.pos-till-devices__presence{align-items:center;color:var(--pos-color-text-muted)}.pos-till-devices__presence--online{color:color-mix(in srgb,var(--pos-color-success) 28%,var(--pos-color-text))}.pos-till-devices__presence--offline{color:var(--pos-color-danger)}.pos-till-devices__dot{flex:0 0 auto;width:var(--pos-space-sm);height:var(--pos-space-sm);margin-top:.15rem;border-radius:var(--pos-radius-pill);background:currentColor}.pos-till-devices__actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--pos-space-sm)}.pos-till-devices__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__button--primary{border-color:var(--pos-color-primary);background:var(--pos-color-primary);color:var(--pos-color-on-primary)}.pos-till-devices__button--primary:hover:not(:disabled){filter:brightness(1.06)}@media(min-width:768px){.pos-till-devices__dialog{padding:var(--pos-space-xl)}.pos-till-devices__grid{grid-template-columns:repeat(2,minmax(0,1fr))}.pos-till-devices__button{flex:0 1 auto;min-width:8rem}}@media(min-width:1024px){.pos-till-devices__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(prefers-reduced-motion:reduce){.pos-till-devices__button--primary{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
388
417
|
}
|
|
389
418
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosTillDevices, decorators: [{
|
|
390
419
|
type: Component,
|
|
@@ -393,9 +422,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
393
422
|
'[class.pos-till-devices--dialog]': 'variant() === "dialog"',
|
|
394
423
|
'[class.pos-till-devices--summary]': 'variant() === "summary"',
|
|
395
424
|
'[class.pos-till-devices--link]': 'variant() === "link"',
|
|
396
|
-
}, template: "@if (variant() === 'summary') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__summary\"\r\n [class.pos-till-devices__summary--attention]=\"!selectedCard()\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n <span class=\"pos-till-devices__eyebrow\">\r\n {{ connectorLabel() }}\r\n @if (selectedCard(); as card) {\r\n <span> \u00B7 {{ card.kindText }}</span>\r\n }\r\n </span>\r\n <span\r\n class=\"pos-till-devices__summary-title\"\r\n [class.pos-till-devices__summary-title--attention]=\"!selectedCard()\"\r\n >\r\n @if (selectedCard(); as card) {\r\n {{ card.device.name }}\r\n } @else {\r\n {{ setupLabel() }}\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </span>\r\n @if (selectedCard(); as card) {\r\n @if (card.printer || card.payment) {\r\n <span class=\"pos-till-devices__summary-meta\">\r\n @if (card.printer) {\r\n <span>{{ printerCaption() }}: {{ card.printer }}</span>\r\n }\r\n @if (card.printer && card.payment) {\r\n <span aria-hidden=\"true\"> \u00B7 </span>\r\n }\r\n @if (card.payment) {\r\n <span>{{ paymentCaption() }}: {{ card.payment }}</span>\r\n }\r\n </span>\r\n }\r\n }\r\n </button>\r\n}\r\n\r\n@if (variant() === 'link') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__link\"\r\n [class.pos-till-devices__link--attention]=\"icon() === 'none' && !selectedCard()\"\r\n [class.pos-till-devices__link--button]=\"icon() === 'plug'\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n @if (icon() === 'plug') {\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n }\r\n {{ linkText() }}\r\n @if (icon() === 'none') {\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </button>\r\n}\r\n\r\n@if (showDialog()) {\r\n <div class=\"pos-till-devices__overlay\" (click)=\"dismiss()\">\r\n <div\r\n #dialog\r\n class=\"pos-till-devices__dialog\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabindex=\"-1\"\r\n [attr.aria-labelledby]=\"titleId\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (click)=\"$event.stopPropagation()\"\r\n (keydown)=\"onDialogKeydown($event)\"\r\n >\r\n <header class=\"pos-till-devices__header\">\r\n <h2 [id]=\"titleId\" class=\"pos-till-devices__title\">{{ title() }}</h2>\r\n @if (description()) {\r\n <p [id]=\"descriptionId\" class=\"pos-till-devices__description\">{{ description() }}</p>\r\n }\r\n </header>\r\n\r\n @if (cards().length === 0) {\r\n <p class=\"pos-till-devices__empty\">{{ emptyLabel() }}</p>\r\n } @else {\r\n <div class=\"pos-till-devices__grid\" role=\"radiogroup\" [attr.aria-label]=\"listLabel()\">\r\n @for (card of cards(); track card.key) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__card\"\r\n [class.pos-till-devices__card--selected]=\"card.selected\"\r\n [class.pos-till-devices__card--offline]=\"card.offline\"\r\n role=\"radio\"\r\n [attr.data-card-index]=\"card.index\"\r\n [attr.aria-checked]=\"card.selected\"\r\n [disabled]=\"disabled() || card.offline\"\r\n (click)=\"pick(card)\"\r\n (keydown.arrowRight)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowDown)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowLeft)=\"moveSelection(card.index, -1, $event)\"\r\n (keydown.arrowUp)=\"moveSelection(card.index, -1, $event)\"\r\n >\r\n <span class=\"pos-till-devices__card-head\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n @if (card.kind === 'virtual') {\r\n <path\r\n d=\"M13 2 4 14h7l-1 8 10-14h-7l0-6Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n } @else {\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n }\r\n </svg>\r\n <span class=\"pos-till-devices__name\">{{ card.device.name }}</span>\r\n <span\r\n class=\"pos-till-devices__badge\"\r\n [class.pos-till-devices__badge--virtual]=\"card.kind === 'virtual'\"\r\n [class.pos-till-devices__badge--software]=\"card.kind === 'software'\"\r\n >\r\n {{ card.kindText }}\r\n </span>\r\n </span>\r\n\r\n @if (card.printer) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M7 8V4h10v4M7 17H5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M7 14h10v6H7z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ printerCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.printer }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.payment) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <rect\r\n x=\"3\"\r\n y=\"6\"\r\n width=\"18\"\r\n height=\"12\"\r\n rx=\"2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n />\r\n <path d=\"M3 10h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ paymentCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.payment }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.detail) {\r\n <span\r\n class=\"pos-till-devices__presence\"\r\n [class.pos-till-devices__presence--online]=\"card.presence === 'online'\"\r\n [class.pos-till-devices__presence--offline]=\"card.presence === 'offline'\"\r\n >\r\n <span class=\"pos-till-devices__dot\" aria-hidden=\"true\"></span>\r\n <span>{{ card.detail }}</span>\r\n </span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"pos-till-devices__actions\">\r\n <button type=\"button\" class=\"pos-till-devices__button\" (click)=\"dismiss()\">\r\n {{ cancelLabel() }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__button pos-till-devices__button--primary\"\r\n [disabled]=\"!canConfirm()\"\r\n (click)=\"confirm()\"\r\n >\r\n {{ confirmLabel() }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:block;box-sizing:border-box;min-width:0;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}:host(.pos-till-devices--link){display:flex;justify-content:center}*{box-sizing:border-box}.pos-till-devices__summary,.pos-till-devices__link,.pos-till-devices__card,.pos-till-devices__button{font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-till-devices__summary{display:flex;flex-direction:column;align-items:flex-start;gap:var(--pos-space-xs);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);text-align:left}.pos-till-devices__summary--attention{border-style:dashed;border-color:var(--pos-color-danger)}.pos-till-devices__eyebrow{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);letter-spacing:var(--pos-letter-spacing-brand);text-transform:uppercase}.pos-till-devices__summary-title{font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.25}.pos-till-devices__summary-title--attention{color:var(--pos-color-danger)}.pos-till-devices__summary-meta{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__link{display:inline-flex;align-items:center;justify-content:center;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-md);border:0;background:transparent;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__link--attention{color:var(--pos-color-danger);font-weight:var(--pos-font-weight-bold)}.pos-till-devices__link--button{width:100%;gap:var(--pos-space-sm);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);box-shadow:var(--pos-shadow-key)}.pos-till-devices__link--button .pos-till-devices__icon{width:1.15rem;height:1.15rem;margin-top:0;color:var(--pos-color-text)}.pos-till-devices__summary:hover:not(:disabled),.pos-till-devices__link:hover:not(:disabled),.pos-till-devices__card:hover:not(:disabled){border-color:var(--pos-color-primary)}.pos-till-devices__link:hover:not(:disabled){text-decoration:underline}.pos-till-devices__link--button:hover:not(:disabled){text-decoration:none}.pos-till-devices__summary:focus-visible,.pos-till-devices__link:focus-visible,.pos-till-devices__card:focus-visible,.pos-till-devices__button:focus-visible{outline:3px solid var(--pos-color-primary);outline-offset:2px}.pos-till-devices__summary:disabled,.pos-till-devices__link:disabled,.pos-till-devices__card:disabled,.pos-till-devices__button:disabled{cursor:not-allowed;opacity:.45}.pos-till-devices__overlay{position:fixed;inset:0;z-index:40;display:flex;align-items:flex-start;justify-content:center;padding:var(--pos-space-lg);overflow:auto;background:color-mix(in srgb,var(--pos-color-ink) 45%,transparent)}.pos-till-devices__dialog{display:flex;flex-direction:column;gap:var(--pos-space-lg);width:min(64rem,100%);max-height:calc(100vh - var(--pos-space-lg) * 2);margin-block:auto;padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay)}.pos-till-devices__header{display:flex;flex-direction:column;gap:var(--pos-space-xs)}.pos-till-devices__title{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-till-devices__description,.pos-till-devices__empty{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__empty{padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface-muted)}.pos-till-devices__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--pos-space-md);min-height:0;margin:0;padding:0;overflow:auto}.pos-till-devices__card{display:flex;flex-direction:column;align-items:stretch;gap:var(--pos-space-sm);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);box-shadow:var(--pos-shadow-key);text-align:left}.pos-till-devices__card--selected{border-color:var(--pos-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--pos-color-primary) 55%,transparent)}.pos-till-devices__card-head{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0}.pos-till-devices__icon{flex:0 0 auto;width:1.15rem;height:1.15rem;margin-top:.1rem;color:var(--pos-color-text-muted)}.pos-till-devices__name{flex:1 1 auto;min-width:0;font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);line-height:1.3;overflow-wrap:anywhere}.pos-till-devices__badge{flex:0 0 auto;padding:var(--pos-space-xs) var(--pos-space-sm);border-radius:var(--pos-radius-pill);background:var(--pos-color-surface-muted);color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);line-height:1.2}.pos-till-devices__badge--virtual{background:color-mix(in srgb,var(--pos-color-primary) 45%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__badge--software{background:color-mix(in srgb,var(--pos-color-warning) 40%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__row,.pos-till-devices__presence{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0;font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__row-label{color:var(--pos-color-text-muted)}.pos-till-devices__row-value{font-weight:var(--pos-font-weight-semibold);overflow-wrap:anywhere}.pos-till-devices__presence{align-items:center;color:var(--pos-color-text-muted)}.pos-till-devices__presence--online{color:color-mix(in srgb,var(--pos-color-success) 28%,var(--pos-color-text))}.pos-till-devices__presence--offline{color:var(--pos-color-danger)}.pos-till-devices__dot{flex:0 0 auto;width:var(--pos-space-sm);height:var(--pos-space-sm);margin-top:.15rem;border-radius:var(--pos-radius-pill);background:currentColor}.pos-till-devices__actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--pos-space-sm)}.pos-till-devices__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__button--primary{border-color:var(--pos-color-primary);background:var(--pos-color-primary);color:var(--pos-color-on-primary)}.pos-till-devices__button--primary:hover:not(:disabled){filter:brightness(1.06)}@media(min-width:768px){.pos-till-devices__dialog{padding:var(--pos-space-xl)}.pos-till-devices__grid{grid-template-columns:repeat(2,minmax(0,1fr))}.pos-till-devices__button{flex:0 1 auto;min-width:8rem}}@media(min-width:1024px){.pos-till-devices__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(prefers-reduced-motion:reduce){.pos-till-devices__button--primary{transition:none}}\n"] }]
|
|
425
|
+
}, template: "@if (variant() === 'summary') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__summary\"\r\n [class.pos-till-devices__summary--attention]=\"!selectedCard()\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n <span class=\"pos-till-devices__eyebrow\">\r\n {{ connectorLabel() }}\r\n @if (selectedCard(); as card) {\r\n <span> \u00B7 {{ card.kindText }}</span>\r\n }\r\n </span>\r\n <span\r\n class=\"pos-till-devices__summary-title\"\r\n [class.pos-till-devices__summary-title--attention]=\"!selectedCard()\"\r\n >\r\n @if (selectedCard(); as card) {\r\n {{ card.device.name }}\r\n } @else {\r\n {{ setupLabel() }}\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </span>\r\n @if (selectedCard(); as card) {\r\n @if (card.printer || card.payment) {\r\n <span class=\"pos-till-devices__summary-meta\">\r\n @if (card.printer) {\r\n <span>{{ printerCaption() }}: {{ card.printer }}</span>\r\n }\r\n @if (card.printer && card.payment) {\r\n <span aria-hidden=\"true\"> \u00B7 </span>\r\n }\r\n @if (card.payment) {\r\n <span>{{ paymentCaption() }}: {{ card.payment }}</span>\r\n }\r\n </span>\r\n }\r\n }\r\n </button>\r\n}\r\n\r\n@if (variant() === 'link') {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__link\"\r\n [class.pos-till-devices__link--attention]=\"icon() === 'none' && !selectedCard()\"\r\n [class.pos-till-devices__link--button]=\"icon() === 'plug'\"\r\n [disabled]=\"disabled()\"\r\n aria-haspopup=\"dialog\"\r\n (click)=\"openDialog()\"\r\n >\r\n @if (icon() === 'plug') {\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n }\r\n {{ linkText() }}\r\n @if (icon() === 'none') {\r\n <span aria-hidden=\"true\"> \u203A</span>\r\n }\r\n </button>\r\n}\r\n\r\n@if (showDialog()) {\r\n <div class=\"pos-till-devices__overlay\" role=\"presentation\" (click)=\"dismiss()\">\r\n <div\r\n #dialog\r\n class=\"pos-till-devices__dialog\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabindex=\"-1\"\r\n [attr.aria-labelledby]=\"titleId\"\r\n [attr.aria-describedby]=\"description() ? descriptionId : null\"\r\n (click)=\"$event.stopPropagation()\"\r\n (keydown)=\"onDialogKeydown($event)\"\r\n >\r\n <header class=\"pos-till-devices__header\">\r\n <h2 [id]=\"titleId\" class=\"pos-till-devices__title\">{{ title() }}</h2>\r\n @if (description()) {\r\n <p [id]=\"descriptionId\" class=\"pos-till-devices__description\">{{ description() }}</p>\r\n }\r\n </header>\r\n\r\n @if (cards().length === 0) {\r\n <p class=\"pos-till-devices__empty\">{{ emptyLabel() }}</p>\r\n } @else {\r\n <div class=\"pos-till-devices__grid\" role=\"radiogroup\" [attr.aria-label]=\"listLabel()\">\r\n @for (card of cards(); track card.key) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__card\"\r\n [class.pos-till-devices__card--selected]=\"card.selected\"\r\n [class.pos-till-devices__card--offline]=\"card.offline\"\r\n role=\"radio\"\r\n [attr.data-card-index]=\"card.index\"\r\n [attr.aria-checked]=\"card.selected\"\r\n [disabled]=\"disabled() || card.offline\"\r\n (click)=\"pick(card)\"\r\n (keydown.arrowRight)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowDown)=\"moveSelection(card.index, 1, $event)\"\r\n (keydown.arrowLeft)=\"moveSelection(card.index, -1, $event)\"\r\n (keydown.arrowUp)=\"moveSelection(card.index, -1, $event)\"\r\n >\r\n <span class=\"pos-till-devices__card-head\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n @if (card.kind === 'virtual') {\r\n <path\r\n d=\"M13 2 4 14h7l-1 8 10-14h-7l0-6Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n } @else {\r\n <path\r\n d=\"M8 8V4M16 8V4M7 8h10v5a5 5 0 0 1-10 0V8Z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 18v2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linecap=\"round\"\r\n />\r\n }\r\n </svg>\r\n <span class=\"pos-till-devices__name\">{{ card.device.name }}</span>\r\n <span\r\n class=\"pos-till-devices__badge\"\r\n [class.pos-till-devices__badge--virtual]=\"card.kind === 'virtual'\"\r\n [class.pos-till-devices__badge--software]=\"card.kind === 'software'\"\r\n >\r\n {{ card.kindText }}\r\n </span>\r\n </span>\r\n\r\n @if (card.printer) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <path\r\n d=\"M7 8V4h10v4M7 17H5a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M7 14h10v6H7z\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ printerCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.printer }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.payment) {\r\n <span class=\"pos-till-devices__row\">\r\n <svg class=\"pos-till-devices__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <rect\r\n x=\"3\"\r\n y=\"6\"\r\n width=\"18\"\r\n height=\"12\"\r\n rx=\"2\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.7\"\r\n />\r\n <path d=\"M3 10h18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" />\r\n </svg>\r\n <span>\r\n <span class=\"pos-till-devices__row-label\">{{ paymentCaption() }}: </span>\r\n <span class=\"pos-till-devices__row-value\">{{ card.payment }}</span>\r\n </span>\r\n </span>\r\n }\r\n\r\n @if (card.detail) {\r\n <span\r\n class=\"pos-till-devices__presence\"\r\n [class.pos-till-devices__presence--online]=\"card.presence === 'online'\"\r\n [class.pos-till-devices__presence--offline]=\"card.presence === 'offline'\"\r\n >\r\n <span class=\"pos-till-devices__dot\" aria-hidden=\"true\"></span>\r\n <span>{{ card.detail }}</span>\r\n </span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"pos-till-devices__actions\">\r\n <button type=\"button\" class=\"pos-till-devices__button\" (click)=\"dismiss()\">\r\n {{ cancelLabel() }}\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"pos-till-devices__button pos-till-devices__button--primary\"\r\n [disabled]=\"!canConfirm()\"\r\n (click)=\"confirm()\"\r\n >\r\n {{ confirmLabel() }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:block;box-sizing:border-box;min-width:0;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}:host(.pos-till-devices--link){display:flex;justify-content:center}*{box-sizing:border-box}.pos-till-devices__summary,.pos-till-devices__link,.pos-till-devices__card,.pos-till-devices__button{font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-till-devices__summary{display:flex;flex-direction:column;align-items:flex-start;gap:var(--pos-space-xs);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);text-align:left}.pos-till-devices__summary--attention{border-style:dashed;border-color:var(--pos-color-danger)}.pos-till-devices__eyebrow{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);letter-spacing:var(--pos-letter-spacing-brand);text-transform:uppercase}.pos-till-devices__summary-title{font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold);line-height:1.25}.pos-till-devices__summary-title--attention{color:var(--pos-color-danger)}.pos-till-devices__summary-meta{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__link{display:inline-flex;align-items:center;justify-content:center;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-md);border:0;background:transparent;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__link--attention{color:var(--pos-color-danger);font-weight:var(--pos-font-weight-bold)}.pos-till-devices__link--button{width:100%;gap:var(--pos-space-sm);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);box-shadow:var(--pos-shadow-key)}.pos-till-devices__link--button .pos-till-devices__icon{width:1.15rem;height:1.15rem;margin-top:0;color:var(--pos-color-text)}.pos-till-devices__summary:hover:not(:disabled),.pos-till-devices__link:hover:not(:disabled),.pos-till-devices__card:hover:not(:disabled){border-color:var(--pos-color-primary)}.pos-till-devices__link:hover:not(:disabled){text-decoration:underline}.pos-till-devices__link--button:hover:not(:disabled){text-decoration:none}.pos-till-devices__summary:focus-visible,.pos-till-devices__link:focus-visible,.pos-till-devices__card:focus-visible,.pos-till-devices__button:focus-visible{outline:3px solid var(--pos-color-primary);outline-offset:2px}.pos-till-devices__summary:disabled,.pos-till-devices__link:disabled,.pos-till-devices__card:disabled,.pos-till-devices__button:disabled{cursor:not-allowed;opacity:.45}.pos-till-devices__overlay{position:fixed;inset:0;z-index:40;display:flex;align-items:flex-start;justify-content:center;padding:var(--pos-space-lg);overflow:auto;background:color-mix(in srgb,var(--pos-color-ink) 45%,transparent)}.pos-till-devices__dialog{display:flex;flex-direction:column;gap:var(--pos-space-lg);width:min(64rem,100%);max-height:calc(100vh - var(--pos-space-lg) * 2);margin-block:auto;padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay)}.pos-till-devices__header{display:flex;flex-direction:column;gap:var(--pos-space-xs)}.pos-till-devices__title{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-till-devices__description,.pos-till-devices__empty{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__empty{padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface-muted)}.pos-till-devices__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--pos-space-md);min-height:0;margin:0;padding:0;overflow:auto}.pos-till-devices__card{display:flex;flex-direction:column;align-items:stretch;gap:var(--pos-space-sm);width:100%;min-height:var(--pos-button-min-height);padding:var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);color:var(--pos-color-text);box-shadow:var(--pos-shadow-key);text-align:left}.pos-till-devices__card--selected{border-color:var(--pos-color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--pos-color-primary) 55%,transparent)}.pos-till-devices__card-head{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0}.pos-till-devices__icon{flex:0 0 auto;width:1.15rem;height:1.15rem;margin-top:.1rem;color:var(--pos-color-text-muted)}.pos-till-devices__name{flex:1 1 auto;min-width:0;font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);line-height:1.3;overflow-wrap:anywhere}.pos-till-devices__badge{flex:0 0 auto;padding:var(--pos-space-xs) var(--pos-space-sm);border-radius:var(--pos-radius-pill);background:var(--pos-color-surface-muted);color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);line-height:1.2}.pos-till-devices__badge--virtual{background:color-mix(in srgb,var(--pos-color-primary) 45%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__badge--software{background:color-mix(in srgb,var(--pos-color-warning) 40%,var(--pos-color-surface));color:var(--pos-color-text)}.pos-till-devices__row,.pos-till-devices__presence{display:flex;align-items:flex-start;gap:var(--pos-space-sm);min-width:0;font-size:var(--pos-font-size-sm);line-height:1.4}.pos-till-devices__row-label{color:var(--pos-color-text-muted)}.pos-till-devices__row-value{font-weight:var(--pos-font-weight-semibold);overflow-wrap:anywhere}.pos-till-devices__presence{align-items:center;color:var(--pos-color-text-muted)}.pos-till-devices__presence--online{color:color-mix(in srgb,var(--pos-color-success) 28%,var(--pos-color-text))}.pos-till-devices__presence--offline{color:var(--pos-color-danger)}.pos-till-devices__dot{flex:0 0 auto;width:var(--pos-space-sm);height:var(--pos-space-sm);margin-top:.15rem;border-radius:var(--pos-radius-pill);background:currentColor}.pos-till-devices__actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--pos-space-sm)}.pos-till-devices__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);padding:var(--pos-space-sm) var(--pos-space-lg);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface);color:var(--pos-color-text);font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold)}.pos-till-devices__button--primary{border-color:var(--pos-color-primary);background:var(--pos-color-primary);color:var(--pos-color-on-primary)}.pos-till-devices__button--primary:hover:not(:disabled){filter:brightness(1.06)}@media(min-width:768px){.pos-till-devices__dialog{padding:var(--pos-space-xl)}.pos-till-devices__grid{grid-template-columns:repeat(2,minmax(0,1fr))}.pos-till-devices__button{flex:0 1 auto;min-width:8rem}}@media(min-width:1024px){.pos-till-devices__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(prefers-reduced-motion:reduce){.pos-till-devices__button--primary{transition:none}}\n"] }]
|
|
397
426
|
}], ctorParameters: () => [], propDecorators: { devices: [{ type: i0.Input, args: [{ isSignal: true, alias: "devices", required: false }] }], selectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedId", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], listLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "listLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: false }] }], emptyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyLabel", required: false }] }], selectLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectLabel", required: false }] }], changeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "changeLabel", required: false }] }], setupLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "setupLabel", required: false }] }], connectorLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectorLabel", required: false }] }], printerCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "printerCaption", required: false }] }], paymentCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "paymentCaption", required: false }] }], noPaymentLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "noPaymentLabel", required: false }] }], paymentFallbackLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "paymentFallbackLabel", required: false }] }], hardwareLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hardwareLabel", required: false }] }], softwareLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "softwareLabel", required: false }] }], virtualLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualLabel", required: false }] }], offlineLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "offlineLabel", required: false }] }], nothingToInstallLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nothingToInstallLabel", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], dialogRef: [{ type: i0.ViewChild, args: ['dialog', { isSignal: true }] }] } });
|
|
398
427
|
|
|
428
|
+
/** Currency used when the host passes an empty currency code. */
|
|
429
|
+
const POS_DEFAULT_CURRENCY = 'EUR';
|
|
430
|
+
const formatters = new Map();
|
|
431
|
+
/**
|
|
432
|
+
* Formats a display amount as currency in the user's locale, e.g. `formatPosMoney(12, 'GBP')`
|
|
433
|
+
* → `£12.00`. Display only: amounts come from the host and are never calculated here.
|
|
434
|
+
*
|
|
435
|
+
* @param fractionDigits Decimal places to show (2 for prices, 0 for whole notes and coins).
|
|
436
|
+
*/
|
|
437
|
+
function formatPosMoney(amount, currency, fractionDigits = 2) {
|
|
438
|
+
const code = (currency || POS_DEFAULT_CURRENCY).toUpperCase();
|
|
439
|
+
const key = `${code}:${fractionDigits}`;
|
|
440
|
+
let formatter = formatters.get(key);
|
|
441
|
+
if (!formatter) {
|
|
442
|
+
formatter = new Intl.NumberFormat(undefined, {
|
|
443
|
+
style: 'currency',
|
|
444
|
+
currency: code,
|
|
445
|
+
minimumFractionDigits: fractionDigits,
|
|
446
|
+
maximumFractionDigits: fractionDigits,
|
|
447
|
+
});
|
|
448
|
+
formatters.set(key, formatter);
|
|
449
|
+
}
|
|
450
|
+
return formatter.format(amount);
|
|
451
|
+
}
|
|
452
|
+
|
|
399
453
|
const EMPTY_TOTALS$1 = {
|
|
400
454
|
gross: 0,
|
|
401
455
|
net: 0,
|
|
@@ -415,12 +469,7 @@ class PosBasket {
|
|
|
415
469
|
action = output();
|
|
416
470
|
hasLines = computed(() => this.lines().length > 0, ...(ngDevMode ? [{ debugName: "hasLines" }] : /* istanbul ignore next */ []));
|
|
417
471
|
formatMoney(amount) {
|
|
418
|
-
return
|
|
419
|
-
style: 'currency',
|
|
420
|
-
currency: this.totals().currency || 'EUR',
|
|
421
|
-
minimumFractionDigits: 2,
|
|
422
|
-
maximumFractionDigits: 2,
|
|
423
|
-
}).format(amount);
|
|
472
|
+
return formatPosMoney(amount, this.totals().currency);
|
|
424
473
|
}
|
|
425
474
|
canChangeQuantity(line) {
|
|
426
475
|
return !this.disabled() && !line.struckThrough;
|
|
@@ -467,6 +516,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
467
516
|
}, template: "<section\r\n class=\"pos-basket__panel\"\r\n [class.pos-basket__panel--bordered]=\"bordered()\"\r\n [attr.aria-busy]=\"disabled() ? true : null\"\r\n>\r\n <header class=\"pos-basket__header\">\r\n <h2 class=\"pos-basket__title\">{{ title() }}</h2>\r\n <p class=\"pos-basket__count\">\r\n {{ lines().length }}\r\n {{ lines().length === 1 ? 'line' : 'lines' }}\r\n </p>\r\n </header>\r\n\r\n <ul class=\"pos-basket__lines\" aria-label=\"Basket lines\">\r\n @if (!hasLines()) {\r\n <li class=\"pos-basket__empty\">{{ emptyMessage() }}</li>\r\n } @else {\r\n @for (line of lines(); track line.lineId) {\r\n <li>\r\n <article\r\n class=\"pos-basket__line\"\r\n [class.pos-basket__line--voided]=\"line.struckThrough\"\r\n >\r\n <div class=\"pos-basket__line-info\">\r\n <h3 class=\"pos-basket__line-name\">{{ line.name }}</h3>\r\n <p class=\"pos-basket__line-sku\">{{ line.sku }}</p>\r\n @if (line.struckThrough) {\r\n <p class=\"pos-basket__line-voided\">Voided</p>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"pos-basket__stepper\"\r\n role=\"group\"\r\n [attr.aria-label]=\"'Quantity for ' + line.name\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"pos-basket__qty-btn\"\r\n aria-label=\"Decrease quantity\"\r\n [disabled]=\"!canDecrement(line)\"\r\n (click)=\"onDecrement(line)\"\r\n >\r\n \u2212\r\n </button>\r\n <span class=\"pos-basket__qty\" aria-live=\"polite\">{{ line.qty }}</span>\r\n <button\r\n type=\"button\"\r\n class=\"pos-basket__qty-btn\"\r\n aria-label=\"Increase quantity\"\r\n [disabled]=\"!canChangeQuantity(line)\"\r\n (click)=\"onIncrement(line)\"\r\n >\r\n +\r\n </button>\r\n </div>\r\n\r\n <div class=\"pos-basket__line-prices\">\r\n <p class=\"pos-basket__unit-price\">{{ formatMoney(line.unitPrice) }}</p>\r\n <p class=\"pos-basket__line-total\">{{ formatMoney(line.lineTotal) }}</p>\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"pos-basket__void\"\r\n [attr.aria-label]=\"'Void ' + line.name\"\r\n [disabled]=\"!canVoid(line)\"\r\n (click)=\"onVoid(line)\"\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n aria-hidden=\"true\"\r\n >\r\n <path\r\n d=\"M6 6l12 12M18 6 6 18\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </article>\r\n </li>\r\n }\r\n }\r\n </ul>\r\n\r\n <footer class=\"pos-basket__footer\">\r\n <dl class=\"pos-basket__totals\" aria-live=\"polite\">\r\n <div class=\"pos-basket__total-row\">\r\n <dt>Gross</dt>\r\n <dd>{{ formatMoney(totals().gross) }}</dd>\r\n </div>\r\n <div class=\"pos-basket__total-row\">\r\n <dt>Net</dt>\r\n <dd>{{ formatMoney(totals().net) }}</dd>\r\n </div>\r\n <div class=\"pos-basket__total-row\">\r\n <dt>VAT</dt>\r\n <dd>{{ formatMoney(totals().vat) }}</dd>\r\n </div>\r\n <div class=\"pos-basket__total-row\">\r\n <dt>Discount</dt>\r\n <dd>{{ formatMoney(totals().discount) }}</dd>\r\n </div>\r\n <div class=\"pos-basket__total-row pos-basket__total-row--due\">\r\n <dt>Due</dt>\r\n <dd>{{ formatMoney(totals().due) }}</dd>\r\n </div>\r\n </dl>\r\n </footer>\r\n</section>\r\n", styles: [":host{display:flex;flex-direction:column;min-height:0;width:100%;height:100%;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}.pos-basket__panel{display:flex;flex-direction:column;min-height:0;height:100%;padding:var(--pos-space-lg);border-radius:var(--pos-radius-lg);background:var(--pos-color-panel)}.pos-basket__panel--bordered{border:1px solid var(--pos-color-border)}.pos-basket__header{display:flex;align-items:baseline;justify-content:space-between;gap:var(--pos-space-md);margin-bottom:var(--pos-space-md)}.pos-basket__title{margin:0;font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold);letter-spacing:var(--pos-letter-spacing-tight)}.pos-basket__count{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold)}.pos-basket__lines{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--pos-space-sm);min-height:8rem;margin:0;padding:0;overflow-y:auto;list-style:none}.pos-basket__empty{margin:auto 0;padding:var(--pos-space-2xl) var(--pos-space-md);color:var(--pos-color-text-muted);text-align:center}.pos-basket__line{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:\"info void\" \"stepper prices\";align-items:center;gap:var(--pos-space-sm) var(--pos-space-md);padding:var(--pos-space-md);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-panel-elevated)}.pos-basket__line-info{grid-area:info;min-width:0}.pos-basket__line-name{margin:0;font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pos-basket__line-sku,.pos-basket__line-voided{margin:var(--pos-space-xs) 0 0;font-size:var(--pos-font-size-sm)}.pos-basket__line-sku{color:var(--pos-color-text-muted)}.pos-basket__line-voided{color:var(--pos-color-danger);font-weight:var(--pos-font-weight-semibold)}.pos-basket__stepper{grid-area:stepper;display:inline-flex;align-items:center;gap:var(--pos-space-xs);width:fit-content;padding:var(--pos-space-xs);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);background:var(--pos-color-surface)}.pos-basket__qty-btn,.pos-basket__void{display:inline-flex;align-items:center;justify-content:center;margin:0;border:0;background:transparent;color:var(--pos-color-text);font:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-basket__qty-btn{min-width:2.75rem;min-height:2.75rem;border-radius:var(--pos-radius-sm);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold)}.pos-basket__qty-btn:not(:disabled):active,.pos-basket__void:not(:disabled):active{background:var(--pos-color-key-active);color:var(--pos-color-on-key-active)}.pos-basket__qty{min-width:1.75rem;font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);text-align:center}.pos-basket__line-prices{grid-area:prices;display:flex;flex-direction:column;align-items:flex-end;gap:var(--pos-space-xs)}.pos-basket__unit-price{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-basket__line-total{margin:0;font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold)}.pos-basket__void{grid-area:void;justify-self:end;min-width:2.75rem;min-height:2.75rem;border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-md);color:var(--pos-color-text-muted)}.pos-basket__qty-btn:disabled,.pos-basket__void:disabled{cursor:not-allowed;opacity:.55}.pos-basket__qty-btn:focus-visible,.pos-basket__void:focus-visible{outline:2px solid var(--pos-color-primary);outline-offset:2px}.pos-basket__line--voided .pos-basket__line-name,.pos-basket__line--voided .pos-basket__line-sku,.pos-basket__line--voided .pos-basket__line-prices{color:var(--pos-color-text-muted);text-decoration:line-through}.pos-basket__footer{display:flex;flex-direction:column;gap:var(--pos-space-md);margin-top:var(--pos-space-md);padding-top:var(--pos-space-md);border-top:1px solid var(--pos-color-border)}.pos-basket__totals{display:flex;flex-direction:column;gap:var(--pos-space-sm);margin:0}.pos-basket__total-row{display:flex;justify-content:space-between;gap:var(--pos-space-md);margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-basket__total-row dt,.pos-basket__total-row dd{margin:0}.pos-basket__total-row--due{padding-top:var(--pos-space-sm);border-top:1px solid var(--pos-color-border);color:var(--pos-color-text);font-family:var(--pos-font-family-display);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold)}@media(min-width:768px){.pos-basket__panel{padding:var(--pos-space-xl)}.pos-basket__line{grid-template-columns:minmax(0,1fr) auto auto auto;grid-template-areas:\"info stepper prices void\";gap:var(--pos-space-md)}}\n"] }]
|
|
468
517
|
}], propDecorators: { lines: [{ type: i0.Input, args: [{ isSignal: true, alias: "lines", required: false }] }], totals: [{ type: i0.Input, args: [{ isSignal: true, alias: "totals", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], action: [{ type: i0.Output, args: ["action"] }] } });
|
|
469
518
|
|
|
519
|
+
let nextMenuId = 0;
|
|
470
520
|
class PosHeader {
|
|
471
521
|
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
472
522
|
context = input('', ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
@@ -484,7 +534,12 @@ class PosHeader {
|
|
|
484
534
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
485
535
|
action = output();
|
|
486
536
|
sessionRef = viewChild('session', ...(ngDevMode ? [{ debugName: "sessionRef" }] : /* istanbul ignore next */ []));
|
|
537
|
+
menuButtonRef = viewChild('menuButton', ...(ngDevMode ? [{ debugName: "menuButtonRef" }] : /* istanbul ignore next */ []));
|
|
538
|
+
menuRef = viewChild('menu', ...(ngDevMode ? [{ debugName: "menuRef" }] : /* istanbul ignore next */ []));
|
|
487
539
|
destroyRef = inject(DestroyRef);
|
|
540
|
+
injector = inject(Injector);
|
|
541
|
+
menuId = `pos-header-menu-${nextMenuId++}`;
|
|
542
|
+
menuButtonId = `${this.menuId}-button`;
|
|
488
543
|
menuOpen = signal(false, ...(ngDevMode ? [{ debugName: "menuOpen" }] : /* istanbul ignore next */ []));
|
|
489
544
|
menuTop = signal('0px', ...(ngDevMode ? [{ debugName: "menuTop" }] : /* istanbul ignore next */ []));
|
|
490
545
|
menuRight = signal('0px', ...(ngDevMode ? [{ debugName: "menuRight" }] : /* istanbul ignore next */ []));
|
|
@@ -502,17 +557,60 @@ class PosHeader {
|
|
|
502
557
|
});
|
|
503
558
|
}
|
|
504
559
|
toggleMenu() {
|
|
505
|
-
if (this.
|
|
506
|
-
|
|
560
|
+
if (this.menuOpen()) {
|
|
561
|
+
this.closeMenu();
|
|
507
562
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
this.placeMenu();
|
|
563
|
+
else {
|
|
564
|
+
this.openMenu('first');
|
|
511
565
|
}
|
|
512
|
-
this.menuOpen.set(next);
|
|
513
566
|
}
|
|
514
|
-
closeMenu() {
|
|
567
|
+
closeMenu(returnFocus = false) {
|
|
515
568
|
this.menuOpen.set(false);
|
|
569
|
+
if (returnFocus) {
|
|
570
|
+
this.menuButtonRef()?.nativeElement.focus();
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
/** Menu button keys (WAI-ARIA menu button): arrows open the menu and focus an item. */
|
|
574
|
+
onMenuButtonKeydown(event) {
|
|
575
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
576
|
+
event.preventDefault();
|
|
577
|
+
this.openMenu(event.key === 'ArrowDown' ? 'first' : 'last');
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
/** Menu keys: arrows, Home and End move between items; Tab closes the menu. */
|
|
581
|
+
onMenuKeydown(event) {
|
|
582
|
+
const items = this.menuItems();
|
|
583
|
+
if (!items.length) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
const current = items.indexOf(event.target);
|
|
587
|
+
let next = null;
|
|
588
|
+
switch (event.key) {
|
|
589
|
+
case 'ArrowDown':
|
|
590
|
+
next = (current + 1) % items.length;
|
|
591
|
+
break;
|
|
592
|
+
case 'ArrowUp':
|
|
593
|
+
next = (current - 1 + items.length) % items.length;
|
|
594
|
+
break;
|
|
595
|
+
case 'Home':
|
|
596
|
+
next = 0;
|
|
597
|
+
break;
|
|
598
|
+
case 'End':
|
|
599
|
+
next = items.length - 1;
|
|
600
|
+
break;
|
|
601
|
+
case 'Tab':
|
|
602
|
+
this.closeMenu();
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
if (next !== null) {
|
|
606
|
+
event.preventDefault();
|
|
607
|
+
items[next].focus();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
onEscape() {
|
|
611
|
+
if (this.menuOpen()) {
|
|
612
|
+
this.closeMenu(true);
|
|
613
|
+
}
|
|
516
614
|
}
|
|
517
615
|
onViewportChange() {
|
|
518
616
|
if (this.menuOpen()) {
|
|
@@ -526,6 +624,21 @@ class PosHeader {
|
|
|
526
624
|
this.menuOpen.set(false);
|
|
527
625
|
this.action.emit({ type: 'header.signOut' });
|
|
528
626
|
}
|
|
627
|
+
openMenu(focus) {
|
|
628
|
+
if (this.disabled() || !this.canSignOut()) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
this.placeMenu();
|
|
632
|
+
this.menuOpen.set(true);
|
|
633
|
+
afterNextRender(() => {
|
|
634
|
+
const items = this.menuItems();
|
|
635
|
+
items[focus === 'first' ? 0 : items.length - 1]?.focus();
|
|
636
|
+
}, { injector: this.injector });
|
|
637
|
+
}
|
|
638
|
+
menuItems() {
|
|
639
|
+
const menu = this.menuRef()?.nativeElement;
|
|
640
|
+
return menu ? Array.from(menu.querySelectorAll('[role="menuitem"]')) : [];
|
|
641
|
+
}
|
|
529
642
|
placeMenu() {
|
|
530
643
|
const session = this.sessionRef()?.nativeElement;
|
|
531
644
|
if (!session) {
|
|
@@ -536,7 +649,7 @@ class PosHeader {
|
|
|
536
649
|
this.menuRight.set(`${Math.max(0, window.innerWidth - rect.right)}px`);
|
|
537
650
|
}
|
|
538
651
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
539
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosHeader, isStandalone: true, selector: "pos-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, showBrandImage: { classPropertyName: "showBrandImage", publicName: "showBrandImage", isSignal: true, isRequired: false, transformFunction: null }, brandImage: { classPropertyName: "brandImage", publicName: "brandImage", isSignal: true, isRequired: false, transformFunction: null }, brandLabel: { classPropertyName: "brandLabel", publicName: "brandLabel", isSignal: true, isRequired: false, transformFunction: null }, clerkName: { classPropertyName: "clerkName", publicName: "clerkName", isSignal: true, isRequired: false, transformFunction: null }, clerkRole: { classPropertyName: "clerkRole", publicName: "clerkRole", isSignal: true, isRequired: false, transformFunction: null }, signOutLabel: { classPropertyName: "signOutLabel", publicName: "signOutLabel", isSignal: true, isRequired: false, transformFunction: null }, menuLabel: { classPropertyName: "menuLabel", publicName: "menuLabel", isSignal: true, isRequired: false, transformFunction: null }, canSignOut: { classPropertyName: "canSignOut", publicName: "canSignOut", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { attributes: { "role": "banner" }, listeners: { "window:resize": "onViewportChange()" }, classAttribute: "pos-header" }, viewQueries: [{ propertyName: "sessionRef", first: true, predicate: ["session"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pos-header__identity\">\r\n @if (showBrandImage() || brandLabel()) {\r\n <div class=\"pos-header__brand\">\r\n @if (showBrandImage()) {\r\n @if (brandImage()) {\r\n <img\r\n class=\"pos-header__brand-image\"\r\n [src]=\"brandImage()\"\r\n [alt]=\"brandLabel() ? '' : 'Brand'\"\r\n />\r\n } @else {\r\n <svg\r\n class=\"pos-header__brand-image\"\r\n viewBox=\"492.40 241.70 51.34 54.94\"\r\n [attr.aria-hidden]=\"brandLabel() ? true : null\"\r\n [attr.aria-label]=\"brandLabel() ? null : 'Retalia'\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 522.628906 291.910156 C 522.636719 293.0625 523.441406 293.511719 524.425781 292.914062 L 540.464844 283.207031 C 541.449219 282.613281 542.246094 281.195312 542.246094 280.046875 L 542.246094 261.132812 C 542.246094 259.980469 541.441406 259.523438 540.453125 260.113281 L 524.292969 269.691406 C 523.300781 270.277344 522.503906 271.683594 522.511719 272.835938 Z M 522.628906 291.910156\"\r\n />\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M 539.097656 253.351562 L 517.101562 243.664062 C 516.066406 243.203125 514.417969 243.265625 513.421875 243.804688 L 495.835938 253.308594 C 494.839844 253.847656 494.027344 255.214844 494.023438 256.367188 L 493.910156 280.140625 C 493.902344 281.292969 494.699219 282.679688 495.683594 283.234375 L 501.734375 286.640625 C 502.71875 287.199219 503.503906 286.71875 503.480469 285.566406 L 503.214844 271.488281 C 503.207031 271.082031 503.492188 270.894531 503.855469 271.066406 L 506.128906 272.148438 C 507.152344 272.636719 507.980469 273.960938 507.980469 275.113281 L 507.980469 287.839844 C 507.980469 288.992188 508.773438 290.394531 509.746094 290.972656 L 515.777344 294.5625 C 516.753906 295.140625 517.554688 294.679688 517.566406 293.527344 L 517.800781 273.300781 C 517.808594 272.488281 517.539062 271.238281 517.195312 270.503906 L 515.460938 266.789062 C 515.292969 266.421875 515.476562 266.109375 515.871094 266.089844 L 518.925781 265.941406 C 520.050781 265.886719 521.761719 265.378906 522.738281 264.808594 L 539.195312 255.21875 C 540.175781 254.648438 540.132812 253.8125 539.097656 253.351562 M 520.609375 255.050781 L 518.019531 256.585938 C 516.914062 257.125 515.734375 257.289062 514.710938 256.804688 L 511.078125 255.101562 C 510.054688 254.621094 510.023438 253.773438 511.003906 253.210938 L 513.835938 251.597656 C 514.53125 251.203125 515.691406 251.132812 516.425781 251.445312 L 520.449219 253.128906 C 521.488281 253.570312 521.5625 254.429688 520.609375 255.050781\"\r\n />\r\n </svg>\r\n }\r\n }\r\n @if (brandLabel()) {\r\n <span class=\"pos-header__brand-label\">{{ brandLabel() }}</span>\r\n }\r\n </div>\r\n }\r\n @if (title()) {\r\n <h1 class=\"pos-header__title\">{{ title() }}</h1>\r\n }\r\n @if (context()) {\r\n <p class=\"pos-header__context\">{{ context() }}</p>\r\n }\r\n</div>\r\n\r\n<div #session class=\"pos-header__session\">\r\n @if (clerkName()) {\r\n <div class=\"pos-header__clerk\">\r\n @if (canSignOut()) {\r\n <div class=\"pos-header__menu-anchor\">\r\n <button\r\n type=\"button\"\r\n class=\"pos-header__menu-button\"\r\n [attr.aria-label]=\"menuLabel()\"\r\n [attr.aria-expanded]=\"menuOpen()\"\r\n aria-haspopup=\"menu\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"toggleMenu()\"\r\n >\r\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n <circle cx=\"5\" cy=\"12\" r=\"1.6\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1.6\" />\r\n <circle cx=\"19\" cy=\"12\" r=\"1.6\" />\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n <span class=\"pos-header__avatar\" aria-hidden=\"true\">{{ initial() }}</span>\r\n <span class=\"pos-header__clerk-text\">\r\n <span class=\"pos-header__clerk-name\">{{ clerkName() }}</span>\r\n @if (clerkRole()) {\r\n <span class=\"pos-header__clerk-role\">{{ clerkRole() }}</span>\r\n }\r\n </span>\r\n </div>\r\n }\r\n @if (menuOpen()) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-header__backdrop\"\r\n aria-label=\"Close menu\"\r\n (click)=\"closeMenu()\"\r\n ></button>\r\n <div\r\n class=\"pos-header__menu\"\r\n role=\"menu\"\r\n [style.top]=\"menuTop()\"\r\n [style.right]=\"menuRight()\"\r\n >\r\n <button\r\n type=\"button\"\r\n class=\"pos-header__logout\"\r\n role=\"menuitem\"\r\n (click)=\"onSignOut()\"\r\n >\r\n {{ signOutLabel() }}\r\n </button>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--pos-space-sm) var(--pos-space-md);box-sizing:border-box;width:100%;min-width:0;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}.pos-header__identity,.pos-header__session{display:flex;flex-wrap:wrap;align-items:center;gap:var(--pos-space-sm) var(--pos-space-md);min-width:0}.pos-header__session{position:relative;margin-left:auto}.pos-header__brand{display:flex;align-items:center;gap:var(--pos-space-sm);min-width:0}.pos-header__brand-image{flex:0 0 auto;width:auto;height:var(--pos-space-xl);color:var(--pos-color-ink)}.pos-header__brand-label{font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);letter-spacing:var(--pos-letter-spacing-brand)}.pos-header__title{margin:0;font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold)}.pos-header__context{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-header__clerk{display:flex;align-items:center;gap:var(--pos-space-sm);min-width:0}.pos-header__avatar{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--pos-button-min-height);height:var(--pos-button-min-height);border-radius:var(--pos-radius-pill);background:var(--pos-color-primary);color:var(--pos-color-on-primary);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold)}.pos-header__clerk-text{display:flex;flex-direction:column;min-width:0}.pos-header__clerk-name{font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-header__clerk-role{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.2;text-transform:lowercase}.pos-header__menu-anchor{position:relative;flex:0 0 auto}.pos-header__menu-button{display:inline-flex;align-items:center;justify-content:center;width:var(--pos-button-min-height);height:var(--pos-button-min-height);padding:0;border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-pill);background:var(--pos-color-surface);color:var(--pos-color-text-muted);cursor:pointer}.pos-header__menu-button svg{width:1.25rem;height:1.25rem;fill:currentColor}.pos-header__menu-button:disabled{background:var(--pos-color-disabled);color:var(--pos-color-on-disabled);cursor:default}.pos-header__backdrop{position:fixed;inset:0;z-index:20;border:0;background:transparent;cursor:default}.pos-header__menu{position:fixed;z-index:21;box-sizing:border-box;width:16rem;padding:var(--pos-space-sm);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay)}.pos-header__logout{display:flex;align-items:center;width:100%;min-height:var(--pos-button-min-height);padding:0 var(--pos-space-md);border:0;border-radius:var(--pos-radius-md);background:transparent;color:var(--pos-color-danger);font:inherit;font-weight:var(--pos-font-weight-semibold);text-align:left;cursor:pointer}.pos-header__logout:hover{background:color-mix(in srgb,var(--pos-color-danger) 12%,var(--pos-color-surface))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
652
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosHeader, isStandalone: true, selector: "pos-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, showBrandImage: { classPropertyName: "showBrandImage", publicName: "showBrandImage", isSignal: true, isRequired: false, transformFunction: null }, brandImage: { classPropertyName: "brandImage", publicName: "brandImage", isSignal: true, isRequired: false, transformFunction: null }, brandLabel: { classPropertyName: "brandLabel", publicName: "brandLabel", isSignal: true, isRequired: false, transformFunction: null }, clerkName: { classPropertyName: "clerkName", publicName: "clerkName", isSignal: true, isRequired: false, transformFunction: null }, clerkRole: { classPropertyName: "clerkRole", publicName: "clerkRole", isSignal: true, isRequired: false, transformFunction: null }, signOutLabel: { classPropertyName: "signOutLabel", publicName: "signOutLabel", isSignal: true, isRequired: false, transformFunction: null }, menuLabel: { classPropertyName: "menuLabel", publicName: "menuLabel", isSignal: true, isRequired: false, transformFunction: null }, canSignOut: { classPropertyName: "canSignOut", publicName: "canSignOut", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { attributes: { "role": "banner" }, listeners: { "window:resize": "onViewportChange()", "keydown.escape": "onEscape()" }, classAttribute: "pos-header" }, viewQueries: [{ propertyName: "sessionRef", first: true, predicate: ["session"], descendants: true, isSignal: true }, { propertyName: "menuButtonRef", first: true, predicate: ["menuButton"], descendants: true, isSignal: true }, { propertyName: "menuRef", first: true, predicate: ["menu"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pos-header__identity\">\n @if (showBrandImage() || brandLabel()) {\n <div class=\"pos-header__brand\">\n @if (showBrandImage()) {\n @if (brandImage()) {\n <img\n class=\"pos-header__brand-image\"\n [src]=\"brandImage()\"\n [alt]=\"brandLabel() ? '' : 'Brand'\"\n />\n } @else {\n <svg\n class=\"pos-header__brand-image\"\n viewBox=\"492.40 241.70 51.34 54.94\"\n [attr.aria-hidden]=\"brandLabel() ? true : null\"\n [attr.aria-label]=\"brandLabel() ? null : 'Retalia'\"\n >\n <path\n fill=\"currentColor\"\n d=\"M 522.628906 291.910156 C 522.636719 293.0625 523.441406 293.511719 524.425781 292.914062 L 540.464844 283.207031 C 541.449219 282.613281 542.246094 281.195312 542.246094 280.046875 L 542.246094 261.132812 C 542.246094 259.980469 541.441406 259.523438 540.453125 260.113281 L 524.292969 269.691406 C 523.300781 270.277344 522.503906 271.683594 522.511719 272.835938 Z M 522.628906 291.910156\"\n />\n <path\n fill=\"currentColor\"\n d=\"M 539.097656 253.351562 L 517.101562 243.664062 C 516.066406 243.203125 514.417969 243.265625 513.421875 243.804688 L 495.835938 253.308594 C 494.839844 253.847656 494.027344 255.214844 494.023438 256.367188 L 493.910156 280.140625 C 493.902344 281.292969 494.699219 282.679688 495.683594 283.234375 L 501.734375 286.640625 C 502.71875 287.199219 503.503906 286.71875 503.480469 285.566406 L 503.214844 271.488281 C 503.207031 271.082031 503.492188 270.894531 503.855469 271.066406 L 506.128906 272.148438 C 507.152344 272.636719 507.980469 273.960938 507.980469 275.113281 L 507.980469 287.839844 C 507.980469 288.992188 508.773438 290.394531 509.746094 290.972656 L 515.777344 294.5625 C 516.753906 295.140625 517.554688 294.679688 517.566406 293.527344 L 517.800781 273.300781 C 517.808594 272.488281 517.539062 271.238281 517.195312 270.503906 L 515.460938 266.789062 C 515.292969 266.421875 515.476562 266.109375 515.871094 266.089844 L 518.925781 265.941406 C 520.050781 265.886719 521.761719 265.378906 522.738281 264.808594 L 539.195312 255.21875 C 540.175781 254.648438 540.132812 253.8125 539.097656 253.351562 M 520.609375 255.050781 L 518.019531 256.585938 C 516.914062 257.125 515.734375 257.289062 514.710938 256.804688 L 511.078125 255.101562 C 510.054688 254.621094 510.023438 253.773438 511.003906 253.210938 L 513.835938 251.597656 C 514.53125 251.203125 515.691406 251.132812 516.425781 251.445312 L 520.449219 253.128906 C 521.488281 253.570312 521.5625 254.429688 520.609375 255.050781\"\n />\n </svg>\n }\n }\n @if (brandLabel()) {\n <span class=\"pos-header__brand-label\">{{ brandLabel() }}</span>\n }\n </div>\n }\n @if (title()) {\n <h1 class=\"pos-header__title\">{{ title() }}</h1>\n }\n @if (context()) {\n <p class=\"pos-header__context\">{{ context() }}</p>\n }\n</div>\n\n<div #session class=\"pos-header__session\">\n @if (clerkName()) {\n <div class=\"pos-header__clerk\">\n @if (canSignOut()) {\n <div class=\"pos-header__menu-anchor\">\n <button\n #menuButton\n type=\"button\"\n class=\"pos-header__menu-button\"\n [id]=\"menuButtonId\"\n [attr.aria-label]=\"menuLabel()\"\n [attr.aria-expanded]=\"menuOpen()\"\n [attr.aria-controls]=\"menuOpen() ? menuId : null\"\n aria-haspopup=\"menu\"\n [disabled]=\"disabled()\"\n (click)=\"toggleMenu()\"\n (keydown)=\"onMenuButtonKeydown($event)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"12\" r=\"1.6\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.6\" />\n <circle cx=\"19\" cy=\"12\" r=\"1.6\" />\n </svg>\n </button>\n </div>\n }\n <span class=\"pos-header__avatar\" aria-hidden=\"true\">{{ initial() }}</span>\n <span class=\"pos-header__clerk-text\">\n <span class=\"pos-header__clerk-name\">{{ clerkName() }}</span>\n @if (clerkRole()) {\n <span class=\"pos-header__clerk-role\">{{ clerkRole() }}</span>\n }\n </span>\n </div>\n }\n @if (menuOpen()) {\n <button\n type=\"button\"\n class=\"pos-header__backdrop\"\n tabindex=\"-1\"\n aria-label=\"Close menu\"\n (click)=\"closeMenu()\"\n ></button>\n <div\n #menu\n class=\"pos-header__menu\"\n role=\"menu\"\n [id]=\"menuId\"\n [attr.aria-labelledby]=\"menuButtonId\"\n [style.top]=\"menuTop()\"\n [style.right]=\"menuRight()\"\n >\n <button\n type=\"button\"\n class=\"pos-header__logout\"\n role=\"menuitem\"\n tabindex=\"-1\"\n (click)=\"onSignOut()\"\n (keydown)=\"onMenuKeydown($event)\"\n >\n {{ signOutLabel() }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--pos-space-sm) var(--pos-space-md);box-sizing:border-box;width:100%;min-width:0;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}.pos-header__identity,.pos-header__session{display:flex;flex-wrap:wrap;align-items:center;gap:var(--pos-space-sm) var(--pos-space-md);min-width:0}.pos-header__session{position:relative;margin-left:auto}.pos-header__brand{display:flex;align-items:center;gap:var(--pos-space-sm);min-width:0}.pos-header__brand-image{flex:0 0 auto;width:auto;height:var(--pos-space-xl);color:var(--pos-color-ink)}.pos-header__brand-label{font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);letter-spacing:var(--pos-letter-spacing-brand)}.pos-header__title{margin:0;font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold)}.pos-header__context{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-header__clerk{display:flex;align-items:center;gap:var(--pos-space-sm);min-width:0}.pos-header__avatar{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--pos-button-min-height);height:var(--pos-button-min-height);border-radius:var(--pos-radius-pill);background:var(--pos-color-primary);color:var(--pos-color-on-primary);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold)}.pos-header__clerk-text{display:flex;flex-direction:column;min-width:0}.pos-header__clerk-name{font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-header__clerk-role{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.2;text-transform:lowercase}.pos-header__menu-anchor{position:relative;flex:0 0 auto}.pos-header__menu-button{display:inline-flex;align-items:center;justify-content:center;width:var(--pos-button-min-height);height:var(--pos-button-min-height);padding:0;border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-pill);background:var(--pos-color-surface);color:var(--pos-color-text-muted);cursor:pointer}.pos-header__menu-button svg{width:1.25rem;height:1.25rem;fill:currentColor}.pos-header__menu-button:disabled{background:var(--pos-color-disabled);color:var(--pos-color-on-disabled);cursor:default}.pos-header__backdrop{position:fixed;inset:0;z-index:20;border:0;background:transparent;cursor:default}.pos-header__menu{position:fixed;z-index:21;box-sizing:border-box;width:16rem;padding:var(--pos-space-sm);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay)}.pos-header__logout{display:flex;align-items:center;width:100%;min-height:var(--pos-button-min-height);padding:0 var(--pos-space-md);border:0;border-radius:var(--pos-radius-md);background:transparent;color:var(--pos-color-danger);font:inherit;font-weight:var(--pos-font-weight-semibold);text-align:left;cursor:pointer}.pos-header__logout:hover{background:color-mix(in srgb,var(--pos-color-danger) 12%,var(--pos-color-surface))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
540
653
|
}
|
|
541
654
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosHeader, decorators: [{
|
|
542
655
|
type: Component,
|
|
@@ -544,8 +657,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
544
657
|
class: 'pos-header',
|
|
545
658
|
role: 'banner',
|
|
546
659
|
'(window:resize)': 'onViewportChange()',
|
|
547
|
-
|
|
548
|
-
|
|
660
|
+
'(keydown.escape)': 'onEscape()',
|
|
661
|
+
}, template: "<div class=\"pos-header__identity\">\n @if (showBrandImage() || brandLabel()) {\n <div class=\"pos-header__brand\">\n @if (showBrandImage()) {\n @if (brandImage()) {\n <img\n class=\"pos-header__brand-image\"\n [src]=\"brandImage()\"\n [alt]=\"brandLabel() ? '' : 'Brand'\"\n />\n } @else {\n <svg\n class=\"pos-header__brand-image\"\n viewBox=\"492.40 241.70 51.34 54.94\"\n [attr.aria-hidden]=\"brandLabel() ? true : null\"\n [attr.aria-label]=\"brandLabel() ? null : 'Retalia'\"\n >\n <path\n fill=\"currentColor\"\n d=\"M 522.628906 291.910156 C 522.636719 293.0625 523.441406 293.511719 524.425781 292.914062 L 540.464844 283.207031 C 541.449219 282.613281 542.246094 281.195312 542.246094 280.046875 L 542.246094 261.132812 C 542.246094 259.980469 541.441406 259.523438 540.453125 260.113281 L 524.292969 269.691406 C 523.300781 270.277344 522.503906 271.683594 522.511719 272.835938 Z M 522.628906 291.910156\"\n />\n <path\n fill=\"currentColor\"\n d=\"M 539.097656 253.351562 L 517.101562 243.664062 C 516.066406 243.203125 514.417969 243.265625 513.421875 243.804688 L 495.835938 253.308594 C 494.839844 253.847656 494.027344 255.214844 494.023438 256.367188 L 493.910156 280.140625 C 493.902344 281.292969 494.699219 282.679688 495.683594 283.234375 L 501.734375 286.640625 C 502.71875 287.199219 503.503906 286.71875 503.480469 285.566406 L 503.214844 271.488281 C 503.207031 271.082031 503.492188 270.894531 503.855469 271.066406 L 506.128906 272.148438 C 507.152344 272.636719 507.980469 273.960938 507.980469 275.113281 L 507.980469 287.839844 C 507.980469 288.992188 508.773438 290.394531 509.746094 290.972656 L 515.777344 294.5625 C 516.753906 295.140625 517.554688 294.679688 517.566406 293.527344 L 517.800781 273.300781 C 517.808594 272.488281 517.539062 271.238281 517.195312 270.503906 L 515.460938 266.789062 C 515.292969 266.421875 515.476562 266.109375 515.871094 266.089844 L 518.925781 265.941406 C 520.050781 265.886719 521.761719 265.378906 522.738281 264.808594 L 539.195312 255.21875 C 540.175781 254.648438 540.132812 253.8125 539.097656 253.351562 M 520.609375 255.050781 L 518.019531 256.585938 C 516.914062 257.125 515.734375 257.289062 514.710938 256.804688 L 511.078125 255.101562 C 510.054688 254.621094 510.023438 253.773438 511.003906 253.210938 L 513.835938 251.597656 C 514.53125 251.203125 515.691406 251.132812 516.425781 251.445312 L 520.449219 253.128906 C 521.488281 253.570312 521.5625 254.429688 520.609375 255.050781\"\n />\n </svg>\n }\n }\n @if (brandLabel()) {\n <span class=\"pos-header__brand-label\">{{ brandLabel() }}</span>\n }\n </div>\n }\n @if (title()) {\n <h1 class=\"pos-header__title\">{{ title() }}</h1>\n }\n @if (context()) {\n <p class=\"pos-header__context\">{{ context() }}</p>\n }\n</div>\n\n<div #session class=\"pos-header__session\">\n @if (clerkName()) {\n <div class=\"pos-header__clerk\">\n @if (canSignOut()) {\n <div class=\"pos-header__menu-anchor\">\n <button\n #menuButton\n type=\"button\"\n class=\"pos-header__menu-button\"\n [id]=\"menuButtonId\"\n [attr.aria-label]=\"menuLabel()\"\n [attr.aria-expanded]=\"menuOpen()\"\n [attr.aria-controls]=\"menuOpen() ? menuId : null\"\n aria-haspopup=\"menu\"\n [disabled]=\"disabled()\"\n (click)=\"toggleMenu()\"\n (keydown)=\"onMenuButtonKeydown($event)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"12\" r=\"1.6\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.6\" />\n <circle cx=\"19\" cy=\"12\" r=\"1.6\" />\n </svg>\n </button>\n </div>\n }\n <span class=\"pos-header__avatar\" aria-hidden=\"true\">{{ initial() }}</span>\n <span class=\"pos-header__clerk-text\">\n <span class=\"pos-header__clerk-name\">{{ clerkName() }}</span>\n @if (clerkRole()) {\n <span class=\"pos-header__clerk-role\">{{ clerkRole() }}</span>\n }\n </span>\n </div>\n }\n @if (menuOpen()) {\n <button\n type=\"button\"\n class=\"pos-header__backdrop\"\n tabindex=\"-1\"\n aria-label=\"Close menu\"\n (click)=\"closeMenu()\"\n ></button>\n <div\n #menu\n class=\"pos-header__menu\"\n role=\"menu\"\n [id]=\"menuId\"\n [attr.aria-labelledby]=\"menuButtonId\"\n [style.top]=\"menuTop()\"\n [style.right]=\"menuRight()\"\n >\n <button\n type=\"button\"\n class=\"pos-header__logout\"\n role=\"menuitem\"\n tabindex=\"-1\"\n (click)=\"onSignOut()\"\n (keydown)=\"onMenuKeydown($event)\"\n >\n {{ signOutLabel() }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--pos-space-sm) var(--pos-space-md);box-sizing:border-box;width:100%;min-width:0;color:var(--pos-color-text);font-family:var(--pos-font-family);font-size:var(--pos-font-size-md)}.pos-header__identity,.pos-header__session{display:flex;flex-wrap:wrap;align-items:center;gap:var(--pos-space-sm) var(--pos-space-md);min-width:0}.pos-header__session{position:relative;margin-left:auto}.pos-header__brand{display:flex;align-items:center;gap:var(--pos-space-sm);min-width:0}.pos-header__brand-image{flex:0 0 auto;width:auto;height:var(--pos-space-xl);color:var(--pos-color-ink)}.pos-header__brand-label{font-family:var(--pos-font-family-display);font-weight:var(--pos-font-weight-bold);letter-spacing:var(--pos-letter-spacing-brand)}.pos-header__title{margin:0;font-size:var(--pos-font-size-xl);font-weight:var(--pos-font-weight-bold)}.pos-header__context{margin:0;color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm)}.pos-header__clerk{display:flex;align-items:center;gap:var(--pos-space-sm);min-width:0}.pos-header__avatar{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--pos-button-min-height);height:var(--pos-button-min-height);border-radius:var(--pos-radius-pill);background:var(--pos-color-primary);color:var(--pos-color-on-primary);font-size:var(--pos-font-size-lg);font-weight:var(--pos-font-weight-bold)}.pos-header__clerk-text{display:flex;flex-direction:column;min-width:0}.pos-header__clerk-name{font-weight:var(--pos-font-weight-bold);line-height:1.2}.pos-header__clerk-role{color:var(--pos-color-text-muted);font-size:var(--pos-font-size-sm);line-height:1.2;text-transform:lowercase}.pos-header__menu-anchor{position:relative;flex:0 0 auto}.pos-header__menu-button{display:inline-flex;align-items:center;justify-content:center;width:var(--pos-button-min-height);height:var(--pos-button-min-height);padding:0;border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-pill);background:var(--pos-color-surface);color:var(--pos-color-text-muted);cursor:pointer}.pos-header__menu-button svg{width:1.25rem;height:1.25rem;fill:currentColor}.pos-header__menu-button:disabled{background:var(--pos-color-disabled);color:var(--pos-color-on-disabled);cursor:default}.pos-header__backdrop{position:fixed;inset:0;z-index:20;border:0;background:transparent;cursor:default}.pos-header__menu{position:fixed;z-index:21;box-sizing:border-box;width:16rem;padding:var(--pos-space-sm);border:1px solid var(--pos-color-border);border-radius:var(--pos-radius-lg);background:var(--pos-color-surface);box-shadow:var(--pos-shadow-overlay)}.pos-header__logout{display:flex;align-items:center;width:100%;min-height:var(--pos-button-min-height);padding:0 var(--pos-space-md);border:0;border-radius:var(--pos-radius-md);background:transparent;color:var(--pos-color-danger);font:inherit;font-weight:var(--pos-font-weight-semibold);text-align:left;cursor:pointer}.pos-header__logout:hover{background:color-mix(in srgb,var(--pos-color-danger) 12%,var(--pos-color-surface))}\n"] }]
|
|
662
|
+
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }], showBrandImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBrandImage", required: false }] }], brandImage: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandImage", required: false }] }], brandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandLabel", required: false }] }], clerkName: [{ type: i0.Input, args: [{ isSignal: true, alias: "clerkName", required: false }] }], clerkRole: [{ type: i0.Input, args: [{ isSignal: true, alias: "clerkRole", required: false }] }], signOutLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "signOutLabel", required: false }] }], menuLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuLabel", required: false }] }], canSignOut: [{ type: i0.Input, args: [{ isSignal: true, alias: "canSignOut", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], sessionRef: [{ type: i0.ViewChild, args: ['session', { isSignal: true }] }], menuButtonRef: [{ type: i0.ViewChild, args: ['menuButton', { isSignal: true }] }], menuRef: [{ type: i0.ViewChild, args: ['menu', { isSignal: true }] }] } });
|
|
549
663
|
|
|
550
664
|
class PosTransactionActionBar {
|
|
551
665
|
/** Envelope action names. `clearBasket` shows Cancel. `tender` shows Cash and Card. */
|
|
@@ -589,14 +703,14 @@ class PosTransactionActionBar {
|
|
|
589
703
|
this.action.emit({ type: 'actionBar.tenderCard' });
|
|
590
704
|
}
|
|
591
705
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosTransactionActionBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
592
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosTransactionActionBar, isStandalone: true, selector: "pos-transaction-action-bar", inputs: { availableActions: { classPropertyName: "availableActions", publicName: "availableActions", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, cashHotkey: { classPropertyName: "cashHotkey", publicName: "cashHotkey", isSignal: true, isRequired: false, transformFunction: null }, cardHotkey: { classPropertyName: "cardHotkey", publicName: "cardHotkey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { listeners: { "document:keydown": "onDocumentKeydown($event)" }, classAttribute: "pos-transaction-action-bar" }, viewQueries: [{ propertyName: "cashButton", first: true, predicate: ["cashButton"], descendants: true, isSignal: true }, { propertyName: "cardButton", first: true, predicate: ["cardButton"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (availableActions().includes('clearBasket')) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cancel\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"onClear()\"\r\n >\r\n Cancel\r\n </button>\r\n}\r\n@if (availableActions().includes('tender')) {\r\n <button\r\n #cashButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cash\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cashHotkey() || null\"\r\n (click)=\"onCash()\"\r\n >\r\n Cash\r\n @if (cashHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cashHotkey() }}</kbd>\r\n }\r\n </button>\r\n <button\r\n #cardButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--card\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cardHotkey() || null\"\r\n (click)=\"onCard()\"\r\n >\r\n Card\r\n @if (cardHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cardHotkey() }}</kbd>\r\n }\r\n </button>\r\n}\r\n<ng-content />\r\n", styles: [":host{display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--pos-space-sm);width:100%;box-sizing:border-box;padding-top:var(--pos-space-md);border-top:1px solid var(--pos-color-border)}.pos-transaction-action-bar__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);border:1px solid transparent;border-radius:var(--pos-radius-md);font:inherit;font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold);cursor:pointer}.pos-transaction-action-bar__button--cancel{background:var(--pos-color-danger);color:var(--pos-color-on-danger)}.pos-transaction-action-bar__button--cash,.pos-transaction-action-bar__button--card{background:var(--pos-color-success);color:var(--pos-color-on-
|
|
706
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: PosTransactionActionBar, isStandalone: true, selector: "pos-transaction-action-bar", inputs: { availableActions: { classPropertyName: "availableActions", publicName: "availableActions", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, cashHotkey: { classPropertyName: "cashHotkey", publicName: "cashHotkey", isSignal: true, isRequired: false, transformFunction: null }, cardHotkey: { classPropertyName: "cardHotkey", publicName: "cardHotkey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { action: "action" }, host: { listeners: { "document:keydown": "onDocumentKeydown($event)" }, classAttribute: "pos-transaction-action-bar" }, viewQueries: [{ propertyName: "cashButton", first: true, predicate: ["cashButton"], descendants: true, isSignal: true }, { propertyName: "cardButton", first: true, predicate: ["cardButton"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (availableActions().includes('clearBasket')) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cancel\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"onClear()\"\r\n >\r\n Cancel\r\n </button>\r\n}\r\n@if (availableActions().includes('tender')) {\r\n <button\r\n #cashButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cash\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cashHotkey() || null\"\r\n (click)=\"onCash()\"\r\n >\r\n Cash\r\n @if (cashHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cashHotkey() }}</kbd>\r\n }\r\n </button>\r\n <button\r\n #cardButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--card\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cardHotkey() || null\"\r\n (click)=\"onCard()\"\r\n >\r\n Card\r\n @if (cardHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cardHotkey() }}</kbd>\r\n }\r\n </button>\r\n}\r\n<ng-content />\r\n", styles: [":host{display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--pos-space-sm);width:100%;box-sizing:border-box;padding-top:var(--pos-space-md);border-top:1px solid var(--pos-color-border)}.pos-transaction-action-bar__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);border:1px solid transparent;border-radius:var(--pos-radius-md);font:inherit;font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold);cursor:pointer}.pos-transaction-action-bar__button--cancel{background:var(--pos-color-danger);color:var(--pos-color-on-danger)}.pos-transaction-action-bar__button--cash,.pos-transaction-action-bar__button--card{background:var(--pos-color-success);color:var(--pos-color-on-display)}.pos-transaction-action-bar__hotkey{margin:0 0 0 var(--pos-space-sm);padding:0;border:0;background:transparent;color:var(--pos-color-on-disabled);font-family:inherit;font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);line-height:1}.pos-transaction-action-bar__button:disabled{background:var(--pos-color-disabled);color:var(--pos-color-on-disabled);cursor:default}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
593
707
|
}
|
|
594
708
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosTransactionActionBar, decorators: [{
|
|
595
709
|
type: Component,
|
|
596
710
|
args: [{ selector: 'pos-transaction-action-bar', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
597
711
|
class: 'pos-transaction-action-bar',
|
|
598
712
|
'(document:keydown)': 'onDocumentKeydown($event)',
|
|
599
|
-
}, template: "@if (availableActions().includes('clearBasket')) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cancel\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"onClear()\"\r\n >\r\n Cancel\r\n </button>\r\n}\r\n@if (availableActions().includes('tender')) {\r\n <button\r\n #cashButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cash\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cashHotkey() || null\"\r\n (click)=\"onCash()\"\r\n >\r\n Cash\r\n @if (cashHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cashHotkey() }}</kbd>\r\n }\r\n </button>\r\n <button\r\n #cardButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--card\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cardHotkey() || null\"\r\n (click)=\"onCard()\"\r\n >\r\n Card\r\n @if (cardHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cardHotkey() }}</kbd>\r\n }\r\n </button>\r\n}\r\n<ng-content />\r\n", styles: [":host{display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--pos-space-sm);width:100%;box-sizing:border-box;padding-top:var(--pos-space-md);border-top:1px solid var(--pos-color-border)}.pos-transaction-action-bar__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);border:1px solid transparent;border-radius:var(--pos-radius-md);font:inherit;font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold);cursor:pointer}.pos-transaction-action-bar__button--cancel{background:var(--pos-color-danger);color:var(--pos-color-on-danger)}.pos-transaction-action-bar__button--cash,.pos-transaction-action-bar__button--card{background:var(--pos-color-success);color:var(--pos-color-on-
|
|
713
|
+
}, template: "@if (availableActions().includes('clearBasket')) {\r\n <button\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cancel\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"onClear()\"\r\n >\r\n Cancel\r\n </button>\r\n}\r\n@if (availableActions().includes('tender')) {\r\n <button\r\n #cashButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--cash\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cashHotkey() || null\"\r\n (click)=\"onCash()\"\r\n >\r\n Cash\r\n @if (cashHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cashHotkey() }}</kbd>\r\n }\r\n </button>\r\n <button\r\n #cardButton\r\n type=\"button\"\r\n class=\"pos-transaction-action-bar__button pos-transaction-action-bar__button--card\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-keyshortcuts]=\"cardHotkey() || null\"\r\n (click)=\"onCard()\"\r\n >\r\n Card\r\n @if (cardHotkey()) {\r\n <kbd class=\"pos-transaction-action-bar__hotkey\" aria-hidden=\"true\">{{ cardHotkey() }}</kbd>\r\n }\r\n </button>\r\n}\r\n<ng-content />\r\n", styles: [":host{display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--pos-space-sm);width:100%;box-sizing:border-box;padding-top:var(--pos-space-md);border-top:1px solid var(--pos-color-border)}.pos-transaction-action-bar__button{flex:1 1 8rem;min-height:var(--pos-button-min-height);border:1px solid transparent;border-radius:var(--pos-radius-md);font:inherit;font-size:var(--pos-font-size-md);font-weight:var(--pos-font-weight-semibold);cursor:pointer}.pos-transaction-action-bar__button--cancel{background:var(--pos-color-danger);color:var(--pos-color-on-danger)}.pos-transaction-action-bar__button--cash,.pos-transaction-action-bar__button--card{background:var(--pos-color-success);color:var(--pos-color-on-display)}.pos-transaction-action-bar__hotkey{margin:0 0 0 var(--pos-space-sm);padding:0;border:0;background:transparent;color:var(--pos-color-on-disabled);font-family:inherit;font-size:var(--pos-font-size-sm);font-weight:var(--pos-font-weight-semibold);line-height:1}.pos-transaction-action-bar__button:disabled{background:var(--pos-color-disabled);color:var(--pos-color-on-disabled);cursor:default}\n"] }]
|
|
600
714
|
}], propDecorators: { availableActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableActions", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], cashHotkey: [{ type: i0.Input, args: [{ isSignal: true, alias: "cashHotkey", required: false }] }], cardHotkey: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardHotkey", required: false }] }], action: [{ type: i0.Output, args: ["action"] }], cashButton: [{ type: i0.ViewChild, args: ['cashButton', { isSignal: true }] }], cardButton: [{ type: i0.ViewChild, args: ['cardButton', { isSignal: true }] }] } });
|
|
601
715
|
|
|
602
716
|
class PosItemEntry {
|
|
@@ -2467,22 +2581,12 @@ class PosTender {
|
|
|
2467
2581
|
return '';
|
|
2468
2582
|
}, ...(ngDevMode ? [{ debugName: "statusText" }] : /* istanbul ignore next */ []));
|
|
2469
2583
|
formatMoney(amount) {
|
|
2470
|
-
return
|
|
2471
|
-
style: 'currency',
|
|
2472
|
-
currency: this.currency() || 'EUR',
|
|
2473
|
-
minimumFractionDigits: 2,
|
|
2474
|
-
maximumFractionDigits: 2,
|
|
2475
|
-
}).format(amount);
|
|
2584
|
+
return formatPosMoney(amount, this.currency());
|
|
2476
2585
|
}
|
|
2477
2586
|
denominationLabel(amount) {
|
|
2478
|
-
const currency = (this.currency() ||
|
|
2587
|
+
const currency = (this.currency() || POS_DEFAULT_CURRENCY).toUpperCase();
|
|
2479
2588
|
if (amount >= 1) {
|
|
2480
|
-
return
|
|
2481
|
-
style: 'currency',
|
|
2482
|
-
currency,
|
|
2483
|
-
minimumFractionDigits: 0,
|
|
2484
|
-
maximumFractionDigits: 0,
|
|
2485
|
-
}).format(amount);
|
|
2589
|
+
return formatPosMoney(amount, currency, 0);
|
|
2486
2590
|
}
|
|
2487
2591
|
const minor = Math.round(amount * 100);
|
|
2488
2592
|
if (currency === 'GBP') {
|
|
@@ -2584,12 +2688,7 @@ class PosReceipt {
|
|
|
2584
2688
|
: this.preparingLabel(), ...(ngDevMode ? [{ debugName: "statusText" }] : /* istanbul ignore next */ []));
|
|
2585
2689
|
canStartNewSale = computed(() => !this.disabled(), ...(ngDevMode ? [{ debugName: "canStartNewSale" }] : /* istanbul ignore next */ []));
|
|
2586
2690
|
formatMoney(amount) {
|
|
2587
|
-
return
|
|
2588
|
-
style: 'currency',
|
|
2589
|
-
currency: this.totals().currency || 'EUR',
|
|
2590
|
-
minimumFractionDigits: 2,
|
|
2591
|
-
maximumFractionDigits: 2,
|
|
2592
|
-
}).format(amount);
|
|
2691
|
+
return formatPosMoney(amount, this.totals().currency);
|
|
2593
2692
|
}
|
|
2594
2693
|
onNewSale() {
|
|
2595
2694
|
if (!this.canStartNewSale()) {
|