@dso-design-system/ui 0.0.2 → 0.1.0
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/esm2022/lib/alert/alert.component.mjs +54 -0
- package/esm2022/lib/badge/badge.component.mjs +22 -0
- package/esm2022/lib/breadcrumb/breadcrumb.component.mjs +29 -0
- package/esm2022/lib/checkbox/checkbox.component.mjs +82 -0
- package/esm2022/lib/datepicker/datepicker.component.mjs +161 -0
- package/esm2022/lib/dialog/dialog.component.mjs +25 -0
- package/esm2022/lib/directives/truncate.directive.mjs +71 -0
- package/esm2022/lib/dropdown-list/dropdown-list.component.mjs +89 -0
- package/esm2022/lib/file-upload-items/file-upload-items.component.mjs +65 -0
- package/esm2022/lib/file-upload-multiple/file-upload-multiple.component.mjs +232 -0
- package/esm2022/lib/file-upload-multiple/upload-item.model.mjs +2 -0
- package/esm2022/lib/file-upload-multiple/upload-simulator.service.mjs +76 -0
- package/esm2022/lib/file-upload-single/file-upload-single.component.mjs +100 -0
- package/esm2022/lib/input-text/input-text.component.mjs +93 -0
- package/esm2022/lib/pagination/pagination.component.mjs +115 -0
- package/esm2022/lib/progress-bar/progress-bar.component.mjs +25 -0
- package/esm2022/lib/radio/radio.component.mjs +41 -0
- package/esm2022/lib/select-dropdown/select-dropdown.component.mjs +228 -0
- package/esm2022/lib/service/toast.service.mjs +20 -0
- package/esm2022/lib/side-navigation-bar/side-navigation-bar.component.mjs +113 -0
- package/esm2022/lib/spinner/spinner.component.mjs +60 -0
- package/esm2022/lib/table/table.component.mjs +136 -0
- package/esm2022/lib/tabs/tab.component.mjs +20 -0
- package/esm2022/lib/tabs/tabs.component.mjs +40 -0
- package/esm2022/lib/tag/tag.component.mjs +27 -0
- package/esm2022/lib/text-area/text-area.component.mjs +74 -0
- package/esm2022/lib/toast/toast.component.mjs +36 -0
- package/esm2022/lib/tooltip/tooltip.component.mjs +38 -0
- package/esm2022/lib/tooltip/tooltip.directive.mjs +105 -0
- package/esm2022/lib/top-navigation-bar/top-navigation-bar.component.mjs +24 -0
- package/esm2022/public-api.mjs +27 -2
- package/fesm2022/dso-design-system-ui.mjs +2056 -3
- package/fesm2022/dso-design-system-ui.mjs.map +1 -1
- package/lib/alert/alert.component.d.ts +20 -0
- package/lib/badge/badge.component.d.ts +8 -0
- package/lib/breadcrumb/breadcrumb.component.d.ts +15 -0
- package/lib/checkbox/checkbox.component.d.ts +42 -0
- package/lib/datepicker/datepicker.component.d.ts +48 -0
- package/lib/dialog/dialog.component.d.ts +10 -0
- package/lib/directives/truncate.directive.d.ts +23 -0
- package/lib/dropdown-list/dropdown-list.component.d.ts +33 -0
- package/lib/file-upload-items/file-upload-items.component.d.ts +27 -0
- package/lib/file-upload-multiple/file-upload-multiple.component.d.ts +44 -0
- package/lib/file-upload-multiple/upload-item.model.d.ts +7 -0
- package/lib/file-upload-multiple/upload-simulator.service.d.ts +34 -0
- package/lib/file-upload-single/file-upload-single.component.d.ts +28 -0
- package/lib/input-text/input-text.component.d.ts +24 -0
- package/lib/pagination/pagination.component.d.ts +31 -0
- package/lib/progress-bar/progress-bar.component.d.ts +11 -0
- package/lib/radio/radio.component.d.ts +14 -0
- package/lib/select-dropdown/select-dropdown.component.d.ts +78 -0
- package/lib/service/toast.service.d.ts +16 -0
- package/lib/side-navigation-bar/side-navigation-bar.component.d.ts +74 -0
- package/lib/spinner/spinner.component.d.ts +23 -0
- package/lib/table/table.component.d.ts +43 -0
- package/lib/tabs/tab.component.d.ts +9 -0
- package/lib/tabs/tabs.component.d.ts +15 -0
- package/lib/tag/tag.component.d.ts +10 -0
- package/lib/text-area/text-area.component.d.ts +21 -0
- package/lib/toast/toast.component.d.ts +13 -0
- package/lib/tooltip/tooltip.component.d.ts +15 -0
- package/lib/tooltip/tooltip.directive.d.ts +19 -0
- package/lib/top-navigation-bar/top-navigation-bar.component.d.ts +16 -0
- package/package.json +1 -1
- package/public-api.d.ts +25 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, Input, Output, EventEmitter, HostListener, ViewChild } from '@angular/core';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { ButtonComponent } from '../button/button.component';
|
|
5
|
+
import { IconComponent } from '../icon/icon.component';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/forms";
|
|
8
|
+
import * as i2 from "@angular/common";
|
|
9
|
+
export class SingleSelectComponent {
|
|
10
|
+
elementRef;
|
|
11
|
+
// Reference to the dropdown <ul> for scroll management
|
|
12
|
+
dropdownListRef;
|
|
13
|
+
// Inputs for configuration & data binding
|
|
14
|
+
options = [];
|
|
15
|
+
dropdownPosition = 'bottom';
|
|
16
|
+
placeholder = 'Select an option';
|
|
17
|
+
inputTextLabel = 'Dropdown Title'; // Optional input label
|
|
18
|
+
isDisabled = false; // Controls disabled state
|
|
19
|
+
enableValidation = true; // Enables validation checks
|
|
20
|
+
helperText; // Optional helper text
|
|
21
|
+
selectIconName = null; // Icon name/class for clear button
|
|
22
|
+
errorText = 'This field is required'; // Validation error text
|
|
23
|
+
// Output event emitter to notify selection changes
|
|
24
|
+
selectionChange = new EventEmitter();
|
|
25
|
+
// Internal state properties
|
|
26
|
+
selectedOption = null; // Currently selected option object
|
|
27
|
+
searchQuery = ''; // Search input value
|
|
28
|
+
filteredOptions = []; // Options filtered based on search
|
|
29
|
+
isOpen = false; // Dropdown open/close state
|
|
30
|
+
isInvalid = false; // Validation invalid flag
|
|
31
|
+
isExceeded = false; // (Optional) exceeded limit flag, currently unused
|
|
32
|
+
hasOpened = false;
|
|
33
|
+
hasInteracted = false; // (Optional) touched flag, currently unused
|
|
34
|
+
lastScrollTop = 0; // Stores last scroll position of dropdown list
|
|
35
|
+
constructor(elementRef) {
|
|
36
|
+
this.elementRef = elementRef;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* //Handles dropdown scroll events to persist scroll position
|
|
40
|
+
*/
|
|
41
|
+
onDropdownScroll() {
|
|
42
|
+
if (this.dropdownListRef) {
|
|
43
|
+
this.lastScrollTop = this.dropdownListRef.nativeElement.scrollTop;
|
|
44
|
+
console.log(`Dropdown scrollTop updated to: ${this.lastScrollTop}`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.warn('dropdownListRef is undefined on scroll');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Detects clicks outside of the component to close the dropdown if open
|
|
52
|
+
*/
|
|
53
|
+
onOutsideClick(event) {
|
|
54
|
+
const clickedInside = this.elementRef.nativeElement.contains(event.target);
|
|
55
|
+
if (!clickedInside) {
|
|
56
|
+
if (this.isOpen) {
|
|
57
|
+
this.isOpen = false; // Close dropdown if clicked outside
|
|
58
|
+
console.log('Dropdown closed via outside click');
|
|
59
|
+
this.hasInteracted = true;
|
|
60
|
+
// Validate only if nothing is selected
|
|
61
|
+
if (this.enableValidation && !this.selectedOption) {
|
|
62
|
+
this.isInvalid = true;
|
|
63
|
+
console.log('Validation failed: no option selected after outside click');
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
this.isInvalid = false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Initialize component data on creation
|
|
73
|
+
*/
|
|
74
|
+
ngOnInit() {
|
|
75
|
+
// Sample hardcoded options (can be overridden via @Input)
|
|
76
|
+
this.options = [
|
|
77
|
+
{ value: '1', label: 'Apple' },
|
|
78
|
+
{ value: '2', label: 'Banana' },
|
|
79
|
+
{ value: '3', label: 'Cherry' },
|
|
80
|
+
{ value: '4', label: 'Date' },
|
|
81
|
+
{ value: '5', label: 'Grapes' },
|
|
82
|
+
{ value: '6', label: 'AAAA' },
|
|
83
|
+
{ value: '7', label: 'BBBB' },
|
|
84
|
+
{ value: '8', label: 'CCCC' },
|
|
85
|
+
{ value: '9', label: 'DDDD' },
|
|
86
|
+
];
|
|
87
|
+
// Show all options initially
|
|
88
|
+
this.filteredOptions = this.options;
|
|
89
|
+
}
|
|
90
|
+
ngOnDestroy() {
|
|
91
|
+
// Placeholder for any cleanup logic if needed
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Handles click on the main select box
|
|
95
|
+
* Prevents opening if disabled
|
|
96
|
+
*/
|
|
97
|
+
onSelectClick(event) {
|
|
98
|
+
event.stopPropagation();
|
|
99
|
+
if (this.isDisabled) {
|
|
100
|
+
event.stopPropagation();
|
|
101
|
+
event.preventDefault();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.toggleDropdown(event);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Toggles dropdown open/close state and restores scroll position if opening
|
|
108
|
+
*/
|
|
109
|
+
toggleDropdown(event) {
|
|
110
|
+
if (this.isDisabled) {
|
|
111
|
+
event.stopPropagation();
|
|
112
|
+
// console.warn('Dropdown is disabled, toggle prevented.');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.isOpen = !this.isOpen;
|
|
116
|
+
this.hasInteracted = true;
|
|
117
|
+
// console.log(`Dropdown toggled. isOpen: ${this.isOpen}`);
|
|
118
|
+
if (this.isOpen) {
|
|
119
|
+
this.hasOpened = true;
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
if (this.dropdownListRef) {
|
|
122
|
+
// console.log(`Restoring scrollTop to: ${this.lastScrollTop}`);
|
|
123
|
+
this.dropdownListRef.nativeElement.scrollTop = this.lastScrollTop;
|
|
124
|
+
console.log('Scroll Restored');
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// Validate on close
|
|
130
|
+
this.hasInteracted = true;
|
|
131
|
+
console.log('User has interacted and closed the dropdown');
|
|
132
|
+
if (this.enableValidation && !this.selectedOption) {
|
|
133
|
+
this.isInvalid = true;
|
|
134
|
+
console.log('No option selected — validation failed');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this.isInvalid = false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Filters dropdown options based on current search query
|
|
143
|
+
*/
|
|
144
|
+
filterOptions() {
|
|
145
|
+
const query = this.searchQuery.toLowerCase();
|
|
146
|
+
this.filteredOptions = this.options.filter((option) => option.label.toLowerCase().includes(query));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Handles option selection:
|
|
150
|
+
* - Updates selected option
|
|
151
|
+
* - Validates
|
|
152
|
+
* - Emits selection change event
|
|
153
|
+
* - Closes dropdown
|
|
154
|
+
*/
|
|
155
|
+
selectOption(event, option) {
|
|
156
|
+
event.stopPropagation();
|
|
157
|
+
this.selectedOption = option;
|
|
158
|
+
this.isInvalid = false;
|
|
159
|
+
this.selectionChange.emit(this.selectedOption);
|
|
160
|
+
this.isOpen = false;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Clears the selected option and resets validation and scroll
|
|
164
|
+
*/
|
|
165
|
+
clearSelection(event) {
|
|
166
|
+
// console.log('Clear selection triggered');
|
|
167
|
+
// this.hasInteracted = false;
|
|
168
|
+
this.selectedOption = null;
|
|
169
|
+
this.searchQuery = ''; // Clear the search input field as well
|
|
170
|
+
this.filteredOptions = this.options; // Show all options again
|
|
171
|
+
this.isInvalid = false;
|
|
172
|
+
this.lastScrollTop = 0;
|
|
173
|
+
this.selectionChange.emit(this.selectedOption);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Checks validity based on current selection if validation is enabled
|
|
177
|
+
*/
|
|
178
|
+
checkValidity() {
|
|
179
|
+
if (this.enableValidation) {
|
|
180
|
+
this.isInvalid = !this.selectedOption;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Returns the icon path if icon name is provided
|
|
185
|
+
*/
|
|
186
|
+
getIconPath() {
|
|
187
|
+
if (this.selectIconName) {
|
|
188
|
+
return `./assets/icons/${this.selectIconName}.svg`;
|
|
189
|
+
}
|
|
190
|
+
return '';
|
|
191
|
+
}
|
|
192
|
+
showError() {
|
|
193
|
+
return this.enableValidation && this.hasInteracted && !this.selectedOption;
|
|
194
|
+
}
|
|
195
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SingleSelectComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
196
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SingleSelectComponent, isStandalone: true, selector: "dso-single-select", inputs: { options: "options", dropdownPosition: "dropdownPosition", placeholder: "placeholder", inputTextLabel: "inputTextLabel", isDisabled: "isDisabled", enableValidation: "enableValidation", helperText: "helperText", selectIconName: "selectIconName", errorText: "errorText" }, outputs: { selectionChange: "selectionChange" }, host: { listeners: { "document:click": "onOutsideClick($event)" } }, viewQueries: [{ propertyName: "dropdownListRef", first: true, predicate: ["dropdownList"], descendants: true }], ngImport: i0, template: "<div class=\"select-wrapper\">\r\n<!-- Label (optional) -->\r\n<div *ngIf=\"inputTextLabel\" class=\"select-label\">{{ inputTextLabel }}</div>\r\n \r\n<!-- <div class=\"select-container\" (click)=\"toggleDropdown($event)\" [class.disabled]=\"isDisabled\"> -->\r\n<div class=\"select-container\" [class.disabled]=\"isDisabled\" [class.error]=\"enableValidation && hasInteracted && isInvalid\" [class.focused]=\"isOpen\"\r\n > \r\n <div class=\"selected-option\"\r\n (click)=\"onSelectClick($event)\" \r\n [ngClass]=\"{'placeholder': !selectedOption, \r\n 'selected': selectedOption }\">\r\n <span>{{ selectedOption?.label || placeholder }}</span>\r\n <div class=\"clearbtn-wrapper\"> \r\n <dso-button \r\n btnLabel=\"Clear\" \r\n btnType=\"ghost\" \r\n btnSize='smBtn'\r\n *ngIf=\"selectedOption && !isDisabled\" \r\n (click)=\"clearSelection($event)\"></dso-button>\r\n <dso-icon *ngIf=\"selectIconName\" [iconName]=\"selectIconName\" [size]=\"'small'\"></dso-icon>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div class=\"dropdown\" *ngIf=\"isOpen\" \r\n (click)=\"$event.stopPropagation()\" \r\n [ngClass]=\"{'dropdown-bottom': dropdownPosition === 'bottom', 'dropdown-top': dropdownPosition === 'top'}\" >\r\n <input type=\"text\" \r\n [(ngModel)]=\"searchQuery\" \r\n (input)=\"filterOptions()\" \r\n placeholder=\"Search...\" />\r\n <ul #dropdownList \r\n (scroll)=\"onDropdownScroll()\" \r\n class=\"dropdown-list\">\r\n <li *ngFor=\"let option of filteredOptions\" (click)=\"selectOption($event, option)\" [ngClass]=\"{'active': option.value === selectedOption?.value}\">\r\n {{ option.label }}\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Helper Text (when validation is disabled) -->\r\n<div *ngIf=\"enableValidation && helperText && !(hasInteracted && isInvalid)\" class=\"helper-text\">\r\n {{ helperText }}\r\n</div>\r\n\r\n<!-- Error Message (when validation is enabled) -->\r\n<div *ngIf=\"enableValidation && hasInteracted && isInvalid\" class=\"error-message\">\r\n {{ errorText }}\r\n</div>\r\n</div>", styles: [":host{display:inline-block;font-family:inherit}.select-label{font-size:16px;color:#333;display:block}.select-wrapper{display:flex;flex-direction:column;gap:8px}.select-container{position:relative;width:300px;display:flex;flex-direction:column;border:1px solid #ccc;border-radius:4px;background-color:#fff;box-sizing:border-box}.select-container:hover{border:1px solid #071d35}.select-container.disabled{background-color:#f5f5f5;border-color:#ccc;cursor:not-allowed}.select-container.disabled .selected-option{pointer-events:none;color:#aaa}.select-container.error{border-color:red}.select-container.focused{border-color:#007bff}.dropdown-list{max-height:150px;overflow-y:auto}.selected-option{padding:12px 8px;display:flex;justify-content:space-between;align-items:center;cursor:pointer}.selected-option.placeholder{color:#aaa}.selected-option.selected{color:#000}img.button-icon{width:20px;height:20px}.clearbtn-wrapper{display:flex;gap:4px;justify-content:space-between;align-items:center}.dropdown{width:300px;position:absolute;background-color:#fff;border:1px solid #ccc;max-height:200px;overflow-y:auto;box-shadow:0 4px 6px #0000000d}.dropdown input{width:100%;padding:10px;box-sizing:border-box;border:none;border-bottom:1px solid #eee;outline:none}.dropdown ul{list-style:none;padding:0;margin:0}.dropdown ul li{padding:8px 12px;cursor:pointer;transition:background-color .2s}.dropdown ul li:hover{background-color:#f0f0f0}.dropdown ul li.active{background-color:#3784d6;color:#fff;font-weight:700}.dropdown-bottom{top:100%}.dropdown-top{bottom:100%}.helper-text,.error-message{font-size:16px}.helper-text{color:#888}.error-message{color:red}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "dso-button", inputs: ["btnLabel", "btnType", "btnSize", "btnIconName", "isDisabled", "isActive"], outputs: ["onClick"] }, { kind: "component", type: IconComponent, selector: "dso-icon", inputs: ["iconName", "size"] }] });
|
|
197
|
+
}
|
|
198
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SingleSelectComponent, decorators: [{
|
|
199
|
+
type: Component,
|
|
200
|
+
args: [{ selector: 'dso-single-select', standalone: true, imports: [FormsModule, CommonModule, ButtonComponent, IconComponent], template: "<div class=\"select-wrapper\">\r\n<!-- Label (optional) -->\r\n<div *ngIf=\"inputTextLabel\" class=\"select-label\">{{ inputTextLabel }}</div>\r\n \r\n<!-- <div class=\"select-container\" (click)=\"toggleDropdown($event)\" [class.disabled]=\"isDisabled\"> -->\r\n<div class=\"select-container\" [class.disabled]=\"isDisabled\" [class.error]=\"enableValidation && hasInteracted && isInvalid\" [class.focused]=\"isOpen\"\r\n > \r\n <div class=\"selected-option\"\r\n (click)=\"onSelectClick($event)\" \r\n [ngClass]=\"{'placeholder': !selectedOption, \r\n 'selected': selectedOption }\">\r\n <span>{{ selectedOption?.label || placeholder }}</span>\r\n <div class=\"clearbtn-wrapper\"> \r\n <dso-button \r\n btnLabel=\"Clear\" \r\n btnType=\"ghost\" \r\n btnSize='smBtn'\r\n *ngIf=\"selectedOption && !isDisabled\" \r\n (click)=\"clearSelection($event)\"></dso-button>\r\n <dso-icon *ngIf=\"selectIconName\" [iconName]=\"selectIconName\" [size]=\"'small'\"></dso-icon>\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown -->\r\n <div class=\"dropdown\" *ngIf=\"isOpen\" \r\n (click)=\"$event.stopPropagation()\" \r\n [ngClass]=\"{'dropdown-bottom': dropdownPosition === 'bottom', 'dropdown-top': dropdownPosition === 'top'}\" >\r\n <input type=\"text\" \r\n [(ngModel)]=\"searchQuery\" \r\n (input)=\"filterOptions()\" \r\n placeholder=\"Search...\" />\r\n <ul #dropdownList \r\n (scroll)=\"onDropdownScroll()\" \r\n class=\"dropdown-list\">\r\n <li *ngFor=\"let option of filteredOptions\" (click)=\"selectOption($event, option)\" [ngClass]=\"{'active': option.value === selectedOption?.value}\">\r\n {{ option.label }}\r\n </li>\r\n </ul>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Helper Text (when validation is disabled) -->\r\n<div *ngIf=\"enableValidation && helperText && !(hasInteracted && isInvalid)\" class=\"helper-text\">\r\n {{ helperText }}\r\n</div>\r\n\r\n<!-- Error Message (when validation is enabled) -->\r\n<div *ngIf=\"enableValidation && hasInteracted && isInvalid\" class=\"error-message\">\r\n {{ errorText }}\r\n</div>\r\n</div>", styles: [":host{display:inline-block;font-family:inherit}.select-label{font-size:16px;color:#333;display:block}.select-wrapper{display:flex;flex-direction:column;gap:8px}.select-container{position:relative;width:300px;display:flex;flex-direction:column;border:1px solid #ccc;border-radius:4px;background-color:#fff;box-sizing:border-box}.select-container:hover{border:1px solid #071d35}.select-container.disabled{background-color:#f5f5f5;border-color:#ccc;cursor:not-allowed}.select-container.disabled .selected-option{pointer-events:none;color:#aaa}.select-container.error{border-color:red}.select-container.focused{border-color:#007bff}.dropdown-list{max-height:150px;overflow-y:auto}.selected-option{padding:12px 8px;display:flex;justify-content:space-between;align-items:center;cursor:pointer}.selected-option.placeholder{color:#aaa}.selected-option.selected{color:#000}img.button-icon{width:20px;height:20px}.clearbtn-wrapper{display:flex;gap:4px;justify-content:space-between;align-items:center}.dropdown{width:300px;position:absolute;background-color:#fff;border:1px solid #ccc;max-height:200px;overflow-y:auto;box-shadow:0 4px 6px #0000000d}.dropdown input{width:100%;padding:10px;box-sizing:border-box;border:none;border-bottom:1px solid #eee;outline:none}.dropdown ul{list-style:none;padding:0;margin:0}.dropdown ul li{padding:8px 12px;cursor:pointer;transition:background-color .2s}.dropdown ul li:hover{background-color:#f0f0f0}.dropdown ul li.active{background-color:#3784d6;color:#fff;font-weight:700}.dropdown-bottom{top:100%}.dropdown-top{bottom:100%}.helper-text,.error-message{font-size:16px}.helper-text{color:#888}.error-message{color:red}\n"] }]
|
|
201
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { dropdownListRef: [{
|
|
202
|
+
type: ViewChild,
|
|
203
|
+
args: ['dropdownList']
|
|
204
|
+
}], options: [{
|
|
205
|
+
type: Input
|
|
206
|
+
}], dropdownPosition: [{
|
|
207
|
+
type: Input
|
|
208
|
+
}], placeholder: [{
|
|
209
|
+
type: Input
|
|
210
|
+
}], inputTextLabel: [{
|
|
211
|
+
type: Input
|
|
212
|
+
}], isDisabled: [{
|
|
213
|
+
type: Input
|
|
214
|
+
}], enableValidation: [{
|
|
215
|
+
type: Input
|
|
216
|
+
}], helperText: [{
|
|
217
|
+
type: Input
|
|
218
|
+
}], selectIconName: [{
|
|
219
|
+
type: Input
|
|
220
|
+
}], errorText: [{
|
|
221
|
+
type: Input
|
|
222
|
+
}], selectionChange: [{
|
|
223
|
+
type: Output
|
|
224
|
+
}], onOutsideClick: [{
|
|
225
|
+
type: HostListener,
|
|
226
|
+
args: ['document:click', ['$event']]
|
|
227
|
+
}] } });
|
|
228
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpL3NyYy9saWIvc2VsZWN0LWRyb3Bkb3duL3NlbGVjdC1kcm9wZG93bi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3NlbGVjdC1kcm9wZG93bi9zZWxlY3QtZHJvcGRvd24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFpQyxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0gsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7QUFTdkQsTUFBTSxPQUFPLHFCQUFxQjtJQThCWjtJQTdCcEIsdURBQXVEO0lBQzVCLGVBQWUsQ0FBZ0M7SUFFMUUsMENBQTBDO0lBQ2pDLE9BQU8sR0FBdUMsRUFBRSxDQUFDO0lBQ2pELGdCQUFnQixHQUFxQixRQUFRLENBQUM7SUFDOUMsV0FBVyxHQUFXLGtCQUFrQixDQUFDO0lBQ3pDLGNBQWMsR0FBVyxnQkFBZ0IsQ0FBQyxDQUFDLHVCQUF1QjtJQUNsRSxVQUFVLEdBQVksS0FBSyxDQUFDLENBQUMsMEJBQTBCO0lBQ3ZELGdCQUFnQixHQUFZLElBQUksQ0FBQyxDQUFDLDRCQUE0QjtJQUM5RCxVQUFVLENBQVUsQ0FBQyx1QkFBdUI7SUFDNUMsY0FBYyxHQUFrQixJQUFJLENBQUMsQ0FBQyxtQ0FBbUM7SUFDekUsU0FBUyxHQUFXLHdCQUF3QixD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QkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUdJLGVBQWU7c0JBQXhCLE1BQU07Z0JBZ0NQLGNBQWM7c0JBRGIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIEVsZW1lbnRSZWYsIE9uSW5pdCwgT25EZXN0cm95LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJy4uL2J1dHRvbi9idXR0b24uY29tcG9uZW50JztcclxuaW1wb3J0IHsgSWNvbkNvbXBvbmVudCB9IGZyb20gJy4uL2ljb24vaWNvbi5jb21wb25lbnQnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdkc28tc2luZ2xlLXNlbGVjdCcsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICB0ZW1wbGF0ZVVybDogJy4vc2VsZWN0LWRyb3Bkb3duLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9zZWxlY3QtZHJvcGRvd24uY29tcG9uZW50LnNjc3MnXSxcclxuICBpbXBvcnRzOiBbRm9ybXNNb2R1bGUsIENvbW1vbk1vZHVsZSwgQnV0dG9uQ29tcG9uZW50LCBJY29uQ29tcG9uZW50XSxcclxufSlcclxuZXhwb3J0IGNsYXNzIFNpbmdsZVNlbGVjdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICAvLyBSZWZlcmVuY2UgdG8gdGhlIGRyb3Bkb3duIDx1bD4gZm9yIHNjcm9sbCBtYW5hZ2VtZW50XHJcbiAgQFZpZXdDaGlsZCgnZHJvcGRvd25MaXN0JykgZHJvcGRvd25MaXN0UmVmITogRWxlbWVudFJlZjxIVE1MVUxpc3RFbGVtZW50PjtcclxuXHJcbiAgLy8gSW5wdXRzIGZvciBjb25maWd1cmF0aW9uICYgZGF0YSBiaW5kaW5nXHJcbiAgQElucHV0KCkgb3B0aW9uczogeyB2YWx1ZTogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtdO1xyXG4gIEBJbnB1dCgpIGRyb3Bkb3duUG9zaXRpb246ICd0b3AnIHwgJ2JvdHRvbScgPSAnYm90dG9tJztcclxuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJ1NlbGVjdCBhbiBvcHRpb24nO1xyXG4gIEBJbnB1dCgpIGlucHV0VGV4dExhYmVsOiBzdHJpbmcgPSAnRHJvcGRvd24gVGl0bGUnOyAvLyBPcHRpb25hbCBpbnB1dCBsYWJlbFxyXG4gIEBJbnB1dCgpIGlzRGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTsgLy8gQ29udHJvbHMgZGlzYWJsZWQgc3RhdGVcclxuICBASW5wdXQoKSBlbmFibGVWYWxpZGF0aW9uOiBib29sZWFuID0gdHJ1ZTsgLy8gRW5hYmxlcyB2YWxpZGF0aW9uIGNoZWNrc1xyXG4gIEBJbnB1dCgpIGhlbHBlclRleHQ/OiBzdHJpbmc7IC8vIE9wdGlvbmFsIGhlbHBlciB0ZXh0XHJcbiAgQElucHV0KCkgc2VsZWN0SWNvbk5hbWU6IHN0cmluZyB8IG51bGwgPSBudWxsOyAvLyBJY29uIG5hbWUvY2xhc3MgZm9yIGNsZWFyIGJ1dHRvblxyXG4gIEBJbnB1dCgpIGVycm9yVGV4dDogc3RyaW5nID0gJ1RoaXMgZmllbGQgaXMgcmVxdWlyZWQnOyAvLyBWYWxpZGF0aW9uIGVycm9yIHRleHRcclxuXHJcbiAgLy8gT3V0cHV0IGV2ZW50IGVtaXR0ZXIgdG8gbm90aWZ5IHNlbGVjdGlvbiBjaGFuZ2VzXHJcbiAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIC8vIEludGVybmFsIHN0YXRlIHByb3BlcnRpZXNcclxuICBzZWxlY3RlZE9wdGlvbjogYW55ID0gbnVsbDsgLy8gQ3VycmVudGx5IHNlbGVjdGVkIG9wdGlvbiBvYmplY3RcclxuICBzZWFyY2hRdWVyeTogc3RyaW5nID0gJyc7IC8vIFNlYXJjaCBpbnB1dCB2YWx1ZVxyXG4gIGZpbHRlcmVkT3B0aW9uczogYW55W10gPSBbXTsgLy8gT3B0aW9ucyBmaWx0ZXJlZCBiYXNlZCBvbiBzZWFyY2hcclxuICBpc09wZW46IGJvb2xlYW4gPSBmYWxzZTsgLy8gRHJvcGRvd24gb3Blbi9jbG9zZSBzdGF0ZVxyXG4gIGlzSW52YWxpZDogYm9vbGVhbiA9IGZhbHNlOyAvLyBWYWxpZGF0aW9uIGludmFsaWQgZmxhZ1xyXG4gIGlzRXhjZWVkZWQ6IGJvb2xlYW4gPSBmYWxzZTsgLy8gKE9wdGlvbmFsKSBleGNlZWRlZCBsaW1pdCBmbGFnLCBjdXJyZW50bHkgdW51c2VkXHJcbiAgaGFzT3BlbmVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgaGFzSW50ZXJhY3RlZDogYm9vbGVhbiA9IGZhbHNlOyAvLyAoT3B0aW9uYWwpIHRvdWNoZWQgZmxhZywgY3VycmVudGx5IHVudXNlZFxyXG5cclxuICBsYXN0U2Nyb2xsVG9wOiBudW1iZXIgPSAwOyAvLyBTdG9yZXMgbGFzdCBzY3JvbGwgcG9zaXRpb24gb2YgZHJvcGRvd24gbGlzdFxyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIC8vSGFuZGxlcyBkcm9wZG93biBzY3JvbGwgZXZlbnRzIHRvIHBlcnNpc3Qgc2Nyb2xsIHBvc2l0aW9uXHJcbiAgICovXHJcbiAgb25Ecm9wZG93blNjcm9sbCgpIHtcclxuICAgIGlmICh0aGlzLmRyb3Bkb3duTGlzdFJlZikge1xyXG4gICAgICB0aGlzLmxhc3RTY3JvbGxUb3AgPSB0aGlzLmRyb3Bkb3duTGlzdFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcDtcclxuICAgICAgY29uc29sZS5sb2coYERyb3Bkb3duIHNjcm9sbFRvcCB1cGRhdGVkIHRvOiAke3RoaXMubGFzdFNjcm9sbFRvcH1gKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUud2FybignZHJvcGRvd25MaXN0UmVmIGlzIHVuZGVmaW5lZCBvbiBzY3JvbGwnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERldGVjdHMgY2xpY2tzIG91dHNpZGUgb2YgdGhlIGNvbXBvbmVudCB0byBjbG9zZSB0aGUgZHJvcGRvd24gaWYgb3BlblxyXG4gICAqL1xyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcclxuICBvbk91dHNpZGVDbGljayhldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgY29uc3QgY2xpY2tlZEluc2lkZSA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCk7XHJcbiAgICBpZiAoIWNsaWNrZWRJbnNpZGUpIHtcclxuICAgICAgICBpZiAodGhpcy5pc09wZW4pIHtcclxuICAgICAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7IC8vIENsb3NlIGRyb3Bkb3duIGlmIGNsaWNrZWQgb3V0c2lkZVxyXG4gICAgICAgICAgY29uc29sZS5sb2coJ0Ryb3Bkb3duIGNsb3NlZCB2aWEgb3V0c2lkZSBjbGljaycpO1xyXG4gICAgICAgICAgdGhpcy5oYXNJbnRlcmFjdGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgLy8gVmFsaWRhdGUgb25seSBpZiBub3RoaW5nIGlzIHNlbGVjdGVkXHJcbiAgICAgICAgaWYgKHRoaXMuZW5hYmxlVmFsaWRhdGlvbiAmJiAhdGhpcy5zZWxlY3RlZE9wdGlvbikge1xyXG4gICAgICAgICAgdGhpcy5pc0ludmFsaWQgPSB0cnVlO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICBjb25zb2xlLmxvZygnVmFsaWRhdGlvbiBmYWlsZWQ6IG5vIG9wdGlvbiBzZWxlY3RlZCBhZnRlciBvdXRzaWRlIGNsaWNrJyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuaXNJbnZhbGlkID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplIGNvbXBvbmVudCBkYXRhIG9uIGNyZWF0aW9uXHJcbiAgICovXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICAvLyBTYW1wbGUgaGFyZGNvZGVkIG9wdGlvbnMgKGNhbiBiZSBvdmVycmlkZGVuIHZpYSBASW5wdXQpXHJcbiAgICB0aGlzLm9wdGlvbnMgPSBbXHJcbiAgICAgIHsgdmFsdWU6ICcxJywgbGFiZWw6ICdBcHBsZScgfSxcclxuICAgICAgeyB2YWx1ZTogJzInLCBsYWJlbDogJ0JhbmFuYScgfSxcclxuICAgICAgeyB2YWx1ZTogJzMnLCBsYWJlbDogJ0NoZXJyeScgfSxcclxuICAgICAgeyB2YWx1ZTogJzQnLCBsYWJlbDogJ0RhdGUnIH0sXHJcbiAgICAgIHsgdmFsdWU6ICc1JywgbGFiZWw6ICdHcmFwZXMnIH0sXHJcbiAgICAgIHsgdmFsdWU6ICc2JywgbGFiZWw6ICdBQUFBJyB9LFxyXG4gICAgICB7IHZhbHVlOiAnNycsIGxhYmVsOiAnQkJCQicgfSxcclxuICAgICAgeyB2YWx1ZTogJzgnLCBsYWJlbDogJ0NDQ0MnIH0sXHJcbiAgICAgIHsgdmFsdWU6ICc5JywgbGFiZWw6ICdEREREJyB9LFxyXG4gICAgXTtcclxuXHJcbiAgICAvLyBTaG93IGFsbCBvcHRpb25zIGluaXRpYWxseVxyXG4gICAgdGhpcy5maWx0ZXJlZE9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIC8vIFBsYWNlaG9sZGVyIGZvciBhbnkgY2xlYW51cCBsb2dpYyBpZiBuZWVkZWRcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZXMgY2xpY2sgb24gdGhlIG1haW4gc2VsZWN0IGJveFxyXG4gICAqIFByZXZlbnRzIG9wZW5pbmcgaWYgZGlzYWJsZWRcclxuICAgKi9cclxuICBvblNlbGVjdENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGlmICh0aGlzLmlzRGlzYWJsZWQpIHtcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnRvZ2dsZURyb3Bkb3duKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZXMgZHJvcGRvd24gb3Blbi9jbG9zZSBzdGF0ZSBhbmQgcmVzdG9yZXMgc2Nyb2xsIHBvc2l0aW9uIGlmIG9wZW5pbmdcclxuICAgKi9cclxuICB0b2dnbGVEcm9wZG93bihldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKHRoaXMuaXNEaXNhYmxlZCkge1xyXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgLy8gY29uc29sZS53YXJuKCdEcm9wZG93biBpcyBkaXNhYmxlZCwgdG9nZ2xlIHByZXZlbnRlZC4nKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaXNPcGVuID0gIXRoaXMuaXNPcGVuO1xyXG4gICAgdGhpcy5oYXNJbnRlcmFjdGVkID0gdHJ1ZTtcclxuICAgIC8vIGNvbnNvbGUubG9nKGBEcm9wZG93biB0b2dnbGVkLiBpc09wZW46ICR7dGhpcy5pc09wZW59YCk7XHJcblxyXG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XHJcbiAgICAgIHRoaXMuaGFzT3BlbmVkID0gdHJ1ZTtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuZHJvcGRvd25MaXN0UmVmKSB7XHJcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgUmVzdG9yaW5nIHNjcm9sbFRvcCB0bzogJHt0aGlzLmxhc3RTY3JvbGxUb3B9YCk7XHJcbiAgICAgICAgICB0aGlzLmRyb3Bkb3duTGlzdFJlZi5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcCA9IHRoaXMubGFzdFNjcm9sbFRvcDtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKCdTY3JvbGwgUmVzdG9yZWQnKTtcclxuICAgICAgICB9IFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgLy8gVmFsaWRhdGUgb24gY2xvc2VcclxuICAgICAgdGhpcy5oYXNJbnRlcmFjdGVkID0gdHJ1ZTtcclxuICAgICAgY29uc29sZS5sb2coJ1VzZXIgaGFzIGludGVyYWN0ZWQgYW5kIGNsb3NlZCB0aGUgZHJvcGRvd24nKTtcclxuICAgICAgXHJcbiAgICAgIGlmICh0aGlzLmVuYWJsZVZhbGlkYXRpb24gJiYgIXRoaXMuc2VsZWN0ZWRPcHRpb24pIHtcclxuICAgICAgICB0aGlzLmlzSW52YWxpZCA9IHRydWU7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ05vIG9wdGlvbiBzZWxlY3RlZCDigJQgdmFsaWRhdGlvbiBmYWlsZWQnKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmlzSW52YWxpZCA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGaWx0ZXJzIGRyb3Bkb3duIG9wdGlvbnMgYmFzZWQgb24gY3VycmVudCBzZWFyY2ggcXVlcnlcclxuICAgKi9cclxuICBmaWx0ZXJPcHRpb25zKCkge1xyXG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnNlYXJjaFF1ZXJ5LnRvTG93ZXJDYXNlKCk7XHJcbiAgICB0aGlzLmZpbHRlcmVkT3B0aW9ucyA9IHRoaXMub3B0aW9ucy5maWx0ZXIoKG9wdGlvbikgPT5cclxuICAgICAgb3B0aW9uLmxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlcyBvcHRpb24gc2VsZWN0aW9uOlxyXG4gICAqIC0gVXBkYXRlcyBzZWxlY3RlZCBvcHRpb25cclxuICAgKiAtIFZhbGlkYXRlc1xyXG4gICAqIC0gRW1pdHMgc2VsZWN0aW9uIGNoYW5nZSBldmVudFxyXG4gICAqIC0gQ2xvc2VzIGRyb3Bkb3duXHJcbiAgICovXHJcbiAgc2VsZWN0T3B0aW9uKGV2ZW50OiBFdmVudCwgb3B0aW9uOiBhbnkpIHtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgdGhpcy5zZWxlY3RlZE9wdGlvbiA9IG9wdGlvbjtcclxuICAgIHRoaXMuaXNJbnZhbGlkID0gZmFsc2U7XHJcbiAgICB0aGlzLnNlbGVjdGlvbkNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWRPcHRpb24pO1xyXG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENsZWFycyB0aGUgc2VsZWN0ZWQgb3B0aW9uIGFuZCByZXNldHMgdmFsaWRhdGlvbiBhbmQgc2Nyb2xsXHJcbiAgICovXHJcbiAgY2xlYXJTZWxlY3Rpb24oZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIC8vIGNvbnNvbGUubG9nKCdDbGVhciBzZWxlY3Rpb24gdHJpZ2dlcmVkJyk7XHJcbiAgICAvLyB0aGlzLmhhc0ludGVyYWN0ZWQgPSBmYWxzZTtcclxuICAgIHRoaXMuc2VsZWN0ZWRPcHRpb24gPSBudWxsO1xyXG4gICAgdGhpcy5zZWFyY2hRdWVyeSA9ICcnOyAgLy8gQ2xlYXIgdGhlIHNlYXJjaCBpbnB1dCBmaWVsZCBhcyB3ZWxsXHJcbiAgICB0aGlzLmZpbHRlcmVkT3B0aW9ucyA9IHRoaXMub3B0aW9uczsgIC8vIFNob3cgYWxsIG9wdGlvbnMgYWdhaW5cclxuICAgIHRoaXMuaXNJbnZhbGlkID0gZmFsc2U7XHJcbiAgICB0aGlzLmxhc3RTY3JvbGxUb3AgPSAwO1xyXG4gICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdCh0aGlzLnNlbGVjdGVkT3B0aW9uKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyB2YWxpZGl0eSBiYXNlZCBvbiBjdXJyZW50IHNlbGVjdGlvbiBpZiB2YWxpZGF0aW9uIGlzIGVuYWJsZWRcclxuICAgKi9cclxuICBjaGVja1ZhbGlkaXR5KCkge1xyXG4gICAgaWYgKHRoaXMuZW5hYmxlVmFsaWRhdGlvbikge1xyXG4gICAgICB0aGlzLmlzSW52YWxpZCA9ICF0aGlzLnNlbGVjdGVkT3B0aW9uO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgaWNvbiBwYXRoIGlmIGljb24gbmFtZSBpcyBwcm92aWRlZFxyXG4gICAqL1xyXG4gIGdldEljb25QYXRoKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5zZWxlY3RJY29uTmFtZSkge1xyXG4gICAgICByZXR1cm4gYC4vYXNzZXRzL2ljb25zLyR7dGhpcy5zZWxlY3RJY29uTmFtZX0uc3ZnYDtcclxuICAgIH1cclxuICAgIHJldHVybiAnJztcclxuICB9XHJcblxyXG4gIHNob3dFcnJvcigpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmVuYWJsZVZhbGlkYXRpb24gJiYgdGhpcy5oYXNJbnRlcmFjdGVkICYmICF0aGlzLnNlbGVjdGVkT3B0aW9uO1xyXG4gIH1cclxuXHJcblxyXG4gIFxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJzZWxlY3Qtd3JhcHBlclwiPlxyXG48IS0tIExhYmVsIChvcHRpb25hbCkgLS0+XHJcbjxkaXYgKm5nSWY9XCJpbnB1dFRleHRMYWJlbFwiIGNsYXNzPVwic2VsZWN0LWxhYmVsXCI+e3sgaW5wdXRUZXh0TGFiZWwgfX08L2Rpdj5cclxuICBcclxuPCEtLSA8ZGl2IGNsYXNzPVwic2VsZWN0LWNvbnRhaW5lclwiIChjbGljayk9XCJ0b2dnbGVEcm9wZG93bigkZXZlbnQpXCIgW2NsYXNzLmRpc2FibGVkXT1cImlzRGlzYWJsZWRcIj4gICAgIC0tPlxyXG48ZGl2IGNsYXNzPVwic2VsZWN0LWNvbnRhaW5lclwiIFtjbGFzcy5kaXNhYmxlZF09XCJpc0Rpc2FibGVkXCIgW2NsYXNzLmVycm9yXT1cImVuYWJsZVZhbGlkYXRpb24gJiYgaGFzSW50ZXJhY3RlZCAmJiBpc0ludmFsaWRcIiBbY2xhc3MuZm9jdXNlZF09XCJpc09wZW5cIlxyXG4gPiAgICBcclxuICA8ZGl2IGNsYXNzPVwic2VsZWN0ZWQtb3B0aW9uXCJcclxuICAgICAgKGNsaWNrKT1cIm9uU2VsZWN0Q2xpY2soJGV2ZW50KVwiICAgICBcclxuICAgICAgW25nQ2xhc3NdPVwieydwbGFjZWhvbGRlcic6ICFzZWxlY3RlZE9wdGlvbiwgXHJcbiAgICAgICAgICAgICAgICAgICdzZWxlY3RlZCc6IHNlbGVjdGVkT3B0aW9uIH1cIj5cclxuICAgIDxzcGFuPnt7IHNlbGVjdGVkT3B0aW9uPy5sYWJlbCB8fCBwbGFjZWhvbGRlciB9fTwvc3Bhbj5cclxuICAgIDxkaXYgY2xhc3M9XCJjbGVhcmJ0bi13cmFwcGVyXCI+ICBcclxuICAgICAgPGRzby1idXR0b24gXHJcbiAgICAgIGJ0bkxhYmVsPVwiQ2xlYXJcIiBcclxuICAgICAgYnRuVHlwZT1cImdob3N0XCIgXHJcbiAgICAgIGJ0blNpemU9J3NtQnRuJ1xyXG4gICAgICAqbmdJZj1cInNlbGVjdGVkT3B0aW9uICYmICFpc0Rpc2FibGVkXCIgXHJcbiAgICAgIChjbGljayk9XCJjbGVhclNlbGVjdGlvbigkZXZlbnQpXCI+PC9kc28tYnV0dG9uPlxyXG4gICAgICA8ZHNvLWljb24gKm5nSWY9XCJzZWxlY3RJY29uTmFtZVwiIFtpY29uTmFtZV09XCJzZWxlY3RJY29uTmFtZVwiIFtzaXplXT1cIidzbWFsbCdcIj48L2Rzby1pY29uPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBEcm9wZG93biAtLT5cclxuICA8ZGl2IGNsYXNzPVwiZHJvcGRvd25cIiAqbmdJZj1cImlzT3BlblwiIFxyXG4gICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIFxyXG4gICAgW25nQ2xhc3NdPVwieydkcm9wZG93bi1ib3R0b20nOiBkcm9wZG93blBvc2l0aW9uID09PSAnYm90dG9tJywgJ2Ryb3Bkb3duLXRvcCc6IGRyb3Bkb3duUG9zaXRpb24gPT09ICd0b3AnfVwiID5cclxuICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFxyXG4gICAgICBbKG5nTW9kZWwpXT1cInNlYXJjaFF1ZXJ5XCIgXHJcbiAgICAgIChpbnB1dCk9XCJmaWx0ZXJPcHRpb25zKClcIiBcclxuICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIiAvPlxyXG4gICAgPHVsICNkcm9wZG93bkxpc3QgXHJcbiAgICAgIChzY3JvbGwpPVwib25Ecm9wZG93blNjcm9sbCgpXCIgXHJcbiAgICAgIGNsYXNzPVwiZHJvcGRvd24tbGlzdFwiPlxyXG4gICAgICA8bGkgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBmaWx0ZXJlZE9wdGlvbnNcIiAoY2xpY2spPVwic2VsZWN0T3B0aW9uKCRldmVudCwgb3B0aW9uKVwiIFtuZ0NsYXNzXT1cInsnYWN0aXZlJzogb3B0aW9uLnZhbHVlID09PSBzZWxlY3RlZE9wdGlvbj8udmFsdWV9XCI+XHJcbiAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgIDwvbGk+XHJcbiAgICA8L3VsPlxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxuXHJcblxyXG48IS0tIEhlbHBlciBUZXh0ICh3aGVuIHZhbGlkYXRpb24gaXMgZGlzYWJsZWQpIC0tPlxyXG48ZGl2ICpuZ0lmPVwiZW5hYmxlVmFsaWRhdGlvbiAmJiBoZWxwZXJUZXh0ICYmICEoaGFzSW50ZXJhY3RlZCAmJiBpc0ludmFsaWQpXCIgY2xhc3M9XCJoZWxwZXItdGV4dFwiPlxyXG4gIHt7IGhlbHBlclRleHQgfX1cclxuPC9kaXY+XHJcblxyXG48IS0tIEVycm9yIE1lc3NhZ2UgKHdoZW4gdmFsaWRhdGlvbiBpcyBlbmFibGVkKSAtLT5cclxuPGRpdiAqbmdJZj1cImVuYWJsZVZhbGlkYXRpb24gJiYgaGFzSW50ZXJhY3RlZCAmJiBpc0ludmFsaWRcIiBjbGFzcz1cImVycm9yLW1lc3NhZ2VcIj5cclxuICB7eyBlcnJvclRleHQgfX1cclxuPC9kaXY+XHJcbjwvZGl2PiJdfQ==
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
// import { Subject } from 'rxjs';
|
|
3
|
+
import { ReplaySubject } from 'rxjs';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class ToastService {
|
|
6
|
+
// private toastSubject = new Subject<ToastMessage>();
|
|
7
|
+
toastSubject = new ReplaySubject; // keep last message
|
|
8
|
+
toast$ = this.toastSubject.asObservable();
|
|
9
|
+
show(header, message, variant = 'neutral', duration) {
|
|
10
|
+
this.toastSubject.next({ header, message, variant, duration });
|
|
11
|
+
console.log('Toast Service Broadcasting:', { header, message, variant, duration }); // <-- debug
|
|
12
|
+
}
|
|
13
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
14
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ToastService, providedIn: 'root' });
|
|
15
|
+
}
|
|
16
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ToastService, decorators: [{
|
|
17
|
+
type: Injectable,
|
|
18
|
+
args: [{ providedIn: 'root' }]
|
|
19
|
+
}] });
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9hc3Quc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpL3NyYy9saWIvc2VydmljZS90b2FzdC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0Msa0NBQWtDO0FBQ2xDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBb0JyQyxNQUFNLE9BQU8sWUFBWTtJQUN2QixzREFBc0Q7SUFDOUMsWUFBWSxHQUFHLElBQUksYUFBMkIsQ0FBQyxDQUFDLG9CQUFvQjtJQUM1RSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUcxQyxJQUFJLENBQ0YsTUFBYyxFQUNkLE9BQWUsRUFDZixVQUF3QixTQUFTLEVBQ2pDLFFBQWM7UUFFZCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZO0lBRWxHLENBQUM7d0dBZlUsWUFBWTs0R0FBWixZQUFZLGNBREMsTUFBTTs7NEZBQ25CLFlBQVk7a0JBRHhCLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG4vLyBpbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFJlcGxheVN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuXHJcblxyXG5leHBvcnQgdHlwZSBUb2FzdFZhcmlhbnQgPSAnc3VjY2VzcycgfCAnaW5mbycgfCAnd2FybmluZycgfCAnZGFuZ2VyJyB8ICduZXV0cmFsJztcclxuZXhwb3J0IHR5cGUgVG9hc3RQb3NpdGlvbiA9XHJcbiAgfCAndG9wLWxlZnQnXHJcbiAgfCAndG9wLXJpZ2h0J1xyXG4gIHwgJ2JvdHRvbS1sZWZ0J1xyXG4gIHwgJ2JvdHRvbS1yaWdodCdcclxuICB8ICd0b3AtY2VudGVyJ1xyXG4gIHwgJ2JvdHRvbS1jZW50ZXInO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBUb2FzdE1lc3NhZ2Uge1xyXG4gIGhlYWRlcj86IHN0cmluZztcclxuICBtZXNzYWdlOiBzdHJpbmc7XHJcbiAgdmFyaWFudD86IFRvYXN0VmFyaWFudDtcclxuICBkdXJhdGlvbj86IG51bWJlcjtcclxufVxyXG5cclxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcclxuZXhwb3J0IGNsYXNzIFRvYXN0U2VydmljZSB7XHJcbiAgLy8gcHJpdmF0ZSB0b2FzdFN1YmplY3QgPSBuZXcgU3ViamVjdDxUb2FzdE1lc3NhZ2U+KCk7XHJcbiAgcHJpdmF0ZSB0b2FzdFN1YmplY3QgPSBuZXcgUmVwbGF5U3ViamVjdDxUb2FzdE1lc3NhZ2U+OyAvLyBrZWVwIGxhc3QgbWVzc2FnZVxyXG4gIHRvYXN0JCA9IHRoaXMudG9hc3RTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuXHJcbiAgc2hvdyhcclxuICAgIGhlYWRlcjogc3RyaW5nLFxyXG4gICAgbWVzc2FnZTogc3RyaW5nLFxyXG4gICAgdmFyaWFudDogVG9hc3RWYXJpYW50ID0gJ25ldXRyYWwnLFxyXG4gICAgZHVyYXRpb246IDMwMDBcclxuICApIHtcclxuICAgIHRoaXMudG9hc3RTdWJqZWN0Lm5leHQoeyBoZWFkZXIsIG1lc3NhZ2UsIHZhcmlhbnQsIGR1cmF0aW9uIH0pO1xyXG4gICAgY29uc29sZS5sb2coJ1RvYXN0IFNlcnZpY2UgQnJvYWRjYXN0aW5nOicsIHsgaGVhZGVyLCBtZXNzYWdlLCB2YXJpYW50LCBkdXJhdGlvbiB9KTsgLy8gPC0tIGRlYnVnXHJcblxyXG4gIH1cclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
|
|
3
|
+
import { RouterModule } from '@angular/router';
|
|
4
|
+
import { IconComponent } from '../icon/icon.component';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@angular/common";
|
|
7
|
+
import * as i2 from "@angular/router";
|
|
8
|
+
/**
|
|
9
|
+
* DSO Side Navigation Component
|
|
10
|
+
*
|
|
11
|
+
* Features:
|
|
12
|
+
* - Configurable title/logo area.
|
|
13
|
+
* - Dynamic menu items with icons and routing.
|
|
14
|
+
* - Supports default active item by route or index.
|
|
15
|
+
* - Click-outside detection to close the sidebar.
|
|
16
|
+
* - Optional overlay for dimming the background.
|
|
17
|
+
*/
|
|
18
|
+
export class SideNavComponent {
|
|
19
|
+
host;
|
|
20
|
+
/** Title displayed next to the logo */
|
|
21
|
+
title = '';
|
|
22
|
+
/** List of navigation items */
|
|
23
|
+
items = [];
|
|
24
|
+
/** Controls whether the sidebar is visible */
|
|
25
|
+
open = true;
|
|
26
|
+
/** Enable/disable background overlay when sidebar is open */
|
|
27
|
+
overlay = true;
|
|
28
|
+
/** Optional: default active menu item by route */
|
|
29
|
+
defaultActiveRoute;
|
|
30
|
+
/** Optional: default active menu item by index */
|
|
31
|
+
defaultActiveIndex;
|
|
32
|
+
/** Event emitted when sidebar is closed */
|
|
33
|
+
closed = new EventEmitter();
|
|
34
|
+
/**
|
|
35
|
+
* ElementRef to the component host element.
|
|
36
|
+
* Used for detecting click-outside events.
|
|
37
|
+
*/
|
|
38
|
+
constructor(host) {
|
|
39
|
+
this.host = host;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Lifecycle hook: initialize default active menu item.
|
|
43
|
+
*/
|
|
44
|
+
ngOnInit() {
|
|
45
|
+
// Reset all items to inactive first
|
|
46
|
+
this.items.forEach(item => item.isActive = false);
|
|
47
|
+
// Set default active item
|
|
48
|
+
const defaultItem = this.defaultActiveRoute
|
|
49
|
+
? this.items.find(item => item.route === this.defaultActiveRoute)
|
|
50
|
+
: this.items[this.defaultActiveIndex ?? 0]; // fallback to first item if no index
|
|
51
|
+
if (defaultItem) {
|
|
52
|
+
defaultItem.isActive = true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Close the sidebar and emit the `closed` event.
|
|
57
|
+
* Can be called manually or via click-outside detection.
|
|
58
|
+
*/
|
|
59
|
+
closeSidebar() {
|
|
60
|
+
this.open = false;
|
|
61
|
+
this.closed.emit();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* HostListener to detect clicks anywhere in the document.
|
|
65
|
+
* If the click happens outside the sidebar while it's open, it triggers closeSidebar().
|
|
66
|
+
*
|
|
67
|
+
* @param event MouseEvent triggered on document click
|
|
68
|
+
*/
|
|
69
|
+
onDocumentClick(event) {
|
|
70
|
+
if (!this.open)
|
|
71
|
+
return;
|
|
72
|
+
// Check if click was inside the sidebar
|
|
73
|
+
const clickedInside = this.host.nativeElement.contains(event.target);
|
|
74
|
+
if (!clickedInside) {
|
|
75
|
+
this.closeSidebar();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Called when a sidebar menu item is clicked.
|
|
80
|
+
* - Marks the clicked item as active.
|
|
81
|
+
* - Optionally, navigation can be handled via `[routerLink]`.
|
|
82
|
+
*
|
|
83
|
+
* @param item The menu item that was clicked
|
|
84
|
+
*/
|
|
85
|
+
onItemClick(item) {
|
|
86
|
+
this.items.forEach(i => i.isActive = false);
|
|
87
|
+
item.isActive = true;
|
|
88
|
+
}
|
|
89
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SideNavComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
90
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SideNavComponent, isStandalone: true, selector: "dso-side-nav", inputs: { title: "title", items: "items", open: "open", overlay: "overlay", defaultActiveRoute: "defaultActiveRoute", defaultActiveIndex: "defaultActiveIndex" }, outputs: { closed: "closed" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<!-- Optional overlay -->\r\n<div \r\n class=\"sidebar-overlay\" \r\n *ngIf=\"open && overlay\"\r\n (click)=\"closeSidebar()\">\r\n</div>\r\n\r\n<nav class=\"dso-side-nav\" [class.open]=\"open\">\r\n\r\n <!-- Logo and Title -->\r\n <div class=\"side-nav-header\">\r\n <ng-content select=\"[dso-side-logo]\"></ng-content>\r\n <span class=\"side-nav-title\">{{ title }}</span>\r\n </div>\r\n\r\n <!-- Navigation list -->\r\n <ul class=\"side-nav-list\">\r\n <li *ngFor=\"let item of items\" [class.active]=\"item.isActive\">\r\n <a\r\n class=\"nav-item\"\r\n [routerLink]=\"item.route\"\r\n routerLinkActive=\"active\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <!-- <i class=\"nav-icon\" [class]=\"item.icon\"></i> -->\r\n <dso-icon *ngIf=\"item.iconName\" [iconName]=\"item.iconName\" size=\"small\"></dso-icon>\r\n\r\n <span class=\"nav-label\">{{ item.label }}</span>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n <!-- Footer slot (optional) -->\r\n <div class=\"side-nav-footer\">\r\n <ng-content select=\"[dso-side-footer]\"></ng-content>\r\n </div>\r\n\r\n</nav>\r\n", styles: [".dso-side-nav{position:fixed;left:0;top:0;width:240px;height:100vh;background:#fff;border-right:1px solid #e5e5e5;display:flex;flex-direction:column;transform:translate(-100%);transition:transform .25s ease-in-out;z-index:1000}.dso-side-nav.open{transform:translate(0)}.dso-side-nav .side-nav-header{display:flex;align-items:center;gap:.75rem;padding:1rem;white-space:nowrap}.dso-side-nav .side-nav-title{font-size:1rem;font-weight:600}.dso-side-nav .side-nav-list{flex:1;list-style:none;padding:0 4px;margin:.5rem 0}.dso-side-nav .side-nav-list li{margin:.25rem 0}.dso-side-nav .side-nav-list li a.nav-item{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;border-radius:4px;text-decoration:none;color:#333}.dso-side-nav .side-nav-list li a.nav-item:hover{background:#f4f4f4}.dso-side-nav .side-nav-list li.active a.nav-item,.dso-side-nav .side-nav-list li a.nav-item.active{background:#e6f0ff;border-left:3px solid #007bff}.dso-side-nav .side-nav-list li.active a.nav-item .nav-label,.dso-side-nav .side-nav-list li a.nav-item.active .nav-label{font-weight:600}.dso-side-nav .side-nav-footer{padding:1rem;border-top:1px solid #e5e5e5}.sidebar-overlay{position:fixed;inset:0;background:#00000059;z-index:900}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: IconComponent, selector: "dso-icon", inputs: ["iconName", "size"] }] });
|
|
91
|
+
}
|
|
92
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SideNavComponent, decorators: [{
|
|
93
|
+
type: Component,
|
|
94
|
+
args: [{ selector: 'dso-side-nav', standalone: true, imports: [CommonModule, RouterModule, IconComponent], template: "<!-- Optional overlay -->\r\n<div \r\n class=\"sidebar-overlay\" \r\n *ngIf=\"open && overlay\"\r\n (click)=\"closeSidebar()\">\r\n</div>\r\n\r\n<nav class=\"dso-side-nav\" [class.open]=\"open\">\r\n\r\n <!-- Logo and Title -->\r\n <div class=\"side-nav-header\">\r\n <ng-content select=\"[dso-side-logo]\"></ng-content>\r\n <span class=\"side-nav-title\">{{ title }}</span>\r\n </div>\r\n\r\n <!-- Navigation list -->\r\n <ul class=\"side-nav-list\">\r\n <li *ngFor=\"let item of items\" [class.active]=\"item.isActive\">\r\n <a\r\n class=\"nav-item\"\r\n [routerLink]=\"item.route\"\r\n routerLinkActive=\"active\"\r\n (click)=\"onItemClick(item)\"\r\n >\r\n <!-- <i class=\"nav-icon\" [class]=\"item.icon\"></i> -->\r\n <dso-icon *ngIf=\"item.iconName\" [iconName]=\"item.iconName\" size=\"small\"></dso-icon>\r\n\r\n <span class=\"nav-label\">{{ item.label }}</span>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n <!-- Footer slot (optional) -->\r\n <div class=\"side-nav-footer\">\r\n <ng-content select=\"[dso-side-footer]\"></ng-content>\r\n </div>\r\n\r\n</nav>\r\n", styles: [".dso-side-nav{position:fixed;left:0;top:0;width:240px;height:100vh;background:#fff;border-right:1px solid #e5e5e5;display:flex;flex-direction:column;transform:translate(-100%);transition:transform .25s ease-in-out;z-index:1000}.dso-side-nav.open{transform:translate(0)}.dso-side-nav .side-nav-header{display:flex;align-items:center;gap:.75rem;padding:1rem;white-space:nowrap}.dso-side-nav .side-nav-title{font-size:1rem;font-weight:600}.dso-side-nav .side-nav-list{flex:1;list-style:none;padding:0 4px;margin:.5rem 0}.dso-side-nav .side-nav-list li{margin:.25rem 0}.dso-side-nav .side-nav-list li a.nav-item{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem;border-radius:4px;text-decoration:none;color:#333}.dso-side-nav .side-nav-list li a.nav-item:hover{background:#f4f4f4}.dso-side-nav .side-nav-list li.active a.nav-item,.dso-side-nav .side-nav-list li a.nav-item.active{background:#e6f0ff;border-left:3px solid #007bff}.dso-side-nav .side-nav-list li.active a.nav-item .nav-label,.dso-side-nav .side-nav-list li a.nav-item.active .nav-label{font-weight:600}.dso-side-nav .side-nav-footer{padding:1rem;border-top:1px solid #e5e5e5}.sidebar-overlay{position:fixed;inset:0;background:#00000059;z-index:900}\n"] }]
|
|
95
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { title: [{
|
|
96
|
+
type: Input
|
|
97
|
+
}], items: [{
|
|
98
|
+
type: Input
|
|
99
|
+
}], open: [{
|
|
100
|
+
type: Input
|
|
101
|
+
}], overlay: [{
|
|
102
|
+
type: Input
|
|
103
|
+
}], defaultActiveRoute: [{
|
|
104
|
+
type: Input
|
|
105
|
+
}], defaultActiveIndex: [{
|
|
106
|
+
type: Input
|
|
107
|
+
}], closed: [{
|
|
108
|
+
type: Output
|
|
109
|
+
}], onDocumentClick: [{
|
|
110
|
+
type: HostListener,
|
|
111
|
+
args: ['document:click', ['$event']]
|
|
112
|
+
}] } });
|
|
113
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZS1uYXZpZ2F0aW9uLWJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3NpZGUtbmF2aWdhdGlvbi1iYXIvc2lkZS1uYXZpZ2F0aW9uLWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3NpZGUtbmF2aWdhdGlvbi1iYXIvc2lkZS1uYXZpZ2F0aW9uLWJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFNBQVMsRUFBYyxZQUFZLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7OztBQWlCdkQ7Ozs7Ozs7OztHQVNHO0FBUUgsTUFBTSxPQUFPLGdCQUFnQjtJQTBCUDtJQXpCcEIsdUNBQXVDO0lBQzlCLEtBQUssR0FBVyxFQUFFLENBQUM7SUFFNUIsK0JBQStCO0lBQ3RCLEtBQUssR0FBa0IsRUFBRSxDQUFDO0lBRW5DLDhDQUE4QztJQUNyQyxJQUFJLEdBQVksSUFBSSxDQUFDO0lBRTlCLDZEQUE2RDtJQUNwRCxPQUFPLEdBQVksSUFBSSxDQUFDO0lBRWpDLGtEQUFrRDtJQUN6QyxrQkFBa0IsQ0FBVTtJQUVyQyxrREFBa0Q7SUFDekMsa0JBQWtCLENBQVU7SUFFckMsMkNBQTJDO0lBQ2pDLE1BQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBRTVDOzs7T0FHRztJQUNILFlBQW9CLElBQWdCO1FBQWhCLFNBQUksR0FBSixJQUFJLENBQVk7SUFBRyxDQUFDO0lBRXhDOztPQUVHO0lBQ0wsUUFBUTtRQUNOLG9DQUFvQztRQUNwQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFFbEQsMEJBQTBCO1FBQzFCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxrQkFBa0I7WUFDekMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsa0JBQWtCLENBQUM7WUFDakUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMscUNBQXFDO1FBRW5GLElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEIsV0FBVyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUM7SUFFQzs7O09BR0c7SUFDSCxZQUFZO1FBQ1YsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7UUFDbEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFFSCxlQUFlLENBQUMsS0FBaUI7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUV2Qix3Q0FBd0M7UUFDeEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNyRSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsV0FBVyxDQUFDLElBQWlCO1FBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztJQUN2QixDQUFDO3dHQWpGVSxnQkFBZ0I7NEZBQWhCLGdCQUFnQiwrVUNyQzdCLGtvQ0FzQ0EsZ3dDRExZLFlBQVksK1BBQUUsWUFBWSxpZkFBRSxhQUFhOzs0RkFJeEMsZ0JBQWdCO2tCQVA1QixTQUFTOytCQUNFLGNBQWMsY0FDWixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsWUFBWSxFQUFFLGFBQWEsQ0FBQzsrRUFNM0MsS0FBSztzQkFBYixLQUFLO2dCQUdHLEtBQUs7c0JBQWIsS0FBSztnQkFHRyxJQUFJO3NCQUFaLEtBQUs7Z0JBR0csT0FBTztzQkFBZixLQUFLO2dCQUdHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFHRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBR0ksTUFBTTtzQkFBZixNQUFNO2dCQXlDUCxlQUFlO3NCQURkLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFJvdXRlck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IEljb25Db21wb25lbnQgfSBmcm9tICcuLi9pY29uL2ljb24uY29tcG9uZW50JztcclxuXHJcbi8qKlxyXG4gKiBJbnRlcmZhY2UgZGVmaW5pbmcgYSBzaW5nbGUgc2lkZWJhciBtZW51IGl0ZW0uXHJcbiAqIFxyXG4gKiAtIGBsYWJlbGA6IFRoZSB0ZXh0IHRvIGRpc3BsYXkgZm9yIHRoZSBtZW51IGl0ZW0uXHJcbiAqIC0gYGljb25OYW1lYDogT3B0aW9uYWwgaWNvbiB0byBkaXNwbGF5IHVzaW5nIDxkc28taWNvbj4uXHJcbiAqIC0gYHJvdXRlYDogT3B0aW9uYWwgcm91dGVyIHBhdGggdG8gbmF2aWdhdGUgd2hlbiBjbGlja2VkLlxyXG4gKiAtIGBpc0FjdGl2ZWA6IFdoZXRoZXIgdGhpcyBtZW51IGl0ZW0gaXMgY3VycmVudGx5IGFjdGl2ZS5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgU2lkZU5hdkl0ZW0ge1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbiAgaWNvbk5hbWU/OiBzdHJpbmc7XHJcbiAgcm91dGU/OiBzdHJpbmc7XHJcbiAgaXNBY3RpdmU/OiBib29sZWFuO1xyXG59XHJcblxyXG4vKipcclxuICogRFNPIFNpZGUgTmF2aWdhdGlvbiBDb21wb25lbnRcclxuICogXHJcbiAqIEZlYXR1cmVzOlxyXG4gKiAtIENvbmZpZ3VyYWJsZSB0aXRsZS9sb2dvIGFyZWEuXHJcbiAqIC0gRHluYW1pYyBtZW51IGl0ZW1zIHdpdGggaWNvbnMgYW5kIHJvdXRpbmcuXHJcbiAqIC0gU3VwcG9ydHMgZGVmYXVsdCBhY3RpdmUgaXRlbSBieSByb3V0ZSBvciBpbmRleC5cclxuICogLSBDbGljay1vdXRzaWRlIGRldGVjdGlvbiB0byBjbG9zZSB0aGUgc2lkZWJhci5cclxuICogLSBPcHRpb25hbCBvdmVybGF5IGZvciBkaW1taW5nIHRoZSBiYWNrZ3JvdW5kLlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdkc28tc2lkZS1uYXYnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgUm91dGVyTW9kdWxlLCBJY29uQ29tcG9uZW50XSxcclxuICB0ZW1wbGF0ZVVybDogJy4vc2lkZS1uYXZpZ2F0aW9uLWJhci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vc2lkZS1uYXZpZ2F0aW9uLWJhci5jb21wb25lbnQuc2NzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2lkZU5hdkNvbXBvbmVudCB7XHJcbiAgLyoqIFRpdGxlIGRpc3BsYXllZCBuZXh0IHRvIHRoZSBsb2dvICovXHJcbiAgQElucHV0KCkgdGl0bGU6IHN0cmluZyA9ICcnO1xyXG5cclxuICAvKiogTGlzdCBvZiBuYXZpZ2F0aW9uIGl0ZW1zICovXHJcbiAgQElucHV0KCkgaXRlbXM6IFNpZGVOYXZJdGVtW10gPSBbXTtcclxuXHJcbiAgLyoqIENvbnRyb2xzIHdoZXRoZXIgdGhlIHNpZGViYXIgaXMgdmlzaWJsZSAqL1xyXG4gIEBJbnB1dCgpIG9wZW46IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAvKiogRW5hYmxlL2Rpc2FibGUgYmFja2dyb3VuZCBvdmVybGF5IHdoZW4gc2lkZWJhciBpcyBvcGVuICovXHJcbiAgQElucHV0KCkgb3ZlcmxheTogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIC8qKiBPcHRpb25hbDogZGVmYXVsdCBhY3RpdmUgbWVudSBpdGVtIGJ5IHJvdXRlICovXHJcbiAgQElucHV0KCkgZGVmYXVsdEFjdGl2ZVJvdXRlPzogc3RyaW5nO1xyXG5cclxuICAvKiogT3B0aW9uYWw6IGRlZmF1bHQgYWN0aXZlIG1lbnUgaXRlbSBieSBpbmRleCAqL1xyXG4gIEBJbnB1dCgpIGRlZmF1bHRBY3RpdmVJbmRleD86IG51bWJlcjtcclxuXHJcbiAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiBzaWRlYmFyIGlzIGNsb3NlZCAqL1xyXG4gIEBPdXRwdXQoKSBjbG9zZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEVsZW1lbnRSZWYgdG8gdGhlIGNvbXBvbmVudCBob3N0IGVsZW1lbnQuXHJcbiAgICogVXNlZCBmb3IgZGV0ZWN0aW5nIGNsaWNrLW91dHNpZGUgZXZlbnRzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaG9zdDogRWxlbWVudFJlZikge31cclxuXHJcbiAgLyoqXHJcbiAgICogTGlmZWN5Y2xlIGhvb2s6IGluaXRpYWxpemUgZGVmYXVsdCBhY3RpdmUgbWVudSBpdGVtLlxyXG4gICAqL1xyXG5uZ09uSW5pdCgpIHtcclxuICAvLyBSZXNldCBhbGwgaXRlbXMgdG8gaW5hY3RpdmUgZmlyc3RcclxuICB0aGlzLml0ZW1zLmZvckVhY2goaXRlbSA9PiBpdGVtLmlzQWN0aXZlID0gZmFsc2UpO1xyXG5cclxuICAvLyBTZXQgZGVmYXVsdCBhY3RpdmUgaXRlbVxyXG4gIGNvbnN0IGRlZmF1bHRJdGVtID0gdGhpcy5kZWZhdWx0QWN0aXZlUm91dGVcclxuICAgID8gdGhpcy5pdGVtcy5maW5kKGl0ZW0gPT4gaXRlbS5yb3V0ZSA9PT0gdGhpcy5kZWZhdWx0QWN0aXZlUm91dGUpXHJcbiAgICA6IHRoaXMuaXRlbXNbdGhpcy5kZWZhdWx0QWN0aXZlSW5kZXggPz8gMF07IC8vIGZhbGxiYWNrIHRvIGZpcnN0IGl0ZW0gaWYgbm8gaW5kZXhcclxuXHJcbiAgaWYgKGRlZmF1bHRJdGVtKSB7XHJcbiAgICBkZWZhdWx0SXRlbS5pc0FjdGl2ZSA9IHRydWU7XHJcbiAgfVxyXG59XHJcblxyXG4gIC8qKlxyXG4gICAqIENsb3NlIHRoZSBzaWRlYmFyIGFuZCBlbWl0IHRoZSBgY2xvc2VkYCBldmVudC5cclxuICAgKiBDYW4gYmUgY2FsbGVkIG1hbnVhbGx5IG9yIHZpYSBjbGljay1vdXRzaWRlIGRldGVjdGlvbi5cclxuICAgKi9cclxuICBjbG9zZVNpZGViYXIoKSB7XHJcbiAgICB0aGlzLm9wZW4gPSBmYWxzZTtcclxuICAgIHRoaXMuY2xvc2VkLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhvc3RMaXN0ZW5lciB0byBkZXRlY3QgY2xpY2tzIGFueXdoZXJlIGluIHRoZSBkb2N1bWVudC5cclxuICAgKiBJZiB0aGUgY2xpY2sgaGFwcGVucyBvdXRzaWRlIHRoZSBzaWRlYmFyIHdoaWxlIGl0J3Mgb3BlbiwgaXQgdHJpZ2dlcnMgY2xvc2VTaWRlYmFyKCkuXHJcbiAgICogXHJcbiAgICogQHBhcmFtIGV2ZW50IE1vdXNlRXZlbnQgdHJpZ2dlcmVkIG9uIGRvY3VtZW50IGNsaWNrXHJcbiAgICovXHJcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxyXG4gIG9uRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKCF0aGlzLm9wZW4pIHJldHVybjtcclxuXHJcbiAgICAvLyBDaGVjayBpZiBjbGljayB3YXMgaW5zaWRlIHRoZSBzaWRlYmFyXHJcbiAgICBjb25zdCBjbGlja2VkSW5zaWRlID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KTtcclxuICAgIGlmICghY2xpY2tlZEluc2lkZSkge1xyXG4gICAgICB0aGlzLmNsb3NlU2lkZWJhcigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2FsbGVkIHdoZW4gYSBzaWRlYmFyIG1lbnUgaXRlbSBpcyBjbGlja2VkLlxyXG4gICAqIC0gTWFya3MgdGhlIGNsaWNrZWQgaXRlbSBhcyBhY3RpdmUuXHJcbiAgICogLSBPcHRpb25hbGx5LCBuYXZpZ2F0aW9uIGNhbiBiZSBoYW5kbGVkIHZpYSBgW3JvdXRlckxpbmtdYC5cclxuICAgKiBcclxuICAgKiBAcGFyYW0gaXRlbSBUaGUgbWVudSBpdGVtIHRoYXQgd2FzIGNsaWNrZWRcclxuICAgKi9cclxuICBvbkl0ZW1DbGljayhpdGVtOiBTaWRlTmF2SXRlbSkge1xyXG4gICAgdGhpcy5pdGVtcy5mb3JFYWNoKGkgPT4gaS5pc0FjdGl2ZSA9IGZhbHNlKTtcclxuICAgIGl0ZW0uaXNBY3RpdmUgPSB0cnVlO1xyXG4gIH1cclxufVxyXG4iLCI8IS0tIE9wdGlvbmFsIG92ZXJsYXkgLS0+XHJcbjxkaXYgXHJcbiAgY2xhc3M9XCJzaWRlYmFyLW92ZXJsYXlcIiBcclxuICAqbmdJZj1cIm9wZW4gJiYgb3ZlcmxheVwiXHJcbiAgKGNsaWNrKT1cImNsb3NlU2lkZWJhcigpXCI+XHJcbjwvZGl2PlxyXG5cclxuPG5hdiBjbGFzcz1cImRzby1zaWRlLW5hdlwiIFtjbGFzcy5vcGVuXT1cIm9wZW5cIj5cclxuXHJcbiAgPCEtLSBMb2dvIGFuZCBUaXRsZSAtLT5cclxuICA8ZGl2IGNsYXNzPVwic2lkZS1uYXYtaGVhZGVyXCI+XHJcbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbZHNvLXNpZGUtbG9nb11cIj48L25nLWNvbnRlbnQ+XHJcbiAgICA8c3BhbiBjbGFzcz1cInNpZGUtbmF2LXRpdGxlXCI+e3sgdGl0bGUgfX08L3NwYW4+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gTmF2aWdhdGlvbiBsaXN0IC0tPlxyXG4gIDx1bCBjbGFzcz1cInNpZGUtbmF2LWxpc3RcIj5cclxuICAgIDxsaSAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtc1wiIFtjbGFzcy5hY3RpdmVdPVwiaXRlbS5pc0FjdGl2ZVwiPlxyXG4gICAgICA8YVxyXG4gICAgICAgIGNsYXNzPVwibmF2LWl0ZW1cIlxyXG4gICAgICAgIFtyb3V0ZXJMaW5rXT1cIml0ZW0ucm91dGVcIlxyXG4gICAgICAgIHJvdXRlckxpbmtBY3RpdmU9XCJhY3RpdmVcIlxyXG4gICAgICAgIChjbGljayk9XCJvbkl0ZW1DbGljayhpdGVtKVwiXHJcbiAgICAgID5cclxuICAgICAgICA8IS0tIDxpIGNsYXNzPVwibmF2LWljb25cIiBbY2xhc3NdPVwiaXRlbS5pY29uXCI+PC9pPiAtLT5cclxuICAgICAgPGRzby1pY29uICpuZ0lmPVwiaXRlbS5pY29uTmFtZVwiIFtpY29uTmFtZV09XCJpdGVtLmljb25OYW1lXCIgc2l6ZT1cInNtYWxsXCI+PC9kc28taWNvbj5cclxuXHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuYXYtbGFiZWxcIj57eyBpdGVtLmxhYmVsIH19PC9zcGFuPlxyXG4gICAgICA8L2E+XHJcbiAgICA8L2xpPlxyXG4gIDwvdWw+XHJcblxyXG4gIDwhLS0gRm9vdGVyIHNsb3QgKG9wdGlvbmFsKSAtLT5cclxuICA8ZGl2IGNsYXNzPVwic2lkZS1uYXYtZm9vdGVyXCI+XHJcbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbZHNvLXNpZGUtZm9vdGVyXVwiPjwvbmctY29udGVudD5cclxuICA8L2Rpdj5cclxuXHJcbjwvbmF2PlxyXG4iXX0=
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import lottie from 'lottie-web';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/common";
|
|
6
|
+
export class SpinnerComponent {
|
|
7
|
+
el;
|
|
8
|
+
/** Size presets */
|
|
9
|
+
size = 'medium';
|
|
10
|
+
/** Color variants */
|
|
11
|
+
color = 'primary';
|
|
12
|
+
/** Overlay background toggle */
|
|
13
|
+
overlay = false;
|
|
14
|
+
/** Custom overlay background color */
|
|
15
|
+
overlayColor = 'rgba(0,0,0,0.4)';
|
|
16
|
+
/** Optional illustration (inside spinner) */
|
|
17
|
+
illustrationSrc;
|
|
18
|
+
/** Optional label text (below spinner) */
|
|
19
|
+
label;
|
|
20
|
+
// NEW: optional Lottie animation
|
|
21
|
+
animationSrc;
|
|
22
|
+
constructor(el) {
|
|
23
|
+
this.el = el;
|
|
24
|
+
}
|
|
25
|
+
ngAfterViewInit() {
|
|
26
|
+
if (this.animationSrc) {
|
|
27
|
+
lottie.loadAnimation({
|
|
28
|
+
container: this.el.nativeElement.querySelector('.spinner-lottie'),
|
|
29
|
+
renderer: 'svg',
|
|
30
|
+
loop: true,
|
|
31
|
+
autoplay: true,
|
|
32
|
+
path: this.animationSrc, // path to your JSON animation
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
get isIllustrated() {
|
|
37
|
+
return !!this.illustrationSrc;
|
|
38
|
+
}
|
|
39
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpinnerComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
40
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SpinnerComponent, isStandalone: true, selector: "dso-spinner", inputs: { size: "size", color: "color", overlay: "overlay", overlayColor: "overlayColor", illustrationSrc: "illustrationSrc", label: "label", animationSrc: "animationSrc" }, ngImport: i0, template: "<div *ngIf=\"overlay\" class=\"spinner-overlay\" [ngStyle]=\"{'background-color': overlayColor}\">\r\n <div class=\"spinner-wrapper\">\r\n \r\n <!-- Static spinner / illustration -->\r\n <div \r\n class=\"spinner\" \r\n *ngIf=\"!animationSrc\"\r\n [ngClass]=\"[isIllustrated ? 'illustrated' : size, color]\">\r\n <img *ngIf=\"illustrationSrc\" [src]=\"illustrationSrc\" class=\"spinner-illustration\" alt=\"Loading illustration\" />\r\n </div>\r\n\r\n <!-- Lottie animation -->\r\n <div *ngIf=\"animationSrc\" class=\"spinner-lottie\"></div>\r\n\r\n <!-- Optional label -->\r\n <p *ngIf=\"label\" class=\"spinner-label\">{{ label }}</p>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"!overlay\" class=\"spinner-wrapper\">\r\n \r\n <!-- Static spinner / illustration -->\r\n <div \r\n class=\"spinner\" \r\n *ngIf=\"!animationSrc\"\r\n [ngClass]=\"[isIllustrated ? 'illustrated' : size, color]\">\r\n <img *ngIf=\"illustrationSrc\" [src]=\"illustrationSrc\" class=\"spinner-illustration\" alt=\"Loading illustration\" />\r\n </div>\r\n\r\n <!-- Lottie animation -->\r\n <div *ngIf=\"animationSrc\" class=\"spinner-lottie\"></div>\r\n\r\n <!-- Optional label -->\r\n <p *ngIf=\"label\" class=\"spinner-label\">{{ label }}</p>\r\n</div>\r\n", styles: [".spinner-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;display:flex;justify-content:center;align-items:center;z-index:9999}.spinner-wrapper{display:flex;flex-direction:column;align-items:center;gap:8px}.spinner{position:relative;display:flex;justify-content:center;align-items:center}.spinner:before{content:\"\";position:absolute;inset:0;border-radius:50%;border:3px solid rgba(0,0,0,.1);border-top-color:#007bff;animation:spin .8s linear infinite}.spinner.small{width:32px;height:32px}.spinner.small:before{border-width:2px}.spinner.medium{width:48px;height:48px}.spinner.medium:before{border-width:3px}.spinner.large{width:72px;height:72px}.spinner.large:before{border-width:4px}.spinner.illustrated{width:240px;height:240px}.spinner.illustrated:before{border-width:6px}.spinner.illustrated .spinner-illustration{width:180px;height:180px}.spinner.primary:before{border-top-color:#007bff}.spinner.success:before{border-top-color:#28a745}.spinner.warning:before{border-top-color:#ffc107}.spinner.danger:before{border-top-color:#dc3545}.spinner-illustration{object-fit:contain;z-index:1}.spinner-label{font-size:14px;color:#fff;text-align:center}@keyframes spin{to{transform:rotate(360deg)}}.spinner-lottie{width:80px;height:80px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
41
|
+
}
|
|
42
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SpinnerComponent, decorators: [{
|
|
43
|
+
type: Component,
|
|
44
|
+
args: [{ selector: 'dso-spinner', standalone: true, imports: [CommonModule], template: "<div *ngIf=\"overlay\" class=\"spinner-overlay\" [ngStyle]=\"{'background-color': overlayColor}\">\r\n <div class=\"spinner-wrapper\">\r\n \r\n <!-- Static spinner / illustration -->\r\n <div \r\n class=\"spinner\" \r\n *ngIf=\"!animationSrc\"\r\n [ngClass]=\"[isIllustrated ? 'illustrated' : size, color]\">\r\n <img *ngIf=\"illustrationSrc\" [src]=\"illustrationSrc\" class=\"spinner-illustration\" alt=\"Loading illustration\" />\r\n </div>\r\n\r\n <!-- Lottie animation -->\r\n <div *ngIf=\"animationSrc\" class=\"spinner-lottie\"></div>\r\n\r\n <!-- Optional label -->\r\n <p *ngIf=\"label\" class=\"spinner-label\">{{ label }}</p>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"!overlay\" class=\"spinner-wrapper\">\r\n \r\n <!-- Static spinner / illustration -->\r\n <div \r\n class=\"spinner\" \r\n *ngIf=\"!animationSrc\"\r\n [ngClass]=\"[isIllustrated ? 'illustrated' : size, color]\">\r\n <img *ngIf=\"illustrationSrc\" [src]=\"illustrationSrc\" class=\"spinner-illustration\" alt=\"Loading illustration\" />\r\n </div>\r\n\r\n <!-- Lottie animation -->\r\n <div *ngIf=\"animationSrc\" class=\"spinner-lottie\"></div>\r\n\r\n <!-- Optional label -->\r\n <p *ngIf=\"label\" class=\"spinner-label\">{{ label }}</p>\r\n</div>\r\n", styles: [".spinner-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;display:flex;justify-content:center;align-items:center;z-index:9999}.spinner-wrapper{display:flex;flex-direction:column;align-items:center;gap:8px}.spinner{position:relative;display:flex;justify-content:center;align-items:center}.spinner:before{content:\"\";position:absolute;inset:0;border-radius:50%;border:3px solid rgba(0,0,0,.1);border-top-color:#007bff;animation:spin .8s linear infinite}.spinner.small{width:32px;height:32px}.spinner.small:before{border-width:2px}.spinner.medium{width:48px;height:48px}.spinner.medium:before{border-width:3px}.spinner.large{width:72px;height:72px}.spinner.large:before{border-width:4px}.spinner.illustrated{width:240px;height:240px}.spinner.illustrated:before{border-width:6px}.spinner.illustrated .spinner-illustration{width:180px;height:180px}.spinner.primary:before{border-top-color:#007bff}.spinner.success:before{border-top-color:#28a745}.spinner.warning:before{border-top-color:#ffc107}.spinner.danger:before{border-top-color:#dc3545}.spinner-illustration{object-fit:contain;z-index:1}.spinner-label{font-size:14px;color:#fff;text-align:center}@keyframes spin{to{transform:rotate(360deg)}}.spinner-lottie{width:80px;height:80px}\n"] }]
|
|
45
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { size: [{
|
|
46
|
+
type: Input
|
|
47
|
+
}], color: [{
|
|
48
|
+
type: Input
|
|
49
|
+
}], overlay: [{
|
|
50
|
+
type: Input
|
|
51
|
+
}], overlayColor: [{
|
|
52
|
+
type: Input
|
|
53
|
+
}], illustrationSrc: [{
|
|
54
|
+
type: Input
|
|
55
|
+
}], label: [{
|
|
56
|
+
type: Input
|
|
57
|
+
}], animationSrc: [{
|
|
58
|
+
type: Input
|
|
59
|
+
}] } });
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bpbm5lci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3NwaW5uZXIvc3Bpbm5lci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3NwaW5uZXIvc3Bpbm5lci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBOEIsTUFBTSxlQUFlLENBQUM7QUFDN0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sTUFBTSxNQUFNLFlBQVksQ0FBQzs7O0FBU2hDLE1BQU0sT0FBTyxnQkFBZ0I7SUF1QlA7SUF0QnBCLG1CQUFtQjtJQUNWLElBQUksR0FBaUMsUUFBUSxDQUFDO0lBRXZELHFCQUFxQjtJQUNaLEtBQUssR0FBaUQsU0FBUyxDQUFDO0lBRXpFLGdDQUFnQztJQUN2QixPQUFPLEdBQVksS0FBSyxDQUFDO0lBRWxDLHNDQUFzQztJQUM3QixZQUFZLEdBQVcsaUJBQWlCLENBQUM7SUFFbEQsNkNBQTZDO0lBQ3BDLGVBQWUsQ0FBaUI7SUFFekMsMENBQTBDO0lBQ2pDLEtBQUssQ0FBVTtJQUd0QixpQ0FBaUM7SUFDMUIsWUFBWSxDQUFVO0lBRS9CLFlBQW9CLEVBQWM7UUFBZCxPQUFFLEdBQUYsRUFBRSxDQUFZO0lBQUcsQ0FBQztJQUV0QyxlQUFlO1FBQ2IsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEIsTUFBTSxDQUFDLGFBQWEsQ0FBQztnQkFDbkIsU0FBUyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQztnQkFDakUsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsUUFBUSxFQUFFLElBQUk7Z0JBQ2QsSUFBSSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsOEJBQThCO2FBQ3hELENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUNoQyxDQUFDO3dHQXZDVSxnQkFBZ0I7NEZBQWhCLGdCQUFnQixxUENYN0IsbXhDQW1DQSx3eENENUJZLFlBQVk7OzRGQUlYLGdCQUFnQjtrQkFQNUIsU0FBUzsrQkFDRSxhQUFhLGNBQ1gsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDOytFQU1kLElBQUk7c0JBQVosS0FBSztnQkFHRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR0csT0FBTztzQkFBZixLQUFLO2dCQUdHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBR0csZUFBZTtzQkFBdkIsS0FBSztnQkFHRyxLQUFLO3NCQUFiLEtBQUs7Z0JBSUcsWUFBWTtzQkFBcEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIEVsZW1lbnRSZWYsIEFmdGVyVmlld0luaXQgIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCBsb3R0aWUgZnJvbSAnbG90dGllLXdlYic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2Rzby1zcGlubmVyJyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9zcGlubmVyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9zcGlubmVyLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFNwaW5uZXJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcclxuICAvKiogU2l6ZSBwcmVzZXRzICovXHJcbiAgQElucHV0KCkgc2l6ZTogJ3NtYWxsJyB8ICdtZWRpdW0nIHwgJ2xhcmdlJyA9ICdtZWRpdW0nO1xyXG5cclxuICAvKiogQ29sb3IgdmFyaWFudHMgKi9cclxuICBASW5wdXQoKSBjb2xvcjogJ3ByaW1hcnknIHwgJ3N1Y2Nlc3MnIHwgJ3dhcm5pbmcnIHwgJ2RhbmdlcicgPSAncHJpbWFyeSc7XHJcblxyXG4gIC8qKiBPdmVybGF5IGJhY2tncm91bmQgdG9nZ2xlICovXHJcbiAgQElucHV0KCkgb3ZlcmxheTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKiogQ3VzdG9tIG92ZXJsYXkgYmFja2dyb3VuZCBjb2xvciAqL1xyXG4gIEBJbnB1dCgpIG92ZXJsYXlDb2xvcjogc3RyaW5nID0gJ3JnYmEoMCwwLDAsMC40KSc7XHJcblxyXG4gIC8qKiBPcHRpb25hbCBpbGx1c3RyYXRpb24gKGluc2lkZSBzcGlubmVyKSAqL1xyXG4gIEBJbnB1dCgpIGlsbHVzdHJhdGlvblNyYz86IHN0cmluZyB8IG51bGw7XHJcblxyXG4gIC8qKiBPcHRpb25hbCBsYWJlbCB0ZXh0IChiZWxvdyBzcGlubmVyKSAqL1xyXG4gIEBJbnB1dCgpIGxhYmVsPzogc3RyaW5nO1xyXG5cclxuXHJcbiAgICAvLyBORVc6IG9wdGlvbmFsIExvdHRpZSBhbmltYXRpb25cclxuICBASW5wdXQoKSBhbmltYXRpb25TcmM/OiBzdHJpbmc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWw6IEVsZW1lbnRSZWYpIHt9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGlmICh0aGlzLmFuaW1hdGlvblNyYykge1xyXG4gICAgICBsb3R0aWUubG9hZEFuaW1hdGlvbih7XHJcbiAgICAgICAgY29udGFpbmVyOiB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLnNwaW5uZXItbG90dGllJyksXHJcbiAgICAgICAgcmVuZGVyZXI6ICdzdmcnLFxyXG4gICAgICAgIGxvb3A6IHRydWUsXHJcbiAgICAgICAgYXV0b3BsYXk6IHRydWUsXHJcbiAgICAgICAgcGF0aDogdGhpcy5hbmltYXRpb25TcmMsIC8vIHBhdGggdG8geW91ciBKU09OIGFuaW1hdGlvblxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcbiAgXHJcbiAgZ2V0IGlzSWxsdXN0cmF0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gISF0aGlzLmlsbHVzdHJhdGlvblNyYztcclxuICB9XHJcbn1cclxuIiwiPGRpdiAqbmdJZj1cIm92ZXJsYXlcIiBjbGFzcz1cInNwaW5uZXItb3ZlcmxheVwiIFtuZ1N0eWxlXT1cInsnYmFja2dyb3VuZC1jb2xvcic6IG92ZXJsYXlDb2xvcn1cIj5cclxuICA8ZGl2IGNsYXNzPVwic3Bpbm5lci13cmFwcGVyXCI+XHJcbiAgICBcclxuICAgIDwhLS0gU3RhdGljIHNwaW5uZXIgLyBpbGx1c3RyYXRpb24gLS0+XHJcbiAgICA8ZGl2IFxyXG4gICAgICBjbGFzcz1cInNwaW5uZXJcIiBcclxuICAgICAgKm5nSWY9XCIhYW5pbWF0aW9uU3JjXCJcclxuICAgICAgW25nQ2xhc3NdPVwiW2lzSWxsdXN0cmF0ZWQgPyAnaWxsdXN0cmF0ZWQnIDogc2l6ZSwgY29sb3JdXCI+XHJcbiAgICAgIDxpbWcgKm5nSWY9XCJpbGx1c3RyYXRpb25TcmNcIiBbc3JjXT1cImlsbHVzdHJhdGlvblNyY1wiIGNsYXNzPVwic3Bpbm5lci1pbGx1c3RyYXRpb25cIiBhbHQ9XCJMb2FkaW5nIGlsbHVzdHJhdGlvblwiIC8+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIExvdHRpZSBhbmltYXRpb24gLS0+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiYW5pbWF0aW9uU3JjXCIgY2xhc3M9XCJzcGlubmVyLWxvdHRpZVwiPjwvZGl2PlxyXG5cclxuICAgIDwhLS0gT3B0aW9uYWwgbGFiZWwgLS0+XHJcbiAgICA8cCAqbmdJZj1cImxhYmVsXCIgY2xhc3M9XCJzcGlubmVyLWxhYmVsXCI+e3sgbGFiZWwgfX08L3A+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiAqbmdJZj1cIiFvdmVybGF5XCIgY2xhc3M9XCJzcGlubmVyLXdyYXBwZXJcIj5cclxuICBcclxuICA8IS0tIFN0YXRpYyBzcGlubmVyIC8gaWxsdXN0cmF0aW9uIC0tPlxyXG4gIDxkaXYgXHJcbiAgICBjbGFzcz1cInNwaW5uZXJcIiBcclxuICAgICpuZ0lmPVwiIWFuaW1hdGlvblNyY1wiXHJcbiAgICBbbmdDbGFzc109XCJbaXNJbGx1c3RyYXRlZCA/ICdpbGx1c3RyYXRlZCcgOiBzaXplLCBjb2xvcl1cIj5cclxuICAgIDxpbWcgKm5nSWY9XCJpbGx1c3RyYXRpb25TcmNcIiBbc3JjXT1cImlsbHVzdHJhdGlvblNyY1wiIGNsYXNzPVwic3Bpbm5lci1pbGx1c3RyYXRpb25cIiBhbHQ9XCJMb2FkaW5nIGlsbHVzdHJhdGlvblwiIC8+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gTG90dGllIGFuaW1hdGlvbiAtLT5cclxuICA8ZGl2ICpuZ0lmPVwiYW5pbWF0aW9uU3JjXCIgY2xhc3M9XCJzcGlubmVyLWxvdHRpZVwiPjwvZGl2PlxyXG5cclxuICA8IS0tIE9wdGlvbmFsIGxhYmVsIC0tPlxyXG4gIDxwICpuZ0lmPVwibGFiZWxcIiBjbGFzcz1cInNwaW5uZXItbGFiZWxcIj57eyBsYWJlbCB9fTwvcD5cclxuPC9kaXY+XHJcbiJdfQ==
|