399 lines
12 KiB
TypeScript
Executable File
399 lines
12 KiB
TypeScript
Executable File
import { Component, Input, OnInit } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { SelectionService } from '../selection.service/selection.service';
|
|
|
|
@Component({
|
|
selector: 'app-touch-pad-menu',
|
|
standalone: true,
|
|
imports: [CommonModule],
|
|
templateUrl: './touch-pad-menu.component.html',
|
|
styleUrls: ['./touch-pad-menu.component.css']
|
|
})
|
|
export class TouchPadMenuComponent implements OnInit {
|
|
@Input() ticketingActive: boolean = false;
|
|
|
|
public twoGroupLabels = ['FOR', 'QUI'];
|
|
public multiLegLabels = ['TRE', 'MJP', 'JKP'];
|
|
|
|
labels: string[] = [
|
|
'WIN', 'SHP', 'THP', 'PLC', 'SHW', 'FOR',
|
|
'QUI', 'TAN', 'EXA', 'WSP', 'TRE', 'MJP',
|
|
'JKP', 'SJP', '.'
|
|
];
|
|
|
|
numbers: number[] = Array.from({ length: 30 }, (_, i) => i + 1);
|
|
labelRowsFlat: string[] = [];
|
|
numbersFlat: number[] = [];
|
|
|
|
selectedLabel: string | null = null;
|
|
selectedNumbers: (number | string)[] = [];
|
|
padValue: string = '';
|
|
canPrint = false;
|
|
calculatorOpen = false;
|
|
calcDisplay = '';
|
|
maxRowsReached: boolean = false;
|
|
|
|
disabledLabels: string[] = ['SHW', 'SJP'];
|
|
|
|
// ✅ Original TAN logic
|
|
tanGroupStage = 0;
|
|
tanGroups: number[][] = [[], [], []];
|
|
|
|
// ✅ FOR/QUI logic
|
|
isFirstGroupComplete = false;
|
|
firstGroup: number[] = [];
|
|
secondGroup: number[] = [];
|
|
|
|
// ✅ Multi-leg logic (TRE, MJP, JKP)
|
|
multiLegStage = 0;
|
|
multiLegGroups: number[][] = [[], [], [], [], []];
|
|
|
|
isBoxed: boolean = false;
|
|
|
|
// FIELD modal
|
|
fieldModalOpen = false;
|
|
fieldInput: string = '';
|
|
fieldFEntered = false;
|
|
|
|
constructor(private selectionService: SelectionService) {}
|
|
|
|
ngOnInit() {
|
|
this.labelRowsFlat = this.labelRows.flat();
|
|
this.numbersFlat = this.numberRows.flat();
|
|
this.selectionService.selections$.subscribe(selections => {
|
|
this.maxRowsReached = selections.length >= 5;
|
|
});
|
|
}
|
|
|
|
get labelRows() {
|
|
return this.chunk(this.labels, 3);
|
|
}
|
|
|
|
get numberRows() {
|
|
return this.chunk(this.numbers, 6);
|
|
}
|
|
|
|
get numericPadEnabled() {
|
|
return this.selectedLabel !== null && this.selectedNumbers.length > 0;
|
|
}
|
|
|
|
get showShashEnter(): boolean {
|
|
const specialLabels = ['FOR', 'QUI', 'TAN', 'EXA', 'WSP', 'TRE', 'MJP', 'JKP', '.'];
|
|
return specialLabels.includes(this.selectedLabel || '');
|
|
}
|
|
|
|
get isShashEnterDisabled(): boolean {
|
|
if (this.selectedLabel === 'TAN') {
|
|
return this.tanGroupStage >= 2 || this.tanGroups[this.tanGroupStage].length === 0;
|
|
} else if (this.multiLegLabels.includes(this.selectedLabel || '')) {
|
|
const maxLegs = this.getMaxLegs(this.selectedLabel || '');
|
|
return this.multiLegStage >= maxLegs - 1 || this.multiLegGroups[this.multiLegStage].length === 0;
|
|
} else if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
|
return this.isFirstGroupComplete || this.firstGroup.length === 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
get showBackspace(): boolean {
|
|
return this.selectedLabel !== null &&
|
|
this.selectedNumbers.length > 0 &&
|
|
this.padValue.length === 0;
|
|
}
|
|
|
|
private chunk<T>(array: T[], size: number): T[][] {
|
|
return Array.from({ length: Math.ceil(array.length / size) }, (_, i) =>
|
|
array.slice(i * size, i * size + size)
|
|
);
|
|
}
|
|
|
|
isLabelDisabled(label: string): boolean {
|
|
return this.disabledLabels.includes(label);
|
|
}
|
|
|
|
selectLabel(label: string) {
|
|
this.selectedLabel = label;
|
|
this.selectedNumbers = [];
|
|
this.padValue = '';
|
|
this.canPrint = false;
|
|
this.isBoxed = false;
|
|
|
|
// ✅ Reset TAN
|
|
this.tanGroupStage = 0;
|
|
this.tanGroups = [[], [], []];
|
|
|
|
// ✅ Reset FOR/QUI
|
|
this.isFirstGroupComplete = false;
|
|
this.firstGroup = [];
|
|
this.secondGroup = [];
|
|
|
|
// ✅ Reset Multi-leg
|
|
this.multiLegStage = 0;
|
|
this.multiLegGroups = [[], [], [], [], []];
|
|
|
|
this.selectionService.updatePartial({ label });
|
|
}
|
|
|
|
selectNumber(number: number) {
|
|
if (!this.selectedLabel) return;
|
|
|
|
if (this.selectedLabel === 'TAN') {
|
|
if (!this.tanGroups[this.tanGroupStage].includes(number)) {
|
|
this.tanGroups[this.tanGroupStage].push(number);
|
|
const combined: (number | string)[] = [...this.tanGroups[0]];
|
|
if (this.tanGroupStage > 0) combined.push('-', ...this.tanGroups[1]);
|
|
if (this.tanGroupStage > 1) combined.push('-', ...this.tanGroups[2]);
|
|
this.selectedNumbers = combined;
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this.multiLegLabels.includes(this.selectedLabel)) {
|
|
if (!this.multiLegGroups[this.multiLegStage].includes(number)) {
|
|
this.multiLegGroups[this.multiLegStage].push(number);
|
|
this.updateMultiLegSelection();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
|
if (!this.isFirstGroupComplete) {
|
|
if (!this.firstGroup.includes(number)) {
|
|
this.firstGroup.push(number);
|
|
this.selectedNumbers = [...this.firstGroup];
|
|
}
|
|
} else {
|
|
if (!this.secondGroup.includes(number)) {
|
|
this.secondGroup.push(number);
|
|
this.selectedNumbers = [...this.firstGroup, '-', ...this.secondGroup];
|
|
}
|
|
}
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
return;
|
|
}
|
|
|
|
if (!this.selectedNumbers.includes(number)) {
|
|
this.selectedNumbers.push(number);
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
}
|
|
}
|
|
|
|
private updateMultiLegSelection() {
|
|
const combined: (number | string)[] = [];
|
|
for (let i = 0; i <= this.multiLegStage; i++) {
|
|
if (i > 0) combined.push('-');
|
|
combined.push(...this.multiLegGroups[i]);
|
|
}
|
|
this.selectedNumbers = combined;
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
}
|
|
|
|
isNumberDisabled(number: number): boolean {
|
|
if (this.selectedLabel === 'TAN' || this.multiLegLabels.includes(this.selectedLabel || '') || this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
|
return false;
|
|
}
|
|
return this.selectedNumbers.includes(number);
|
|
}
|
|
|
|
onPadEnter() {
|
|
if (this.canPrint) {
|
|
this.print();
|
|
}
|
|
}
|
|
|
|
onShashEnter() {
|
|
if (this.selectedLabel === 'TAN') {
|
|
if (this.tanGroupStage < 2) {
|
|
this.tanGroupStage++;
|
|
const combined: (number | string)[] = [...this.tanGroups[0]];
|
|
if (this.tanGroupStage > 0) combined.push('-', ...this.tanGroups[1]);
|
|
if (this.tanGroupStage > 1) combined.push('-', ...this.tanGroups[2]);
|
|
this.selectedNumbers = combined;
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this.multiLegLabels.includes(this.selectedLabel || '')) {
|
|
const maxLegs = this.getMaxLegs(this.selectedLabel || '');
|
|
if (this.multiLegStage < maxLegs - 1) {
|
|
this.multiLegStage++;
|
|
this.updateMultiLegSelection();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
|
if (!this.isFirstGroupComplete && this.firstGroup.length > 0) {
|
|
this.isFirstGroupComplete = true;
|
|
this.secondGroup = [];
|
|
this.selectedNumbers = [...this.firstGroup, '-'];
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
}
|
|
}
|
|
}
|
|
|
|
enterPadVal(key: string) {
|
|
if (!this.numericPadEnabled) return;
|
|
if (/[0-9]/.test(key)) this.padValue += key;
|
|
else if (key === 'X') this.padValue += 'X';
|
|
|
|
this.updateCanPrint();
|
|
|
|
const value = parseFloat(this.padValue);
|
|
if (!isNaN(value)) {
|
|
this.selectionService.updatePartial({
|
|
value,
|
|
isBoxed: this.isBoxed,
|
|
label: this.selectedLabel || '',
|
|
numbers: [...this.selectedNumbers]
|
|
});
|
|
}
|
|
}
|
|
|
|
updateCanPrint() {
|
|
this.canPrint = this.padValue.trim().length > 0 && /^[0-9]+$/.test(this.padValue);
|
|
}
|
|
|
|
print() {
|
|
this.selectionService.finalizeCurrentRow();
|
|
this.resetSelections();
|
|
}
|
|
|
|
erase() {
|
|
this.selectionService.clearSelections();
|
|
this.resetSelections();
|
|
}
|
|
|
|
resetSelections() {
|
|
this.selectedLabel = null;
|
|
this.selectedNumbers = [];
|
|
this.padValue = '';
|
|
this.canPrint = false;
|
|
this.isBoxed = false;
|
|
|
|
this.tanGroupStage = 0;
|
|
this.tanGroups = [[], [], []];
|
|
|
|
this.isFirstGroupComplete = false;
|
|
this.firstGroup = [];
|
|
this.secondGroup = [];
|
|
|
|
this.multiLegStage = 0;
|
|
this.multiLegGroups = [[], [], [], [], []];
|
|
|
|
this.fieldModalOpen = false;
|
|
this.fieldInput = '';
|
|
this.fieldFEntered = false;
|
|
}
|
|
|
|
toggleBoxMode() {
|
|
this.isBoxed = !this.isBoxed;
|
|
const value = parseFloat(this.padValue) || 0;
|
|
this.selectionService.updatePartial({
|
|
isBoxed: this.isBoxed,
|
|
label: this.selectedLabel || '',
|
|
numbers: [...this.selectedNumbers],
|
|
value
|
|
});
|
|
this.updateCanPrint();
|
|
}
|
|
|
|
removeLastNumber() {
|
|
if (!this.selectedLabel || this.selectedNumbers.length === 0) return;
|
|
|
|
if (this.selectedLabel === 'TAN') {
|
|
const currentGroup = this.tanGroups[this.tanGroupStage];
|
|
if (currentGroup.length > 0) {
|
|
currentGroup.pop();
|
|
let combined: (number | string)[] = [...this.tanGroups[0]];
|
|
if (this.tanGroupStage > 0) combined.push('-', ...this.tanGroups[1]);
|
|
if (this.tanGroupStage > 1) combined.push('-', ...this.tanGroups[2]);
|
|
this.selectedNumbers = combined;
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this.multiLegLabels.includes(this.selectedLabel)) {
|
|
const currentGroup = this.multiLegGroups[this.multiLegStage];
|
|
if (currentGroup.length > 0) {
|
|
currentGroup.pop();
|
|
this.updateMultiLegSelection();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this.twoGroupLabels.includes(this.selectedLabel)) {
|
|
if (!this.isFirstGroupComplete && this.firstGroup.length > 0) {
|
|
this.firstGroup.pop();
|
|
this.selectedNumbers = [...this.firstGroup];
|
|
} else if (this.secondGroup.length > 0) {
|
|
this.secondGroup.pop();
|
|
this.selectedNumbers = [...this.firstGroup, '-', ...this.secondGroup];
|
|
}
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
return;
|
|
}
|
|
|
|
this.selectedNumbers.pop();
|
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
}
|
|
|
|
private getMaxLegs(label: string): number {
|
|
switch (label) {
|
|
case 'TRE': return 3;
|
|
case 'MJP': return 4;
|
|
case 'JKP': return 5;
|
|
default: return 3;
|
|
}
|
|
}
|
|
|
|
// Calculator and Field Modal methods (unchanged)
|
|
openCalculator() { this.calculatorOpen = true; this.calcDisplay = ''; }
|
|
closeCalculator() { this.calculatorOpen = false; }
|
|
press(val: string) { if (this.calcDisplay === 'Error') this.calcDisplay = ''; this.calcDisplay += val; }
|
|
clearDisplay() { this.calcDisplay = ''; }
|
|
backspace() { this.calcDisplay = this.calcDisplay === 'Error' ? '' : this.calcDisplay.slice(0, -1); }
|
|
calculate() {
|
|
try { this.calcDisplay = eval(this.calcDisplay).toString(); }
|
|
catch { this.calcDisplay = 'Error'; }
|
|
}
|
|
|
|
canUseField(): boolean {
|
|
const allowedLabels = ['WIN', 'SHP', 'THP', 'PLC', 'SHW'];
|
|
return this.selectedLabel !== null && allowedLabels.includes(this.selectedLabel) && this.selectedNumbers.length === 0;
|
|
}
|
|
|
|
openFieldModal() { this.fieldModalOpen = true; this.fieldInput = ''; this.fieldFEntered = false; }
|
|
closeFieldModal() { this.fieldModalOpen = false; }
|
|
handleFieldKey(key: string) {
|
|
if (key === 'BACK') {
|
|
this.fieldInput = this.fieldInput.slice(0, -1);
|
|
if (!this.fieldInput.includes('F')) this.fieldFEntered = false;
|
|
return;
|
|
}
|
|
if (key === 'F') {
|
|
if (!this.fieldFEntered) {
|
|
this.fieldFEntered = true;
|
|
this.fieldInput += 'F';
|
|
}
|
|
} else {
|
|
this.fieldInput += key;
|
|
}
|
|
}
|
|
|
|
confirmFieldEntry() {
|
|
if (this.fieldFEntered) {
|
|
this.selectedNumbers = ['F'];
|
|
this.selectionService.updatePartial({
|
|
label: this.selectedLabel!,
|
|
numbers: ['F'],
|
|
isBoxed: false,
|
|
value: 1
|
|
});
|
|
this.closeFieldModal();
|
|
}
|
|
}
|
|
}
|