osl-base-extended 2.0.3 → 2.0.4
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.
|
@@ -18,12 +18,15 @@ import * as i2$1 from '@angular/material/form-field';
|
|
|
18
18
|
import { MatFormFieldModule, MatHint } from '@angular/material/form-field';
|
|
19
19
|
import * as i5 from '@angular/material/datepicker';
|
|
20
20
|
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
21
|
+
import * as i4 from '@ngxmc/datetime-picker';
|
|
22
|
+
import { NgxMatDatetimepicker, NgxMatDatepickerInput, NgxMatDatepickerToggle } from '@ngxmc/datetime-picker';
|
|
21
23
|
import { MatInputModule } from '@angular/material/input';
|
|
22
24
|
import { debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs/operators';
|
|
23
25
|
import { MatMenuModule } from '@angular/material/menu';
|
|
24
26
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
25
27
|
import * as i3$1 from '@angular/cdk/drag-drop';
|
|
26
28
|
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
|
|
29
|
+
import { NativeDateAdapter, DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
|
27
30
|
|
|
28
31
|
class OslBaseExtended {
|
|
29
32
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslBaseExtended, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -280,10 +283,10 @@ class Httpbase {
|
|
|
280
283
|
};
|
|
281
284
|
}
|
|
282
285
|
handleError(error) {
|
|
283
|
-
if (error.status === 401) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
286
|
+
// if (error.status === 401) {
|
|
287
|
+
// // localStorage.clear();
|
|
288
|
+
// window.location.href = '/login';
|
|
289
|
+
// }
|
|
287
290
|
return {
|
|
288
291
|
isSuccessful: false,
|
|
289
292
|
error: this.mapError(error),
|
|
@@ -2089,272 +2092,583 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2089
2092
|
type: Output
|
|
2090
2093
|
}] } });
|
|
2091
2094
|
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
}
|
|
2100
|
-
get model() { return this._model; }
|
|
2101
|
-
placeholder = '';
|
|
2102
|
-
minDatetime = '';
|
|
2103
|
-
maxDatetime = '';
|
|
2104
|
-
skeletonLoading = false;
|
|
2105
|
-
skeletonTheme = 'light';
|
|
2106
|
-
modelChange = new EventEmitter();
|
|
2107
|
-
changeEv = new EventEmitter();
|
|
2108
|
-
onValueChange(val) {
|
|
2109
|
-
if (val === this._model)
|
|
2110
|
-
return;
|
|
2111
|
-
this._model = val ?? '';
|
|
2112
|
-
this.modelChange.emit(this._model);
|
|
2113
|
-
this.changeEv.emit(this._model);
|
|
2114
|
-
}
|
|
2115
|
-
// Trim to YYYY-MM-DDTHH:MM which datetime-local inputs require
|
|
2116
|
-
_normalize(val) {
|
|
2117
|
-
if (!val)
|
|
2118
|
-
return '';
|
|
2119
|
-
const match = val.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2})/);
|
|
2120
|
-
return match ? match[1] : val;
|
|
2121
|
-
}
|
|
2122
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslDatetimepicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2123
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslDatetimepicker, isStandalone: false, selector: "osl-datetimepicker", inputs: { label: "label", required: "required", disabled: "disabled", model: "model", placeholder: "placeholder", minDatetime: "minDatetime", maxDatetime: "maxDatetime", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { modelChange: "modelChange", changeEv: "changeEv" }, ngImport: i0, template: "<div class=\"d-flex flex-column\">\n @if (label) {\n <div [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n <label class=\"label\" [class.txt-clr-red]=\"dtField.touched && dtField.invalid\">\n {{label}} <span class=\"txt-clr-red\">{{required ? '*' : ''}}</span>\n </label>\n </div>\n }\n <div class=\"input-wrapper\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n <input\n type=\"datetime-local\"\n class=\"dt-input\"\n [ngModel]=\"model\"\n (ngModelChange)=\"onValueChange($event)\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [min]=\"minDatetime\"\n [max]=\"maxDatetime\"\n [class.error]=\"dtField.touched && dtField.invalid\"\n #dtField=\"ngModel\"\n >\n </div>\n @if (dtField.touched && dtField.invalid && required) {\n <mat-hint class=\"hint\">{{label}} is Required!</mat-hint>\n }\n</div>\n", styles: [".label{font-size:var(--osl-label-font-size);margin-bottom:5px}.txt-clr-red{color:var(--osl-error-color)}.hint{color:var(--osl-error-color);margin-top:2px;font-size:var(--osl-hint-font-size)}.input-wrapper{position:relative;display:flex;align-items:center}.dt-input{height:var(--osl-control-height);width:100%;border-radius:var(--osl-border-radius);outline:none;border:1px solid var(--osl-border-color);padding:0 10px;font-size:var(--osl-text-font-size);font-family:inherit;color:#333;background-color:#fff;transition:border-color .2s,box-shadow .2s;letter-spacing:.01em;box-sizing:border-box}.dt-input::placeholder{color:#bbb}.dt-input:hover:not(:disabled){border-color:var(--osl-focus-border-color)}.dt-input:focus{border-color:var(--osl-focus-border-color);box-shadow:0 0 0 3px var(--osl-focus-shadow, rgba(99, 102, 241, .14))}.dt-input:disabled{background-color:#f5f5f5;cursor:not-allowed;opacity:.7}.dt-input.error{border-color:var(--osl-error-color)}.dt-input.error:focus{box-shadow:0 0 0 3px var(--osl-error-shadow, rgba(220, 38, 38, .14))}.dt-input::-webkit-calendar-picker-indicator{opacity:.45;cursor:pointer;transition:opacity .15s}.dt-input::-webkit-calendar-picker-indicator:hover{opacity:.9}\n"], dependencies: [{ kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }] });
|
|
2095
|
+
// ─── Date Utilities ───────────────────────────────────────────────────────────
|
|
2096
|
+
const MONTH_NAMES_SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
2097
|
+
const MONTH_NAMES_FULL = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
2098
|
+
const DAY_NAMES_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
2099
|
+
const DAY_NAMES_FULL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
2100
|
+
function pad(n) {
|
|
2101
|
+
return String(n).padStart(2, '0');
|
|
2124
2102
|
}
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
}], propDecorators: { label: [{
|
|
2129
|
-
type: Input,
|
|
2130
|
-
args: ['label']
|
|
2131
|
-
}], required: [{
|
|
2132
|
-
type: Input,
|
|
2133
|
-
args: ['required']
|
|
2134
|
-
}], disabled: [{
|
|
2135
|
-
type: Input,
|
|
2136
|
-
args: ['disabled']
|
|
2137
|
-
}], model: [{
|
|
2138
|
-
type: Input,
|
|
2139
|
-
args: ['model']
|
|
2140
|
-
}], placeholder: [{
|
|
2141
|
-
type: Input,
|
|
2142
|
-
args: ['placeholder']
|
|
2143
|
-
}], minDatetime: [{
|
|
2144
|
-
type: Input,
|
|
2145
|
-
args: ['minDatetime']
|
|
2146
|
-
}], maxDatetime: [{
|
|
2147
|
-
type: Input,
|
|
2148
|
-
args: ['maxDatetime']
|
|
2149
|
-
}], skeletonLoading: [{
|
|
2150
|
-
type: Input,
|
|
2151
|
-
args: ['skeletonLoading']
|
|
2152
|
-
}], skeletonTheme: [{
|
|
2153
|
-
type: Input,
|
|
2154
|
-
args: ['skeletonTheme']
|
|
2155
|
-
}], modelChange: [{
|
|
2156
|
-
type: Output
|
|
2157
|
-
}], changeEv: [{
|
|
2158
|
-
type: Output
|
|
2159
|
-
}] } });
|
|
2160
|
-
|
|
2161
|
-
class OslCheckbox {
|
|
2162
|
-
checkboxEl;
|
|
2163
|
-
label = '';
|
|
2164
|
-
disabled = false;
|
|
2165
|
-
required = false;
|
|
2166
|
-
model = false;
|
|
2167
|
-
indeterminate = false;
|
|
2168
|
-
skeletonLoading = false;
|
|
2169
|
-
skeletonTheme = 'light';
|
|
2170
|
-
modelChange = new EventEmitter();
|
|
2171
|
-
changeEv = new EventEmitter();
|
|
2172
|
-
touched = false;
|
|
2173
|
-
get isInvalid() {
|
|
2174
|
-
return this.touched && this.required && !this.model;
|
|
2175
|
-
}
|
|
2176
|
-
ngOnChanges(changes) {
|
|
2177
|
-
if (changes['indeterminate'] && this.checkboxEl) {
|
|
2178
|
-
this.checkboxEl.nativeElement.indeterminate = this.indeterminate;
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
ngAfterViewInit() {
|
|
2182
|
-
if (this.checkboxEl) {
|
|
2183
|
-
this.checkboxEl.nativeElement.indeterminate = this.indeterminate;
|
|
2184
|
-
}
|
|
2185
|
-
}
|
|
2186
|
-
onModelChange(event) {
|
|
2187
|
-
this.touched = true;
|
|
2188
|
-
this.model = event;
|
|
2189
|
-
this.modelChange.emit(this.model);
|
|
2190
|
-
this.changeEv.emit(this.model);
|
|
2191
|
-
}
|
|
2192
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2193
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslCheckbox, isStandalone: false, selector: "osl-checkbox", inputs: { label: "label", disabled: "disabled", required: "required", model: "model", indeterminate: "indeterminate", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { modelChange: "modelChange", changeEv: "changeEv" }, viewQueries: [{ propertyName: "checkboxEl", first: true, predicate: ["checkboxEl"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex flex-column\">\r\n\r\n <label class=\"checkbox-wrapper\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\" [class.checkbox-disabled]=\"disabled\" [class.checkbox-invalid]=\"isInvalid\">\r\n <input\r\n #checkboxEl\r\n type=\"checkbox\"\r\n [ngModel]=\"model\"\r\n (ngModelChange)=\"onModelChange($event)\"\r\n [disabled]=\"disabled\"\r\n >\r\n <span class=\"checkbox-label\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\r\n {{label}} <span class=\"txt-clr-red\">{{required?'*':''}}</span>\r\n </span>\r\n </label>\r\n @if(isInvalid) {\r\n <mat-hint class=\"hint\">{{label}} is Required!</mat-hint>\r\n }\r\n</div>\r\n", styles: [".checkbox-wrapper{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:var(--osl-label-font-size);width:fit-content}.checkbox-wrapper input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:#333;flex-shrink:0}.checkbox-wrapper .checkbox-label{-webkit-user-select:none;user-select:none}.checkbox-wrapper.checkbox-disabled{opacity:.6;cursor:not-allowed}.checkbox-wrapper.checkbox-disabled input[type=checkbox]{cursor:not-allowed}.checkbox-wrapper.checkbox-invalid{color:var(--osl-error-color)}.hint{color:var(--osl-error-color);margin-top:2px;font-size:var(--osl-hint-font-size)}.txt-clr-red{color:var(--osl-error-color)}\n"], dependencies: [{ kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }] });
|
|
2103
|
+
/** Returns the current date and time. */
|
|
2104
|
+
function now() {
|
|
2105
|
+
return new Date();
|
|
2194
2106
|
}
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
}], propDecorators: { checkboxEl: [{
|
|
2199
|
-
type: ViewChild,
|
|
2200
|
-
args: ['checkboxEl']
|
|
2201
|
-
}], label: [{
|
|
2202
|
-
type: Input,
|
|
2203
|
-
args: ['label']
|
|
2204
|
-
}], disabled: [{
|
|
2205
|
-
type: Input,
|
|
2206
|
-
args: ['disabled']
|
|
2207
|
-
}], required: [{
|
|
2208
|
-
type: Input,
|
|
2209
|
-
args: ['required']
|
|
2210
|
-
}], model: [{
|
|
2211
|
-
type: Input,
|
|
2212
|
-
args: ['model']
|
|
2213
|
-
}], indeterminate: [{
|
|
2214
|
-
type: Input,
|
|
2215
|
-
args: ['indeterminate']
|
|
2216
|
-
}], skeletonLoading: [{
|
|
2217
|
-
type: Input,
|
|
2218
|
-
args: ['skeletonLoading']
|
|
2219
|
-
}], skeletonTheme: [{
|
|
2220
|
-
type: Input,
|
|
2221
|
-
args: ['skeletonTheme']
|
|
2222
|
-
}], modelChange: [{
|
|
2223
|
-
type: Output
|
|
2224
|
-
}], changeEv: [{
|
|
2225
|
-
type: Output
|
|
2226
|
-
}] } });
|
|
2227
|
-
|
|
2228
|
-
class OslButton {
|
|
2229
|
-
label = 'Button';
|
|
2230
|
-
icon = '';
|
|
2231
|
-
variant = 'primary';
|
|
2232
|
-
size = 'md';
|
|
2233
|
-
disabled = false;
|
|
2234
|
-
loading = false;
|
|
2235
|
-
type = 'button';
|
|
2236
|
-
fullWidth = false;
|
|
2237
|
-
clickEv = new EventEmitter();
|
|
2238
|
-
get classes() {
|
|
2239
|
-
return [
|
|
2240
|
-
'osl-btn',
|
|
2241
|
-
`osl-btn--${this.variant}`,
|
|
2242
|
-
`osl-btn--${this.size}`,
|
|
2243
|
-
this.fullWidth ? 'osl-btn--full' : '',
|
|
2244
|
-
]
|
|
2245
|
-
.filter(Boolean)
|
|
2246
|
-
.join(' ');
|
|
2247
|
-
}
|
|
2248
|
-
onClick() {
|
|
2249
|
-
if (!this.disabled && !this.loading) {
|
|
2250
|
-
this.clickEv.emit();
|
|
2251
|
-
}
|
|
2252
|
-
}
|
|
2253
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2254
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslButton, isStandalone: false, selector: "osl-button", inputs: { label: "label", icon: "icon", variant: "variant", size: "size", disabled: "disabled", loading: "loading", type: "type", fullWidth: "fullWidth" }, outputs: { clickEv: "clickEv" }, ngImport: i0, template: "@if (variant == 'icon' && icon) {\r\n <button class=\"icon-btn\" [type]=\"type\" [disabled]=\"disabled || loading\" (click)=\"onClick()\">\r\n @if (loading) {\r\n <span class=\"osl-btn__spinner\"></span>\r\n } @else {\r\n <mat-icon>{{ icon }}</mat-icon>\r\n }\r\n </button>\r\n} @else {\r\n <button [class]=\"classes\" [type]=\"type\" [disabled]=\"disabled || loading\" (click)=\"onClick()\">\r\n @if (loading) {\r\n <span class=\"osl-btn__spinner\"></span>\r\n }\r\n <span class=\"osl-btn__label\">{{ label }}</span>\r\n @if (icon) {\r\n <span class=\"osl-btn__label-icon\"\r\n ><mat-icon>{{ icon }}</mat-icon></span\r\n >\r\n }\r\n </button>\r\n}\r\n", styles: ["@charset \"UTF-8\";.osl-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:none;border-radius:var(--osl-border-radius);cursor:pointer;font-size:var(--osl-label-font-size);font-weight:500;line-height:1;transition:background-color .2s ease,border-color .2s ease,opacity .2s ease;white-space:nowrap;outline:none}.osl-btn--sm{height:28px;padding:0 var(--osl-hint-font-size);font-size:var(--osl-hint-font-size)}.osl-btn--sm mat-icon{font-size:var(--osl-hint-font-size)}.osl-btn--md{height:36px;padding:0 18px;font-size:var(--osl-label-font-size)}.osl-btn--lg{height:44px;padding:0 24px;font-size:16px}.osl-btn--full{width:100%}.osl-btn:disabled{opacity:var(--osl-disabled-opacity);cursor:not-allowed}.osl-btn--primary{background-color:var(--osl-primary);color:var(--osl-primary-text)}.osl-btn--primary:hover:not(:disabled){background-color:var(--osl-primary-hover)}.osl-btn--secondary{background-color:var(--osl-secondary);color:var(--osl-secondary-text)}.osl-btn--secondary:hover:not(:disabled){background-color:var(--osl-secondary-hover)}.osl-btn--success{background-color:var(--osl-success);color:var(--osl-success-text)}.osl-btn--success:hover:not(:disabled){background-color:var(--osl-success-hover)}.osl-btn--danger{background-color:var(--osl-danger);color:var(--osl-danger-text)}.osl-btn--danger:hover:not(:disabled){background-color:var(--osl-danger-hover)}.osl-btn--warning{background-color:var(--osl-warning);color:var(--osl-warning-text)}.osl-btn--warning:hover:not(:disabled){background-color:var(--osl-warning-hover)}.osl-btn--info{background-color:var(--osl-info);color:var(--osl-info-text)}.osl-btn--info:hover:not(:disabled){background-color:var(--osl-info-hover)}.osl-btn--outline-primary{background-color:transparent;border:1.5px solid var(--osl-primary);color:var(--osl-primary)}.osl-btn--outline-primary:hover:not(:disabled){background-color:var(--osl-primary);color:var(--osl-primary-text)}.osl-btn--outline-secondary{background-color:transparent;border:1.5px solid var(--osl-secondary);color:var(--osl-secondary)}.osl-btn--outline-secondary:hover:not(:disabled){background-color:var(--osl-secondary);color:var(--osl-secondary-text)}.osl-btn--outline-success{background-color:transparent;border:1.5px solid var(--osl-success);color:var(--osl-success)}.osl-btn--outline-success:hover:not(:disabled){background-color:var(--osl-success);color:var(--osl-success-text)}.osl-btn--outline-danger{background-color:transparent;border:1.5px solid var(--osl-danger);color:var(--osl-danger)}.osl-btn--outline-danger:hover:not(:disabled){background-color:var(--osl-danger);color:var(--osl-danger-text)}.osl-btn--outline-warning{background-color:transparent;border:1.5px solid var(--osl-warning);color:var(--osl-warning)}.osl-btn--outline-warning:hover:not(:disabled){background-color:var(--osl-warning);color:var(--osl-warning-text)}.osl-btn--outline-info{background-color:transparent;border:1.5px solid var(--osl-info);color:var(--osl-info)}.osl-btn--outline-info:hover:not(:disabled){background-color:var(--osl-info);color:var(--osl-info-text)}.osl-btn__spinner{display:inline-block;width:var(--osl-label-font-size);height:var(--osl-label-font-size);border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:osl-spin .7s linear infinite}@keyframes osl-spin{to{transform:rotate(360deg)}}.osl-btn__label-icon{color:var(--color-white)}.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid var(--osl-border-color);border-radius:var(--osl-border-radius);background:transparent;color:#6b7280;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s;margin:0 2px}.icon-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.icon-btn:hover{border-color:var(--osl-primary);color:var(--osl-primary);background:#6366f10f}.icon-btn--danger:hover{border-color:#ef4444;color:#ef4444;background:#ef44440f}\n"], dependencies: [{ kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
2107
|
+
/** Returns today's date with time set to midnight. */
|
|
2108
|
+
function today() {
|
|
2109
|
+
return startOfDay(new Date());
|
|
2255
2110
|
}
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2111
|
+
/** Returns true if the value is a valid Date object. */
|
|
2112
|
+
function isValidDate$1(value) {
|
|
2113
|
+
return value instanceof Date && !isNaN(value.getTime());
|
|
2114
|
+
}
|
|
2115
|
+
/**
|
|
2116
|
+
* Formats a Date using a pattern string.
|
|
2117
|
+
* Tokens: YYYY, YY, MM, M, DD, D, HH, H, mm, m, ss, s,
|
|
2118
|
+
* MMM (short month), MMMM (full month),
|
|
2119
|
+
* ddd (short day), dddd (full day).
|
|
2120
|
+
*/
|
|
2121
|
+
function formatDate(date, pattern) {
|
|
2122
|
+
const d = new Date(date);
|
|
2123
|
+
if (!isValidDate$1(d))
|
|
2124
|
+
return '';
|
|
2125
|
+
const year = d.getFullYear();
|
|
2126
|
+
const month = d.getMonth();
|
|
2127
|
+
const day = d.getDate();
|
|
2128
|
+
const hours = d.getHours();
|
|
2129
|
+
const mins = d.getMinutes();
|
|
2130
|
+
const secs = d.getSeconds();
|
|
2131
|
+
const dayOfWeek = d.getDay();
|
|
2132
|
+
return pattern
|
|
2133
|
+
.replace('YYYY', String(year))
|
|
2134
|
+
.replace('YY', String(year).slice(-2))
|
|
2135
|
+
.replace('MMMM', MONTH_NAMES_FULL[month])
|
|
2136
|
+
.replace('MMM', MONTH_NAMES_SHORT[month])
|
|
2137
|
+
.replace('MM', pad(month + 1))
|
|
2138
|
+
.replace('M', String(month + 1))
|
|
2139
|
+
.replace('dddd', DAY_NAMES_FULL[dayOfWeek])
|
|
2140
|
+
.replace('ddd', DAY_NAMES_SHORT[dayOfWeek])
|
|
2141
|
+
.replace('DD', pad(day))
|
|
2142
|
+
.replace('D', String(day))
|
|
2143
|
+
.replace('HH', pad(hours))
|
|
2144
|
+
.replace('H', String(hours))
|
|
2145
|
+
.replace('mm', pad(mins))
|
|
2146
|
+
.replace('m', String(mins))
|
|
2147
|
+
.replace('ss', pad(secs))
|
|
2148
|
+
.replace('s', String(secs));
|
|
2149
|
+
}
|
|
2150
|
+
/** Returns date as `YYYY-MM-DD`. */
|
|
2151
|
+
function toDateOnly(date) {
|
|
2152
|
+
return formatDate(date, 'YYYY-MM-DD');
|
|
2153
|
+
}
|
|
2154
|
+
/** Returns the ISO 8601 string for a date. */
|
|
2155
|
+
function toISOString(date) {
|
|
2156
|
+
return date.toISOString();
|
|
2157
|
+
}
|
|
2158
|
+
/** Returns a new date with `days` added. */
|
|
2159
|
+
function addDays(date, days) {
|
|
2160
|
+
const result = new Date(date);
|
|
2161
|
+
result.setDate(result.getDate() + days);
|
|
2162
|
+
return result;
|
|
2163
|
+
}
|
|
2164
|
+
/** Returns a new date with `months` added. */
|
|
2165
|
+
function addMonths(date, months) {
|
|
2166
|
+
const result = new Date(date);
|
|
2167
|
+
result.setMonth(result.getMonth() + months);
|
|
2168
|
+
return result;
|
|
2169
|
+
}
|
|
2170
|
+
/** Returns a new date with `years` added. */
|
|
2171
|
+
function addYears(date, years) {
|
|
2172
|
+
const result = new Date(date);
|
|
2173
|
+
result.setFullYear(result.getFullYear() + years);
|
|
2174
|
+
return result;
|
|
2175
|
+
}
|
|
2176
|
+
/** Returns a new date with `hours` added. */
|
|
2177
|
+
function addHours(date, hours) {
|
|
2178
|
+
return new Date(date.getTime() + hours * 3_600_000);
|
|
2179
|
+
}
|
|
2180
|
+
/** Returns a new date with `minutes` added. */
|
|
2181
|
+
function addMinutes(date, minutes) {
|
|
2182
|
+
return new Date(date.getTime() + minutes * 60_000);
|
|
2183
|
+
}
|
|
2184
|
+
/** Returns a new date with `days` subtracted. */
|
|
2185
|
+
function subtractDays(date, days) {
|
|
2186
|
+
return addDays(date, -days);
|
|
2187
|
+
}
|
|
2188
|
+
/** Returns a new date with `months` subtracted. */
|
|
2189
|
+
function subtractMonths(date, months) {
|
|
2190
|
+
return addMonths(date, -months);
|
|
2191
|
+
}
|
|
2192
|
+
/** Returns a new date with `years` subtracted. */
|
|
2193
|
+
function subtractYears(date, years) {
|
|
2194
|
+
return addYears(date, -years);
|
|
2195
|
+
}
|
|
2196
|
+
/** Returns the absolute difference in whole days between two dates. */
|
|
2197
|
+
function diffInDays(date1, date2) {
|
|
2198
|
+
return Math.abs(Math.floor((date1.getTime() - date2.getTime()) / 86_400_000));
|
|
2199
|
+
}
|
|
2200
|
+
/** Returns the absolute difference in whole months between two dates. */
|
|
2201
|
+
function diffInMonths(date1, date2) {
|
|
2202
|
+
return Math.abs((date1.getFullYear() - date2.getFullYear()) * 12 +
|
|
2203
|
+
(date1.getMonth() - date2.getMonth()));
|
|
2204
|
+
}
|
|
2205
|
+
/** Returns the absolute difference in whole years between two dates. */
|
|
2206
|
+
function diffInYears(date1, date2) {
|
|
2207
|
+
return Math.abs(date1.getFullYear() - date2.getFullYear());
|
|
2208
|
+
}
|
|
2209
|
+
/** Returns the difference in minutes between two dates (date1 - date2). */
|
|
2210
|
+
function diffInMinutes(date1, date2) {
|
|
2211
|
+
return Math.floor((date1.getTime() - date2.getTime()) / 60_000);
|
|
2212
|
+
}
|
|
2213
|
+
/** Returns true if date1 is strictly before date2. */
|
|
2214
|
+
function isBefore(date1, date2) {
|
|
2215
|
+
return date1.getTime() < date2.getTime();
|
|
2216
|
+
}
|
|
2217
|
+
/** Returns true if date1 is strictly after date2. */
|
|
2218
|
+
function isAfter(date1, date2) {
|
|
2219
|
+
return date1.getTime() > date2.getTime();
|
|
2220
|
+
}
|
|
2221
|
+
/** Returns true if both dates fall on the same calendar day. */
|
|
2222
|
+
function isSameDay(date1, date2) {
|
|
2223
|
+
return (date1.getFullYear() === date2.getFullYear() &&
|
|
2224
|
+
date1.getMonth() === date2.getMonth() &&
|
|
2225
|
+
date1.getDate() === date2.getDate());
|
|
2226
|
+
}
|
|
2227
|
+
/** Returns true if the date falls on a Saturday or Sunday. */
|
|
2228
|
+
function isWeekend(date) {
|
|
2229
|
+
return date.getDay() === 0 || date.getDay() === 6;
|
|
2230
|
+
}
|
|
2231
|
+
/** Returns true if the date is today. */
|
|
2232
|
+
function isToday(date) {
|
|
2233
|
+
return isSameDay(date, new Date());
|
|
2234
|
+
}
|
|
2235
|
+
/** Returns true if the date falls in the past (before now). */
|
|
2236
|
+
function isPast(date) {
|
|
2237
|
+
return date.getTime() < Date.now();
|
|
2238
|
+
}
|
|
2239
|
+
/** Returns true if the date falls in the future (after now). */
|
|
2240
|
+
function isFuture(date) {
|
|
2241
|
+
return date.getTime() > Date.now();
|
|
2242
|
+
}
|
|
2243
|
+
/** Returns the date with time set to 00:00:00.000. */
|
|
2244
|
+
function startOfDay(date) {
|
|
2245
|
+
const result = new Date(date);
|
|
2246
|
+
result.setHours(0, 0, 0, 0);
|
|
2247
|
+
return result;
|
|
2248
|
+
}
|
|
2249
|
+
/** Returns the date with time set to 23:59:59.999. */
|
|
2250
|
+
function endOfDay(date) {
|
|
2251
|
+
const result = new Date(date);
|
|
2252
|
+
result.setHours(23, 59, 59, 999);
|
|
2253
|
+
return result;
|
|
2254
|
+
}
|
|
2255
|
+
/** Returns the first day of the month (time 00:00:00.000). */
|
|
2256
|
+
function startOfMonth(date) {
|
|
2257
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
2258
|
+
}
|
|
2259
|
+
/** Returns the last day of the month (time 23:59:59.999). */
|
|
2260
|
+
function endOfMonth(date) {
|
|
2261
|
+
const result = new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
|
2262
|
+
result.setHours(23, 59, 59, 999);
|
|
2263
|
+
return result;
|
|
2264
|
+
}
|
|
2265
|
+
/** Returns the first day of the year (Jan 1, 00:00:00.000). */
|
|
2266
|
+
function startOfYear(date) {
|
|
2267
|
+
return new Date(date.getFullYear(), 0, 1);
|
|
2268
|
+
}
|
|
2269
|
+
/** Returns the last day of the year (Dec 31, 23:59:59.999). */
|
|
2270
|
+
function endOfYear(date) {
|
|
2271
|
+
const result = new Date(date.getFullYear(), 11, 31);
|
|
2272
|
+
result.setHours(23, 59, 59, 999);
|
|
2273
|
+
return result;
|
|
2274
|
+
}
|
|
2275
|
+
/** Calculates the age in years from a birth date. */
|
|
2276
|
+
function getAge(birthDate) {
|
|
2277
|
+
const n = new Date();
|
|
2278
|
+
let age = n.getFullYear() - birthDate.getFullYear();
|
|
2279
|
+
const monthDiff = n.getMonth() - birthDate.getMonth();
|
|
2280
|
+
if (monthDiff < 0 || (monthDiff === 0 && n.getDate() < birthDate.getDate()))
|
|
2281
|
+
age--;
|
|
2282
|
+
return age;
|
|
2283
|
+
}
|
|
2284
|
+
/** Returns the number of days in a given month (0-based month). */
|
|
2285
|
+
function daysInMonth(year, month) {
|
|
2286
|
+
return new Date(year, month + 1, 0).getDate();
|
|
2287
|
+
}
|
|
2288
|
+
/** Returns true if the given year is a leap year. */
|
|
2289
|
+
function isLeapYear(year) {
|
|
2290
|
+
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
2291
|
+
}
|
|
2292
|
+
/**
|
|
2293
|
+
* Returns a human-friendly relative time string.
|
|
2294
|
+
* @example timeAgo(new Date(Date.now() - 3600_000)) → '1 hour ago'
|
|
2295
|
+
*/
|
|
2296
|
+
function timeAgo(date) {
|
|
2297
|
+
const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
|
|
2298
|
+
const abs = Math.abs(seconds);
|
|
2299
|
+
const future = seconds < 0;
|
|
2300
|
+
const intervals = [
|
|
2301
|
+
[31_536_000, 'year'],
|
|
2302
|
+
[2_592_000, 'month'],
|
|
2303
|
+
[604_800, 'week'],
|
|
2304
|
+
[86_400, 'day'],
|
|
2305
|
+
[3_600, 'hour'],
|
|
2306
|
+
[60, 'minute'],
|
|
2307
|
+
[1, 'second'],
|
|
2308
|
+
];
|
|
2309
|
+
for (const [secs, label] of intervals) {
|
|
2310
|
+
const count = Math.floor(abs / secs);
|
|
2311
|
+
if (count >= 1) {
|
|
2312
|
+
const unit = count === 1 ? label : `${label}s`;
|
|
2313
|
+
return future ? `in ${count} ${unit}` : `${count} ${unit} ago`;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
return 'just now';
|
|
2317
|
+
}
|
|
2318
|
+
/** Returns the ISO week number (1–53) for the given date. */
|
|
2319
|
+
function getWeekNumber(date) {
|
|
2320
|
+
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
|
2321
|
+
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
|
|
2322
|
+
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
|
2323
|
+
return Math.ceil((((d.getTime() - yearStart.getTime()) / 86_400_000) + 1) / 7);
|
|
2324
|
+
}
|
|
2325
|
+
/** Returns the next weekday (Mon–Fri) after the given date. */
|
|
2326
|
+
function nextWorkday(date) {
|
|
2327
|
+
const result = addDays(date, 1);
|
|
2328
|
+
while (isWeekend(result)) {
|
|
2329
|
+
result.setDate(result.getDate() + 1);
|
|
2330
|
+
}
|
|
2331
|
+
return result;
|
|
2332
|
+
}
|
|
2333
|
+
/** Returns true if a date falls within the range [start, end] (inclusive). */
|
|
2334
|
+
function inRange$2(date, start, end) {
|
|
2335
|
+
return date >= start && date <= end;
|
|
2336
|
+
}
|
|
2337
|
+
/** Parses a `YYYY-MM-DD` string and returns a local-midnight Date or null. */
|
|
2338
|
+
function parseDate(dateStr) {
|
|
2339
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dateStr);
|
|
2340
|
+
if (!match)
|
|
2341
|
+
return null;
|
|
2342
|
+
const [, y, mo, d] = match.map(Number);
|
|
2343
|
+
const result = new Date(y, mo - 1, d);
|
|
2344
|
+
return isValidDate$1(result) ? result : null;
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
var date_util = /*#__PURE__*/Object.freeze({
|
|
2348
|
+
__proto__: null,
|
|
2349
|
+
addDays: addDays,
|
|
2350
|
+
addHours: addHours,
|
|
2351
|
+
addMinutes: addMinutes,
|
|
2352
|
+
addMonths: addMonths,
|
|
2353
|
+
addYears: addYears,
|
|
2354
|
+
daysInMonth: daysInMonth,
|
|
2355
|
+
diffInDays: diffInDays,
|
|
2356
|
+
diffInMinutes: diffInMinutes,
|
|
2357
|
+
diffInMonths: diffInMonths,
|
|
2358
|
+
diffInYears: diffInYears,
|
|
2359
|
+
endOfDay: endOfDay,
|
|
2360
|
+
endOfMonth: endOfMonth,
|
|
2361
|
+
endOfYear: endOfYear,
|
|
2362
|
+
formatDate: formatDate,
|
|
2363
|
+
getAge: getAge,
|
|
2364
|
+
getWeekNumber: getWeekNumber,
|
|
2365
|
+
inRange: inRange$2,
|
|
2366
|
+
isAfter: isAfter,
|
|
2367
|
+
isBefore: isBefore,
|
|
2368
|
+
isFuture: isFuture,
|
|
2369
|
+
isLeapYear: isLeapYear,
|
|
2370
|
+
isPast: isPast,
|
|
2371
|
+
isSameDay: isSameDay,
|
|
2372
|
+
isToday: isToday,
|
|
2373
|
+
isValidDate: isValidDate$1,
|
|
2374
|
+
isWeekend: isWeekend,
|
|
2375
|
+
nextWorkday: nextWorkday,
|
|
2376
|
+
now: now,
|
|
2377
|
+
parseDate: parseDate,
|
|
2378
|
+
startOfDay: startOfDay,
|
|
2379
|
+
startOfMonth: startOfMonth,
|
|
2380
|
+
startOfYear: startOfYear,
|
|
2381
|
+
subtractDays: subtractDays,
|
|
2382
|
+
subtractMonths: subtractMonths,
|
|
2383
|
+
subtractYears: subtractYears,
|
|
2384
|
+
timeAgo: timeAgo,
|
|
2385
|
+
toDateOnly: toDateOnly,
|
|
2386
|
+
toISOString: toISOString,
|
|
2387
|
+
today: today
|
|
2388
|
+
});
|
|
2389
|
+
|
|
2390
|
+
class OslDatetimepicker {
|
|
2391
|
+
label = '';
|
|
2392
|
+
required = false;
|
|
2393
|
+
disabled = false;
|
|
2394
|
+
dateModel = null;
|
|
2395
|
+
set model(val) {
|
|
2396
|
+
this.dateModel = this._parseToDate(val);
|
|
2397
|
+
}
|
|
2398
|
+
placeholder = '';
|
|
2399
|
+
minDate = null;
|
|
2400
|
+
maxDate = null;
|
|
2401
|
+
set minDatetime(val) {
|
|
2402
|
+
this.minDate = this._parseToDate(val);
|
|
2403
|
+
}
|
|
2404
|
+
set maxDatetime(val) {
|
|
2405
|
+
this.maxDate = this._parseToDate(val);
|
|
2406
|
+
}
|
|
2407
|
+
/** Output format for the emitted string value. Uses date.util tokens: YYYY, MM, DD, HH, mm, ss */
|
|
2408
|
+
format = 'YYYY-MM-DDTHH:mm';
|
|
2409
|
+
showSeconds = false;
|
|
2410
|
+
enableMeridian = false;
|
|
2411
|
+
skeletonLoading = false;
|
|
2412
|
+
skeletonTheme = 'light';
|
|
2413
|
+
modelChange = new EventEmitter();
|
|
2414
|
+
changeEv = new EventEmitter();
|
|
2415
|
+
onDateChange(date) {
|
|
2416
|
+
this.dateModel = date;
|
|
2417
|
+
const str = date ? formatDate(date, this.format) : '';
|
|
2418
|
+
this.modelChange.emit(str);
|
|
2419
|
+
this.changeEv.emit(str);
|
|
2420
|
+
}
|
|
2421
|
+
_parseToDate(val) {
|
|
2422
|
+
if (!val)
|
|
2423
|
+
return null;
|
|
2424
|
+
const d = new Date(val);
|
|
2425
|
+
return isNaN(d.getTime()) ? null : d;
|
|
2426
|
+
}
|
|
2427
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslDatetimepicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2428
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslDatetimepicker, isStandalone: false, selector: "osl-datetimepicker", inputs: { label: "label", required: "required", disabled: "disabled", model: "model", placeholder: "placeholder", minDatetime: "minDatetime", maxDatetime: "maxDatetime", format: "format", showSeconds: "showSeconds", enableMeridian: "enableMeridian", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { modelChange: "modelChange", changeEv: "changeEv" }, ngImport: i0, template: "<div class=\"d-flex flex-column\">\n @if (label) {\n <div [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n <label class=\"label\" [class.txt-clr-red]=\"dtField.touched && dtField.invalid\">\n {{label}} <span class=\"txt-clr-red\">{{required ? '*' : ''}}</span>\n </label>\n </div>\n }\n <div class=\"input-wrapper\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n <input\n class=\"dt-input\"\n [ngxMatDatetimePicker]=\"picker\"\n [ngModel]=\"dateModel\"\n (ngModelChange)=\"onDateChange($event)\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [min]=\"minDate\"\n [max]=\"maxDate\"\n [placeholder]=\"placeholder\"\n [class.error]=\"dtField.touched && dtField.invalid\"\n #dtField=\"ngModel\"\n />\n <ngx-mat-datepicker-toggle\n [for]=\"picker\"\n [disabled]=\"disabled\"\n class=\"dt-toggle\">\n </ngx-mat-datepicker-toggle>\n <ngx-mat-datetime-picker\n #picker\n [showSpinners]=\"true\"\n [showSeconds]=\"showSeconds\"\n [enableMeridian]=\"enableMeridian\">\n </ngx-mat-datetime-picker>\n </div>\n @if (dtField.touched && dtField.invalid && required) {\n <mat-hint class=\"hint\">{{label}} is Required!</mat-hint>\n }\n</div>\n", styles: [".label{font-size:var(--osl-label-font-size);margin-bottom:5px}.txt-clr-red{color:var(--osl-error-color)}.hint{color:var(--osl-error-color);margin-top:2px;font-size:var(--osl-hint-font-size)}.input-wrapper{position:relative;display:flex;align-items:center}.dt-toggle{position:absolute;right:2px;top:50%;transform:translateY(-50%);display:flex;align-items:center}.dt-toggle ::ng-deep .mat-mdc-icon-button{width:32px;height:32px;padding:4px;color:#666}.dt-toggle ::ng-deep .mat-mdc-icon-button:hover:not([disabled]){color:var(--osl-focus-border-color)}.dt-toggle ::ng-deep .mat-mdc-icon-button[disabled]{opacity:.4;cursor:not-allowed}.dt-input{height:var(--osl-control-height);width:100%;border-radius:var(--osl-border-radius);outline:none;border:1px solid var(--osl-border-color);padding:0 38px 0 10px;font-size:var(--osl-text-font-size);font-family:inherit;color:#333;background-color:#fff;transition:border-color .2s,box-shadow .2s;letter-spacing:.01em;box-sizing:border-box}.dt-input::placeholder{color:#bbb}.dt-input:hover:not(:disabled){border-color:var(--osl-focus-border-color)}.dt-input:focus{border-color:var(--osl-focus-border-color);box-shadow:0 0 0 3px var(--osl-focus-shadow, rgba(99, 102, 241, .14))}.dt-input:disabled{background-color:#f5f5f5;cursor:not-allowed;opacity:.7}.dt-input.error{border-color:var(--osl-error-color)}.dt-input.error:focus{box-shadow:0 0 0 3px var(--osl-error-shadow, rgba(220, 38, 38, .14))}\n"], dependencies: [{ kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }, { kind: "component", type: i4.NgxMatDatetimepicker, selector: "ngx-mat-datetime-picker", exportAs: ["ngxMatDatetimePicker"] }, { kind: "directive", type: i4.NgxMatDatepickerInput, selector: "input[ngxMatDatetimePicker]", inputs: ["ngxMatDatetimePicker", "min", "max", "matDatepickerFilter"], exportAs: ["ngxMatDatepickerInput"] }, { kind: "component", type: i4.NgxMatDatepickerToggle, selector: "ngx-mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["ngxMatDatepickerToggle"] }] });
|
|
2429
|
+
}
|
|
2430
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslDatetimepicker, decorators: [{
|
|
2431
|
+
type: Component,
|
|
2432
|
+
args: [{ selector: 'osl-datetimepicker', standalone: false, template: "<div class=\"d-flex flex-column\">\n @if (label) {\n <div [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n <label class=\"label\" [class.txt-clr-red]=\"dtField.touched && dtField.invalid\">\n {{label}} <span class=\"txt-clr-red\">{{required ? '*' : ''}}</span>\n </label>\n </div>\n }\n <div class=\"input-wrapper\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\n <input\n class=\"dt-input\"\n [ngxMatDatetimePicker]=\"picker\"\n [ngModel]=\"dateModel\"\n (ngModelChange)=\"onDateChange($event)\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n [min]=\"minDate\"\n [max]=\"maxDate\"\n [placeholder]=\"placeholder\"\n [class.error]=\"dtField.touched && dtField.invalid\"\n #dtField=\"ngModel\"\n />\n <ngx-mat-datepicker-toggle\n [for]=\"picker\"\n [disabled]=\"disabled\"\n class=\"dt-toggle\">\n </ngx-mat-datepicker-toggle>\n <ngx-mat-datetime-picker\n #picker\n [showSpinners]=\"true\"\n [showSeconds]=\"showSeconds\"\n [enableMeridian]=\"enableMeridian\">\n </ngx-mat-datetime-picker>\n </div>\n @if (dtField.touched && dtField.invalid && required) {\n <mat-hint class=\"hint\">{{label}} is Required!</mat-hint>\n }\n</div>\n", styles: [".label{font-size:var(--osl-label-font-size);margin-bottom:5px}.txt-clr-red{color:var(--osl-error-color)}.hint{color:var(--osl-error-color);margin-top:2px;font-size:var(--osl-hint-font-size)}.input-wrapper{position:relative;display:flex;align-items:center}.dt-toggle{position:absolute;right:2px;top:50%;transform:translateY(-50%);display:flex;align-items:center}.dt-toggle ::ng-deep .mat-mdc-icon-button{width:32px;height:32px;padding:4px;color:#666}.dt-toggle ::ng-deep .mat-mdc-icon-button:hover:not([disabled]){color:var(--osl-focus-border-color)}.dt-toggle ::ng-deep .mat-mdc-icon-button[disabled]{opacity:.4;cursor:not-allowed}.dt-input{height:var(--osl-control-height);width:100%;border-radius:var(--osl-border-radius);outline:none;border:1px solid var(--osl-border-color);padding:0 38px 0 10px;font-size:var(--osl-text-font-size);font-family:inherit;color:#333;background-color:#fff;transition:border-color .2s,box-shadow .2s;letter-spacing:.01em;box-sizing:border-box}.dt-input::placeholder{color:#bbb}.dt-input:hover:not(:disabled){border-color:var(--osl-focus-border-color)}.dt-input:focus{border-color:var(--osl-focus-border-color);box-shadow:0 0 0 3px var(--osl-focus-shadow, rgba(99, 102, 241, .14))}.dt-input:disabled{background-color:#f5f5f5;cursor:not-allowed;opacity:.7}.dt-input.error{border-color:var(--osl-error-color)}.dt-input.error:focus{box-shadow:0 0 0 3px var(--osl-error-shadow, rgba(220, 38, 38, .14))}\n"] }]
|
|
2433
|
+
}], propDecorators: { label: [{
|
|
2434
|
+
type: Input,
|
|
2435
|
+
args: ['label']
|
|
2436
|
+
}], required: [{
|
|
2437
|
+
type: Input,
|
|
2438
|
+
args: ['required']
|
|
2439
|
+
}], disabled: [{
|
|
2440
|
+
type: Input,
|
|
2441
|
+
args: ['disabled']
|
|
2442
|
+
}], model: [{
|
|
2443
|
+
type: Input,
|
|
2444
|
+
args: ['model']
|
|
2445
|
+
}], placeholder: [{
|
|
2446
|
+
type: Input,
|
|
2447
|
+
args: ['placeholder']
|
|
2448
|
+
}], minDatetime: [{
|
|
2449
|
+
type: Input,
|
|
2450
|
+
args: ['minDatetime']
|
|
2451
|
+
}], maxDatetime: [{
|
|
2452
|
+
type: Input,
|
|
2453
|
+
args: ['maxDatetime']
|
|
2454
|
+
}], format: [{
|
|
2455
|
+
type: Input,
|
|
2456
|
+
args: ['format']
|
|
2457
|
+
}], showSeconds: [{
|
|
2458
|
+
type: Input,
|
|
2459
|
+
args: ['showSeconds']
|
|
2460
|
+
}], enableMeridian: [{
|
|
2461
|
+
type: Input,
|
|
2462
|
+
args: ['enableMeridian']
|
|
2463
|
+
}], skeletonLoading: [{
|
|
2464
|
+
type: Input,
|
|
2465
|
+
args: ['skeletonLoading']
|
|
2466
|
+
}], skeletonTheme: [{
|
|
2467
|
+
type: Input,
|
|
2468
|
+
args: ['skeletonTheme']
|
|
2469
|
+
}], modelChange: [{
|
|
2470
|
+
type: Output
|
|
2471
|
+
}], changeEv: [{
|
|
2472
|
+
type: Output
|
|
2473
|
+
}] } });
|
|
2474
|
+
|
|
2475
|
+
class OslCheckbox {
|
|
2476
|
+
checkboxEl;
|
|
2477
|
+
label = '';
|
|
2478
|
+
disabled = false;
|
|
2479
|
+
required = false;
|
|
2480
|
+
model = false;
|
|
2481
|
+
indeterminate = false;
|
|
2482
|
+
skeletonLoading = false;
|
|
2483
|
+
skeletonTheme = 'light';
|
|
2484
|
+
modelChange = new EventEmitter();
|
|
2485
|
+
changeEv = new EventEmitter();
|
|
2486
|
+
touched = false;
|
|
2487
|
+
get isInvalid() {
|
|
2488
|
+
return this.touched && this.required && !this.model;
|
|
2489
|
+
}
|
|
2490
|
+
ngOnChanges(changes) {
|
|
2491
|
+
if (changes['indeterminate'] && this.checkboxEl) {
|
|
2492
|
+
this.checkboxEl.nativeElement.indeterminate = this.indeterminate;
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
ngAfterViewInit() {
|
|
2496
|
+
if (this.checkboxEl) {
|
|
2497
|
+
this.checkboxEl.nativeElement.indeterminate = this.indeterminate;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
onModelChange(event) {
|
|
2501
|
+
this.touched = true;
|
|
2502
|
+
this.model = event;
|
|
2503
|
+
this.modelChange.emit(this.model);
|
|
2504
|
+
this.changeEv.emit(this.model);
|
|
2505
|
+
}
|
|
2506
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2507
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslCheckbox, isStandalone: false, selector: "osl-checkbox", inputs: { label: "label", disabled: "disabled", required: "required", model: "model", indeterminate: "indeterminate", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { modelChange: "modelChange", changeEv: "changeEv" }, viewQueries: [{ propertyName: "checkboxEl", first: true, predicate: ["checkboxEl"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex flex-column\">\r\n\r\n <label class=\"checkbox-wrapper\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\" [class.checkbox-disabled]=\"disabled\" [class.checkbox-invalid]=\"isInvalid\">\r\n <input\r\n #checkboxEl\r\n type=\"checkbox\"\r\n [ngModel]=\"model\"\r\n (ngModelChange)=\"onModelChange($event)\"\r\n [disabled]=\"disabled\"\r\n >\r\n <span class=\"checkbox-label\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\r\n {{label}} <span class=\"txt-clr-red\">{{required?'*':''}}</span>\r\n </span>\r\n </label>\r\n @if(isInvalid) {\r\n <mat-hint class=\"hint\">{{label}} is Required!</mat-hint>\r\n }\r\n</div>\r\n", styles: [".checkbox-wrapper{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:var(--osl-label-font-size);width:fit-content}.checkbox-wrapper input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:#333;flex-shrink:0}.checkbox-wrapper .checkbox-label{-webkit-user-select:none;user-select:none}.checkbox-wrapper.checkbox-disabled{opacity:.6;cursor:not-allowed}.checkbox-wrapper.checkbox-disabled input[type=checkbox]{cursor:not-allowed}.checkbox-wrapper.checkbox-invalid{color:var(--osl-error-color)}.hint{color:var(--osl-error-color);margin-top:2px;font-size:var(--osl-hint-font-size)}.txt-clr-red{color:var(--osl-error-color)}\n"], dependencies: [{ kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }] });
|
|
2508
|
+
}
|
|
2509
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslCheckbox, decorators: [{
|
|
2510
|
+
type: Component,
|
|
2511
|
+
args: [{ selector: 'osl-checkbox', standalone: false, template: "<div class=\"d-flex flex-column\">\r\n\r\n <label class=\"checkbox-wrapper\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\" [class.checkbox-disabled]=\"disabled\" [class.checkbox-invalid]=\"isInvalid\">\r\n <input\r\n #checkboxEl\r\n type=\"checkbox\"\r\n [ngModel]=\"model\"\r\n (ngModelChange)=\"onModelChange($event)\"\r\n [disabled]=\"disabled\"\r\n >\r\n <span class=\"checkbox-label\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\r\n {{label}} <span class=\"txt-clr-red\">{{required?'*':''}}</span>\r\n </span>\r\n </label>\r\n @if(isInvalid) {\r\n <mat-hint class=\"hint\">{{label}} is Required!</mat-hint>\r\n }\r\n</div>\r\n", styles: [".checkbox-wrapper{display:flex;align-items:center;gap:8px;cursor:pointer;font-size:var(--osl-label-font-size);width:fit-content}.checkbox-wrapper input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:#333;flex-shrink:0}.checkbox-wrapper .checkbox-label{-webkit-user-select:none;user-select:none}.checkbox-wrapper.checkbox-disabled{opacity:.6;cursor:not-allowed}.checkbox-wrapper.checkbox-disabled input[type=checkbox]{cursor:not-allowed}.checkbox-wrapper.checkbox-invalid{color:var(--osl-error-color)}.hint{color:var(--osl-error-color);margin-top:2px;font-size:var(--osl-hint-font-size)}.txt-clr-red{color:var(--osl-error-color)}\n"] }]
|
|
2512
|
+
}], propDecorators: { checkboxEl: [{
|
|
2513
|
+
type: ViewChild,
|
|
2514
|
+
args: ['checkboxEl']
|
|
2515
|
+
}], label: [{
|
|
2516
|
+
type: Input,
|
|
2517
|
+
args: ['label']
|
|
2518
|
+
}], disabled: [{
|
|
2519
|
+
type: Input,
|
|
2520
|
+
args: ['disabled']
|
|
2521
|
+
}], required: [{
|
|
2522
|
+
type: Input,
|
|
2523
|
+
args: ['required']
|
|
2524
|
+
}], model: [{
|
|
2525
|
+
type: Input,
|
|
2526
|
+
args: ['model']
|
|
2527
|
+
}], indeterminate: [{
|
|
2528
|
+
type: Input,
|
|
2529
|
+
args: ['indeterminate']
|
|
2530
|
+
}], skeletonLoading: [{
|
|
2531
|
+
type: Input,
|
|
2532
|
+
args: ['skeletonLoading']
|
|
2533
|
+
}], skeletonTheme: [{
|
|
2534
|
+
type: Input,
|
|
2535
|
+
args: ['skeletonTheme']
|
|
2536
|
+
}], modelChange: [{
|
|
2537
|
+
type: Output
|
|
2538
|
+
}], changeEv: [{
|
|
2539
|
+
type: Output
|
|
2540
|
+
}] } });
|
|
2541
|
+
|
|
2542
|
+
class OslButton {
|
|
2543
|
+
label = 'Button';
|
|
2544
|
+
icon = '';
|
|
2545
|
+
variant = 'primary';
|
|
2546
|
+
size = 'md';
|
|
2547
|
+
disabled = false;
|
|
2548
|
+
loading = false;
|
|
2549
|
+
type = 'button';
|
|
2550
|
+
fullWidth = false;
|
|
2551
|
+
clickEv = new EventEmitter();
|
|
2552
|
+
get classes() {
|
|
2553
|
+
return [
|
|
2554
|
+
'osl-btn',
|
|
2555
|
+
`osl-btn--${this.variant}`,
|
|
2556
|
+
`osl-btn--${this.size}`,
|
|
2557
|
+
this.fullWidth ? 'osl-btn--full' : '',
|
|
2558
|
+
]
|
|
2559
|
+
.filter(Boolean)
|
|
2560
|
+
.join(' ');
|
|
2561
|
+
}
|
|
2562
|
+
onClick() {
|
|
2563
|
+
if (!this.disabled && !this.loading) {
|
|
2564
|
+
this.clickEv.emit();
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2568
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslButton, isStandalone: false, selector: "osl-button", inputs: { label: "label", icon: "icon", variant: "variant", size: "size", disabled: "disabled", loading: "loading", type: "type", fullWidth: "fullWidth" }, outputs: { clickEv: "clickEv" }, ngImport: i0, template: "@if (variant == 'icon' && icon) {\r\n <button class=\"icon-btn\" [type]=\"type\" [disabled]=\"disabled || loading\" (click)=\"onClick()\">\r\n @if (loading) {\r\n <span class=\"osl-btn__spinner\"></span>\r\n } @else {\r\n <mat-icon>{{ icon }}</mat-icon>\r\n }\r\n </button>\r\n} @else {\r\n <button [class]=\"classes\" [type]=\"type\" [disabled]=\"disabled || loading\" (click)=\"onClick()\">\r\n @if (loading) {\r\n <span class=\"osl-btn__spinner\"></span>\r\n }\r\n <span class=\"osl-btn__label\">{{ label }}</span>\r\n @if (icon) {\r\n <span class=\"osl-btn__label-icon\"\r\n ><mat-icon>{{ icon }}</mat-icon></span\r\n >\r\n }\r\n </button>\r\n}\r\n", styles: ["@charset \"UTF-8\";.osl-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:none;border-radius:var(--osl-border-radius);cursor:pointer;font-size:var(--osl-label-font-size);font-weight:500;line-height:1;transition:background-color .2s ease,border-color .2s ease,opacity .2s ease;white-space:nowrap;outline:none}.osl-btn--sm{height:28px;padding:0 var(--osl-hint-font-size);font-size:var(--osl-hint-font-size)}.osl-btn--sm mat-icon{font-size:var(--osl-hint-font-size)}.osl-btn--md{height:36px;padding:0 18px;font-size:var(--osl-label-font-size)}.osl-btn--lg{height:44px;padding:0 24px;font-size:16px}.osl-btn--full{width:100%}.osl-btn:disabled{opacity:var(--osl-disabled-opacity);cursor:not-allowed}.osl-btn--primary{background-color:var(--osl-primary);color:var(--osl-primary-text)}.osl-btn--primary:hover:not(:disabled){background-color:var(--osl-primary-hover)}.osl-btn--secondary{background-color:var(--osl-secondary);color:var(--osl-secondary-text)}.osl-btn--secondary:hover:not(:disabled){background-color:var(--osl-secondary-hover)}.osl-btn--success{background-color:var(--osl-success);color:var(--osl-success-text)}.osl-btn--success:hover:not(:disabled){background-color:var(--osl-success-hover)}.osl-btn--danger{background-color:var(--osl-danger);color:var(--osl-danger-text)}.osl-btn--danger:hover:not(:disabled){background-color:var(--osl-danger-hover)}.osl-btn--warning{background-color:var(--osl-warning);color:var(--osl-warning-text)}.osl-btn--warning:hover:not(:disabled){background-color:var(--osl-warning-hover)}.osl-btn--info{background-color:var(--osl-info);color:var(--osl-info-text)}.osl-btn--info:hover:not(:disabled){background-color:var(--osl-info-hover)}.osl-btn--outline-primary{background-color:transparent;border:1.5px solid var(--osl-primary);color:var(--osl-primary)}.osl-btn--outline-primary:hover:not(:disabled){background-color:var(--osl-primary);color:var(--osl-primary-text)}.osl-btn--outline-secondary{background-color:transparent;border:1.5px solid var(--osl-secondary);color:var(--osl-secondary)}.osl-btn--outline-secondary:hover:not(:disabled){background-color:var(--osl-secondary);color:var(--osl-secondary-text)}.osl-btn--outline-success{background-color:transparent;border:1.5px solid var(--osl-success);color:var(--osl-success)}.osl-btn--outline-success:hover:not(:disabled){background-color:var(--osl-success);color:var(--osl-success-text)}.osl-btn--outline-danger{background-color:transparent;border:1.5px solid var(--osl-danger);color:var(--osl-danger)}.osl-btn--outline-danger:hover:not(:disabled){background-color:var(--osl-danger);color:var(--osl-danger-text)}.osl-btn--outline-warning{background-color:transparent;border:1.5px solid var(--osl-warning);color:var(--osl-warning)}.osl-btn--outline-warning:hover:not(:disabled){background-color:var(--osl-warning);color:var(--osl-warning-text)}.osl-btn--outline-info{background-color:transparent;border:1.5px solid var(--osl-info);color:var(--osl-info)}.osl-btn--outline-info:hover:not(:disabled){background-color:var(--osl-info);color:var(--osl-info-text)}.osl-btn__spinner{display:inline-block;width:var(--osl-label-font-size);height:var(--osl-label-font-size);border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:osl-spin .7s linear infinite}@keyframes osl-spin{to{transform:rotate(360deg)}}.osl-btn__label-icon{color:var(--color-white)}.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid var(--osl-border-color);border-radius:var(--osl-border-radius);background:transparent;color:#6b7280;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s;margin:0 2px}.icon-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.icon-btn:hover{border-color:var(--osl-primary);color:var(--osl-primary);background:#6366f10f}.icon-btn--danger:hover{border-color:#ef4444;color:#ef4444;background:#ef44440f}\n"], dependencies: [{ kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
2569
|
+
}
|
|
2570
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslButton, decorators: [{
|
|
2571
|
+
type: Component,
|
|
2572
|
+
args: [{ selector: 'osl-button', standalone: false, template: "@if (variant == 'icon' && icon) {\r\n <button class=\"icon-btn\" [type]=\"type\" [disabled]=\"disabled || loading\" (click)=\"onClick()\">\r\n @if (loading) {\r\n <span class=\"osl-btn__spinner\"></span>\r\n } @else {\r\n <mat-icon>{{ icon }}</mat-icon>\r\n }\r\n </button>\r\n} @else {\r\n <button [class]=\"classes\" [type]=\"type\" [disabled]=\"disabled || loading\" (click)=\"onClick()\">\r\n @if (loading) {\r\n <span class=\"osl-btn__spinner\"></span>\r\n }\r\n <span class=\"osl-btn__label\">{{ label }}</span>\r\n @if (icon) {\r\n <span class=\"osl-btn__label-icon\"\r\n ><mat-icon>{{ icon }}</mat-icon></span\r\n >\r\n }\r\n </button>\r\n}\r\n", styles: ["@charset \"UTF-8\";.osl-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:none;border-radius:var(--osl-border-radius);cursor:pointer;font-size:var(--osl-label-font-size);font-weight:500;line-height:1;transition:background-color .2s ease,border-color .2s ease,opacity .2s ease;white-space:nowrap;outline:none}.osl-btn--sm{height:28px;padding:0 var(--osl-hint-font-size);font-size:var(--osl-hint-font-size)}.osl-btn--sm mat-icon{font-size:var(--osl-hint-font-size)}.osl-btn--md{height:36px;padding:0 18px;font-size:var(--osl-label-font-size)}.osl-btn--lg{height:44px;padding:0 24px;font-size:16px}.osl-btn--full{width:100%}.osl-btn:disabled{opacity:var(--osl-disabled-opacity);cursor:not-allowed}.osl-btn--primary{background-color:var(--osl-primary);color:var(--osl-primary-text)}.osl-btn--primary:hover:not(:disabled){background-color:var(--osl-primary-hover)}.osl-btn--secondary{background-color:var(--osl-secondary);color:var(--osl-secondary-text)}.osl-btn--secondary:hover:not(:disabled){background-color:var(--osl-secondary-hover)}.osl-btn--success{background-color:var(--osl-success);color:var(--osl-success-text)}.osl-btn--success:hover:not(:disabled){background-color:var(--osl-success-hover)}.osl-btn--danger{background-color:var(--osl-danger);color:var(--osl-danger-text)}.osl-btn--danger:hover:not(:disabled){background-color:var(--osl-danger-hover)}.osl-btn--warning{background-color:var(--osl-warning);color:var(--osl-warning-text)}.osl-btn--warning:hover:not(:disabled){background-color:var(--osl-warning-hover)}.osl-btn--info{background-color:var(--osl-info);color:var(--osl-info-text)}.osl-btn--info:hover:not(:disabled){background-color:var(--osl-info-hover)}.osl-btn--outline-primary{background-color:transparent;border:1.5px solid var(--osl-primary);color:var(--osl-primary)}.osl-btn--outline-primary:hover:not(:disabled){background-color:var(--osl-primary);color:var(--osl-primary-text)}.osl-btn--outline-secondary{background-color:transparent;border:1.5px solid var(--osl-secondary);color:var(--osl-secondary)}.osl-btn--outline-secondary:hover:not(:disabled){background-color:var(--osl-secondary);color:var(--osl-secondary-text)}.osl-btn--outline-success{background-color:transparent;border:1.5px solid var(--osl-success);color:var(--osl-success)}.osl-btn--outline-success:hover:not(:disabled){background-color:var(--osl-success);color:var(--osl-success-text)}.osl-btn--outline-danger{background-color:transparent;border:1.5px solid var(--osl-danger);color:var(--osl-danger)}.osl-btn--outline-danger:hover:not(:disabled){background-color:var(--osl-danger);color:var(--osl-danger-text)}.osl-btn--outline-warning{background-color:transparent;border:1.5px solid var(--osl-warning);color:var(--osl-warning)}.osl-btn--outline-warning:hover:not(:disabled){background-color:var(--osl-warning);color:var(--osl-warning-text)}.osl-btn--outline-info{background-color:transparent;border:1.5px solid var(--osl-info);color:var(--osl-info)}.osl-btn--outline-info:hover:not(:disabled){background-color:var(--osl-info);color:var(--osl-info-text)}.osl-btn__spinner{display:inline-block;width:var(--osl-label-font-size);height:var(--osl-label-font-size);border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:osl-spin .7s linear infinite}@keyframes osl-spin{to{transform:rotate(360deg)}}.osl-btn__label-icon{color:var(--color-white)}.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid var(--osl-border-color);border-radius:var(--osl-border-radius);background:transparent;color:#6b7280;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s;margin:0 2px}.icon-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.icon-btn:hover{border-color:var(--osl-primary);color:var(--osl-primary);background:#6366f10f}.icon-btn--danger:hover{border-color:#ef4444;color:#ef4444;background:#ef44440f}\n"] }]
|
|
2573
|
+
}], propDecorators: { label: [{
|
|
2574
|
+
type: Input,
|
|
2575
|
+
args: ['label']
|
|
2576
|
+
}], icon: [{
|
|
2577
|
+
type: Input,
|
|
2578
|
+
args: ['icon']
|
|
2579
|
+
}], variant: [{
|
|
2580
|
+
type: Input,
|
|
2581
|
+
args: ['variant']
|
|
2582
|
+
}], size: [{
|
|
2583
|
+
type: Input,
|
|
2584
|
+
args: ['size']
|
|
2585
|
+
}], disabled: [{
|
|
2586
|
+
type: Input,
|
|
2587
|
+
args: ['disabled']
|
|
2588
|
+
}], loading: [{
|
|
2589
|
+
type: Input,
|
|
2590
|
+
args: ['loading']
|
|
2591
|
+
}], type: [{
|
|
2592
|
+
type: Input,
|
|
2593
|
+
args: ['type']
|
|
2594
|
+
}], fullWidth: [{
|
|
2595
|
+
type: Input,
|
|
2596
|
+
args: ['fullWidth']
|
|
2597
|
+
}], clickEv: [{
|
|
2598
|
+
type: Output
|
|
2599
|
+
}] } });
|
|
2600
|
+
|
|
2601
|
+
class DynamicForm {
|
|
2602
|
+
cdr;
|
|
2603
|
+
elements = [];
|
|
2604
|
+
_model;
|
|
2605
|
+
set model(val) {
|
|
2606
|
+
this._model = val;
|
|
2607
|
+
}
|
|
2608
|
+
get model() {
|
|
2609
|
+
return this._model;
|
|
2610
|
+
}
|
|
2611
|
+
skeletonLoading = false;
|
|
2612
|
+
skeletonTheme = 'light';
|
|
2613
|
+
modelChange = new EventEmitter();
|
|
2614
|
+
datasourceCache = inject(DatasourceCacheService);
|
|
2615
|
+
constructor(cdr) {
|
|
2616
|
+
this.cdr = cdr;
|
|
2617
|
+
}
|
|
2618
|
+
ngOnInit() {
|
|
2619
|
+
this.loadApiDatasources();
|
|
2620
|
+
}
|
|
2621
|
+
ngOnChanges(changes) {
|
|
2622
|
+
if (changes['elements']) {
|
|
2623
|
+
this.loadApiDatasources();
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
loadApiDatasources() {
|
|
2627
|
+
this._loadForList(this.elements);
|
|
2628
|
+
}
|
|
2629
|
+
async _loadForList(list) {
|
|
2630
|
+
for (const elem of list) {
|
|
2631
|
+
if (elem.elementType === 'fieldset' && elem.rows?.length) {
|
|
2632
|
+
this._loadForList(elem.rows);
|
|
2633
|
+
}
|
|
2634
|
+
else if (elem.apiService && elem.apiMethod && (!elem.searchType || elem.searchType == 'Local')) {
|
|
2635
|
+
elem.loadingIf = () => true;
|
|
2636
|
+
const data = await this.datasourceCache.load(elem.apiService, elem.apiMethod, elem.apiBody ? elem.apiBody(this.model) : null);
|
|
2637
|
+
elem.loadingIf = () => false;
|
|
2638
|
+
this.cdr.markForCheck();
|
|
2639
|
+
if (data && data.length > 0) {
|
|
2640
|
+
elem.datasource = data;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
onModelChange(event, key) {
|
|
2646
|
+
this.model[key] = event;
|
|
2647
|
+
this.modelChange.emit(this.model);
|
|
2648
|
+
}
|
|
2649
|
+
onSelectChange(elem, value) {
|
|
2650
|
+
if (!elem.change)
|
|
2651
|
+
return;
|
|
2652
|
+
let selectedObj = undefined;
|
|
2653
|
+
if (elem.datasource) {
|
|
2654
|
+
if (Array.isArray(value)) {
|
|
2655
|
+
selectedObj = value.map(v => elem.datasource.find(item => (elem.valueField ? item[elem.valueField] : item) === v) ?? null);
|
|
2656
|
+
}
|
|
2657
|
+
else if (value !== null && value !== undefined) {
|
|
2658
|
+
selectedObj = elem.datasource.find(item => (elem.valueField ? item[elem.valueField] : item) === (isNaN(Number(value)) ? value : Number(value))) ?? null;
|
|
2659
|
+
}
|
|
2660
|
+
else {
|
|
2661
|
+
selectedObj = null;
|
|
2662
|
+
}
|
|
2349
2663
|
}
|
|
2350
2664
|
elem.change(this.model, undefined, selectedObj);
|
|
2351
2665
|
}
|
|
2352
2666
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DynamicForm, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2353
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DynamicForm, isStandalone: false, selector: "osl-dynamic-form", inputs: { elements: "elements", model: "model", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { modelChange: "modelChange" }, usesOnChanges: true, ngImport: i0, template: "@if(elements && elements.length > 0) {\r\n <div class=\"row align-items-center w-100\">\r\n @for(elem of elements; track elem) {\r\n @if(!(elem.hideIf ? elem.hideIf(model) : elem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: elem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<ng-template #formField let-elem>\r\n @if(elem.hideIf ? !elem.hideIf(model) : true) {\r\n @switch (elem.elementType) {\r\n\r\n @case (\"textbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-input\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [type]=\"elem.inputType || 'text'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [mask]=\"elem.mask || ''\"\r\n [min]=\"elem.min ?? ''\"\r\n [max]=\"elem.max ?? ''\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [prefixIcon]=\"elem.prefixIcon || ''\"\r\n [suffixIcon]=\"elem.suffixIcon || ''\"\r\n [onlyChars]=\"!!elem.onlyChars\"\r\n [decimalPortion]=\"elem.decimalPortion ?? null\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [isCapitalize]=\"elem.isCapitalize\"\r\n ></osl-input>\r\n </div>\r\n }\r\n\r\n @case (\"textarea\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-textarea\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [rows]=\"elem.textareaRows || 3\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [characterCounter]=\"!!elem.characterCounter\"\r\n [resize]=\"elem.resize || 'none'\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-textarea>\r\n </div>\r\n }\r\n\r\n @case (\"select\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-select\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.selectPlaceholder || 'Select...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n [clearable]=\"!!elem.clearable\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-select>\r\n </div>\r\n }\r\n\r\n @case (\"radio\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-radio\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [inline]=\"!!elem.inline\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-radio>\r\n </div>\r\n }\r\n\r\n @case (\"slide-toggle\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-slide-toggle\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [labelPosition]=\"elem.labelPosition || 'after'\"\r\n [trueLabel]=\"elem.trueLabel || ''\"\r\n [falseLabel]=\"elem.falseLabel || ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-slide-toggle>\r\n </div>\r\n }\r\n\r\n @case (\"autocomplete\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-autocomplete\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [(datasource)]=\"elem.datasource\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.autocompletePlaceholder || 'Type to search...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [methodName]=\"elem.apiMethod\"\r\n [service]=\"elem.apiService\"\r\n [object]=\"model[elem.objectName]\"\r\n [searchType]=\"elem.searchType\"\r\n [configMethodName]=\"elem.apiConfigMethod\"\r\n [isLister]=\"elem.isListerAutocomplete\"\r\n \r\n \r\n ></osl-autocomplete>\r\n </div>\r\n }\r\n\r\n @case (\"file-uploader\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-file-upload\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [accept]=\"elem.accept || ''\"\r\n [multiple]=\"!!elem.multiple\"\r\n [maxSize]=\"elem.maxFileSize || 0\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-file-upload>\r\n </div>\r\n }\r\n\r\n @case (\"datepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [dateType]=\"elem.dateType || 'date'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDate]=\"elem.minDateIf ? elem.minDateIf(model): elem.minDate ? elem.minDate : ''\"\r\n [maxDate]=\"elem.maxDateIf ? elem.maxDateIf(model): elem.maxDate ? elem.maxDate : ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datepicker>\r\n </div>\r\n }\r\n\r\n @case (\"datetimepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datetimepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDatetime]=\"elem.minDatetimeIf ? elem.minDatetimeIf(model) : elem.minDatetime || ''\"\r\n [maxDatetime]=\"elem.maxDatetimeIf ? elem.maxDatetimeIf(model) : elem.maxDatetime || ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datetimepicker>\r\n </div>\r\n }\r\n\r\n @case (\"checkbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-checkbox\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [indeterminate]=\"!!elem.indeterminate\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-checkbox>\r\n </div>\r\n }\r\n\r\n @case (\"button\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-button\r\n \r\n [label]=\"elem.label\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n variant=\"secondary\"\r\n (clickEv)=\"elem.change ? elem.change(model) : null\"\r\n ></osl-button>\r\n </div>\r\n }\r\n\r\n @case (\"fieldset\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <fieldset class=\"osl-fieldset\">\r\n @if(elem.label) {\r\n <legend class=\"osl-fieldset-legend\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\r\n <span class=\"osl-fieldset-legend__text\">{{ elem.label }}</span>\r\n </legend>\r\n }\r\n <div class=\"row w-100 osl-fieldset-body\">\r\n @for(innerElem of elem.rows; track innerElem) {\r\n @if(!(innerElem.hideIf ? innerElem.hideIf(model) : innerElem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: innerElem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n </fieldset>\r\n </div>\r\n }\r\n\r\n @case (\"templateRef\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container>\r\n\r\n \r\n </div>\r\n }\r\n @case (\"spacer\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <!-- <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container> -->\r\n\r\n \r\n </div>\r\n }\r\n\r\n }\r\n }\r\n</ng-template>\r\n", styles: [".osl-fieldset{border:1.5px solid var(--osl-border-color, #e5e7eb);border-radius:10px;padding:0 16px 16px;margin:0;background:linear-gradient(135deg,#f9fafb,#fff);box-shadow:0 1px 4px #0000000d;position:relative;transition:box-shadow .2s}.osl-fieldset:focus-within{box-shadow:0 0 0 3px #6366f114,0 2px 8px #0000000f;border-color:var(--osl-primary, #6366f1)}.osl-fieldset-legend{padding:0 6px;margin-left:8px;line-height:1;float:none;width:auto}.osl-fieldset-legend__text{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;background:#fff;padding:2px 10px;border:1.5px solid var(--osl-border-color, #e5e7eb);box-shadow:0 1px 3px #6366f11a}.osl-fieldset-body{margin-top:4px}\n"], dependencies: [{ kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }, { kind: "component", type: Oslinput, selector: "osl-input", inputs: ["label", "required", "disabled", "model", "type", "placeholder", "mask", "min", "max", "minLength", "maxLength", "prefixIcon", "suffixIcon", "skeletonLoading", "skeletonTheme", "onlyChars", "isCapitalize", "decimalPortion"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: Osltextarea, selector: "osl-textarea", inputs: ["label", "rows", "required", "disabled", "model", "placeholder", "maxLength", "minLength", "characterCounter", "resize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSelect, selector: "osl-select", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "clearable", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslRadio, selector: "osl-radio", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "inline", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSlideToggle, selector: "osl-slide-toggle", inputs: ["label", "disabled", "model", "labelPosition", "trueLabel", "falseLabel", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslAutocomplete, selector: "osl-autocomplete", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "searchType", "methodName", "configMethodName", "service", "object", "skeletonLoading", "skeletonTheme", "isLister"], outputs: ["datasourceChange", "modelChange", "changeEv"] }, { kind: "component", type: OslFileUpload, selector: "osl-file-upload", inputs: ["label", "required", "disabled", "model", "accept", "multiple", "maxSize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatepicker, selector: "osl-datepicker", inputs: ["label", "required", "disabled", "model", "dateType", "placeholder", "minDate", "maxDate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatetimepicker, selector: "osl-datetimepicker", inputs: ["label", "required", "disabled", "model", "placeholder", "minDatetime", "maxDatetime", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslCheckbox, selector: "osl-checkbox", inputs: ["label", "disabled", "required", "model", "indeterminate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslButton, selector: "osl-button", inputs: ["label", "icon", "variant", "size", "disabled", "loading", "type", "fullWidth"], outputs: ["clickEv"] }] });
|
|
2667
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DynamicForm, isStandalone: false, selector: "osl-dynamic-form", inputs: { elements: "elements", model: "model", skeletonLoading: "skeletonLoading", skeletonTheme: "skeletonTheme" }, outputs: { modelChange: "modelChange" }, usesOnChanges: true, ngImport: i0, template: "@if(elements && elements.length > 0) {\r\n <div class=\"row align-items-center w-100\">\r\n @for(elem of elements; track elem) {\r\n @if(!(elem.hideIf ? elem.hideIf(model) : elem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: elem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<ng-template #formField let-elem>\r\n @if(elem.hideIf ? !elem.hideIf(model) : true) {\r\n @switch (elem.elementType) {\r\n\r\n @case (\"textbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-input\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [type]=\"elem.inputType || 'text'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [mask]=\"elem.mask || ''\"\r\n [min]=\"elem.min ?? ''\"\r\n [max]=\"elem.max ?? ''\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [prefixIcon]=\"elem.prefixIcon || ''\"\r\n [suffixIcon]=\"elem.suffixIcon || ''\"\r\n [onlyChars]=\"!!elem.onlyChars\"\r\n [decimalPortion]=\"elem.decimalPortion ?? null\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [isCapitalize]=\"elem.isCapitalize\"\r\n ></osl-input>\r\n </div>\r\n }\r\n\r\n @case (\"textarea\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-textarea\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [rows]=\"elem.textareaRows || 3\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [characterCounter]=\"!!elem.characterCounter\"\r\n [resize]=\"elem.resize || 'none'\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-textarea>\r\n </div>\r\n }\r\n\r\n @case (\"select\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-select\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.selectPlaceholder || 'Select...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n [clearable]=\"!!elem.clearable\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-select>\r\n </div>\r\n }\r\n\r\n @case (\"radio\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-radio\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [inline]=\"!!elem.inline\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-radio>\r\n </div>\r\n }\r\n\r\n @case (\"slide-toggle\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-slide-toggle\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [labelPosition]=\"elem.labelPosition || 'after'\"\r\n [trueLabel]=\"elem.trueLabel || ''\"\r\n [falseLabel]=\"elem.falseLabel || ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-slide-toggle>\r\n </div>\r\n }\r\n\r\n @case (\"autocomplete\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-autocomplete\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [(datasource)]=\"elem.datasource\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.autocompletePlaceholder || 'Type to search...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [methodName]=\"elem.apiMethod\"\r\n [service]=\"elem.apiService\"\r\n [object]=\"model[elem.objectName]\"\r\n [searchType]=\"elem.searchType\"\r\n [configMethodName]=\"elem.apiConfigMethod\"\r\n [isLister]=\"elem.isListerAutocomplete\"\r\n \r\n \r\n ></osl-autocomplete>\r\n </div>\r\n }\r\n\r\n @case (\"file-uploader\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-file-upload\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [accept]=\"elem.accept || ''\"\r\n [multiple]=\"!!elem.multiple\"\r\n [maxSize]=\"elem.maxFileSize || 0\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-file-upload>\r\n </div>\r\n }\r\n\r\n @case (\"datepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [dateType]=\"elem.dateType || 'date'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDate]=\"elem.minDateIf ? elem.minDateIf(model): elem.minDate ? elem.minDate : ''\"\r\n [maxDate]=\"elem.maxDateIf ? elem.maxDateIf(model): elem.maxDate ? elem.maxDate : ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datepicker>\r\n </div>\r\n }\r\n\r\n @case (\"datetimepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datetimepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDatetime]=\"elem.minDatetimeIf ? elem.minDatetimeIf(model) : elem.minDatetime || ''\"\r\n [maxDatetime]=\"elem.maxDatetimeIf ? elem.maxDatetimeIf(model) : elem.maxDatetime || ''\"\r\n [format]=\"elem.datetimepickerFormat || 'YYYY-MM-DDTHH:mm'\"\r\n [showSeconds]=\"!!elem.datetimepickerShowSeconds\"\r\n [enableMeridian]=\"!!elem.datetimepickerEnableMeridian\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datetimepicker>\r\n </div>\r\n }\r\n\r\n @case (\"checkbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-checkbox\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [indeterminate]=\"!!elem.indeterminate\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-checkbox>\r\n </div>\r\n }\r\n\r\n @case (\"button\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-button\r\n \r\n [label]=\"elem.label\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n variant=\"secondary\"\r\n (clickEv)=\"elem.change ? elem.change(model) : null\"\r\n ></osl-button>\r\n </div>\r\n }\r\n\r\n @case (\"fieldset\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <fieldset class=\"osl-fieldset\">\r\n @if(elem.label) {\r\n <legend class=\"osl-fieldset-legend\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\r\n <span class=\"osl-fieldset-legend__text\">{{ elem.label }}</span>\r\n </legend>\r\n }\r\n <div class=\"row w-100 osl-fieldset-body\">\r\n @for(innerElem of elem.rows; track innerElem) {\r\n @if(!(innerElem.hideIf ? innerElem.hideIf(model) : innerElem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: innerElem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n </fieldset>\r\n </div>\r\n }\r\n\r\n @case (\"templateRef\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container>\r\n\r\n \r\n </div>\r\n }\r\n @case (\"spacer\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <!-- <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container> -->\r\n\r\n \r\n </div>\r\n }\r\n\r\n }\r\n }\r\n</ng-template>\r\n", styles: [".osl-fieldset{border:1.5px solid var(--osl-border-color, #e5e7eb);border-radius:10px;padding:0 16px 16px;margin:0;background:linear-gradient(135deg,#f9fafb,#fff);box-shadow:0 1px 4px #0000000d;position:relative;transition:box-shadow .2s}.osl-fieldset:focus-within{box-shadow:0 0 0 3px #6366f114,0 2px 8px #0000000f;border-color:var(--osl-primary, #6366f1)}.osl-fieldset-legend{padding:0 6px;margin-left:8px;line-height:1;float:none;width:auto}.osl-fieldset-legend__text{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;background:#fff;padding:2px 10px;border:1.5px solid var(--osl-border-color, #e5e7eb);box-shadow:0 1px 3px #6366f11a}.osl-fieldset-body{margin-top:4px}\n"], dependencies: [{ kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: OslSkeletonDirective, selector: "[oslSkeleton]", inputs: ["oslSkeleton", "oslSkeletonType", "oslSkeletonAnimation", "oslSkeletonTheme", "oslSkeletonColor", "oslSkeletonHighlight", "oslSkeletonRadius", "oslSkeletonRows", "oslSkeletonRowGap", "oslSkeletonZIndex", "oslSkeletonDelay", "oslSkeletonDuration", "oslSkeletonMinHeight", "oslSkeletonForceReread", "oslSkeletonCircleSize", "oslSkeletonListItems", "oslSkeletonTableRows", "oslSkeletonTableCols", "oslSkeletonCardLines", "oslSkeletonBgColor"] }, { kind: "component", type: Oslinput, selector: "osl-input", inputs: ["label", "required", "disabled", "model", "type", "placeholder", "mask", "min", "max", "minLength", "maxLength", "prefixIcon", "suffixIcon", "skeletonLoading", "skeletonTheme", "onlyChars", "isCapitalize", "decimalPortion"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: Osltextarea, selector: "osl-textarea", inputs: ["label", "rows", "required", "disabled", "model", "placeholder", "maxLength", "minLength", "characterCounter", "resize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSelect, selector: "osl-select", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "clearable", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslRadio, selector: "osl-radio", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "inline", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSlideToggle, selector: "osl-slide-toggle", inputs: ["label", "disabled", "model", "labelPosition", "trueLabel", "falseLabel", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslAutocomplete, selector: "osl-autocomplete", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "searchType", "methodName", "configMethodName", "service", "object", "skeletonLoading", "skeletonTheme", "isLister"], outputs: ["datasourceChange", "modelChange", "changeEv"] }, { kind: "component", type: OslFileUpload, selector: "osl-file-upload", inputs: ["label", "required", "disabled", "model", "accept", "multiple", "maxSize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatepicker, selector: "osl-datepicker", inputs: ["label", "required", "disabled", "model", "dateType", "placeholder", "minDate", "maxDate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatetimepicker, selector: "osl-datetimepicker", inputs: ["label", "required", "disabled", "model", "placeholder", "minDatetime", "maxDatetime", "format", "showSeconds", "enableMeridian", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslCheckbox, selector: "osl-checkbox", inputs: ["label", "disabled", "required", "model", "indeterminate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslButton, selector: "osl-button", inputs: ["label", "icon", "variant", "size", "disabled", "loading", "type", "fullWidth"], outputs: ["clickEv"] }] });
|
|
2354
2668
|
}
|
|
2355
2669
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DynamicForm, decorators: [{
|
|
2356
2670
|
type: Component,
|
|
2357
|
-
args: [{ selector: 'osl-dynamic-form', standalone: false, template: "@if(elements && elements.length > 0) {\r\n <div class=\"row align-items-center w-100\">\r\n @for(elem of elements; track elem) {\r\n @if(!(elem.hideIf ? elem.hideIf(model) : elem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: elem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<ng-template #formField let-elem>\r\n @if(elem.hideIf ? !elem.hideIf(model) : true) {\r\n @switch (elem.elementType) {\r\n\r\n @case (\"textbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-input\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [type]=\"elem.inputType || 'text'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [mask]=\"elem.mask || ''\"\r\n [min]=\"elem.min ?? ''\"\r\n [max]=\"elem.max ?? ''\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [prefixIcon]=\"elem.prefixIcon || ''\"\r\n [suffixIcon]=\"elem.suffixIcon || ''\"\r\n [onlyChars]=\"!!elem.onlyChars\"\r\n [decimalPortion]=\"elem.decimalPortion ?? null\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [isCapitalize]=\"elem.isCapitalize\"\r\n ></osl-input>\r\n </div>\r\n }\r\n\r\n @case (\"textarea\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-textarea\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [rows]=\"elem.textareaRows || 3\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [characterCounter]=\"!!elem.characterCounter\"\r\n [resize]=\"elem.resize || 'none'\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-textarea>\r\n </div>\r\n }\r\n\r\n @case (\"select\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-select\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.selectPlaceholder || 'Select...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n [clearable]=\"!!elem.clearable\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-select>\r\n </div>\r\n }\r\n\r\n @case (\"radio\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-radio\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [inline]=\"!!elem.inline\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-radio>\r\n </div>\r\n }\r\n\r\n @case (\"slide-toggle\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-slide-toggle\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [labelPosition]=\"elem.labelPosition || 'after'\"\r\n [trueLabel]=\"elem.trueLabel || ''\"\r\n [falseLabel]=\"elem.falseLabel || ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-slide-toggle>\r\n </div>\r\n }\r\n\r\n @case (\"autocomplete\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-autocomplete\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [(datasource)]=\"elem.datasource\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.autocompletePlaceholder || 'Type to search...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [methodName]=\"elem.apiMethod\"\r\n [service]=\"elem.apiService\"\r\n [object]=\"model[elem.objectName]\"\r\n [searchType]=\"elem.searchType\"\r\n [configMethodName]=\"elem.apiConfigMethod\"\r\n [isLister]=\"elem.isListerAutocomplete\"\r\n \r\n \r\n ></osl-autocomplete>\r\n </div>\r\n }\r\n\r\n @case (\"file-uploader\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-file-upload\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [accept]=\"elem.accept || ''\"\r\n [multiple]=\"!!elem.multiple\"\r\n [maxSize]=\"elem.maxFileSize || 0\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-file-upload>\r\n </div>\r\n }\r\n\r\n @case (\"datepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [dateType]=\"elem.dateType || 'date'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDate]=\"elem.minDateIf ? elem.minDateIf(model): elem.minDate ? elem.minDate : ''\"\r\n [maxDate]=\"elem.maxDateIf ? elem.maxDateIf(model): elem.maxDate ? elem.maxDate : ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datepicker>\r\n </div>\r\n }\r\n\r\n @case (\"datetimepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datetimepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDatetime]=\"elem.minDatetimeIf ? elem.minDatetimeIf(model) : elem.minDatetime || ''\"\r\n [maxDatetime]=\"elem.maxDatetimeIf ? elem.maxDatetimeIf(model) : elem.maxDatetime || ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datetimepicker>\r\n </div>\r\n }\r\n\r\n @case (\"checkbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-checkbox\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [indeterminate]=\"!!elem.indeterminate\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-checkbox>\r\n </div>\r\n }\r\n\r\n @case (\"button\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-button\r\n \r\n [label]=\"elem.label\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n variant=\"secondary\"\r\n (clickEv)=\"elem.change ? elem.change(model) : null\"\r\n ></osl-button>\r\n </div>\r\n }\r\n\r\n @case (\"fieldset\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <fieldset class=\"osl-fieldset\">\r\n @if(elem.label) {\r\n <legend class=\"osl-fieldset-legend\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\r\n <span class=\"osl-fieldset-legend__text\">{{ elem.label }}</span>\r\n </legend>\r\n }\r\n <div class=\"row w-100 osl-fieldset-body\">\r\n @for(innerElem of elem.rows; track innerElem) {\r\n @if(!(innerElem.hideIf ? innerElem.hideIf(model) : innerElem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: innerElem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n </fieldset>\r\n </div>\r\n }\r\n\r\n @case (\"templateRef\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container>\r\n\r\n \r\n </div>\r\n }\r\n @case (\"spacer\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <!-- <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container> -->\r\n\r\n \r\n </div>\r\n }\r\n\r\n }\r\n }\r\n</ng-template>\r\n", styles: [".osl-fieldset{border:1.5px solid var(--osl-border-color, #e5e7eb);border-radius:10px;padding:0 16px 16px;margin:0;background:linear-gradient(135deg,#f9fafb,#fff);box-shadow:0 1px 4px #0000000d;position:relative;transition:box-shadow .2s}.osl-fieldset:focus-within{box-shadow:0 0 0 3px #6366f114,0 2px 8px #0000000f;border-color:var(--osl-primary, #6366f1)}.osl-fieldset-legend{padding:0 6px;margin-left:8px;line-height:1;float:none;width:auto}.osl-fieldset-legend__text{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;background:#fff;padding:2px 10px;border:1.5px solid var(--osl-border-color, #e5e7eb);box-shadow:0 1px 3px #6366f11a}.osl-fieldset-body{margin-top:4px}\n"] }]
|
|
2671
|
+
args: [{ selector: 'osl-dynamic-form', standalone: false, template: "@if(elements && elements.length > 0) {\r\n <div class=\"row align-items-center w-100\">\r\n @for(elem of elements; track elem) {\r\n @if(!(elem.hideIf ? elem.hideIf(model) : elem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: elem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n}\r\n\r\n<ng-template #formField let-elem>\r\n @if(elem.hideIf ? !elem.hideIf(model) : true) {\r\n @switch (elem.elementType) {\r\n\r\n @case (\"textbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-input\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [type]=\"elem.inputType || 'text'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [mask]=\"elem.mask || ''\"\r\n [min]=\"elem.min ?? ''\"\r\n [max]=\"elem.max ?? ''\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [prefixIcon]=\"elem.prefixIcon || ''\"\r\n [suffixIcon]=\"elem.suffixIcon || ''\"\r\n [onlyChars]=\"!!elem.onlyChars\"\r\n [decimalPortion]=\"elem.decimalPortion ?? null\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [isCapitalize]=\"elem.isCapitalize\"\r\n ></osl-input>\r\n </div>\r\n }\r\n\r\n @case (\"textarea\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-textarea\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [rows]=\"elem.textareaRows || 3\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [maxLength]=\"elem.maxLength ?? null\"\r\n [minLength]=\"elem.minLength ?? null\"\r\n [characterCounter]=\"!!elem.characterCounter\"\r\n [resize]=\"elem.resize || 'none'\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-textarea>\r\n </div>\r\n }\r\n\r\n @case (\"select\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-select\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.selectPlaceholder || 'Select...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n [clearable]=\"!!elem.clearable\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-select>\r\n </div>\r\n }\r\n\r\n @case (\"radio\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-radio\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [datasource]=\"elem.datasource || []\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [inline]=\"!!elem.inline\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-radio>\r\n </div>\r\n }\r\n\r\n @case (\"slide-toggle\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-slide-toggle\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [labelPosition]=\"elem.labelPosition || 'after'\"\r\n [trueLabel]=\"elem.trueLabel || ''\"\r\n [falseLabel]=\"elem.falseLabel || ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-slide-toggle>\r\n </div>\r\n }\r\n\r\n @case (\"autocomplete\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-autocomplete\r\n [label]=\"elem.label\"\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [(datasource)]=\"elem.datasource\"\r\n [displayField]=\"elem.displayField || ''\"\r\n [valueField]=\"elem.valueField || ''\"\r\n [placeholder]=\"elem.autocompletePlaceholder || 'Type to search...'\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n (changeEv)=\"elem.change ? onSelectChange(elem, $event) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n [methodName]=\"elem.apiMethod\"\r\n [service]=\"elem.apiService\"\r\n [object]=\"model[elem.objectName]\"\r\n [searchType]=\"elem.searchType\"\r\n [configMethodName]=\"elem.apiConfigMethod\"\r\n [isLister]=\"elem.isListerAutocomplete\"\r\n \r\n \r\n ></osl-autocomplete>\r\n </div>\r\n }\r\n\r\n @case (\"file-uploader\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-file-upload\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [accept]=\"elem.accept || ''\"\r\n [multiple]=\"!!elem.multiple\"\r\n [maxSize]=\"elem.maxFileSize || 0\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-file-upload>\r\n </div>\r\n }\r\n\r\n @case (\"datepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [dateType]=\"elem.dateType || 'date'\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDate]=\"elem.minDateIf ? elem.minDateIf(model): elem.minDate ? elem.minDate : ''\"\r\n [maxDate]=\"elem.maxDateIf ? elem.maxDateIf(model): elem.maxDate ? elem.maxDate : ''\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datepicker>\r\n </div>\r\n }\r\n\r\n @case (\"datetimepicker\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-datetimepicker\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [placeholder]=\"elem.placeholder || ''\"\r\n [minDatetime]=\"elem.minDatetimeIf ? elem.minDatetimeIf(model) : elem.minDatetime || ''\"\r\n [maxDatetime]=\"elem.maxDatetimeIf ? elem.maxDatetimeIf(model) : elem.maxDatetime || ''\"\r\n [format]=\"elem.datetimepickerFormat || 'YYYY-MM-DDTHH:mm'\"\r\n [showSeconds]=\"!!elem.datetimepickerShowSeconds\"\r\n [enableMeridian]=\"!!elem.datetimepickerEnableMeridian\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-datetimepicker>\r\n </div>\r\n }\r\n\r\n @case (\"checkbox\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-checkbox\r\n [skeletonLoading]=\"skeletonLoading\"\r\n [skeletonTheme]=\"skeletonTheme\"\r\n\r\n [label]=\"elem.label\"\r\n [disabled]=\"elem.disabledIf ? elem.disabledIf(model) : !!elem.disabled\"\r\n [required]=\"elem.requiredIf ? elem.requiredIf(model) : !!elem.required\"\r\n [indeterminate]=\"!!elem.indeterminate\"\r\n (changeEv)=\"elem.change ? elem.change(model) : null\"\r\n [(model)]=\"model[elem.key]\"\r\n ></osl-checkbox>\r\n </div>\r\n }\r\n\r\n @case (\"button\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-2'\">\r\n <osl-button\r\n \r\n [label]=\"elem.label\"\r\n [loading]=\"elem.loadingIf ? elem.loadingIf(model) : false\"\r\n variant=\"secondary\"\r\n (clickEv)=\"elem.change ? elem.change(model) : null\"\r\n ></osl-button>\r\n </div>\r\n }\r\n\r\n @case (\"fieldset\") {\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <fieldset class=\"osl-fieldset\">\r\n @if(elem.label) {\r\n <legend class=\"osl-fieldset-legend\" [oslSkeleton]=\"skeletonLoading\" [oslSkeletonTheme]=\"skeletonTheme\">\r\n <span class=\"osl-fieldset-legend__text\">{{ elem.label }}</span>\r\n </legend>\r\n }\r\n <div class=\"row w-100 osl-fieldset-body\">\r\n @for(innerElem of elem.rows; track innerElem) {\r\n @if(!(innerElem.hideIf ? innerElem.hideIf(model) : innerElem.hide)) {\r\n <ng-container *ngTemplateOutlet=\"formField; context: { $implicit: innerElem }\"></ng-container>\r\n }\r\n }\r\n </div>\r\n </fieldset>\r\n </div>\r\n }\r\n\r\n @case (\"templateRef\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container>\r\n\r\n \r\n </div>\r\n }\r\n @case (\"spacer\"){\r\n <div [class]=\"'col-md-'+elem.columns+' mt-3'\">\r\n <!-- <ng-container *ngTemplateOutlet=\"elem.templateRef; context: { $implicit: elem}\"></ng-container> -->\r\n\r\n \r\n </div>\r\n }\r\n\r\n }\r\n }\r\n</ng-template>\r\n", styles: [".osl-fieldset{border:1.5px solid var(--osl-border-color, #e5e7eb);border-radius:10px;padding:0 16px 16px;margin:0;background:linear-gradient(135deg,#f9fafb,#fff);box-shadow:0 1px 4px #0000000d;position:relative;transition:box-shadow .2s}.osl-fieldset:focus-within{box-shadow:0 0 0 3px #6366f114,0 2px 8px #0000000f;border-color:var(--osl-primary, #6366f1)}.osl-fieldset-legend{padding:0 6px;margin-left:8px;line-height:1;float:none;width:auto}.osl-fieldset-legend__text{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;background:#fff;padding:2px 10px;border:1.5px solid var(--osl-border-color, #e5e7eb);box-shadow:0 1px 3px #6366f11a}.osl-fieldset-body{margin-top:4px}\n"] }]
|
|
2358
2672
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { elements: [{
|
|
2359
2673
|
type: Input,
|
|
2360
2674
|
args: ['elements']
|
|
@@ -3401,11 +3715,11 @@ class OslFormGrid {
|
|
|
3401
3715
|
elem.change(row, i, selectedObj);
|
|
3402
3716
|
}
|
|
3403
3717
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslFormGrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3404
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslFormGrid, isStandalone: false, selector: "osl-form-grid", inputs: { columns: "columns", datasource: "datasource", isPaginated: "isPaginated", pageSize: "pageSize", canAdd: "canAdd", canDelete: "canDelete", loading: "loading", tableHeight: "tableHeight", footerColumns: "footerColumns" }, outputs: { datasourceChange: "datasourceChange", rowAdd: "rowAdd", rowDelete: "rowDelete" }, ngImport: i0, template: "<div class=\"osl-fg-wrapper\">\r\n\r\n <div class=\"osl-fg-table-container\" [style.height]=\"tableHeight\">\r\n <table class=\"osl-fg-table\">\r\n\r\n <thead class=\"osl-fg-thead\">\r\n <tr>\r\n <!-- Actions column: + add button in header -->\r\n @if (hasActions) {\r\n <th class=\"osl-fg-th osl-fg-th--actions\">\r\n @if (canAdd) {\r\n <button class=\"osl-grid-icon-btn\" (click)=\"addRow()\" [disabled]=\"loading\" title=\"Add row\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n </th>\r\n }\r\n @for (col of columns; track col.key) {\r\n <th class=\"osl-fg-th\" [style.width]=\"col.width\">\r\n {{ col.displayName }}\r\n @if (colRequired(col)) {\r\n <span class=\"osl-fg-th-required\">*</span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n\r\n @if (loading) {\r\n @for (sk of skeletonRows; track $index) {\r\n <tr class=\"osl-fg-row osl-fg-row--skeleton\">\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n <div class=\"osl-fg-skeleton osl-fg-skeleton--sm\"></div>\r\n </td>\r\n }\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\"><div class=\"osl-fg-skeleton\"></div></td>\r\n }\r\n </tr>\r\n }\r\n\r\n } @else if (pagedData.length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columns.length + (hasActions ? 1 : 0)\" class=\"osl-fg-empty\">\r\n <div class=\"osl-fg-empty-inner\">\r\n <svg width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>\r\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/>\r\n <line x1=\"9\" y1=\"9\" x2=\"9\" y2=\"21\"/>\r\n </svg>\r\n <p>No rows yet.{{ canAdd ? ' Use + to get started.' : '' }}</p>\r\n </div>\r\n </td>\r\n </tr>\r\n\r\n } @else {\r\n @for (row of pagedData; track $index; let i = $index) {\r\n <tr class=\"osl-fg-row\">\r\n\r\n <!-- Delete button first -->\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n @if (canDelete) {\r\n <button class=\"osl-grid-icon-btn osl-grid-icon-btn--danger\" (click)=\"deleteRow(i)\" title=\"Delete\">\r\n <mat-icon>delete_outline</mat-icon>\r\n </button>\r\n }\r\n </td>\r\n }\r\n\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\" [style.width]=\"col.width\">\r\n @if (col.formElem) {\r\n <div class=\"osl-fg-cell-form\" [style.width]=\"col.width\">\r\n @switch (col.formElem.elementType) {\r\n\r\n @case ('textbox') {\r\n <osl-input\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [type]=\"col.formElem.inputType || 'text'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [mask]=\"col.formElem.mask || ''\"\r\n [min]=\"col.formElem.min ?? ''\"\r\n [max]=\"col.formElem.max ?? ''\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [prefixIcon]=\"col.formElem.prefixIcon || ''\"\r\n [suffixIcon]=\"col.formElem.suffixIcon || ''\"\r\n [decimalPortion]=\"col.formElem.decimalPortion ?? null\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-input>\r\n }\r\n\r\n @case ('textarea') {\r\n <osl-textarea\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [rows]=\"col.formElem.textareaRows || 3\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [characterCounter]=\"!!col.formElem.characterCounter\"\r\n [resize]=\"col.formElem.resize || 'none'\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-textarea>\r\n }\r\n\r\n @case ('select') {\r\n <osl-select\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.selectPlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [clearable]=\"!!col.formElem.clearable\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-select>\r\n }\r\n\r\n @case ('autocomplete') {\r\n <osl-autocomplete\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.autocompletePlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [searchType]=\"col.formElem.searchType ? col.formElem.searchType : 'Local'\"\r\n [methodName]=\"col.formElem.apiMethod || ''\"\r\n [configMethodName]=\"col.formElem.apiConfigMethod || ''\"\r\n [service]=\"col.formElem.apiService\"\r\n [object]=\"col.formElem.objectName ? row[col.formElem.objectName] : null\"\r\n [isLister]=\"!!col.formElem.isListerAutocomplete\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-autocomplete>\r\n }\r\n\r\n @case ('radio') {\r\n <osl-radio\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [inline]=\"!!col.formElem.inline\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-radio>\r\n }\r\n\r\n @case ('checkbox') {\r\n <osl-checkbox\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [indeterminate]=\"!!col.formElem.indeterminate\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-checkbox>\r\n }\r\n\r\n @case ('slide-toggle') {\r\n <osl-slide-toggle\r\n [label]=\"''\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [labelPosition]=\"col.formElem.labelPosition || 'after'\"\r\n [trueLabel]=\"col.formElem.trueLabel || ''\"\r\n [falseLabel]=\"col.formElem.falseLabel || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-slide-toggle>\r\n }\r\n\r\n @case ('datepicker') {\r\n <osl-datepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [dateType]=\"col.formElem.dateType || 'date'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDate]=\"col.formElem.minDate || ''\"\r\n [maxDate]=\"col.formElem.maxDate || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datepicker>\r\n }\r\n\r\n @case ('datetimepicker') {\r\n <osl-datetimepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDatetime]=\"col.formElem.minDatetime || ''\"\r\n [maxDatetime]=\"col.formElem.maxDatetime || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datetimepicker>\r\n }\r\n\r\n @case ('file-uploader') {\r\n <osl-file-upload\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [accept]=\"col.formElem.accept || ''\"\r\n [multiple]=\"!!col.formElem.multiple\"\r\n [maxSize]=\"col.formElem.maxFileSize || 0\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-file-upload>\r\n }\r\n\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"osl-fg-cell-text\">{{ row[col.key] ?? '--' }}</span>\r\n }\r\n </td>\r\n }\r\n\r\n </tr>\r\n }\r\n }\r\n\r\n </tbody>\r\n\r\n @if (footerColumns && footerColumns.length > 0 && datasource && datasource.length > 0) {\r\n <tfoot class=\"osl-fg-tfoot\">\r\n <tr class=\"osl-fg-footer-row\">\r\n @for (fcol of footerColumns; track $index) {\r\n <td\r\n [class]=\"'osl-fg-footer-td ' + (fcol.class || '')\"\r\n [attr.colspan]=\"fcol.colspan || 1\">\r\n {{ fcol.displayFn ? fcol.displayFn(datasource) : (fcol.display || '') }}\r\n </td>\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n\r\n @if (isPaginated) {\r\n <div class=\"osl-fg-pagination\">\r\n\r\n <span class=\"osl-fg-pagination__info\">\r\n @if (loading) {\r\n Loading...\r\n } @else if (_total > 0) {\r\n {{ startRecord }}\u2013{{ endRecord }} of {{ _total }} rows\r\n } @else {\r\n No rows\r\n }\r\n </span>\r\n\r\n <div class=\"osl-fg-pagination__controls\">\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(1)\" [disabled]=\"currentPage === 1 || loading\">\u00AB</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1 || loading\">\u2039 Prev</button>\r\n\r\n @for (page of pageNumbers; track $index) {\r\n @if (page === -1) {\r\n <span class=\"osl-fg-page-ellipsis\">\u2026</span>\r\n } @else {\r\n <button\r\n class=\"osl-fg-page-btn osl-fg-page-btn--num\"\r\n [class.osl-fg-page-btn--active]=\"page === currentPage\"\r\n [disabled]=\"loading\"\r\n (click)=\"goToPage(page)\">\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage === totalPages || loading\">Next \u203A</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(totalPages)\" [disabled]=\"currentPage === totalPages || loading\">\u00BB</button>\r\n </div>\r\n\r\n <div class=\"osl-fg-pagination__size\">\r\n <select class=\"osl-fg-page-size\" [ngModel]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\" [disabled]=\"loading\">\r\n @for (opt of pageSizeOptions; track opt) {\r\n <option [value]=\"opt\">{{ opt }} per page</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n</div>\r\n", styles: [".osl-fg-wrapper{display:flex;flex-direction:column;width:100%;font-size:var(--osl-text-font-size);font-family:inherit;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 8px);overflow:hidden;background:#fff}.osl-fg-table-container{overflow-x:auto;overflow-y:auto;min-height:120px}.osl-fg-table{width:100%;border-collapse:collapse;table-layout:auto}.osl-fg-thead{position:sticky;top:0;z-index:2}.osl-fg-th{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-bottom:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-th:last-child{border-right:none}.osl-fg-th--actions{width:44px;min-width:44px;text-align:center;padding:6px}.osl-fg-th-required{color:#ef4444;margin-left:2px;font-size:14px;line-height:1;vertical-align:middle}.osl-fg-row{border-bottom:1px solid #f0f0f0;transition:background .1s}.osl-fg-row:nth-child(odd){background:#f8fafc}.osl-fg-row:nth-child(2n){background:#fff}.osl-fg-row:hover{background:#eef2ff!important}.osl-fg-row:last-child{border-bottom:none}.osl-fg-row--skeleton{pointer-events:none}.osl-fg-td{padding:4px 10px;vertical-align:middle;border-right:1px solid #f0f0f0}.osl-fg-td:last-child{border-right:none}.osl-fg-td--actions{width:44px;min-width:44px;text-align:center;padding:4px 6px}.osl-fg-cell-form{min-width:100px}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field,.osl-fg-cell-form ::ng-deep mat-form-field{width:100%}.osl-fg-cell-form ::ng-deep .mat-mdc-text-field-wrapper{padding-top:0}.osl-fg-cell-text{color:#111827;font-size:var(--osl-text-font-size)}.osl-fg-add-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;border-radius:6px;background:var(--osl-primary, #6366f1);color:#fff;cursor:pointer;padding:0;box-shadow:0 1px 4px #6366f159;transition:background .15s,box-shadow .15s,transform .1s}.osl-fg-add-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.osl-fg-add-btn:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);box-shadow:0 2px 8px #6366f173;transform:scale(1.05)}.osl-fg-add-btn:disabled{opacity:.4;cursor:not-allowed;transform:none}.osl-fg-delete-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid transparent;border-radius:6px;background:transparent;color:#d1d5db;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s}.osl-fg-delete-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-fg-delete-btn:hover{border-color:#fca5a5;color:#ef4444;background:#fef2f2}.osl-fg-empty{padding:40px 16px;text-align:center}.osl-fg-empty-inner{display:flex;flex-direction:column;align-items:center;gap:10px;color:#9ca3af}.osl-fg-empty-inner svg{opacity:.4}.osl-fg-empty-inner p{margin:0;font-size:13px}@keyframes osl-fg-pulse{0%,to{opacity:1}50%{opacity:.4}}.osl-fg-skeleton{height:36px;border-radius:6px;background:#e5e7eb;animation:osl-fg-pulse 1.4s ease-in-out infinite}.osl-fg-skeleton--sm{height:28px;width:28px;border-radius:4px;margin:0 auto}.osl-fg-tfoot{position:sticky;bottom:0;z-index:2}.osl-fg-footer-td{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-top:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-footer-td:last-child{border-right:none}.osl-fg-pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 16px;border-top:1px solid var(--osl-border-color, #e5e7eb);background:#f9fafb;flex-shrink:0;flex-wrap:wrap}.osl-fg-pagination__info{font-size:12px;color:#6b7280;white-space:nowrap;min-width:120px}.osl-fg-pagination__controls{display:flex;align-items:center;gap:3px;flex-wrap:nowrap}.osl-fg-pagination__size{display:flex;align-items:center;justify-content:flex-end;min-width:120px}.osl-fg-page-btn{display:inline-flex;align-items:center;justify-content:center;height:30px;padding:0 10px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:13px;font-family:inherit;cursor:pointer;transition:background .12s,border-color .12s,color .12s;white-space:nowrap}.osl-fg-page-btn:hover:not(:disabled){background:#f3f4f6;border-color:#9ca3af}.osl-fg-page-btn:disabled{opacity:.35;cursor:not-allowed}.osl-fg-page-btn--nav{font-size:12px;color:#6b7280}.osl-fg-page-btn--num{min-width:30px;padding:0;font-size:13px}.osl-fg-page-btn--active{background:var(--osl-primary, #6366f1);border-color:var(--osl-primary, #6366f1);color:#fff;font-weight:600}.osl-fg-page-btn--active:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);border-color:var(--osl-primary-hover, #4f46e5)}.osl-fg-page-ellipsis{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;color:#9ca3af;font-size:13px;pointer-events:none}.osl-fg-page-size{height:30px;padding:0 8px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:12px;font-family:inherit;cursor:pointer;outline:none}.osl-fg-page-size:focus{border-color:var(--osl-primary, #6366f1)}.osl-fg-page-size:disabled{opacity:.4;cursor:not-allowed}.osl-grid-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid var(--osl-border-color);border-radius:var(--osl-border-radius);background:transparent;color:#6b7280;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s;margin:0 2px}.osl-grid-icon-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-grid-icon-btn:hover{border-color:var(--osl-primary);color:var(--osl-primary);background:#6366f10f}.osl-grid-icon-btn--danger:hover{border-color:#ef4444;color:#ef4444;background:#ef44440f}\n"], dependencies: [{ kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: Oslinput, selector: "osl-input", inputs: ["label", "required", "disabled", "model", "type", "placeholder", "mask", "min", "max", "minLength", "maxLength", "prefixIcon", "suffixIcon", "skeletonLoading", "skeletonTheme", "onlyChars", "isCapitalize", "decimalPortion"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: Osltextarea, selector: "osl-textarea", inputs: ["label", "rows", "required", "disabled", "model", "placeholder", "maxLength", "minLength", "characterCounter", "resize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSelect, selector: "osl-select", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "clearable", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslRadio, selector: "osl-radio", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "inline", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSlideToggle, selector: "osl-slide-toggle", inputs: ["label", "disabled", "model", "labelPosition", "trueLabel", "falseLabel", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslAutocomplete, selector: "osl-autocomplete", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "searchType", "methodName", "configMethodName", "service", "object", "skeletonLoading", "skeletonTheme", "isLister"], outputs: ["datasourceChange", "modelChange", "changeEv"] }, { kind: "component", type: OslFileUpload, selector: "osl-file-upload", inputs: ["label", "required", "disabled", "model", "accept", "multiple", "maxSize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatepicker, selector: "osl-datepicker", inputs: ["label", "required", "disabled", "model", "dateType", "placeholder", "minDate", "maxDate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatetimepicker, selector: "osl-datetimepicker", inputs: ["label", "required", "disabled", "model", "placeholder", "minDatetime", "maxDatetime", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslCheckbox, selector: "osl-checkbox", inputs: ["label", "disabled", "required", "model", "indeterminate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }] });
|
|
3718
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: OslFormGrid, isStandalone: false, selector: "osl-form-grid", inputs: { columns: "columns", datasource: "datasource", isPaginated: "isPaginated", pageSize: "pageSize", canAdd: "canAdd", canDelete: "canDelete", loading: "loading", tableHeight: "tableHeight", footerColumns: "footerColumns" }, outputs: { datasourceChange: "datasourceChange", rowAdd: "rowAdd", rowDelete: "rowDelete" }, ngImport: i0, template: "<div class=\"osl-fg-wrapper\">\r\n\r\n <div class=\"osl-fg-table-container\" [style.height]=\"tableHeight\">\r\n <table class=\"osl-fg-table\">\r\n\r\n <thead class=\"osl-fg-thead\">\r\n <tr>\r\n <!-- Actions column: + add button in header -->\r\n @if (hasActions) {\r\n <th class=\"osl-fg-th osl-fg-th--actions\">\r\n @if (canAdd) {\r\n <button class=\"osl-grid-icon-btn\" (click)=\"addRow()\" [disabled]=\"loading\" title=\"Add row\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n </th>\r\n }\r\n @for (col of columns; track col.key) {\r\n <th class=\"osl-fg-th\" [style.width]=\"col.width\">\r\n {{ col.displayName }}\r\n @if (colRequired(col)) {\r\n <span class=\"osl-fg-th-required\">*</span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n\r\n @if (loading) {\r\n @for (sk of skeletonRows; track $index) {\r\n <tr class=\"osl-fg-row osl-fg-row--skeleton\">\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n <div class=\"osl-fg-skeleton osl-fg-skeleton--sm\"></div>\r\n </td>\r\n }\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\"><div class=\"osl-fg-skeleton\"></div></td>\r\n }\r\n </tr>\r\n }\r\n\r\n } @else if (pagedData.length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columns.length + (hasActions ? 1 : 0)\" class=\"osl-fg-empty\">\r\n <div class=\"osl-fg-empty-inner\">\r\n <svg width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>\r\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/>\r\n <line x1=\"9\" y1=\"9\" x2=\"9\" y2=\"21\"/>\r\n </svg>\r\n <p>No rows yet.{{ canAdd ? ' Use + to get started.' : '' }}</p>\r\n </div>\r\n </td>\r\n </tr>\r\n\r\n } @else {\r\n @for (row of pagedData; track $index; let i = $index) {\r\n <tr class=\"osl-fg-row\">\r\n\r\n <!-- Delete button first -->\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n @if (canDelete) {\r\n <button class=\"osl-grid-icon-btn osl-grid-icon-btn--danger\" (click)=\"deleteRow(i)\" title=\"Delete\">\r\n <mat-icon>delete_outline</mat-icon>\r\n </button>\r\n }\r\n </td>\r\n }\r\n\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\" [style.width]=\"col.width\">\r\n @if (col.formElem) {\r\n <div class=\"osl-fg-cell-form\" [style.width]=\"col.width\">\r\n @switch (col.formElem.elementType) {\r\n\r\n @case ('textbox') {\r\n <osl-input\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [type]=\"col.formElem.inputType || 'text'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [mask]=\"col.formElem.mask || ''\"\r\n [min]=\"col.formElem.min ?? ''\"\r\n [max]=\"col.formElem.max ?? ''\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [prefixIcon]=\"col.formElem.prefixIcon || ''\"\r\n [suffixIcon]=\"col.formElem.suffixIcon || ''\"\r\n [decimalPortion]=\"col.formElem.decimalPortion ?? null\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-input>\r\n }\r\n\r\n @case ('textarea') {\r\n <osl-textarea\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [rows]=\"col.formElem.textareaRows || 3\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [characterCounter]=\"!!col.formElem.characterCounter\"\r\n [resize]=\"col.formElem.resize || 'none'\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-textarea>\r\n }\r\n\r\n @case ('select') {\r\n <osl-select\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.selectPlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [clearable]=\"!!col.formElem.clearable\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-select>\r\n }\r\n\r\n @case ('autocomplete') {\r\n <osl-autocomplete\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.autocompletePlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [searchType]=\"col.formElem.searchType ? col.formElem.searchType : 'Local'\"\r\n [methodName]=\"col.formElem.apiMethod || ''\"\r\n [configMethodName]=\"col.formElem.apiConfigMethod || ''\"\r\n [service]=\"col.formElem.apiService\"\r\n [object]=\"col.formElem.objectName ? row[col.formElem.objectName] : null\"\r\n [isLister]=\"!!col.formElem.isListerAutocomplete\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-autocomplete>\r\n }\r\n\r\n @case ('radio') {\r\n <osl-radio\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [inline]=\"!!col.formElem.inline\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-radio>\r\n }\r\n\r\n @case ('checkbox') {\r\n <osl-checkbox\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [indeterminate]=\"!!col.formElem.indeterminate\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-checkbox>\r\n }\r\n\r\n @case ('slide-toggle') {\r\n <osl-slide-toggle\r\n [label]=\"''\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [labelPosition]=\"col.formElem.labelPosition || 'after'\"\r\n [trueLabel]=\"col.formElem.trueLabel || ''\"\r\n [falseLabel]=\"col.formElem.falseLabel || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-slide-toggle>\r\n }\r\n\r\n @case ('datepicker') {\r\n <osl-datepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [dateType]=\"col.formElem.dateType || 'date'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDate]=\"col.formElem.minDate || ''\"\r\n [maxDate]=\"col.formElem.maxDate || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datepicker>\r\n }\r\n\r\n @case ('datetimepicker') {\r\n <osl-datetimepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDatetime]=\"col.formElem.minDatetime || ''\"\r\n [maxDatetime]=\"col.formElem.maxDatetime || ''\"\r\n [format]=\"col.formElem.datetimepickerFormat || 'YYYY-MM-DDTHH:mm'\"\r\n [showSeconds]=\"!!col.formElem.datetimepickerShowSeconds\"\r\n [enableMeridian]=\"!!col.formElem.datetimepickerEnableMeridian\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datetimepicker>\r\n }\r\n\r\n @case ('file-uploader') {\r\n <osl-file-upload\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [accept]=\"col.formElem.accept || ''\"\r\n [multiple]=\"!!col.formElem.multiple\"\r\n [maxSize]=\"col.formElem.maxFileSize || 0\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-file-upload>\r\n }\r\n\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"osl-fg-cell-text\">{{ row[col.key] ?? '--' }}</span>\r\n }\r\n </td>\r\n }\r\n\r\n </tr>\r\n }\r\n }\r\n\r\n </tbody>\r\n\r\n @if (footerColumns && footerColumns.length > 0 && datasource && datasource.length > 0) {\r\n <tfoot class=\"osl-fg-tfoot\">\r\n <tr class=\"osl-fg-footer-row\">\r\n @for (fcol of footerColumns; track $index) {\r\n <td\r\n [class]=\"'osl-fg-footer-td ' + (fcol.class || '')\"\r\n [attr.colspan]=\"fcol.colspan || 1\">\r\n {{ fcol.displayFn ? fcol.displayFn(datasource) : (fcol.display || '') }}\r\n </td>\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n\r\n @if (isPaginated) {\r\n <div class=\"osl-fg-pagination\">\r\n\r\n <span class=\"osl-fg-pagination__info\">\r\n @if (loading) {\r\n Loading...\r\n } @else if (_total > 0) {\r\n {{ startRecord }}\u2013{{ endRecord }} of {{ _total }} rows\r\n } @else {\r\n No rows\r\n }\r\n </span>\r\n\r\n <div class=\"osl-fg-pagination__controls\">\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(1)\" [disabled]=\"currentPage === 1 || loading\">\u00AB</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1 || loading\">\u2039 Prev</button>\r\n\r\n @for (page of pageNumbers; track $index) {\r\n @if (page === -1) {\r\n <span class=\"osl-fg-page-ellipsis\">\u2026</span>\r\n } @else {\r\n <button\r\n class=\"osl-fg-page-btn osl-fg-page-btn--num\"\r\n [class.osl-fg-page-btn--active]=\"page === currentPage\"\r\n [disabled]=\"loading\"\r\n (click)=\"goToPage(page)\">\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage === totalPages || loading\">Next \u203A</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(totalPages)\" [disabled]=\"currentPage === totalPages || loading\">\u00BB</button>\r\n </div>\r\n\r\n <div class=\"osl-fg-pagination__size\">\r\n <select class=\"osl-fg-page-size\" [ngModel]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\" [disabled]=\"loading\">\r\n @for (opt of pageSizeOptions; track opt) {\r\n <option [value]=\"opt\">{{ opt }} per page</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n</div>\r\n", styles: [".osl-fg-wrapper{display:flex;flex-direction:column;width:100%;font-size:var(--osl-text-font-size);font-family:inherit;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 8px);overflow:hidden;background:#fff}.osl-fg-table-container{overflow-x:auto;overflow-y:auto;min-height:120px}.osl-fg-table{width:100%;border-collapse:collapse;table-layout:auto}.osl-fg-thead{position:sticky;top:0;z-index:2}.osl-fg-th{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-bottom:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-th:last-child{border-right:none}.osl-fg-th--actions{width:44px;min-width:44px;text-align:center;padding:6px}.osl-fg-th-required{color:#ef4444;margin-left:2px;font-size:14px;line-height:1;vertical-align:middle}.osl-fg-row{border-bottom:1px solid #f0f0f0;transition:background .1s}.osl-fg-row:nth-child(odd){background:#f8fafc}.osl-fg-row:nth-child(2n){background:#fff}.osl-fg-row:hover{background:#eef2ff!important}.osl-fg-row:last-child{border-bottom:none}.osl-fg-row--skeleton{pointer-events:none}.osl-fg-td{padding:4px 10px;vertical-align:middle;border-right:1px solid #f0f0f0}.osl-fg-td:last-child{border-right:none}.osl-fg-td--actions{width:44px;min-width:44px;text-align:center;padding:4px 6px}.osl-fg-cell-form{min-width:100px}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field,.osl-fg-cell-form ::ng-deep mat-form-field{width:100%}.osl-fg-cell-form ::ng-deep .mat-mdc-text-field-wrapper{padding-top:0}.osl-fg-cell-text{color:#111827;font-size:var(--osl-text-font-size)}.osl-fg-add-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;border-radius:6px;background:var(--osl-primary, #6366f1);color:#fff;cursor:pointer;padding:0;box-shadow:0 1px 4px #6366f159;transition:background .15s,box-shadow .15s,transform .1s}.osl-fg-add-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.osl-fg-add-btn:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);box-shadow:0 2px 8px #6366f173;transform:scale(1.05)}.osl-fg-add-btn:disabled{opacity:.4;cursor:not-allowed;transform:none}.osl-fg-delete-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid transparent;border-radius:6px;background:transparent;color:#d1d5db;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s}.osl-fg-delete-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-fg-delete-btn:hover{border-color:#fca5a5;color:#ef4444;background:#fef2f2}.osl-fg-empty{padding:40px 16px;text-align:center}.osl-fg-empty-inner{display:flex;flex-direction:column;align-items:center;gap:10px;color:#9ca3af}.osl-fg-empty-inner svg{opacity:.4}.osl-fg-empty-inner p{margin:0;font-size:13px}@keyframes osl-fg-pulse{0%,to{opacity:1}50%{opacity:.4}}.osl-fg-skeleton{height:36px;border-radius:6px;background:#e5e7eb;animation:osl-fg-pulse 1.4s ease-in-out infinite}.osl-fg-skeleton--sm{height:28px;width:28px;border-radius:4px;margin:0 auto}.osl-fg-tfoot{position:sticky;bottom:0;z-index:2}.osl-fg-footer-td{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-top:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-footer-td:last-child{border-right:none}.osl-fg-pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 16px;border-top:1px solid var(--osl-border-color, #e5e7eb);background:#f9fafb;flex-shrink:0;flex-wrap:wrap}.osl-fg-pagination__info{font-size:12px;color:#6b7280;white-space:nowrap;min-width:120px}.osl-fg-pagination__controls{display:flex;align-items:center;gap:3px;flex-wrap:nowrap}.osl-fg-pagination__size{display:flex;align-items:center;justify-content:flex-end;min-width:120px}.osl-fg-page-btn{display:inline-flex;align-items:center;justify-content:center;height:30px;padding:0 10px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:13px;font-family:inherit;cursor:pointer;transition:background .12s,border-color .12s,color .12s;white-space:nowrap}.osl-fg-page-btn:hover:not(:disabled){background:#f3f4f6;border-color:#9ca3af}.osl-fg-page-btn:disabled{opacity:.35;cursor:not-allowed}.osl-fg-page-btn--nav{font-size:12px;color:#6b7280}.osl-fg-page-btn--num{min-width:30px;padding:0;font-size:13px}.osl-fg-page-btn--active{background:var(--osl-primary, #6366f1);border-color:var(--osl-primary, #6366f1);color:#fff;font-weight:600}.osl-fg-page-btn--active:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);border-color:var(--osl-primary-hover, #4f46e5)}.osl-fg-page-ellipsis{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;color:#9ca3af;font-size:13px;pointer-events:none}.osl-fg-page-size{height:30px;padding:0 8px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:12px;font-family:inherit;cursor:pointer;outline:none}.osl-fg-page-size:focus{border-color:var(--osl-primary, #6366f1)}.osl-fg-page-size:disabled{opacity:.4;cursor:not-allowed}.osl-grid-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid var(--osl-border-color);border-radius:var(--osl-border-radius);background:transparent;color:#6b7280;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s;margin:0 2px}.osl-grid-icon-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-grid-icon-btn:hover{border-color:var(--osl-primary);color:var(--osl-primary);background:#6366f10f}.osl-grid-icon-btn--danger:hover{border-color:#ef4444;color:#ef4444;background:#ef44440f}\n"], dependencies: [{ kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: Oslinput, selector: "osl-input", inputs: ["label", "required", "disabled", "model", "type", "placeholder", "mask", "min", "max", "minLength", "maxLength", "prefixIcon", "suffixIcon", "skeletonLoading", "skeletonTheme", "onlyChars", "isCapitalize", "decimalPortion"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: Osltextarea, selector: "osl-textarea", inputs: ["label", "rows", "required", "disabled", "model", "placeholder", "maxLength", "minLength", "characterCounter", "resize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSelect, selector: "osl-select", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "clearable", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslRadio, selector: "osl-radio", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "inline", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslSlideToggle, selector: "osl-slide-toggle", inputs: ["label", "disabled", "model", "labelPosition", "trueLabel", "falseLabel", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslAutocomplete, selector: "osl-autocomplete", inputs: ["label", "required", "disabled", "model", "datasource", "displayField", "valueField", "placeholder", "loading", "searchType", "methodName", "configMethodName", "service", "object", "skeletonLoading", "skeletonTheme", "isLister"], outputs: ["datasourceChange", "modelChange", "changeEv"] }, { kind: "component", type: OslFileUpload, selector: "osl-file-upload", inputs: ["label", "required", "disabled", "model", "accept", "multiple", "maxSize", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatepicker, selector: "osl-datepicker", inputs: ["label", "required", "disabled", "model", "dateType", "placeholder", "minDate", "maxDate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslDatetimepicker, selector: "osl-datetimepicker", inputs: ["label", "required", "disabled", "model", "placeholder", "minDatetime", "maxDatetime", "format", "showSeconds", "enableMeridian", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }, { kind: "component", type: OslCheckbox, selector: "osl-checkbox", inputs: ["label", "disabled", "required", "model", "indeterminate", "skeletonLoading", "skeletonTheme"], outputs: ["modelChange", "changeEv"] }] });
|
|
3405
3719
|
}
|
|
3406
3720
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: OslFormGrid, decorators: [{
|
|
3407
3721
|
type: Component,
|
|
3408
|
-
args: [{ selector: 'osl-form-grid', standalone: false, template: "<div class=\"osl-fg-wrapper\">\r\n\r\n <div class=\"osl-fg-table-container\" [style.height]=\"tableHeight\">\r\n <table class=\"osl-fg-table\">\r\n\r\n <thead class=\"osl-fg-thead\">\r\n <tr>\r\n <!-- Actions column: + add button in header -->\r\n @if (hasActions) {\r\n <th class=\"osl-fg-th osl-fg-th--actions\">\r\n @if (canAdd) {\r\n <button class=\"osl-grid-icon-btn\" (click)=\"addRow()\" [disabled]=\"loading\" title=\"Add row\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n </th>\r\n }\r\n @for (col of columns; track col.key) {\r\n <th class=\"osl-fg-th\" [style.width]=\"col.width\">\r\n {{ col.displayName }}\r\n @if (colRequired(col)) {\r\n <span class=\"osl-fg-th-required\">*</span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n\r\n @if (loading) {\r\n @for (sk of skeletonRows; track $index) {\r\n <tr class=\"osl-fg-row osl-fg-row--skeleton\">\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n <div class=\"osl-fg-skeleton osl-fg-skeleton--sm\"></div>\r\n </td>\r\n }\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\"><div class=\"osl-fg-skeleton\"></div></td>\r\n }\r\n </tr>\r\n }\r\n\r\n } @else if (pagedData.length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columns.length + (hasActions ? 1 : 0)\" class=\"osl-fg-empty\">\r\n <div class=\"osl-fg-empty-inner\">\r\n <svg width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>\r\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/>\r\n <line x1=\"9\" y1=\"9\" x2=\"9\" y2=\"21\"/>\r\n </svg>\r\n <p>No rows yet.{{ canAdd ? ' Use + to get started.' : '' }}</p>\r\n </div>\r\n </td>\r\n </tr>\r\n\r\n } @else {\r\n @for (row of pagedData; track $index; let i = $index) {\r\n <tr class=\"osl-fg-row\">\r\n\r\n <!-- Delete button first -->\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n @if (canDelete) {\r\n <button class=\"osl-grid-icon-btn osl-grid-icon-btn--danger\" (click)=\"deleteRow(i)\" title=\"Delete\">\r\n <mat-icon>delete_outline</mat-icon>\r\n </button>\r\n }\r\n </td>\r\n }\r\n\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\" [style.width]=\"col.width\">\r\n @if (col.formElem) {\r\n <div class=\"osl-fg-cell-form\" [style.width]=\"col.width\">\r\n @switch (col.formElem.elementType) {\r\n\r\n @case ('textbox') {\r\n <osl-input\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [type]=\"col.formElem.inputType || 'text'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [mask]=\"col.formElem.mask || ''\"\r\n [min]=\"col.formElem.min ?? ''\"\r\n [max]=\"col.formElem.max ?? ''\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [prefixIcon]=\"col.formElem.prefixIcon || ''\"\r\n [suffixIcon]=\"col.formElem.suffixIcon || ''\"\r\n [decimalPortion]=\"col.formElem.decimalPortion ?? null\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-input>\r\n }\r\n\r\n @case ('textarea') {\r\n <osl-textarea\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [rows]=\"col.formElem.textareaRows || 3\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [characterCounter]=\"!!col.formElem.characterCounter\"\r\n [resize]=\"col.formElem.resize || 'none'\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-textarea>\r\n }\r\n\r\n @case ('select') {\r\n <osl-select\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.selectPlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [clearable]=\"!!col.formElem.clearable\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-select>\r\n }\r\n\r\n @case ('autocomplete') {\r\n <osl-autocomplete\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.autocompletePlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [searchType]=\"col.formElem.searchType ? col.formElem.searchType : 'Local'\"\r\n [methodName]=\"col.formElem.apiMethod || ''\"\r\n [configMethodName]=\"col.formElem.apiConfigMethod || ''\"\r\n [service]=\"col.formElem.apiService\"\r\n [object]=\"col.formElem.objectName ? row[col.formElem.objectName] : null\"\r\n [isLister]=\"!!col.formElem.isListerAutocomplete\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-autocomplete>\r\n }\r\n\r\n @case ('radio') {\r\n <osl-radio\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [inline]=\"!!col.formElem.inline\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-radio>\r\n }\r\n\r\n @case ('checkbox') {\r\n <osl-checkbox\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [indeterminate]=\"!!col.formElem.indeterminate\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-checkbox>\r\n }\r\n\r\n @case ('slide-toggle') {\r\n <osl-slide-toggle\r\n [label]=\"''\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [labelPosition]=\"col.formElem.labelPosition || 'after'\"\r\n [trueLabel]=\"col.formElem.trueLabel || ''\"\r\n [falseLabel]=\"col.formElem.falseLabel || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-slide-toggle>\r\n }\r\n\r\n @case ('datepicker') {\r\n <osl-datepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [dateType]=\"col.formElem.dateType || 'date'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDate]=\"col.formElem.minDate || ''\"\r\n [maxDate]=\"col.formElem.maxDate || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datepicker>\r\n }\r\n\r\n @case ('datetimepicker') {\r\n <osl-datetimepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDatetime]=\"col.formElem.minDatetime || ''\"\r\n [maxDatetime]=\"col.formElem.maxDatetime || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datetimepicker>\r\n }\r\n\r\n @case ('file-uploader') {\r\n <osl-file-upload\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [accept]=\"col.formElem.accept || ''\"\r\n [multiple]=\"!!col.formElem.multiple\"\r\n [maxSize]=\"col.formElem.maxFileSize || 0\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-file-upload>\r\n }\r\n\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"osl-fg-cell-text\">{{ row[col.key] ?? '--' }}</span>\r\n }\r\n </td>\r\n }\r\n\r\n </tr>\r\n }\r\n }\r\n\r\n </tbody>\r\n\r\n @if (footerColumns && footerColumns.length > 0 && datasource && datasource.length > 0) {\r\n <tfoot class=\"osl-fg-tfoot\">\r\n <tr class=\"osl-fg-footer-row\">\r\n @for (fcol of footerColumns; track $index) {\r\n <td\r\n [class]=\"'osl-fg-footer-td ' + (fcol.class || '')\"\r\n [attr.colspan]=\"fcol.colspan || 1\">\r\n {{ fcol.displayFn ? fcol.displayFn(datasource) : (fcol.display || '') }}\r\n </td>\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n\r\n @if (isPaginated) {\r\n <div class=\"osl-fg-pagination\">\r\n\r\n <span class=\"osl-fg-pagination__info\">\r\n @if (loading) {\r\n Loading...\r\n } @else if (_total > 0) {\r\n {{ startRecord }}\u2013{{ endRecord }} of {{ _total }} rows\r\n } @else {\r\n No rows\r\n }\r\n </span>\r\n\r\n <div class=\"osl-fg-pagination__controls\">\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(1)\" [disabled]=\"currentPage === 1 || loading\">\u00AB</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1 || loading\">\u2039 Prev</button>\r\n\r\n @for (page of pageNumbers; track $index) {\r\n @if (page === -1) {\r\n <span class=\"osl-fg-page-ellipsis\">\u2026</span>\r\n } @else {\r\n <button\r\n class=\"osl-fg-page-btn osl-fg-page-btn--num\"\r\n [class.osl-fg-page-btn--active]=\"page === currentPage\"\r\n [disabled]=\"loading\"\r\n (click)=\"goToPage(page)\">\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage === totalPages || loading\">Next \u203A</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(totalPages)\" [disabled]=\"currentPage === totalPages || loading\">\u00BB</button>\r\n </div>\r\n\r\n <div class=\"osl-fg-pagination__size\">\r\n <select class=\"osl-fg-page-size\" [ngModel]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\" [disabled]=\"loading\">\r\n @for (opt of pageSizeOptions; track opt) {\r\n <option [value]=\"opt\">{{ opt }} per page</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n</div>\r\n", styles: [".osl-fg-wrapper{display:flex;flex-direction:column;width:100%;font-size:var(--osl-text-font-size);font-family:inherit;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 8px);overflow:hidden;background:#fff}.osl-fg-table-container{overflow-x:auto;overflow-y:auto;min-height:120px}.osl-fg-table{width:100%;border-collapse:collapse;table-layout:auto}.osl-fg-thead{position:sticky;top:0;z-index:2}.osl-fg-th{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-bottom:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-th:last-child{border-right:none}.osl-fg-th--actions{width:44px;min-width:44px;text-align:center;padding:6px}.osl-fg-th-required{color:#ef4444;margin-left:2px;font-size:14px;line-height:1;vertical-align:middle}.osl-fg-row{border-bottom:1px solid #f0f0f0;transition:background .1s}.osl-fg-row:nth-child(odd){background:#f8fafc}.osl-fg-row:nth-child(2n){background:#fff}.osl-fg-row:hover{background:#eef2ff!important}.osl-fg-row:last-child{border-bottom:none}.osl-fg-row--skeleton{pointer-events:none}.osl-fg-td{padding:4px 10px;vertical-align:middle;border-right:1px solid #f0f0f0}.osl-fg-td:last-child{border-right:none}.osl-fg-td--actions{width:44px;min-width:44px;text-align:center;padding:4px 6px}.osl-fg-cell-form{min-width:100px}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field,.osl-fg-cell-form ::ng-deep mat-form-field{width:100%}.osl-fg-cell-form ::ng-deep .mat-mdc-text-field-wrapper{padding-top:0}.osl-fg-cell-text{color:#111827;font-size:var(--osl-text-font-size)}.osl-fg-add-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;border-radius:6px;background:var(--osl-primary, #6366f1);color:#fff;cursor:pointer;padding:0;box-shadow:0 1px 4px #6366f159;transition:background .15s,box-shadow .15s,transform .1s}.osl-fg-add-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.osl-fg-add-btn:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);box-shadow:0 2px 8px #6366f173;transform:scale(1.05)}.osl-fg-add-btn:disabled{opacity:.4;cursor:not-allowed;transform:none}.osl-fg-delete-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid transparent;border-radius:6px;background:transparent;color:#d1d5db;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s}.osl-fg-delete-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-fg-delete-btn:hover{border-color:#fca5a5;color:#ef4444;background:#fef2f2}.osl-fg-empty{padding:40px 16px;text-align:center}.osl-fg-empty-inner{display:flex;flex-direction:column;align-items:center;gap:10px;color:#9ca3af}.osl-fg-empty-inner svg{opacity:.4}.osl-fg-empty-inner p{margin:0;font-size:13px}@keyframes osl-fg-pulse{0%,to{opacity:1}50%{opacity:.4}}.osl-fg-skeleton{height:36px;border-radius:6px;background:#e5e7eb;animation:osl-fg-pulse 1.4s ease-in-out infinite}.osl-fg-skeleton--sm{height:28px;width:28px;border-radius:4px;margin:0 auto}.osl-fg-tfoot{position:sticky;bottom:0;z-index:2}.osl-fg-footer-td{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-top:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-footer-td:last-child{border-right:none}.osl-fg-pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 16px;border-top:1px solid var(--osl-border-color, #e5e7eb);background:#f9fafb;flex-shrink:0;flex-wrap:wrap}.osl-fg-pagination__info{font-size:12px;color:#6b7280;white-space:nowrap;min-width:120px}.osl-fg-pagination__controls{display:flex;align-items:center;gap:3px;flex-wrap:nowrap}.osl-fg-pagination__size{display:flex;align-items:center;justify-content:flex-end;min-width:120px}.osl-fg-page-btn{display:inline-flex;align-items:center;justify-content:center;height:30px;padding:0 10px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:13px;font-family:inherit;cursor:pointer;transition:background .12s,border-color .12s,color .12s;white-space:nowrap}.osl-fg-page-btn:hover:not(:disabled){background:#f3f4f6;border-color:#9ca3af}.osl-fg-page-btn:disabled{opacity:.35;cursor:not-allowed}.osl-fg-page-btn--nav{font-size:12px;color:#6b7280}.osl-fg-page-btn--num{min-width:30px;padding:0;font-size:13px}.osl-fg-page-btn--active{background:var(--osl-primary, #6366f1);border-color:var(--osl-primary, #6366f1);color:#fff;font-weight:600}.osl-fg-page-btn--active:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);border-color:var(--osl-primary-hover, #4f46e5)}.osl-fg-page-ellipsis{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;color:#9ca3af;font-size:13px;pointer-events:none}.osl-fg-page-size{height:30px;padding:0 8px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:12px;font-family:inherit;cursor:pointer;outline:none}.osl-fg-page-size:focus{border-color:var(--osl-primary, #6366f1)}.osl-fg-page-size:disabled{opacity:.4;cursor:not-allowed}.osl-grid-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid var(--osl-border-color);border-radius:var(--osl-border-radius);background:transparent;color:#6b7280;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s;margin:0 2px}.osl-grid-icon-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-grid-icon-btn:hover{border-color:var(--osl-primary);color:var(--osl-primary);background:#6366f10f}.osl-grid-icon-btn--danger:hover{border-color:#ef4444;color:#ef4444;background:#ef44440f}\n"] }]
|
|
3722
|
+
args: [{ selector: 'osl-form-grid', standalone: false, template: "<div class=\"osl-fg-wrapper\">\r\n\r\n <div class=\"osl-fg-table-container\" [style.height]=\"tableHeight\">\r\n <table class=\"osl-fg-table\">\r\n\r\n <thead class=\"osl-fg-thead\">\r\n <tr>\r\n <!-- Actions column: + add button in header -->\r\n @if (hasActions) {\r\n <th class=\"osl-fg-th osl-fg-th--actions\">\r\n @if (canAdd) {\r\n <button class=\"osl-grid-icon-btn\" (click)=\"addRow()\" [disabled]=\"loading\" title=\"Add row\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n </th>\r\n }\r\n @for (col of columns; track col.key) {\r\n <th class=\"osl-fg-th\" [style.width]=\"col.width\">\r\n {{ col.displayName }}\r\n @if (colRequired(col)) {\r\n <span class=\"osl-fg-th-required\">*</span>\r\n }\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n\r\n @if (loading) {\r\n @for (sk of skeletonRows; track $index) {\r\n <tr class=\"osl-fg-row osl-fg-row--skeleton\">\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n <div class=\"osl-fg-skeleton osl-fg-skeleton--sm\"></div>\r\n </td>\r\n }\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\"><div class=\"osl-fg-skeleton\"></div></td>\r\n }\r\n </tr>\r\n }\r\n\r\n } @else if (pagedData.length === 0) {\r\n <tr>\r\n <td [attr.colspan]=\"columns.length + (hasActions ? 1 : 0)\" class=\"osl-fg-empty\">\r\n <div class=\"osl-fg-empty-inner\">\r\n <svg width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>\r\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"/>\r\n <line x1=\"9\" y1=\"9\" x2=\"9\" y2=\"21\"/>\r\n </svg>\r\n <p>No rows yet.{{ canAdd ? ' Use + to get started.' : '' }}</p>\r\n </div>\r\n </td>\r\n </tr>\r\n\r\n } @else {\r\n @for (row of pagedData; track $index; let i = $index) {\r\n <tr class=\"osl-fg-row\">\r\n\r\n <!-- Delete button first -->\r\n @if (hasActions) {\r\n <td class=\"osl-fg-td osl-fg-td--actions\">\r\n @if (canDelete) {\r\n <button class=\"osl-grid-icon-btn osl-grid-icon-btn--danger\" (click)=\"deleteRow(i)\" title=\"Delete\">\r\n <mat-icon>delete_outline</mat-icon>\r\n </button>\r\n }\r\n </td>\r\n }\r\n\r\n @for (col of columns; track col.key) {\r\n <td class=\"osl-fg-td\" [style.width]=\"col.width\">\r\n @if (col.formElem) {\r\n <div class=\"osl-fg-cell-form\" [style.width]=\"col.width\">\r\n @switch (col.formElem.elementType) {\r\n\r\n @case ('textbox') {\r\n <osl-input\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [type]=\"col.formElem.inputType || 'text'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [mask]=\"col.formElem.mask || ''\"\r\n [min]=\"col.formElem.min ?? ''\"\r\n [max]=\"col.formElem.max ?? ''\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [prefixIcon]=\"col.formElem.prefixIcon || ''\"\r\n [suffixIcon]=\"col.formElem.suffixIcon || ''\"\r\n [decimalPortion]=\"col.formElem.decimalPortion ?? null\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-input>\r\n }\r\n\r\n @case ('textarea') {\r\n <osl-textarea\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [rows]=\"col.formElem.textareaRows || 3\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [maxLength]=\"col.formElem.maxLength ?? null\"\r\n [minLength]=\"col.formElem.minLength ?? null\"\r\n [characterCounter]=\"!!col.formElem.characterCounter\"\r\n [resize]=\"col.formElem.resize || 'none'\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-textarea>\r\n }\r\n\r\n @case ('select') {\r\n <osl-select\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.selectPlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [clearable]=\"!!col.formElem.clearable\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-select>\r\n }\r\n\r\n @case ('autocomplete') {\r\n <osl-autocomplete\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [placeholder]=\"col.formElem.autocompletePlaceholder || col.displayName\"\r\n [loading]=\"isLoading(row, col.formElem)\"\r\n [searchType]=\"col.formElem.searchType ? col.formElem.searchType : 'Local'\"\r\n [methodName]=\"col.formElem.apiMethod || ''\"\r\n [configMethodName]=\"col.formElem.apiConfigMethod || ''\"\r\n [service]=\"col.formElem.apiService\"\r\n [object]=\"col.formElem.objectName ? row[col.formElem.objectName] : null\"\r\n [isLister]=\"!!col.formElem.isListerAutocomplete\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? onSelectChange(col, row, i, $event) : null\">\r\n </osl-autocomplete>\r\n }\r\n\r\n @case ('radio') {\r\n <osl-radio\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [datasource]=\"col.formElem.datasource || []\"\r\n [displayField]=\"col.formElem.displayField || ''\"\r\n [valueField]=\"col.formElem.valueField || ''\"\r\n [inline]=\"!!col.formElem.inline\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-radio>\r\n }\r\n\r\n @case ('checkbox') {\r\n <osl-checkbox\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [indeterminate]=\"!!col.formElem.indeterminate\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-checkbox>\r\n }\r\n\r\n @case ('slide-toggle') {\r\n <osl-slide-toggle\r\n [label]=\"''\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [labelPosition]=\"col.formElem.labelPosition || 'after'\"\r\n [trueLabel]=\"col.formElem.trueLabel || ''\"\r\n [falseLabel]=\"col.formElem.falseLabel || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-slide-toggle>\r\n }\r\n\r\n @case ('datepicker') {\r\n <osl-datepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [dateType]=\"col.formElem.dateType || 'date'\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDate]=\"col.formElem.minDate || ''\"\r\n [maxDate]=\"col.formElem.maxDate || ''\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datepicker>\r\n }\r\n\r\n @case ('datetimepicker') {\r\n <osl-datetimepicker\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [placeholder]=\"col.formElem.placeholder || col.displayName\"\r\n [minDatetime]=\"col.formElem.minDatetime || ''\"\r\n [maxDatetime]=\"col.formElem.maxDatetime || ''\"\r\n [format]=\"col.formElem.datetimepickerFormat || 'YYYY-MM-DDTHH:mm'\"\r\n [showSeconds]=\"!!col.formElem.datetimepickerShowSeconds\"\r\n [enableMeridian]=\"!!col.formElem.datetimepickerEnableMeridian\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-datetimepicker>\r\n }\r\n\r\n @case ('file-uploader') {\r\n <osl-file-upload\r\n [label]=\"''\"\r\n [required]=\"false\"\r\n [disabled]=\"isDisabled(col.formElem,row,i)\"\r\n [accept]=\"col.formElem.accept || ''\"\r\n [multiple]=\"!!col.formElem.multiple\"\r\n [maxSize]=\"col.formElem.maxFileSize || 0\"\r\n [model]=\"row[col.key]\"\r\n (modelChange)=\"onCellChange(row, col, $event)\"\r\n (changeEv)=\"col.formElem.change ? col.formElem.change(row,i) : null\">\r\n </osl-file-upload>\r\n }\r\n\r\n }\r\n </div>\r\n } @else {\r\n <span class=\"osl-fg-cell-text\">{{ row[col.key] ?? '--' }}</span>\r\n }\r\n </td>\r\n }\r\n\r\n </tr>\r\n }\r\n }\r\n\r\n </tbody>\r\n\r\n @if (footerColumns && footerColumns.length > 0 && datasource && datasource.length > 0) {\r\n <tfoot class=\"osl-fg-tfoot\">\r\n <tr class=\"osl-fg-footer-row\">\r\n @for (fcol of footerColumns; track $index) {\r\n <td\r\n [class]=\"'osl-fg-footer-td ' + (fcol.class || '')\"\r\n [attr.colspan]=\"fcol.colspan || 1\">\r\n {{ fcol.displayFn ? fcol.displayFn(datasource) : (fcol.display || '') }}\r\n </td>\r\n }\r\n </tr>\r\n </tfoot>\r\n }\r\n\r\n </table>\r\n </div>\r\n\r\n @if (isPaginated) {\r\n <div class=\"osl-fg-pagination\">\r\n\r\n <span class=\"osl-fg-pagination__info\">\r\n @if (loading) {\r\n Loading...\r\n } @else if (_total > 0) {\r\n {{ startRecord }}\u2013{{ endRecord }} of {{ _total }} rows\r\n } @else {\r\n No rows\r\n }\r\n </span>\r\n\r\n <div class=\"osl-fg-pagination__controls\">\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(1)\" [disabled]=\"currentPage === 1 || loading\">\u00AB</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1 || loading\">\u2039 Prev</button>\r\n\r\n @for (page of pageNumbers; track $index) {\r\n @if (page === -1) {\r\n <span class=\"osl-fg-page-ellipsis\">\u2026</span>\r\n } @else {\r\n <button\r\n class=\"osl-fg-page-btn osl-fg-page-btn--num\"\r\n [class.osl-fg-page-btn--active]=\"page === currentPage\"\r\n [disabled]=\"loading\"\r\n (click)=\"goToPage(page)\">\r\n {{ page }}\r\n </button>\r\n }\r\n }\r\n\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(currentPage + 1)\" [disabled]=\"currentPage === totalPages || loading\">Next \u203A</button>\r\n <button class=\"osl-fg-page-btn osl-fg-page-btn--nav\" (click)=\"goToPage(totalPages)\" [disabled]=\"currentPage === totalPages || loading\">\u00BB</button>\r\n </div>\r\n\r\n <div class=\"osl-fg-pagination__size\">\r\n <select class=\"osl-fg-page-size\" [ngModel]=\"pageSize\" (ngModelChange)=\"onPageSizeChange($event)\" [disabled]=\"loading\">\r\n @for (opt of pageSizeOptions; track opt) {\r\n <option [value]=\"opt\">{{ opt }} per page</option>\r\n }\r\n </select>\r\n </div>\r\n\r\n </div>\r\n }\r\n\r\n</div>\r\n", styles: [".osl-fg-wrapper{display:flex;flex-direction:column;width:100%;font-size:var(--osl-text-font-size);font-family:inherit;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 8px);overflow:hidden;background:#fff}.osl-fg-table-container{overflow-x:auto;overflow-y:auto;min-height:120px}.osl-fg-table{width:100%;border-collapse:collapse;table-layout:auto}.osl-fg-thead{position:sticky;top:0;z-index:2}.osl-fg-th{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-bottom:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-th:last-child{border-right:none}.osl-fg-th--actions{width:44px;min-width:44px;text-align:center;padding:6px}.osl-fg-th-required{color:#ef4444;margin-left:2px;font-size:14px;line-height:1;vertical-align:middle}.osl-fg-row{border-bottom:1px solid #f0f0f0;transition:background .1s}.osl-fg-row:nth-child(odd){background:#f8fafc}.osl-fg-row:nth-child(2n){background:#fff}.osl-fg-row:hover{background:#eef2ff!important}.osl-fg-row:last-child{border-bottom:none}.osl-fg-row--skeleton{pointer-events:none}.osl-fg-td{padding:4px 10px;vertical-align:middle;border-right:1px solid #f0f0f0}.osl-fg-td:last-child{border-right:none}.osl-fg-td--actions{width:44px;min-width:44px;text-align:center;padding:4px 6px}.osl-fg-cell-form{min-width:100px}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none!important}.osl-fg-cell-form ::ng-deep .mat-mdc-form-field,.osl-fg-cell-form ::ng-deep mat-form-field{width:100%}.osl-fg-cell-form ::ng-deep .mat-mdc-text-field-wrapper{padding-top:0}.osl-fg-cell-text{color:#111827;font-size:var(--osl-text-font-size)}.osl-fg-add-btn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;border-radius:6px;background:var(--osl-primary, #6366f1);color:#fff;cursor:pointer;padding:0;box-shadow:0 1px 4px #6366f159;transition:background .15s,box-shadow .15s,transform .1s}.osl-fg-add-btn mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.osl-fg-add-btn:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);box-shadow:0 2px 8px #6366f173;transform:scale(1.05)}.osl-fg-add-btn:disabled{opacity:.4;cursor:not-allowed;transform:none}.osl-fg-delete-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid transparent;border-radius:6px;background:transparent;color:#d1d5db;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s}.osl-fg-delete-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-fg-delete-btn:hover{border-color:#fca5a5;color:#ef4444;background:#fef2f2}.osl-fg-empty{padding:40px 16px;text-align:center}.osl-fg-empty-inner{display:flex;flex-direction:column;align-items:center;gap:10px;color:#9ca3af}.osl-fg-empty-inner svg{opacity:.4}.osl-fg-empty-inner p{margin:0;font-size:13px}@keyframes osl-fg-pulse{0%,to{opacity:1}50%{opacity:.4}}.osl-fg-skeleton{height:36px;border-radius:6px;background:#e5e7eb;animation:osl-fg-pulse 1.4s ease-in-out infinite}.osl-fg-skeleton--sm{height:28px;width:28px;border-radius:4px;margin:0 auto}.osl-fg-tfoot{position:sticky;bottom:0;z-index:2}.osl-fg-footer-td{background:#f3f4f6;color:#4b5563;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;text-align:left;border-top:2px solid var(--osl-border-color, #e5e7eb);border-right:1px solid var(--osl-border-color, #e5e7eb);white-space:nowrap;vertical-align:middle}.osl-fg-footer-td:last-child{border-right:none}.osl-fg-pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 16px;border-top:1px solid var(--osl-border-color, #e5e7eb);background:#f9fafb;flex-shrink:0;flex-wrap:wrap}.osl-fg-pagination__info{font-size:12px;color:#6b7280;white-space:nowrap;min-width:120px}.osl-fg-pagination__controls{display:flex;align-items:center;gap:3px;flex-wrap:nowrap}.osl-fg-pagination__size{display:flex;align-items:center;justify-content:flex-end;min-width:120px}.osl-fg-page-btn{display:inline-flex;align-items:center;justify-content:center;height:30px;padding:0 10px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:13px;font-family:inherit;cursor:pointer;transition:background .12s,border-color .12s,color .12s;white-space:nowrap}.osl-fg-page-btn:hover:not(:disabled){background:#f3f4f6;border-color:#9ca3af}.osl-fg-page-btn:disabled{opacity:.35;cursor:not-allowed}.osl-fg-page-btn--nav{font-size:12px;color:#6b7280}.osl-fg-page-btn--num{min-width:30px;padding:0;font-size:13px}.osl-fg-page-btn--active{background:var(--osl-primary, #6366f1);border-color:var(--osl-primary, #6366f1);color:#fff;font-weight:600}.osl-fg-page-btn--active:hover:not(:disabled){background:var(--osl-primary-hover, #4f46e5);border-color:var(--osl-primary-hover, #4f46e5)}.osl-fg-page-ellipsis{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;color:#9ca3af;font-size:13px;pointer-events:none}.osl-fg-page-size{height:30px;padding:0 8px;border:1px solid var(--osl-border-color, #e5e7eb);border-radius:var(--osl-border-radius, 6px);background:#fff;color:#374151;font-size:12px;font-family:inherit;cursor:pointer;outline:none}.osl-fg-page-size:focus{border-color:var(--osl-primary, #6366f1)}.osl-fg-page-size:disabled{opacity:.4;cursor:not-allowed}.osl-grid-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1.5px solid var(--osl-border-color);border-radius:var(--osl-border-radius);background:transparent;color:#6b7280;cursor:pointer;padding:0;transition:border-color .15s,color .15s,background .15s;margin:0 2px}.osl-grid-icon-btn mat-icon{font-size:16px;width:16px;height:16px;line-height:16px}.osl-grid-icon-btn:hover{border-color:var(--osl-primary);color:var(--osl-primary);background:#6366f10f}.osl-grid-icon-btn--danger:hover{border-color:#ef4444;color:#ef4444;background:#ef44440f}\n"] }]
|
|
3409
3723
|
}], propDecorators: { columns: [{
|
|
3410
3724
|
type: Input,
|
|
3411
3725
|
args: ['columns']
|
|
@@ -4753,7 +5067,10 @@ class FormStructureModule {
|
|
|
4753
5067
|
MatDatepickerModule,
|
|
4754
5068
|
MatMenuModule,
|
|
4755
5069
|
ScrollingModule,
|
|
4756
|
-
DragDropModule
|
|
5070
|
+
DragDropModule,
|
|
5071
|
+
NgxMatDatetimepicker,
|
|
5072
|
+
NgxMatDatepickerInput,
|
|
5073
|
+
NgxMatDatepickerToggle], exports: [DynamicForm, OslSetup, OslGrid, OslFormGrid, Oslinput,
|
|
4757
5074
|
Osltextarea,
|
|
4758
5075
|
OslSelect,
|
|
4759
5076
|
OslRadio,
|
|
@@ -4768,6 +5085,19 @@ class FormStructureModule {
|
|
|
4768
5085
|
OslSearchbar, OslAutocompleteLister, OslReportGrid, OslReportForm] });
|
|
4769
5086
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormStructureModule, providers: [
|
|
4770
5087
|
{ provide: AUTOCOMPLETE_LISTER_COMPONENT, useValue: OslAutocompleteLister },
|
|
5088
|
+
{ provide: DateAdapter, useClass: NativeDateAdapter },
|
|
5089
|
+
{
|
|
5090
|
+
provide: MAT_DATE_FORMATS,
|
|
5091
|
+
useValue: {
|
|
5092
|
+
parse: { dateInput: null },
|
|
5093
|
+
display: {
|
|
5094
|
+
dateInput: { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' },
|
|
5095
|
+
monthYearLabel: { year: 'numeric', month: 'short' },
|
|
5096
|
+
dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
|
|
5097
|
+
monthYearA11yLabel: { year: 'numeric', month: 'long' },
|
|
5098
|
+
},
|
|
5099
|
+
},
|
|
5100
|
+
},
|
|
4771
5101
|
], imports: [FormsModule,
|
|
4772
5102
|
ReactiveFormsModule,
|
|
4773
5103
|
MatFormFieldModule,
|
|
@@ -4779,7 +5109,9 @@ class FormStructureModule {
|
|
|
4779
5109
|
MatDatepickerModule,
|
|
4780
5110
|
MatMenuModule,
|
|
4781
5111
|
ScrollingModule,
|
|
4782
|
-
DragDropModule
|
|
5112
|
+
DragDropModule,
|
|
5113
|
+
NgxMatDatetimepicker,
|
|
5114
|
+
NgxMatDatepickerToggle] });
|
|
4783
5115
|
}
|
|
4784
5116
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FormStructureModule, decorators: [{
|
|
4785
5117
|
type: NgModule,
|
|
@@ -4825,6 +5157,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
4825
5157
|
MatMenuModule,
|
|
4826
5158
|
ScrollingModule,
|
|
4827
5159
|
DragDropModule,
|
|
5160
|
+
NgxMatDatetimepicker,
|
|
5161
|
+
NgxMatDatepickerInput,
|
|
5162
|
+
NgxMatDatepickerToggle,
|
|
4828
5163
|
],
|
|
4829
5164
|
exports: [DynamicForm, OslSetup, OslGrid, OslFormGrid, Oslinput,
|
|
4830
5165
|
Osltextarea,
|
|
@@ -4841,516 +5176,234 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
4841
5176
|
OslSearchbar, OslAutocompleteLister, OslReportGrid, OslReportForm],
|
|
4842
5177
|
providers: [
|
|
4843
5178
|
{ provide: AUTOCOMPLETE_LISTER_COMPONENT, useValue: OslAutocompleteLister },
|
|
5179
|
+
{ provide: DateAdapter, useClass: NativeDateAdapter },
|
|
5180
|
+
{
|
|
5181
|
+
provide: MAT_DATE_FORMATS,
|
|
5182
|
+
useValue: {
|
|
5183
|
+
parse: { dateInput: null },
|
|
5184
|
+
display: {
|
|
5185
|
+
dateInput: { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' },
|
|
5186
|
+
monthYearLabel: { year: 'numeric', month: 'short' },
|
|
5187
|
+
dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
|
|
5188
|
+
monthYearA11yLabel: { year: 'numeric', month: 'long' },
|
|
5189
|
+
},
|
|
5190
|
+
},
|
|
5191
|
+
},
|
|
4844
5192
|
],
|
|
4845
5193
|
}]
|
|
4846
5194
|
}] });
|
|
4847
|
-
|
|
4848
|
-
// ─── Array Utilities ────────────────────────────────────────────────────────
|
|
4849
|
-
/** Splits an array into chunks of the given size. */
|
|
4850
|
-
function chunk(array, size) {
|
|
4851
|
-
if (size <= 0)
|
|
4852
|
-
return [];
|
|
4853
|
-
const result = [];
|
|
4854
|
-
for (let i = 0; i < array.length; i += size) {
|
|
4855
|
-
result.push(array.slice(i, i + size));
|
|
4856
|
-
}
|
|
4857
|
-
return result;
|
|
4858
|
-
}
|
|
4859
|
-
/** Removes duplicate primitive values. */
|
|
4860
|
-
function unique(array) {
|
|
4861
|
-
return [...new Set(array)];
|
|
4862
|
-
}
|
|
4863
|
-
/** Removes duplicates by object key. */
|
|
4864
|
-
function uniqueBy(array, key) {
|
|
4865
|
-
const seen = new Set();
|
|
4866
|
-
return array.filter(item => {
|
|
4867
|
-
const val = item[key];
|
|
4868
|
-
if (seen.has(val))
|
|
4869
|
-
return false;
|
|
4870
|
-
seen.add(val);
|
|
4871
|
-
return true;
|
|
4872
|
-
});
|
|
4873
|
-
}
|
|
4874
|
-
/** Flattens one level of nesting. */
|
|
4875
|
-
function flatten(array) {
|
|
4876
|
-
return array.flat();
|
|
4877
|
-
}
|
|
4878
|
-
/** Deeply flattens a nested array. */
|
|
4879
|
-
function flattenDeep(array) {
|
|
4880
|
-
return array.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : [...acc, val], []);
|
|
4881
|
-
}
|
|
4882
|
-
/** Groups array elements by a key. */
|
|
4883
|
-
function groupBy(array, key) {
|
|
4884
|
-
return array.reduce((acc, item) => {
|
|
4885
|
-
const group = String(item[key]);
|
|
4886
|
-
acc[group] = acc[group] ?? [];
|
|
4887
|
-
acc[group].push(item);
|
|
4888
|
-
return acc;
|
|
4889
|
-
}, {});
|
|
4890
|
-
}
|
|
4891
|
-
/** Sorts array by key ascending or descending. */
|
|
4892
|
-
function sortBy(array, key, direction = 'asc') {
|
|
4893
|
-
return [...array].sort((a, b) => {
|
|
4894
|
-
const aVal = a[key];
|
|
4895
|
-
const bVal = b[key];
|
|
4896
|
-
if (aVal < bVal)
|
|
4897
|
-
return direction === 'asc' ? -1 : 1;
|
|
4898
|
-
if (aVal > bVal)
|
|
4899
|
-
return direction === 'asc' ? 1 : -1;
|
|
4900
|
-
return 0;
|
|
4901
|
-
});
|
|
4902
|
-
}
|
|
4903
|
-
/** Filters array where key matches value (strict equality). */
|
|
4904
|
-
function filterBy(array, key, value) {
|
|
4905
|
-
return array.filter(item => item[key] === value);
|
|
4906
|
-
}
|
|
4907
|
-
/** Sums values at the given numeric key. */
|
|
4908
|
-
function sumBy(array, key) {
|
|
4909
|
-
return array.reduce((acc, item) => acc + Number(item[key]), 0);
|
|
4910
|
-
}
|
|
4911
|
-
/** Returns the item with the minimum value at key. */
|
|
4912
|
-
function minBy(array, key) {
|
|
4913
|
-
if (!array.length)
|
|
4914
|
-
return undefined;
|
|
4915
|
-
return array.reduce((min, item) => (item[key] < min[key] ? item : min));
|
|
4916
|
-
}
|
|
4917
|
-
/** Returns the item with the maximum value at key. */
|
|
4918
|
-
function maxBy(array, key) {
|
|
4919
|
-
if (!array.length)
|
|
4920
|
-
return undefined;
|
|
4921
|
-
return array.reduce((max, item) => (item[key] > max[key] ? item : max));
|
|
4922
|
-
}
|
|
4923
|
-
/** Computes the average of an array of numbers. */
|
|
4924
|
-
function average$1(numbers) {
|
|
4925
|
-
if (!numbers.length)
|
|
4926
|
-
return 0;
|
|
4927
|
-
return numbers.reduce((a, b) => a + b, 0) / numbers.length;
|
|
4928
|
-
}
|
|
4929
|
-
/** Returns true if the array is null, undefined, or has no elements. */
|
|
4930
|
-
function isEmpty$2(array) {
|
|
4931
|
-
return !array || array.length === 0;
|
|
4932
|
-
}
|
|
4933
|
-
/** Returns the last element. */
|
|
4934
|
-
function last(array) {
|
|
4935
|
-
return array[array.length - 1];
|
|
4936
|
-
}
|
|
4937
|
-
/** Returns the first element. */
|
|
4938
|
-
function first(array) {
|
|
4939
|
-
return array[0];
|
|
4940
|
-
}
|
|
4941
|
-
/** Returns a slice of the array for the given page (1-based). */
|
|
4942
|
-
function paginate(array, page, pageSize) {
|
|
4943
|
-
const start = (page - 1) * pageSize;
|
|
4944
|
-
return array.slice(start, start + pageSize);
|
|
4945
|
-
}
|
|
4946
|
-
/** Moves an element from one index to another (immutable). */
|
|
4947
|
-
function move(array, fromIndex, toIndex) {
|
|
4948
|
-
const result = [...array];
|
|
4949
|
-
const [item] = result.splice(fromIndex, 1);
|
|
4950
|
-
result.splice(toIndex, 0, item);
|
|
4951
|
-
return result;
|
|
4952
|
-
}
|
|
4953
|
-
/** Adds the item if absent, removes it if present. */
|
|
4954
|
-
function toggle(array, item) {
|
|
4955
|
-
return array.includes(item) ? array.filter(i => i !== item) : [...array, item];
|
|
4956
|
-
}
|
|
4957
|
-
/** Returns elements present in both arrays. */
|
|
4958
|
-
function intersection(a, b) {
|
|
4959
|
-
const setB = new Set(b);
|
|
4960
|
-
return a.filter(item => setB.has(item));
|
|
4961
|
-
}
|
|
4962
|
-
/** Returns elements in `a` not present in `b`. */
|
|
4963
|
-
function difference(a, b) {
|
|
4964
|
-
const setB = new Set(b);
|
|
4965
|
-
return a.filter(item => !setB.has(item));
|
|
4966
|
-
}
|
|
4967
|
-
/** Converts an array to a lookup map keyed by the given property. */
|
|
4968
|
-
function toMap(array, key) {
|
|
4969
|
-
return array.reduce((acc, item) => {
|
|
4970
|
-
acc[String(item[key])] = item;
|
|
4971
|
-
return acc;
|
|
4972
|
-
}, {});
|
|
4973
|
-
}
|
|
4974
|
-
/** Removes falsy values (null, undefined, 0, '', false). */
|
|
4975
|
-
function compact(array) {
|
|
4976
|
-
return array.filter(Boolean);
|
|
4977
|
-
}
|
|
4978
|
-
/** Returns a new randomly shuffled copy. */
|
|
4979
|
-
function shuffle(array) {
|
|
4980
|
-
const result = [...array];
|
|
4981
|
-
for (let i = result.length - 1; i > 0; i--) {
|
|
4982
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
4983
|
-
[result[i], result[j]] = [result[j], result[i]];
|
|
5195
|
+
|
|
5196
|
+
// ─── Array Utilities ────────────────────────────────────────────────────────
|
|
5197
|
+
/** Splits an array into chunks of the given size. */
|
|
5198
|
+
function chunk(array, size) {
|
|
5199
|
+
if (size <= 0)
|
|
5200
|
+
return [];
|
|
5201
|
+
const result = [];
|
|
5202
|
+
for (let i = 0; i < array.length; i += size) {
|
|
5203
|
+
result.push(array.slice(i, i + size));
|
|
4984
5204
|
}
|
|
4985
5205
|
return result;
|
|
4986
5206
|
}
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
return shuffle(array).slice(0, count);
|
|
5207
|
+
/** Removes duplicate primitive values. */
|
|
5208
|
+
function unique(array) {
|
|
5209
|
+
return [...new Set(array)];
|
|
4991
5210
|
}
|
|
4992
|
-
/**
|
|
4993
|
-
function
|
|
5211
|
+
/** Removes duplicates by object key. */
|
|
5212
|
+
function uniqueBy(array, key) {
|
|
5213
|
+
const seen = new Set();
|
|
5214
|
+
return array.filter(item => {
|
|
5215
|
+
const val = item[key];
|
|
5216
|
+
if (seen.has(val))
|
|
5217
|
+
return false;
|
|
5218
|
+
seen.add(val);
|
|
5219
|
+
return true;
|
|
5220
|
+
});
|
|
5221
|
+
}
|
|
5222
|
+
/** Flattens one level of nesting. */
|
|
5223
|
+
function flatten(array) {
|
|
5224
|
+
return array.flat();
|
|
5225
|
+
}
|
|
5226
|
+
/** Deeply flattens a nested array. */
|
|
5227
|
+
function flattenDeep(array) {
|
|
5228
|
+
return array.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : [...acc, val], []);
|
|
5229
|
+
}
|
|
5230
|
+
/** Groups array elements by a key. */
|
|
5231
|
+
function groupBy(array, key) {
|
|
4994
5232
|
return array.reduce((acc, item) => {
|
|
4995
5233
|
const group = String(item[key]);
|
|
4996
|
-
acc[group] =
|
|
5234
|
+
acc[group] = acc[group] ?? [];
|
|
5235
|
+
acc[group].push(item);
|
|
4997
5236
|
return acc;
|
|
4998
5237
|
}, {});
|
|
4999
5238
|
}
|
|
5000
|
-
/**
|
|
5001
|
-
function
|
|
5002
|
-
return
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
return array.every(predicate);
|
|
5012
|
-
}
|
|
5013
|
-
/** Returns true if predicate holds for at least one element. */
|
|
5014
|
-
function some(array, predicate) {
|
|
5015
|
-
return array.some(predicate);
|
|
5016
|
-
}
|
|
5017
|
-
/** Partitions an array into two groups based on predicate. */
|
|
5018
|
-
function partition(array, predicate) {
|
|
5019
|
-
const pass = [];
|
|
5020
|
-
const fail = [];
|
|
5021
|
-
for (const item of array) {
|
|
5022
|
-
(predicate(item) ? pass : fail).push(item);
|
|
5023
|
-
}
|
|
5024
|
-
return [pass, fail];
|
|
5025
|
-
}
|
|
5026
|
-
|
|
5027
|
-
var array_util = /*#__PURE__*/Object.freeze({
|
|
5028
|
-
__proto__: null,
|
|
5029
|
-
average: average$1,
|
|
5030
|
-
chunk: chunk,
|
|
5031
|
-
compact: compact,
|
|
5032
|
-
countBy: countBy,
|
|
5033
|
-
difference: difference,
|
|
5034
|
-
every: every,
|
|
5035
|
-
filterBy: filterBy,
|
|
5036
|
-
first: first,
|
|
5037
|
-
flatten: flatten,
|
|
5038
|
-
flattenDeep: flattenDeep,
|
|
5039
|
-
groupBy: groupBy,
|
|
5040
|
-
intersection: intersection,
|
|
5041
|
-
isEmpty: isEmpty$2,
|
|
5042
|
-
last: last,
|
|
5043
|
-
maxBy: maxBy,
|
|
5044
|
-
minBy: minBy,
|
|
5045
|
-
move: move,
|
|
5046
|
-
paginate: paginate,
|
|
5047
|
-
partition: partition,
|
|
5048
|
-
sample: sample,
|
|
5049
|
-
shuffle: shuffle,
|
|
5050
|
-
some: some,
|
|
5051
|
-
sortBy: sortBy,
|
|
5052
|
-
sumBy: sumBy,
|
|
5053
|
-
toMap: toMap,
|
|
5054
|
-
toggle: toggle,
|
|
5055
|
-
union: union,
|
|
5056
|
-
unique: unique,
|
|
5057
|
-
uniqueBy: uniqueBy,
|
|
5058
|
-
zip: zip
|
|
5059
|
-
});
|
|
5060
|
-
|
|
5061
|
-
// ─── Date Utilities ───────────────────────────────────────────────────────────
|
|
5062
|
-
const MONTH_NAMES_SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
5063
|
-
const MONTH_NAMES_FULL = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
5064
|
-
const DAY_NAMES_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
5065
|
-
const DAY_NAMES_FULL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
5066
|
-
function pad(n) {
|
|
5067
|
-
return String(n).padStart(2, '0');
|
|
5068
|
-
}
|
|
5069
|
-
/** Returns the current date and time. */
|
|
5070
|
-
function now() {
|
|
5071
|
-
return new Date();
|
|
5072
|
-
}
|
|
5073
|
-
/** Returns today's date with time set to midnight. */
|
|
5074
|
-
function today() {
|
|
5075
|
-
return startOfDay(new Date());
|
|
5076
|
-
}
|
|
5077
|
-
/** Returns true if the value is a valid Date object. */
|
|
5078
|
-
function isValidDate$1(value) {
|
|
5079
|
-
return value instanceof Date && !isNaN(value.getTime());
|
|
5080
|
-
}
|
|
5081
|
-
/**
|
|
5082
|
-
* Formats a Date using a pattern string.
|
|
5083
|
-
* Tokens: YYYY, YY, MM, M, DD, D, HH, H, mm, m, ss, s,
|
|
5084
|
-
* MMM (short month), MMMM (full month),
|
|
5085
|
-
* ddd (short day), dddd (full day).
|
|
5086
|
-
*/
|
|
5087
|
-
function formatDate(date, pattern) {
|
|
5088
|
-
const d = new Date(date);
|
|
5089
|
-
if (!isValidDate$1(d))
|
|
5090
|
-
return '';
|
|
5091
|
-
const year = d.getFullYear();
|
|
5092
|
-
const month = d.getMonth();
|
|
5093
|
-
const day = d.getDate();
|
|
5094
|
-
const hours = d.getHours();
|
|
5095
|
-
const mins = d.getMinutes();
|
|
5096
|
-
const secs = d.getSeconds();
|
|
5097
|
-
const dayOfWeek = d.getDay();
|
|
5098
|
-
return pattern
|
|
5099
|
-
.replace('YYYY', String(year))
|
|
5100
|
-
.replace('YY', String(year).slice(-2))
|
|
5101
|
-
.replace('MMMM', MONTH_NAMES_FULL[month])
|
|
5102
|
-
.replace('MMM', MONTH_NAMES_SHORT[month])
|
|
5103
|
-
.replace('MM', pad(month + 1))
|
|
5104
|
-
.replace('M', String(month + 1))
|
|
5105
|
-
.replace('dddd', DAY_NAMES_FULL[dayOfWeek])
|
|
5106
|
-
.replace('ddd', DAY_NAMES_SHORT[dayOfWeek])
|
|
5107
|
-
.replace('DD', pad(day))
|
|
5108
|
-
.replace('D', String(day))
|
|
5109
|
-
.replace('HH', pad(hours))
|
|
5110
|
-
.replace('H', String(hours))
|
|
5111
|
-
.replace('mm', pad(mins))
|
|
5112
|
-
.replace('m', String(mins))
|
|
5113
|
-
.replace('ss', pad(secs))
|
|
5114
|
-
.replace('s', String(secs));
|
|
5115
|
-
}
|
|
5116
|
-
/** Returns date as `YYYY-MM-DD`. */
|
|
5117
|
-
function toDateOnly(date) {
|
|
5118
|
-
return formatDate(date, 'YYYY-MM-DD');
|
|
5119
|
-
}
|
|
5120
|
-
/** Returns the ISO 8601 string for a date. */
|
|
5121
|
-
function toISOString(date) {
|
|
5122
|
-
return date.toISOString();
|
|
5123
|
-
}
|
|
5124
|
-
/** Returns a new date with `days` added. */
|
|
5125
|
-
function addDays(date, days) {
|
|
5126
|
-
const result = new Date(date);
|
|
5127
|
-
result.setDate(result.getDate() + days);
|
|
5128
|
-
return result;
|
|
5129
|
-
}
|
|
5130
|
-
/** Returns a new date with `months` added. */
|
|
5131
|
-
function addMonths(date, months) {
|
|
5132
|
-
const result = new Date(date);
|
|
5133
|
-
result.setMonth(result.getMonth() + months);
|
|
5134
|
-
return result;
|
|
5135
|
-
}
|
|
5136
|
-
/** Returns a new date with `years` added. */
|
|
5137
|
-
function addYears(date, years) {
|
|
5138
|
-
const result = new Date(date);
|
|
5139
|
-
result.setFullYear(result.getFullYear() + years);
|
|
5140
|
-
return result;
|
|
5141
|
-
}
|
|
5142
|
-
/** Returns a new date with `hours` added. */
|
|
5143
|
-
function addHours(date, hours) {
|
|
5144
|
-
return new Date(date.getTime() + hours * 3_600_000);
|
|
5145
|
-
}
|
|
5146
|
-
/** Returns a new date with `minutes` added. */
|
|
5147
|
-
function addMinutes(date, minutes) {
|
|
5148
|
-
return new Date(date.getTime() + minutes * 60_000);
|
|
5149
|
-
}
|
|
5150
|
-
/** Returns a new date with `days` subtracted. */
|
|
5151
|
-
function subtractDays(date, days) {
|
|
5152
|
-
return addDays(date, -days);
|
|
5153
|
-
}
|
|
5154
|
-
/** Returns a new date with `months` subtracted. */
|
|
5155
|
-
function subtractMonths(date, months) {
|
|
5156
|
-
return addMonths(date, -months);
|
|
5157
|
-
}
|
|
5158
|
-
/** Returns a new date with `years` subtracted. */
|
|
5159
|
-
function subtractYears(date, years) {
|
|
5160
|
-
return addYears(date, -years);
|
|
5161
|
-
}
|
|
5162
|
-
/** Returns the absolute difference in whole days between two dates. */
|
|
5163
|
-
function diffInDays(date1, date2) {
|
|
5164
|
-
return Math.abs(Math.floor((date1.getTime() - date2.getTime()) / 86_400_000));
|
|
5165
|
-
}
|
|
5166
|
-
/** Returns the absolute difference in whole months between two dates. */
|
|
5167
|
-
function diffInMonths(date1, date2) {
|
|
5168
|
-
return Math.abs((date1.getFullYear() - date2.getFullYear()) * 12 +
|
|
5169
|
-
(date1.getMonth() - date2.getMonth()));
|
|
5170
|
-
}
|
|
5171
|
-
/** Returns the absolute difference in whole years between two dates. */
|
|
5172
|
-
function diffInYears(date1, date2) {
|
|
5173
|
-
return Math.abs(date1.getFullYear() - date2.getFullYear());
|
|
5239
|
+
/** Sorts array by key ascending or descending. */
|
|
5240
|
+
function sortBy(array, key, direction = 'asc') {
|
|
5241
|
+
return [...array].sort((a, b) => {
|
|
5242
|
+
const aVal = a[key];
|
|
5243
|
+
const bVal = b[key];
|
|
5244
|
+
if (aVal < bVal)
|
|
5245
|
+
return direction === 'asc' ? -1 : 1;
|
|
5246
|
+
if (aVal > bVal)
|
|
5247
|
+
return direction === 'asc' ? 1 : -1;
|
|
5248
|
+
return 0;
|
|
5249
|
+
});
|
|
5174
5250
|
}
|
|
5175
|
-
/**
|
|
5176
|
-
function
|
|
5177
|
-
return
|
|
5251
|
+
/** Filters array where key matches value (strict equality). */
|
|
5252
|
+
function filterBy(array, key, value) {
|
|
5253
|
+
return array.filter(item => item[key] === value);
|
|
5178
5254
|
}
|
|
5179
|
-
/**
|
|
5180
|
-
function
|
|
5181
|
-
return
|
|
5255
|
+
/** Sums values at the given numeric key. */
|
|
5256
|
+
function sumBy(array, key) {
|
|
5257
|
+
return array.reduce((acc, item) => acc + Number(item[key]), 0);
|
|
5182
5258
|
}
|
|
5183
|
-
/** Returns
|
|
5184
|
-
function
|
|
5185
|
-
|
|
5259
|
+
/** Returns the item with the minimum value at key. */
|
|
5260
|
+
function minBy(array, key) {
|
|
5261
|
+
if (!array.length)
|
|
5262
|
+
return undefined;
|
|
5263
|
+
return array.reduce((min, item) => (item[key] < min[key] ? item : min));
|
|
5186
5264
|
}
|
|
5187
|
-
/** Returns
|
|
5188
|
-
function
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5265
|
+
/** Returns the item with the maximum value at key. */
|
|
5266
|
+
function maxBy(array, key) {
|
|
5267
|
+
if (!array.length)
|
|
5268
|
+
return undefined;
|
|
5269
|
+
return array.reduce((max, item) => (item[key] > max[key] ? item : max));
|
|
5192
5270
|
}
|
|
5193
|
-
/**
|
|
5194
|
-
function
|
|
5195
|
-
|
|
5271
|
+
/** Computes the average of an array of numbers. */
|
|
5272
|
+
function average$1(numbers) {
|
|
5273
|
+
if (!numbers.length)
|
|
5274
|
+
return 0;
|
|
5275
|
+
return numbers.reduce((a, b) => a + b, 0) / numbers.length;
|
|
5196
5276
|
}
|
|
5197
|
-
/** Returns true if the
|
|
5198
|
-
function
|
|
5199
|
-
return
|
|
5277
|
+
/** Returns true if the array is null, undefined, or has no elements. */
|
|
5278
|
+
function isEmpty$2(array) {
|
|
5279
|
+
return !array || array.length === 0;
|
|
5200
5280
|
}
|
|
5201
|
-
/** Returns
|
|
5202
|
-
function
|
|
5203
|
-
return
|
|
5281
|
+
/** Returns the last element. */
|
|
5282
|
+
function last(array) {
|
|
5283
|
+
return array[array.length - 1];
|
|
5204
5284
|
}
|
|
5205
|
-
/** Returns
|
|
5206
|
-
function
|
|
5207
|
-
return
|
|
5285
|
+
/** Returns the first element. */
|
|
5286
|
+
function first(array) {
|
|
5287
|
+
return array[0];
|
|
5208
5288
|
}
|
|
5209
|
-
/** Returns the
|
|
5210
|
-
function
|
|
5211
|
-
const
|
|
5212
|
-
|
|
5213
|
-
return result;
|
|
5289
|
+
/** Returns a slice of the array for the given page (1-based). */
|
|
5290
|
+
function paginate(array, page, pageSize) {
|
|
5291
|
+
const start = (page - 1) * pageSize;
|
|
5292
|
+
return array.slice(start, start + pageSize);
|
|
5214
5293
|
}
|
|
5215
|
-
/**
|
|
5216
|
-
function
|
|
5217
|
-
const result =
|
|
5218
|
-
result.
|
|
5294
|
+
/** Moves an element from one index to another (immutable). */
|
|
5295
|
+
function move(array, fromIndex, toIndex) {
|
|
5296
|
+
const result = [...array];
|
|
5297
|
+
const [item] = result.splice(fromIndex, 1);
|
|
5298
|
+
result.splice(toIndex, 0, item);
|
|
5219
5299
|
return result;
|
|
5220
5300
|
}
|
|
5221
|
-
/**
|
|
5222
|
-
function
|
|
5223
|
-
return
|
|
5301
|
+
/** Adds the item if absent, removes it if present. */
|
|
5302
|
+
function toggle(array, item) {
|
|
5303
|
+
return array.includes(item) ? array.filter(i => i !== item) : [...array, item];
|
|
5224
5304
|
}
|
|
5225
|
-
/** Returns
|
|
5226
|
-
function
|
|
5227
|
-
const
|
|
5228
|
-
|
|
5229
|
-
return result;
|
|
5305
|
+
/** Returns elements present in both arrays. */
|
|
5306
|
+
function intersection(a, b) {
|
|
5307
|
+
const setB = new Set(b);
|
|
5308
|
+
return a.filter(item => setB.has(item));
|
|
5230
5309
|
}
|
|
5231
|
-
/** Returns
|
|
5232
|
-
function
|
|
5233
|
-
|
|
5310
|
+
/** Returns elements in `a` not present in `b`. */
|
|
5311
|
+
function difference(a, b) {
|
|
5312
|
+
const setB = new Set(b);
|
|
5313
|
+
return a.filter(item => !setB.has(item));
|
|
5234
5314
|
}
|
|
5235
|
-
/**
|
|
5236
|
-
function
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5315
|
+
/** Converts an array to a lookup map keyed by the given property. */
|
|
5316
|
+
function toMap(array, key) {
|
|
5317
|
+
return array.reduce((acc, item) => {
|
|
5318
|
+
acc[String(item[key])] = item;
|
|
5319
|
+
return acc;
|
|
5320
|
+
}, {});
|
|
5240
5321
|
}
|
|
5241
|
-
/**
|
|
5242
|
-
function
|
|
5243
|
-
|
|
5244
|
-
let age = n.getFullYear() - birthDate.getFullYear();
|
|
5245
|
-
const monthDiff = n.getMonth() - birthDate.getMonth();
|
|
5246
|
-
if (monthDiff < 0 || (monthDiff === 0 && n.getDate() < birthDate.getDate()))
|
|
5247
|
-
age--;
|
|
5248
|
-
return age;
|
|
5322
|
+
/** Removes falsy values (null, undefined, 0, '', false). */
|
|
5323
|
+
function compact(array) {
|
|
5324
|
+
return array.filter(Boolean);
|
|
5249
5325
|
}
|
|
5250
|
-
/** Returns
|
|
5251
|
-
function
|
|
5252
|
-
|
|
5326
|
+
/** Returns a new randomly shuffled copy. */
|
|
5327
|
+
function shuffle(array) {
|
|
5328
|
+
const result = [...array];
|
|
5329
|
+
for (let i = result.length - 1; i > 0; i--) {
|
|
5330
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
5331
|
+
[result[i], result[j]] = [result[j], result[i]];
|
|
5332
|
+
}
|
|
5333
|
+
return result;
|
|
5253
5334
|
}
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5335
|
+
function sample(array, count) {
|
|
5336
|
+
if (count === undefined)
|
|
5337
|
+
return array[Math.floor(Math.random() * array.length)];
|
|
5338
|
+
return shuffle(array).slice(0, count);
|
|
5257
5339
|
}
|
|
5258
|
-
/**
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
const future = seconds < 0;
|
|
5266
|
-
const intervals = [
|
|
5267
|
-
[31_536_000, 'year'],
|
|
5268
|
-
[2_592_000, 'month'],
|
|
5269
|
-
[604_800, 'week'],
|
|
5270
|
-
[86_400, 'day'],
|
|
5271
|
-
[3_600, 'hour'],
|
|
5272
|
-
[60, 'minute'],
|
|
5273
|
-
[1, 'second'],
|
|
5274
|
-
];
|
|
5275
|
-
for (const [secs, label] of intervals) {
|
|
5276
|
-
const count = Math.floor(abs / secs);
|
|
5277
|
-
if (count >= 1) {
|
|
5278
|
-
const unit = count === 1 ? label : `${label}s`;
|
|
5279
|
-
return future ? `in ${count} ${unit}` : `${count} ${unit} ago`;
|
|
5280
|
-
}
|
|
5281
|
-
}
|
|
5282
|
-
return 'just now';
|
|
5340
|
+
/** Counts occurrences of each value at the given key. */
|
|
5341
|
+
function countBy(array, key) {
|
|
5342
|
+
return array.reduce((acc, item) => {
|
|
5343
|
+
const group = String(item[key]);
|
|
5344
|
+
acc[group] = (acc[group] ?? 0) + 1;
|
|
5345
|
+
return acc;
|
|
5346
|
+
}, {});
|
|
5283
5347
|
}
|
|
5284
|
-
/** Returns the
|
|
5285
|
-
function
|
|
5286
|
-
|
|
5287
|
-
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
|
|
5288
|
-
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
|
5289
|
-
return Math.ceil((((d.getTime() - yearStart.getTime()) / 86_400_000) + 1) / 7);
|
|
5348
|
+
/** Returns the union of two arrays (unique values from both). */
|
|
5349
|
+
function union(a, b) {
|
|
5350
|
+
return unique([...a, ...b]);
|
|
5290
5351
|
}
|
|
5291
|
-
/**
|
|
5292
|
-
function
|
|
5293
|
-
const
|
|
5294
|
-
|
|
5295
|
-
result.setDate(result.getDate() + 1);
|
|
5296
|
-
}
|
|
5297
|
-
return result;
|
|
5352
|
+
/** Zips multiple arrays into an array of tuples. */
|
|
5353
|
+
function zip(...arrays) {
|
|
5354
|
+
const length = Math.max(...arrays.map(a => a.length));
|
|
5355
|
+
return Array.from({ length }, (_, i) => arrays.map(a => a[i]));
|
|
5298
5356
|
}
|
|
5299
|
-
/** Returns true if
|
|
5300
|
-
function
|
|
5301
|
-
return
|
|
5357
|
+
/** Returns true if predicate holds for all elements. */
|
|
5358
|
+
function every(array, predicate) {
|
|
5359
|
+
return array.every(predicate);
|
|
5302
5360
|
}
|
|
5303
|
-
/**
|
|
5304
|
-
function
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
const
|
|
5310
|
-
|
|
5361
|
+
/** Returns true if predicate holds for at least one element. */
|
|
5362
|
+
function some(array, predicate) {
|
|
5363
|
+
return array.some(predicate);
|
|
5364
|
+
}
|
|
5365
|
+
/** Partitions an array into two groups based on predicate. */
|
|
5366
|
+
function partition(array, predicate) {
|
|
5367
|
+
const pass = [];
|
|
5368
|
+
const fail = [];
|
|
5369
|
+
for (const item of array) {
|
|
5370
|
+
(predicate(item) ? pass : fail).push(item);
|
|
5371
|
+
}
|
|
5372
|
+
return [pass, fail];
|
|
5311
5373
|
}
|
|
5312
5374
|
|
|
5313
|
-
var
|
|
5375
|
+
var array_util = /*#__PURE__*/Object.freeze({
|
|
5314
5376
|
__proto__: null,
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
startOfMonth: startOfMonth,
|
|
5346
|
-
startOfYear: startOfYear,
|
|
5347
|
-
subtractDays: subtractDays,
|
|
5348
|
-
subtractMonths: subtractMonths,
|
|
5349
|
-
subtractYears: subtractYears,
|
|
5350
|
-
timeAgo: timeAgo,
|
|
5351
|
-
toDateOnly: toDateOnly,
|
|
5352
|
-
toISOString: toISOString,
|
|
5353
|
-
today: today
|
|
5377
|
+
average: average$1,
|
|
5378
|
+
chunk: chunk,
|
|
5379
|
+
compact: compact,
|
|
5380
|
+
countBy: countBy,
|
|
5381
|
+
difference: difference,
|
|
5382
|
+
every: every,
|
|
5383
|
+
filterBy: filterBy,
|
|
5384
|
+
first: first,
|
|
5385
|
+
flatten: flatten,
|
|
5386
|
+
flattenDeep: flattenDeep,
|
|
5387
|
+
groupBy: groupBy,
|
|
5388
|
+
intersection: intersection,
|
|
5389
|
+
isEmpty: isEmpty$2,
|
|
5390
|
+
last: last,
|
|
5391
|
+
maxBy: maxBy,
|
|
5392
|
+
minBy: minBy,
|
|
5393
|
+
move: move,
|
|
5394
|
+
paginate: paginate,
|
|
5395
|
+
partition: partition,
|
|
5396
|
+
sample: sample,
|
|
5397
|
+
shuffle: shuffle,
|
|
5398
|
+
some: some,
|
|
5399
|
+
sortBy: sortBy,
|
|
5400
|
+
sumBy: sumBy,
|
|
5401
|
+
toMap: toMap,
|
|
5402
|
+
toggle: toggle,
|
|
5403
|
+
union: union,
|
|
5404
|
+
unique: unique,
|
|
5405
|
+
uniqueBy: uniqueBy,
|
|
5406
|
+
zip: zip
|
|
5354
5407
|
});
|
|
5355
5408
|
|
|
5356
5409
|
// ─── Number Utilities ────────────────────────────────────────────────────────
|