mn-angular-lib 0.0.59 → 0.0.61
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Injectable, Optional, Inject, inject, Input, ChangeDetectionStrategy, Component, HostBinding, signal, ElementRef, DestroyRef, Self, APP_INITIALIZER, HostListener, forwardRef, Directive, EventEmitter, TemplateRef, Output, ViewContainerRef, ViewChild, ViewChildren, ApplicationRef, EnvironmentInjector, createComponent, SkipSelf, Attribute, Pipe } from '@angular/core';
|
|
2
|
+
import { InjectionToken, Injectable, Optional, Inject, inject, Input, ChangeDetectionStrategy, Component, HostBinding, signal, ElementRef, DestroyRef, Self, APP_INITIALIZER, HostListener, forwardRef, Directive, EventEmitter, ChangeDetectorRef, TemplateRef, Output, ViewContainerRef, ViewChild, ViewChildren, ApplicationRef, EnvironmentInjector, createComponent, SkipSelf, Attribute, Pipe } from '@angular/core';
|
|
3
3
|
export { TemplateRef, Type } from '@angular/core';
|
|
4
4
|
import { BehaviorSubject, firstValueFrom, skip, Subject, debounceTime, of, takeUntil, map, catchError } from 'rxjs';
|
|
5
5
|
import * as i1 from '@angular/common';
|
|
@@ -3317,6 +3317,7 @@ class MnTable {
|
|
|
3317
3317
|
loadingMoreRows = false;
|
|
3318
3318
|
currentSort = null;
|
|
3319
3319
|
selectedIds = new Set();
|
|
3320
|
+
cdr = inject(ChangeDetectorRef);
|
|
3320
3321
|
dataSubscription;
|
|
3321
3322
|
searchSubject = new Subject();
|
|
3322
3323
|
searchSubscription;
|
|
@@ -3325,12 +3326,14 @@ class MnTable {
|
|
|
3325
3326
|
this.filteredItems = this.dataSource.dataRows.value;
|
|
3326
3327
|
this.dataSubscription = this.dataSource.dataRows.subscribe(() => {
|
|
3327
3328
|
this.applyFilterAndSort(false);
|
|
3329
|
+
this.cdr.markForCheck();
|
|
3328
3330
|
});
|
|
3329
3331
|
this.searchSubscription = this.searchSubject
|
|
3330
3332
|
.pipe(debounceTime(300))
|
|
3331
3333
|
.subscribe(value => {
|
|
3332
3334
|
this.searchValue = value;
|
|
3333
3335
|
this.applyFilterAndSort(true);
|
|
3336
|
+
this.cdr.markForCheck();
|
|
3334
3337
|
});
|
|
3335
3338
|
}
|
|
3336
3339
|
ngOnDestroy() {
|
|
@@ -3521,11 +3524,11 @@ class MnTable {
|
|
|
3521
3524
|
this.selectionChange.emit(rows);
|
|
3522
3525
|
}
|
|
3523
3526
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3524
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnTable, isStandalone: true, selector: "mn-table", inputs: { dataSource: "dataSource" }, outputs: { sortChange: "sortChange", selectionChange: "selectionChange", rowClick: "rowClick" }, ngImport: i0, template: "<!-- Toolbar: search + custom toolbar template -->\n<div class=\"flex flex-row items-center justify-end gap-2 mb-3\">\n @if (dataSource.canSearch) {\n <div>\n <input\n type=\"text\"\n class=\"input input-sm rounded border border-base-300 bg-base-200 px-3 py-1.5 text-sm text-base-content placeholder-base-content/50 focus:outline-none focus:border-brand-500 w-full max-w-xs\"\n [placeholder]=\"dataSource.searchPlaceholder ?? 'Search...'\"\n (input)=\"onSearch($any($event.target).value)\"\n aria-label=\"Search table\"\n />\n </div>\n }\n @if (dataSource.toolbarTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.toolbarTemplate\"></ng-container>\n }\n</div>\n\n<!-- Table wrapper with horizontal scroll -->\n<div class=\"overflow-x-auto\" role=\"region\" aria-label=\"Data table\">\n <table [class]=\"tableClasses\">\n <thead>\n <tr class=\"bg-base-100\">\n <!-- Selection checkbox column header -->\n @if (hasSelection) {\n <th class=\"w-10 text-center text-sm bg-base-200 px-2 py-2\">\n @if (isMultiSelect) {\n <label>\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"allSelected\"\n (change)=\"toggleAll()\"\n aria-label=\"Select all rows\"\n />\n </label>\n }\n </th>\n }\n\n <!-- Data columns -->\n @for (column of dataSource.columns; track column.key) {\n <th\n class=\"text-sm px-4 py-2\"\n [class.cursor-pointer]=\"isSortable(column)\"\n [class.select-none]=\"isSortable(column)\"\n [class.hover:bg-base-200]=\"isSortable(column)\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n [attr.aria-sort]=\"currentSort?.columnKey === column.key ? (currentSort!.direction === 'asc' ? 'ascending' : 'descending') : null\"\n (click)=\"sort(column)\"\n >\n <span class=\"inline-flex items-center gap-1\">\n @if (isTemplateRef(column.header)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.header)\"></ng-container>\n } @else {\n <span>{{ column.header }}</span>\n }\n @if (isSortable(column)) {\n <span class=\"text-[0.65rem] opacity-70 min-w-3 inline-block\">{{ getSortIcon(column) }}</span>\n }\n </span>\n </th>\n }\n\n <!-- Actions column header -->\n @if (hasRowActions) {\n <th class=\"text-sm px-4 py-2 text-right\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n <!-- Loading state -->\n @if (dataSource.isDataLoading) {\n @for (_ of skeletonRows; track $index) {\n <tr class=\"animate-pulse\">\n @if (hasSelection) {\n <td class=\"px-2 py-3\"><div class=\"h-4 w-4 rounded bg-base-300\"></div></td>\n }\n @for (column of dataSource.columns; track column.key) {\n <td class=\"px-4 py-3\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n >\n <div class=\"h-4 w-3/4 rounded bg-base-300\"></div>\n </td>\n }\n @if (hasRowActions) {\n <td class=\"px-4 py-3\"><div class=\"h-4 w-16 rounded bg-base-300\"></div></td>\n }\n </tr>\n }\n } @else {\n <!-- Empty state -->\n @if (filteredItems.length === 0) {\n <tr class=\"bg-base-100\">\n <td [attr.colspan]=\"totalColumnCount\" class=\"text-center text-xs py-8\">\n @if (dataSource.emptyTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.emptyTemplate\"></ng-container>\n } @else {\n <div class=\"flex flex-col items-center gap-2 text-base-content/50\">\n <p class=\"text-sm\">{{ dataSource.emptyMessage }}</p>\n </div>\n }\n </td>\n </tr>\n }\n\n <!-- Data rows -->\n @for (row of filteredItems; track trackByID($index, row); let odd = $odd; let last = $last) {\n <tr\n class=\"bg-base-100 transition-colors duration-150\"\n [class.bg-brand-50]=\"isSelected(row)\"\n [class.bg-base-200]=\"!isSelected(row) && odd && dataSource.appearance?.striped\"\n [class.hover:bg-base-200]=\"dataSource.appearance?.hover !== false\"\n [class.cursor-pointer]=\"!!dataSource.onRowClick\"\n [class.border-b]=\"!last\"\n [class.border-base-300]=\"!last\"\n [class.border-b-1]=\"last\"\n [class.border-black]=\"last\"\n [class.shadow-3xl]=\"last\"\n (click)=\"onRowClick(row)\"\n >\n <!-- Selection checkbox -->\n @if (hasSelection) {\n <td class=\"w-10 text-center px-2 py-2\">\n <label>\n @if (isMultiSelect) {\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n />\n } @else {\n <input\n type=\"radio\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n name=\"mn-table-single-select\"\n />\n }\n </label>\n </td>\n }\n\n <!-- Data cells -->\n @for (column of dataSource.columns; track column.key) {\n <td\n class=\"text-xs px-4 py-2\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n >\n @if (isTemplateRef(column.cell)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.cell)\" [ngTemplateOutletContext]=\"{ $implicit: row, data: row }\"></ng-container>\n } @else {\n {{ getCellValue(column, row) }}\n }\n </td>\n }\n\n <!-- Row actions -->\n @if (hasRowActions) {\n <td class=\"text-right px-4 py-2\">\n <div class=\"inline-flex items-center justify-end gap-2\">\n @for (action of getVisibleActions(row); track action.label) {\n <button\n class=\"px-2 py-1 text-xs rounded hover:bg-base-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n [ngClass]=\"action.cssClass ?? ''\"\n [disabled]=\"action.isDisabled ? action.isDisabled(row) : false\"\n (click)=\"$event.stopPropagation(); action.onClick(row)\"\n [attr.aria-label]=\"action.label\"\n >\n @if (action.icon) {\n <span [innerHTML]=\"action.icon\"></span>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Load more button -->\n@if (showLoadMore) {\n <div class=\"flex justify-center py-4\">\n <button\n class=\"px-4 py-1.5 text-sm rounded border border-brand-500 text-brand-500 hover:bg-brand-100 transition-colors disabled:opacity-50\"\n (click)=\"loadMoreRows()\"\n [disabled]=\"loadingMoreRows\"\n >\n @if (loadingMoreRows) {\n <span class=\"inline-block w-3 h-3 border-2 border-brand-500 border-t-transparent rounded-full animate-spin mr-2\"></span>\n }\n Load more\n </button>\n </div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
3527
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnTable, isStandalone: true, selector: "mn-table", inputs: { dataSource: "dataSource" }, outputs: { sortChange: "sortChange", selectionChange: "selectionChange", rowClick: "rowClick" }, ngImport: i0, template: "<!-- Toolbar: search + custom toolbar template -->\n<div class=\"flex flex-row items-center justify-end gap-2 mb-3\">\n @if (dataSource.canSearch) {\n <div>\n <input\n type=\"text\"\n class=\"input input-sm rounded border border-base-300 bg-base-200 px-3 py-1.5 text-sm text-base-content placeholder-base-content/50 focus:outline-none focus:border-brand-500 w-full max-w-xs\"\n [placeholder]=\"dataSource.searchPlaceholder ?? 'Search...'\"\n (input)=\"onSearch($any($event.target).value)\"\n aria-label=\"Search table\"\n />\n </div>\n }\n @if (dataSource.toolbarTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.toolbarTemplate\"></ng-container>\n }\n</div>\n\n<!-- Table wrapper with horizontal scroll -->\n<div class=\"overflow-x-auto\" role=\"region\" aria-label=\"Data table\">\n <table [class]=\"tableClasses\">\n <thead>\n <tr class=\"bg-base-100\">\n <!-- Selection checkbox column header -->\n @if (hasSelection) {\n <th class=\"w-10 text-center text-sm bg-base-200 px-2 py-2\">\n @if (isMultiSelect) {\n <label>\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"allSelected\"\n (change)=\"toggleAll()\"\n aria-label=\"Select all rows\"\n />\n </label>\n }\n </th>\n }\n\n <!-- Data columns -->\n @for (column of dataSource.columns; track column.key) {\n <th\n class=\"text-sm px-4 py-2\"\n [class.cursor-pointer]=\"isSortable(column)\"\n [class.select-none]=\"isSortable(column)\"\n [class.hover:bg-base-200]=\"isSortable(column)\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n [attr.aria-sort]=\"currentSort?.columnKey === column.key ? (currentSort!.direction === 'asc' ? 'ascending' : 'descending') : null\"\n (click)=\"sort(column)\"\n >\n <span class=\"inline-flex items-center gap-1\">\n @if (isTemplateRef(column.header)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.header)\"></ng-container>\n } @else {\n <span>{{ column.header }}</span>\n }\n @if (isSortable(column)) {\n <span class=\"text-[0.65rem] opacity-70 min-w-3 inline-block\">{{ getSortIcon(column) }}</span>\n }\n </span>\n </th>\n }\n\n <!-- Actions column header -->\n @if (hasRowActions) {\n <th class=\"text-sm px-4 py-2 text-right\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n <!-- Loading state -->\n @if (dataSource.isDataLoading) {\n @for (_ of skeletonRows; track $index) {\n <tr class=\"animate-pulse\">\n @if (hasSelection) {\n <td class=\"px-2 py-3\"><div class=\"h-4 w-4 rounded bg-base-300\"></div></td>\n }\n @for (column of dataSource.columns; track column.key) {\n <td class=\"px-4 py-3\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n >\n <div class=\"h-4 w-3/4 rounded bg-base-300\"></div>\n </td>\n }\n @if (hasRowActions) {\n <td class=\"px-4 py-3\"><div class=\"h-4 w-16 rounded bg-base-300\"></div></td>\n }\n </tr>\n }\n } @else {\n <!-- Empty state -->\n @if (filteredItems.length === 0) {\n <tr class=\"bg-base-100\">\n <td [attr.colspan]=\"totalColumnCount\" class=\"text-center text-xs py-8\">\n @if (dataSource.emptyTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.emptyTemplate\"></ng-container>\n } @else {\n <div class=\"flex flex-col items-center gap-2 text-base-content/50\">\n <p class=\"text-sm\">{{ dataSource.emptyMessage }}</p>\n </div>\n }\n </td>\n </tr>\n }\n\n <!-- Data rows -->\n @for (row of filteredItems; track trackByID($index, row); let odd = $odd; let last = $last) {\n <tr\n class=\"bg-base-100 transition-colors duration-150\"\n [class.bg-brand-50]=\"isSelected(row)\"\n [class.bg-base-200]=\"!isSelected(row) && odd && dataSource.appearance?.striped\"\n [class.hover:bg-base-200]=\"dataSource.appearance?.hover !== false\"\n [class.cursor-pointer]=\"!!dataSource.onRowClick\"\n [class.border-b]=\"!last\"\n [class.border-base-300]=\"!last\"\n [class.border-b-1]=\"last\"\n [class.border-black]=\"last\"\n [class.shadow-3xl]=\"last\"\n (click)=\"onRowClick(row)\"\n >\n <!-- Selection checkbox -->\n @if (hasSelection) {\n <td class=\"w-10 text-center px-2 py-2\">\n <label>\n @if (isMultiSelect) {\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n />\n } @else {\n <input\n type=\"radio\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n name=\"mn-table-single-select\"\n />\n }\n </label>\n </td>\n }\n\n <!-- Data cells -->\n @for (column of dataSource.columns; track column.key) {\n <td\n class=\"text-xs px-4 py-2\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n >\n @if (isTemplateRef(column.cell)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.cell)\" [ngTemplateOutletContext]=\"{ $implicit: row, data: row }\"></ng-container>\n } @else {\n {{ getCellValue(column, row) }}\n }\n </td>\n }\n\n <!-- Row actions -->\n @if (hasRowActions) {\n <td class=\"text-right px-4 py-2\">\n <div class=\"inline-flex items-center justify-end gap-2\">\n @for (action of getVisibleActions(row); track action.label) {\n <button\n class=\"px-2 py-1 text-xs rounded hover:bg-base-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n [ngClass]=\"action.cssClass ?? ''\"\n [disabled]=\"action.isDisabled ? action.isDisabled(row) : false\"\n (click)=\"$event.stopPropagation(); action.onClick(row)\"\n [attr.aria-label]=\"action.label\"\n >\n @if (action.icon) {\n <span [innerHTML]=\"action.icon\"></span>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Load more button -->\n@if (showLoadMore) {\n <div class=\"flex justify-center py-4\">\n <button\n class=\"px-4 py-1.5 text-sm rounded border border-brand-500 text-brand-500 hover:bg-brand-100 transition-colors disabled:opacity-50\"\n (click)=\"loadMoreRows()\"\n [disabled]=\"loadingMoreRows\"\n >\n @if (loadingMoreRows) {\n <span class=\"inline-block w-3 h-3 border-2 border-brand-500 border-t-transparent rounded-full animate-spin mr-2\"></span>\n }\n Load more\n </button>\n </div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3525
3528
|
}
|
|
3526
3529
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnTable, decorators: [{
|
|
3527
3530
|
type: Component,
|
|
3528
|
-
args: [{ selector: 'mn-table', standalone: true, imports: [NgClass, NgTemplateOutlet], template: "<!-- Toolbar: search + custom toolbar template -->\n<div class=\"flex flex-row items-center justify-end gap-2 mb-3\">\n @if (dataSource.canSearch) {\n <div>\n <input\n type=\"text\"\n class=\"input input-sm rounded border border-base-300 bg-base-200 px-3 py-1.5 text-sm text-base-content placeholder-base-content/50 focus:outline-none focus:border-brand-500 w-full max-w-xs\"\n [placeholder]=\"dataSource.searchPlaceholder ?? 'Search...'\"\n (input)=\"onSearch($any($event.target).value)\"\n aria-label=\"Search table\"\n />\n </div>\n }\n @if (dataSource.toolbarTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.toolbarTemplate\"></ng-container>\n }\n</div>\n\n<!-- Table wrapper with horizontal scroll -->\n<div class=\"overflow-x-auto\" role=\"region\" aria-label=\"Data table\">\n <table [class]=\"tableClasses\">\n <thead>\n <tr class=\"bg-base-100\">\n <!-- Selection checkbox column header -->\n @if (hasSelection) {\n <th class=\"w-10 text-center text-sm bg-base-200 px-2 py-2\">\n @if (isMultiSelect) {\n <label>\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"allSelected\"\n (change)=\"toggleAll()\"\n aria-label=\"Select all rows\"\n />\n </label>\n }\n </th>\n }\n\n <!-- Data columns -->\n @for (column of dataSource.columns; track column.key) {\n <th\n class=\"text-sm px-4 py-2\"\n [class.cursor-pointer]=\"isSortable(column)\"\n [class.select-none]=\"isSortable(column)\"\n [class.hover:bg-base-200]=\"isSortable(column)\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n [attr.aria-sort]=\"currentSort?.columnKey === column.key ? (currentSort!.direction === 'asc' ? 'ascending' : 'descending') : null\"\n (click)=\"sort(column)\"\n >\n <span class=\"inline-flex items-center gap-1\">\n @if (isTemplateRef(column.header)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.header)\"></ng-container>\n } @else {\n <span>{{ column.header }}</span>\n }\n @if (isSortable(column)) {\n <span class=\"text-[0.65rem] opacity-70 min-w-3 inline-block\">{{ getSortIcon(column) }}</span>\n }\n </span>\n </th>\n }\n\n <!-- Actions column header -->\n @if (hasRowActions) {\n <th class=\"text-sm px-4 py-2 text-right\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n <!-- Loading state -->\n @if (dataSource.isDataLoading) {\n @for (_ of skeletonRows; track $index) {\n <tr class=\"animate-pulse\">\n @if (hasSelection) {\n <td class=\"px-2 py-3\"><div class=\"h-4 w-4 rounded bg-base-300\"></div></td>\n }\n @for (column of dataSource.columns; track column.key) {\n <td class=\"px-4 py-3\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n >\n <div class=\"h-4 w-3/4 rounded bg-base-300\"></div>\n </td>\n }\n @if (hasRowActions) {\n <td class=\"px-4 py-3\"><div class=\"h-4 w-16 rounded bg-base-300\"></div></td>\n }\n </tr>\n }\n } @else {\n <!-- Empty state -->\n @if (filteredItems.length === 0) {\n <tr class=\"bg-base-100\">\n <td [attr.colspan]=\"totalColumnCount\" class=\"text-center text-xs py-8\">\n @if (dataSource.emptyTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.emptyTemplate\"></ng-container>\n } @else {\n <div class=\"flex flex-col items-center gap-2 text-base-content/50\">\n <p class=\"text-sm\">{{ dataSource.emptyMessage }}</p>\n </div>\n }\n </td>\n </tr>\n }\n\n <!-- Data rows -->\n @for (row of filteredItems; track trackByID($index, row); let odd = $odd; let last = $last) {\n <tr\n class=\"bg-base-100 transition-colors duration-150\"\n [class.bg-brand-50]=\"isSelected(row)\"\n [class.bg-base-200]=\"!isSelected(row) && odd && dataSource.appearance?.striped\"\n [class.hover:bg-base-200]=\"dataSource.appearance?.hover !== false\"\n [class.cursor-pointer]=\"!!dataSource.onRowClick\"\n [class.border-b]=\"!last\"\n [class.border-base-300]=\"!last\"\n [class.border-b-1]=\"last\"\n [class.border-black]=\"last\"\n [class.shadow-3xl]=\"last\"\n (click)=\"onRowClick(row)\"\n >\n <!-- Selection checkbox -->\n @if (hasSelection) {\n <td class=\"w-10 text-center px-2 py-2\">\n <label>\n @if (isMultiSelect) {\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n />\n } @else {\n <input\n type=\"radio\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n name=\"mn-table-single-select\"\n />\n }\n </label>\n </td>\n }\n\n <!-- Data cells -->\n @for (column of dataSource.columns; track column.key) {\n <td\n class=\"text-xs px-4 py-2\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n >\n @if (isTemplateRef(column.cell)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.cell)\" [ngTemplateOutletContext]=\"{ $implicit: row, data: row }\"></ng-container>\n } @else {\n {{ getCellValue(column, row) }}\n }\n </td>\n }\n\n <!-- Row actions -->\n @if (hasRowActions) {\n <td class=\"text-right px-4 py-2\">\n <div class=\"inline-flex items-center justify-end gap-2\">\n @for (action of getVisibleActions(row); track action.label) {\n <button\n class=\"px-2 py-1 text-xs rounded hover:bg-base-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n [ngClass]=\"action.cssClass ?? ''\"\n [disabled]=\"action.isDisabled ? action.isDisabled(row) : false\"\n (click)=\"$event.stopPropagation(); action.onClick(row)\"\n [attr.aria-label]=\"action.label\"\n >\n @if (action.icon) {\n <span [innerHTML]=\"action.icon\"></span>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Load more button -->\n@if (showLoadMore) {\n <div class=\"flex justify-center py-4\">\n <button\n class=\"px-4 py-1.5 text-sm rounded border border-brand-500 text-brand-500 hover:bg-brand-100 transition-colors disabled:opacity-50\"\n (click)=\"loadMoreRows()\"\n [disabled]=\"loadingMoreRows\"\n >\n @if (loadingMoreRows) {\n <span class=\"inline-block w-3 h-3 border-2 border-brand-500 border-t-transparent rounded-full animate-spin mr-2\"></span>\n }\n Load more\n </button>\n </div>\n}\n" }]
|
|
3531
|
+
args: [{ selector: 'mn-table', standalone: true, imports: [NgClass, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Toolbar: search + custom toolbar template -->\n<div class=\"flex flex-row items-center justify-end gap-2 mb-3\">\n @if (dataSource.canSearch) {\n <div>\n <input\n type=\"text\"\n class=\"input input-sm rounded border border-base-300 bg-base-200 px-3 py-1.5 text-sm text-base-content placeholder-base-content/50 focus:outline-none focus:border-brand-500 w-full max-w-xs\"\n [placeholder]=\"dataSource.searchPlaceholder ?? 'Search...'\"\n (input)=\"onSearch($any($event.target).value)\"\n aria-label=\"Search table\"\n />\n </div>\n }\n @if (dataSource.toolbarTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.toolbarTemplate\"></ng-container>\n }\n</div>\n\n<!-- Table wrapper with horizontal scroll -->\n<div class=\"overflow-x-auto\" role=\"region\" aria-label=\"Data table\">\n <table [class]=\"tableClasses\">\n <thead>\n <tr class=\"bg-base-100\">\n <!-- Selection checkbox column header -->\n @if (hasSelection) {\n <th class=\"w-10 text-center text-sm bg-base-200 px-2 py-2\">\n @if (isMultiSelect) {\n <label>\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"allSelected\"\n (change)=\"toggleAll()\"\n aria-label=\"Select all rows\"\n />\n </label>\n }\n </th>\n }\n\n <!-- Data columns -->\n @for (column of dataSource.columns; track column.key) {\n <th\n class=\"text-sm px-4 py-2\"\n [class.cursor-pointer]=\"isSortable(column)\"\n [class.select-none]=\"isSortable(column)\"\n [class.hover:bg-base-200]=\"isSortable(column)\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n [attr.aria-sort]=\"currentSort?.columnKey === column.key ? (currentSort!.direction === 'asc' ? 'ascending' : 'descending') : null\"\n (click)=\"sort(column)\"\n >\n <span class=\"inline-flex items-center gap-1\">\n @if (isTemplateRef(column.header)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.header)\"></ng-container>\n } @else {\n <span>{{ column.header }}</span>\n }\n @if (isSortable(column)) {\n <span class=\"text-[0.65rem] opacity-70 min-w-3 inline-block\">{{ getSortIcon(column) }}</span>\n }\n </span>\n </th>\n }\n\n <!-- Actions column header -->\n @if (hasRowActions) {\n <th class=\"text-sm px-4 py-2 text-right\">Actions</th>\n }\n </tr>\n </thead>\n\n <tbody>\n <!-- Loading state -->\n @if (dataSource.isDataLoading) {\n @for (_ of skeletonRows; track $index) {\n <tr class=\"animate-pulse\">\n @if (hasSelection) {\n <td class=\"px-2 py-3\"><div class=\"h-4 w-4 rounded bg-base-300\"></div></td>\n }\n @for (column of dataSource.columns; track column.key) {\n <td class=\"px-4 py-3\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n >\n <div class=\"h-4 w-3/4 rounded bg-base-300\"></div>\n </td>\n }\n @if (hasRowActions) {\n <td class=\"px-4 py-3\"><div class=\"h-4 w-16 rounded bg-base-300\"></div></td>\n }\n </tr>\n }\n } @else {\n <!-- Empty state -->\n @if (filteredItems.length === 0) {\n <tr class=\"bg-base-100\">\n <td [attr.colspan]=\"totalColumnCount\" class=\"text-center text-xs py-8\">\n @if (dataSource.emptyTemplate) {\n <ng-container [ngTemplateOutlet]=\"dataSource.emptyTemplate\"></ng-container>\n } @else {\n <div class=\"flex flex-col items-center gap-2 text-base-content/50\">\n <p class=\"text-sm\">{{ dataSource.emptyMessage }}</p>\n </div>\n }\n </td>\n </tr>\n }\n\n <!-- Data rows -->\n @for (row of filteredItems; track trackByID($index, row); let odd = $odd; let last = $last) {\n <tr\n class=\"bg-base-100 transition-colors duration-150\"\n [class.bg-brand-50]=\"isSelected(row)\"\n [class.bg-base-200]=\"!isSelected(row) && odd && dataSource.appearance?.striped\"\n [class.hover:bg-base-200]=\"dataSource.appearance?.hover !== false\"\n [class.cursor-pointer]=\"!!dataSource.onRowClick\"\n [class.border-b]=\"!last\"\n [class.border-base-300]=\"!last\"\n [class.border-b-1]=\"last\"\n [class.border-black]=\"last\"\n [class.shadow-3xl]=\"last\"\n (click)=\"onRowClick(row)\"\n >\n <!-- Selection checkbox -->\n @if (hasSelection) {\n <td class=\"w-10 text-center px-2 py-2\">\n <label>\n @if (isMultiSelect) {\n <input\n type=\"checkbox\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n />\n } @else {\n <input\n type=\"radio\"\n class=\"accent-brand-500\"\n [checked]=\"isSelected(row)\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleRow(row)\"\n name=\"mn-table-single-select\"\n />\n }\n </label>\n </td>\n }\n\n <!-- Data cells -->\n @for (column of dataSource.columns; track column.key) {\n <td\n class=\"text-xs px-4 py-2\"\n [class.text-left]=\"(column.align ?? 'left') === 'left'\"\n [class.text-center]=\"column.align === 'center'\"\n [class.text-right]=\"column.align === 'right'\"\n [class.hidden]=\"column.hiddenBelow === 'sm' || column.hiddenBelow === 'md' || column.hiddenBelow === 'lg'\"\n [class.sm:table-cell]=\"column.hiddenBelow === 'sm'\"\n [class.md:table-cell]=\"column.hiddenBelow === 'md'\"\n [class.lg:table-cell]=\"column.hiddenBelow === 'lg'\"\n [style.width]=\"column.width ?? null\"\n >\n @if (isTemplateRef(column.cell)) {\n <ng-container [ngTemplateOutlet]=\"$any(column.cell)\" [ngTemplateOutletContext]=\"{ $implicit: row, data: row }\"></ng-container>\n } @else {\n {{ getCellValue(column, row) }}\n }\n </td>\n }\n\n <!-- Row actions -->\n @if (hasRowActions) {\n <td class=\"text-right px-4 py-2\">\n <div class=\"inline-flex items-center justify-end gap-2\">\n @for (action of getVisibleActions(row); track action.label) {\n <button\n class=\"px-2 py-1 text-xs rounded hover:bg-base-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n [ngClass]=\"action.cssClass ?? ''\"\n [disabled]=\"action.isDisabled ? action.isDisabled(row) : false\"\n (click)=\"$event.stopPropagation(); action.onClick(row)\"\n [attr.aria-label]=\"action.label\"\n >\n @if (action.icon) {\n <span [innerHTML]=\"action.icon\"></span>\n }\n @if (action.label) {\n <span>{{ action.label }}</span>\n }\n </button>\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Load more button -->\n@if (showLoadMore) {\n <div class=\"flex justify-center py-4\">\n <button\n class=\"px-4 py-1.5 text-sm rounded border border-brand-500 text-brand-500 hover:bg-brand-100 transition-colors disabled:opacity-50\"\n (click)=\"loadMoreRows()\"\n [disabled]=\"loadingMoreRows\"\n >\n @if (loadingMoreRows) {\n <span class=\"inline-block w-3 h-3 border-2 border-brand-500 border-t-transparent rounded-full animate-spin mr-2\"></span>\n }\n Load more\n </button>\n </div>\n}\n" }]
|
|
3529
3532
|
}], propDecorators: { dataSource: [{
|
|
3530
3533
|
type: Input
|
|
3531
3534
|
}], sortChange: [{
|
|
@@ -5209,11 +5212,11 @@ class CalendarMonthComponent {
|
|
|
5209
5212
|
};
|
|
5210
5213
|
}
|
|
5211
5214
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarMonthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5212
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarMonthComponent, isStandalone: true, selector: "app-calendar-month", inputs: { focusDay: "focusDay", eventsChanged: "eventsChanged", focusDayChanged: "focusDayChanged", config: "config" }, outputs: { dayClicked: "dayClicked" }, ngImport: i0, template: "<div class=\"calendar-month\" role=\"grid\" aria-label=\"Month view\">\n <div class=\"month-header\">\n @for (day of longDayNames; track day) {\n <div class=\"day-header\" role=\"columnheader\">{{ day }}</div>\n }\n </div>\n <div class=\"month-grid\">\n @for (item of monthItems; track item.date.getTime()) {\n <div\n class=\"month-cell\"\n [class.other-month]=\"!item.isCurrentMonth\"\n [class.today]=\"item.isToday\"\n (click)=\"onDayClick(item.date)\"\n role=\"gridcell\"\n [attr.aria-label]=\"item.date.toDateString()\">\n <span class=\"day-number\">{{ item.dayNumber }}</span>\n <div class=\"month-events\">\n @for (event of item.events.slice(0, 3); track event.id) {\n <div\n class=\"month-event-dot\"\n [style.background-color]=\"event.color.primaryColor\"\n [title]=\"event.title\">\n </div>\n }\n @if (item.events.length > 3) {\n <span class=\"more-events\">+{{ item.events.length - 3 }}</span>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [".calendar-month{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.month-header{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;font-weight:600;font-size:13px;padding:8px 0;border-bottom:1px solid
|
|
5215
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarMonthComponent, isStandalone: true, selector: "app-calendar-month", inputs: { focusDay: "focusDay", eventsChanged: "eventsChanged", focusDayChanged: "focusDayChanged", config: "config" }, outputs: { dayClicked: "dayClicked" }, ngImport: i0, template: "<div class=\"calendar-month\" role=\"grid\" aria-label=\"Month view\">\n <div class=\"month-header\">\n @for (day of longDayNames; track day) {\n <div class=\"day-header\" role=\"columnheader\">{{ day }}</div>\n }\n </div>\n <div class=\"month-grid\">\n @for (item of monthItems; track item.date.getTime()) {\n <div\n class=\"month-cell\"\n [class.other-month]=\"!item.isCurrentMonth\"\n [class.today]=\"item.isToday\"\n (click)=\"onDayClick(item.date)\"\n role=\"gridcell\"\n [attr.aria-label]=\"item.date.toDateString()\">\n <span class=\"day-number\">{{ item.dayNumber }}</span>\n <div class=\"month-events\">\n @for (event of item.events.slice(0, 3); track event.id) {\n <div\n class=\"month-event-dot\"\n [style.background-color]=\"event.color.primaryColor\"\n [title]=\"event.title\">\n </div>\n }\n @if (item.events.length > 3) {\n <span class=\"more-events\">+{{ item.events.length - 3 }}</span>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [".calendar-month{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.month-header{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;font-weight:600;font-size:13px;padding:8px 0;border-bottom:1px solid var(--color-base-300)}.month-grid{display:grid;grid-template-columns:repeat(7,1fr);grid-template-rows:repeat(6,1fr);flex:1;min-height:0}.month-cell{min-height:0;padding:4px 8px;border:1px solid var(--color-base-200);cursor:pointer;transition:background .15s}.month-cell:hover{background:var(--color-base-200)}.month-cell.other-month{opacity:.4}.month-cell.today .day-number{background:var(--color-primary);color:var(--color-primary-content, white);border-radius:50%;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center}.day-number{font-size:13px;font-weight:500}.month-events{display:flex;gap:2px;flex-wrap:wrap;margin-top:4px}.month-event-dot{width:8px;height:8px;border-radius:50%}.more-events{font-size:10px;color:var(--color-base-content, #6b7280);opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
5213
5216
|
}
|
|
5214
5217
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarMonthComponent, decorators: [{
|
|
5215
5218
|
type: Component,
|
|
5216
|
-
args: [{ selector: 'app-calendar-month', standalone: true, imports: [CommonModule], template: "<div class=\"calendar-month\" role=\"grid\" aria-label=\"Month view\">\n <div class=\"month-header\">\n @for (day of longDayNames; track day) {\n <div class=\"day-header\" role=\"columnheader\">{{ day }}</div>\n }\n </div>\n <div class=\"month-grid\">\n @for (item of monthItems; track item.date.getTime()) {\n <div\n class=\"month-cell\"\n [class.other-month]=\"!item.isCurrentMonth\"\n [class.today]=\"item.isToday\"\n (click)=\"onDayClick(item.date)\"\n role=\"gridcell\"\n [attr.aria-label]=\"item.date.toDateString()\">\n <span class=\"day-number\">{{ item.dayNumber }}</span>\n <div class=\"month-events\">\n @for (event of item.events.slice(0, 3); track event.id) {\n <div\n class=\"month-event-dot\"\n [style.background-color]=\"event.color.primaryColor\"\n [title]=\"event.title\">\n </div>\n }\n @if (item.events.length > 3) {\n <span class=\"more-events\">+{{ item.events.length - 3 }}</span>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [".calendar-month{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.month-header{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;font-weight:600;font-size:13px;padding:8px 0;border-bottom:1px solid
|
|
5219
|
+
args: [{ selector: 'app-calendar-month', standalone: true, imports: [CommonModule], template: "<div class=\"calendar-month\" role=\"grid\" aria-label=\"Month view\">\n <div class=\"month-header\">\n @for (day of longDayNames; track day) {\n <div class=\"day-header\" role=\"columnheader\">{{ day }}</div>\n }\n </div>\n <div class=\"month-grid\">\n @for (item of monthItems; track item.date.getTime()) {\n <div\n class=\"month-cell\"\n [class.other-month]=\"!item.isCurrentMonth\"\n [class.today]=\"item.isToday\"\n (click)=\"onDayClick(item.date)\"\n role=\"gridcell\"\n [attr.aria-label]=\"item.date.toDateString()\">\n <span class=\"day-number\">{{ item.dayNumber }}</span>\n <div class=\"month-events\">\n @for (event of item.events.slice(0, 3); track event.id) {\n <div\n class=\"month-event-dot\"\n [style.background-color]=\"event.color.primaryColor\"\n [title]=\"event.title\">\n </div>\n }\n @if (item.events.length > 3) {\n <span class=\"more-events\">+{{ item.events.length - 3 }}</span>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [".calendar-month{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.month-header{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;font-weight:600;font-size:13px;padding:8px 0;border-bottom:1px solid var(--color-base-300)}.month-grid{display:grid;grid-template-columns:repeat(7,1fr);grid-template-rows:repeat(6,1fr);flex:1;min-height:0}.month-cell{min-height:0;padding:4px 8px;border:1px solid var(--color-base-200);cursor:pointer;transition:background .15s}.month-cell:hover{background:var(--color-base-200)}.month-cell.other-month{opacity:.4}.month-cell.today .day-number{background:var(--color-primary);color:var(--color-primary-content, white);border-radius:50%;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center}.day-number{font-size:13px;font-weight:500}.month-events{display:flex;gap:2px;flex-wrap:wrap;margin-top:4px}.month-event-dot{width:8px;height:8px;border-radius:50%}.more-events{font-size:10px;color:var(--color-base-content, #6b7280);opacity:.6}\n"] }]
|
|
5217
5220
|
}], ctorParameters: () => [], propDecorators: { focusDay: [{
|
|
5218
5221
|
type: Input
|
|
5219
5222
|
}], eventsChanged: [{
|
|
@@ -5416,11 +5419,11 @@ class CalendarEventDefaultComponent {
|
|
|
5416
5419
|
}
|
|
5417
5420
|
}
|
|
5418
5421
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarEventDefaultComponent, deps: [{ token: CALENDAR_DATE_FORMATTER, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
5419
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarEventDefaultComponent, isStandalone: true, selector: "app-calendar-event-default", ngImport: i0, template: "<div class=\"calendar-event-default\" [style.background-color]=\"event.color.secondaryColor\" [style.border-left-color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedTime }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".calendar-event-default{padding:4px 8px;border-left:3px solid #3b82f6;border-radius:4px;font-size:12px;height:100%;overflow:hidden;cursor:pointer}.event-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.event-time{font-size:11px;opacity:.
|
|
5422
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarEventDefaultComponent, isStandalone: true, selector: "app-calendar-event-default", ngImport: i0, template: "<div class=\"calendar-event-default\" [style.background-color]=\"event.color.secondaryColor\" [style.border-left-color]=\"event.color.primaryColor\" [style.color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedTime }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".calendar-event-default{padding:4px 8px;border-left:3px solid var(--color-primary, #3b82f6);border-radius:4px;font-size:12px;height:100%;overflow:hidden;cursor:pointer}.event-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}.event-time{font-size:11px;opacity:.85;color:inherit}.event-description{font-size:11px;opacity:.75;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
5420
5423
|
}
|
|
5421
5424
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarEventDefaultComponent, decorators: [{
|
|
5422
5425
|
type: Component,
|
|
5423
|
-
args: [{ selector: 'app-calendar-event-default', standalone: true, imports: [CommonModule], template: "<div class=\"calendar-event-default\" [style.background-color]=\"event.color.secondaryColor\" [style.border-left-color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedTime }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".calendar-event-default{padding:4px 8px;border-left:3px solid #3b82f6;border-radius:4px;font-size:12px;height:100%;overflow:hidden;cursor:pointer}.event-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.event-time{font-size:11px;opacity:.
|
|
5426
|
+
args: [{ selector: 'app-calendar-event-default', standalone: true, imports: [CommonModule], template: "<div class=\"calendar-event-default\" [style.background-color]=\"event.color.secondaryColor\" [style.border-left-color]=\"event.color.primaryColor\" [style.color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedTime }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".calendar-event-default{padding:4px 8px;border-left:3px solid var(--color-primary, #3b82f6);border-radius:4px;font-size:12px;height:100%;overflow:hidden;cursor:pointer}.event-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}.event-time{font-size:11px;opacity:.85;color:inherit}.event-description{font-size:11px;opacity:.75;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:inherit}\n"] }]
|
|
5424
5427
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
5425
5428
|
type: Optional
|
|
5426
5429
|
}, {
|
|
@@ -5684,11 +5687,11 @@ class CalendarWeekComponent {
|
|
|
5684
5687
|
}
|
|
5685
5688
|
}
|
|
5686
5689
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarWeekComponent, deps: [{ token: CalendarEventLayoutService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5687
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarWeekComponent, isStandalone: true, selector: "app-calendar-week", inputs: { focusDay: "focusDay", eventsChanged: "eventsChanged", focusDayChanged: "focusDayChanged", config: "config", calendarEventComponent: "calendarEventComponent" }, outputs: { eventClicked: "eventClicked" }, providers: [CalendarEventLayoutService], ngImport: i0, template: "<div class=\"calendar-week\" role=\"grid\" aria-label=\"Week view\">\n <div class=\"week-header\" [style.grid-template-columns]=\"'60px ' + gridTemplateColumns\">\n <div class=\"time-gutter-header\"></div>\n @for (col of columns; track col.dayName; let i = $index) {\n <div class=\"day-column-header\"\n [class.today]=\"col.isToday\"\n [style.grid-column]=\"getHeaderColumn(i)\"\n role=\"columnheader\">\n <span class=\"day-name\">{{ col.dayName }}</span>\n <span class=\"day-number\">{{ col.dayNumber }}</span>\n </div>\n }\n </div>\n <div class=\"week-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"week-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"gridTemplateColumns\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && currentTimeCol) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"currentTimeCol\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"week-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-week{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.week-header{display:grid;border-bottom:1px solid
|
|
5690
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarWeekComponent, isStandalone: true, selector: "app-calendar-week", inputs: { focusDay: "focusDay", eventsChanged: "eventsChanged", focusDayChanged: "focusDayChanged", config: "config", calendarEventComponent: "calendarEventComponent" }, outputs: { eventClicked: "eventClicked" }, providers: [CalendarEventLayoutService], ngImport: i0, template: "<div class=\"calendar-week\" role=\"grid\" aria-label=\"Week view\">\n <div class=\"week-header\" [style.grid-template-columns]=\"'60px ' + gridTemplateColumns\">\n <div class=\"time-gutter-header\"></div>\n @for (col of columns; track col.dayName; let i = $index) {\n <div class=\"day-column-header\"\n [class.today]=\"col.isToday\"\n [style.grid-column]=\"getHeaderColumn(i)\"\n role=\"columnheader\">\n <span class=\"day-name\">{{ col.dayName }}</span>\n <span class=\"day-number\">{{ col.dayNumber }}</span>\n </div>\n }\n </div>\n <div class=\"week-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"week-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"gridTemplateColumns\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && currentTimeCol) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"currentTimeCol\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"week-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-week{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.week-header{display:grid;border-bottom:1px solid var(--color-base-300)}.time-gutter-header{min-width:60px}.day-column-header{text-align:center;padding:8px 4px;font-size:13px}.day-column-header.today{color:var(--color-primary);font-weight:700}.day-name{display:block;font-size:11px;text-transform:uppercase;color:var(--color-base-content, #6b7280);opacity:.7}.day-number{font-size:18px;font-weight:600}.week-body{display:grid;grid-template-columns:60px 1fr;flex:1;min-height:0;overflow:hidden;align-items:stretch}.time-gutter{display:grid;height:100%;min-height:0}.hour-label{font-size:11px;color:var(--color-base-content, #6b7280);opacity:.7;text-align:right;padding-right:8px;display:flex;align-items:start;min-height:0;overflow:hidden}.week-grid{display:grid;position:relative;grid-auto-rows:1fr;height:100%;min-height:0}.hour-line{border-top:1px solid var(--color-base-200);pointer-events:none;min-height:0}.week-event{z-index:1;padding:1px 2px;overflow:hidden;min-height:0}.current-time-line{position:relative;z-index:2;pointer-events:none}.current-time-dot{width:8px;height:8px;background:var(--color-error, #ef4444);border-radius:50%;position:absolute;left:-4px;top:-4px}.current-time-rule{height:2px;background:var(--color-error, #ef4444);width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CalendarEventComponent, selector: "app-calendar-event", inputs: ["event", "customComponent"], outputs: ["eventClicked"] }] });
|
|
5688
5691
|
}
|
|
5689
5692
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarWeekComponent, decorators: [{
|
|
5690
5693
|
type: Component,
|
|
5691
|
-
args: [{ selector: 'app-calendar-week', standalone: true, imports: [CommonModule, CalendarEventComponent], providers: [CalendarEventLayoutService], template: "<div class=\"calendar-week\" role=\"grid\" aria-label=\"Week view\">\n <div class=\"week-header\" [style.grid-template-columns]=\"'60px ' + gridTemplateColumns\">\n <div class=\"time-gutter-header\"></div>\n @for (col of columns; track col.dayName; let i = $index) {\n <div class=\"day-column-header\"\n [class.today]=\"col.isToday\"\n [style.grid-column]=\"getHeaderColumn(i)\"\n role=\"columnheader\">\n <span class=\"day-name\">{{ col.dayName }}</span>\n <span class=\"day-number\">{{ col.dayNumber }}</span>\n </div>\n }\n </div>\n <div class=\"week-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"week-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"gridTemplateColumns\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && currentTimeCol) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"currentTimeCol\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"week-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-week{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.week-header{display:grid;border-bottom:1px solid
|
|
5694
|
+
args: [{ selector: 'app-calendar-week', standalone: true, imports: [CommonModule, CalendarEventComponent], providers: [CalendarEventLayoutService], template: "<div class=\"calendar-week\" role=\"grid\" aria-label=\"Week view\">\n <div class=\"week-header\" [style.grid-template-columns]=\"'60px ' + gridTemplateColumns\">\n <div class=\"time-gutter-header\"></div>\n @for (col of columns; track col.dayName; let i = $index) {\n <div class=\"day-column-header\"\n [class.today]=\"col.isToday\"\n [style.grid-column]=\"getHeaderColumn(i)\"\n role=\"columnheader\">\n <span class=\"day-name\">{{ col.dayName }}</span>\n <span class=\"day-number\">{{ col.dayNumber }}</span>\n </div>\n }\n </div>\n <div class=\"week-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"week-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"gridTemplateColumns\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && currentTimeCol) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"currentTimeCol\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"week-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-week{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.week-header{display:grid;border-bottom:1px solid var(--color-base-300)}.time-gutter-header{min-width:60px}.day-column-header{text-align:center;padding:8px 4px;font-size:13px}.day-column-header.today{color:var(--color-primary);font-weight:700}.day-name{display:block;font-size:11px;text-transform:uppercase;color:var(--color-base-content, #6b7280);opacity:.7}.day-number{font-size:18px;font-weight:600}.week-body{display:grid;grid-template-columns:60px 1fr;flex:1;min-height:0;overflow:hidden;align-items:stretch}.time-gutter{display:grid;height:100%;min-height:0}.hour-label{font-size:11px;color:var(--color-base-content, #6b7280);opacity:.7;text-align:right;padding-right:8px;display:flex;align-items:start;min-height:0;overflow:hidden}.week-grid{display:grid;position:relative;grid-auto-rows:1fr;height:100%;min-height:0}.hour-line{border-top:1px solid var(--color-base-200);pointer-events:none;min-height:0}.week-event{z-index:1;padding:1px 2px;overflow:hidden;min-height:0}.current-time-line{position:relative;z-index:2;pointer-events:none}.current-time-dot{width:8px;height:8px;background:var(--color-error, #ef4444);border-radius:50%;position:absolute;left:-4px;top:-4px}.current-time-rule{height:2px;background:var(--color-error, #ef4444);width:100%}\n"] }]
|
|
5692
5695
|
}], ctorParameters: () => [{ type: CalendarEventLayoutService }], propDecorators: { focusDay: [{
|
|
5693
5696
|
type: Input
|
|
5694
5697
|
}], eventsChanged: [{
|
|
@@ -5844,11 +5847,11 @@ class CalendarDayComponent {
|
|
|
5844
5847
|
}
|
|
5845
5848
|
}
|
|
5846
5849
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarDayComponent, deps: [{ token: CalendarEventLayoutService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5847
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarDayComponent, isStandalone: true, selector: "app-calendar-day", inputs: { focusDay: "focusDay", eventsChanged: "eventsChanged", focusDayChanged: "focusDayChanged", config: "config", calendarEventComponent: "calendarEventComponent" }, outputs: { eventClicked: "eventClicked" }, providers: [CalendarEventLayoutService], ngImport: i0, template: "<div class=\"calendar-day\" role=\"grid\" aria-label=\"Day view\">\n <div class=\"day-header\">\n <div class=\"time-gutter-header\"></div>\n <div class=\"day-column-header\" [class.today]=\"isToday\" role=\"columnheader\">\n <span class=\"day-name\">{{ dayName }}</span>\n <span class=\"day-number\">{{ focusDay.getDate() }}</span>\n </div>\n </div>\n <div class=\"day-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"day-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"'repeat(' + totalColumns + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && isToday) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"'1 / -1'\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"day-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-day{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.day-header{display:grid;grid-template-columns:60px 1fr;border-bottom:1px solid
|
|
5850
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarDayComponent, isStandalone: true, selector: "app-calendar-day", inputs: { focusDay: "focusDay", eventsChanged: "eventsChanged", focusDayChanged: "focusDayChanged", config: "config", calendarEventComponent: "calendarEventComponent" }, outputs: { eventClicked: "eventClicked" }, providers: [CalendarEventLayoutService], ngImport: i0, template: "<div class=\"calendar-day\" role=\"grid\" aria-label=\"Day view\">\n <div class=\"day-header\">\n <div class=\"time-gutter-header\"></div>\n <div class=\"day-column-header\" [class.today]=\"isToday\" role=\"columnheader\">\n <span class=\"day-name\">{{ dayName }}</span>\n <span class=\"day-number\">{{ focusDay.getDate() }}</span>\n </div>\n </div>\n <div class=\"day-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"day-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"'repeat(' + totalColumns + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && isToday) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"'1 / -1'\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"day-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-day{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.day-header{display:grid;grid-template-columns:60px 1fr;border-bottom:1px solid var(--color-base-300)}.time-gutter-header{min-width:60px}.day-column-header{text-align:center;padding:8px 4px;font-size:13px}.day-column-header.today{color:var(--color-primary);font-weight:700}.day-name{display:block;font-size:11px;text-transform:uppercase;color:var(--color-base-content, #6b7280);opacity:.7}.day-number{font-size:18px;font-weight:600}.day-body{display:grid;grid-template-columns:60px 1fr;flex:1;min-height:0;overflow:hidden;align-items:stretch}.time-gutter{display:grid;height:100%;min-height:0}.hour-label{font-size:11px;color:var(--color-base-content, #6b7280);opacity:.7;text-align:right;padding-right:8px;display:flex;align-items:start;min-height:0;overflow:hidden}.day-grid{display:grid;position:relative;grid-auto-rows:1fr;height:100%;min-height:0}.hour-line{border-top:1px solid var(--color-base-200);pointer-events:none;min-height:0}.day-event{z-index:1;padding:1px 2px;overflow:hidden;min-height:0}.current-time-line{position:relative;z-index:2;pointer-events:none}.current-time-dot{width:8px;height:8px;background:var(--color-error, #ef4444);border-radius:50%;position:absolute;left:-4px;top:-4px}.current-time-rule{height:2px;background:var(--color-error, #ef4444);width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CalendarEventComponent, selector: "app-calendar-event", inputs: ["event", "customComponent"], outputs: ["eventClicked"] }] });
|
|
5848
5851
|
}
|
|
5849
5852
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarDayComponent, decorators: [{
|
|
5850
5853
|
type: Component,
|
|
5851
|
-
args: [{ selector: 'app-calendar-day', standalone: true, imports: [CommonModule, CalendarEventComponent], providers: [CalendarEventLayoutService], template: "<div class=\"calendar-day\" role=\"grid\" aria-label=\"Day view\">\n <div class=\"day-header\">\n <div class=\"time-gutter-header\"></div>\n <div class=\"day-column-header\" [class.today]=\"isToday\" role=\"columnheader\">\n <span class=\"day-name\">{{ dayName }}</span>\n <span class=\"day-number\">{{ focusDay.getDate() }}</span>\n </div>\n </div>\n <div class=\"day-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"day-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"'repeat(' + totalColumns + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && isToday) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"'1 / -1'\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"day-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-day{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.day-header{display:grid;grid-template-columns:60px 1fr;border-bottom:1px solid
|
|
5854
|
+
args: [{ selector: 'app-calendar-day', standalone: true, imports: [CommonModule, CalendarEventComponent], providers: [CalendarEventLayoutService], template: "<div class=\"calendar-day\" role=\"grid\" aria-label=\"Day view\">\n <div class=\"day-header\">\n <div class=\"time-gutter-header\"></div>\n <div class=\"day-column-header\" [class.today]=\"isToday\" role=\"columnheader\">\n <span class=\"day-name\">{{ dayName }}</span>\n <span class=\"day-number\">{{ focusDay.getDate() }}</span>\n </div>\n </div>\n <div class=\"day-body\">\n <div class=\"time-gutter\" [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-label\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\">\n {{ row.hourLabel }}\n </div>\n }\n </div>\n <div class=\"day-grid\"\n [style.grid-template-rows]=\"'repeat(' + totalRows + ', 1fr)'\"\n [style.grid-template-columns]=\"'repeat(' + totalColumns + ', 1fr)'\">\n @for (row of hourRows; track row.topRow) {\n <div class=\"hour-line\"\n [style.grid-row]=\"row.topRow + '/' + row.bottomRow\"\n [style.grid-column]=\"'1 / -1'\">\n </div>\n }\n @if (currentTimeRow > 0 && isToday) {\n <div class=\"current-time-line\"\n [style.grid-row]=\"currentTimeRow\"\n [style.grid-column]=\"'1 / -1'\">\n <div class=\"current-time-dot\"></div>\n <div class=\"current-time-rule\"></div>\n </div>\n }\n @for (event of displayEvents; track event.id) {\n <div class=\"day-event\"\n [style.grid-row]=\"getEventRow(event)\"\n [style.grid-column]=\"getEventColumn(event)\"\n (click)=\"onEventClick(event)\">\n <app-calendar-event [event]=\"event\" [customComponent]=\"calendarEventComponent\"></app-calendar-event>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".calendar-day{width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden}.day-header{display:grid;grid-template-columns:60px 1fr;border-bottom:1px solid var(--color-base-300)}.time-gutter-header{min-width:60px}.day-column-header{text-align:center;padding:8px 4px;font-size:13px}.day-column-header.today{color:var(--color-primary);font-weight:700}.day-name{display:block;font-size:11px;text-transform:uppercase;color:var(--color-base-content, #6b7280);opacity:.7}.day-number{font-size:18px;font-weight:600}.day-body{display:grid;grid-template-columns:60px 1fr;flex:1;min-height:0;overflow:hidden;align-items:stretch}.time-gutter{display:grid;height:100%;min-height:0}.hour-label{font-size:11px;color:var(--color-base-content, #6b7280);opacity:.7;text-align:right;padding-right:8px;display:flex;align-items:start;min-height:0;overflow:hidden}.day-grid{display:grid;position:relative;grid-auto-rows:1fr;height:100%;min-height:0}.hour-line{border-top:1px solid var(--color-base-200);pointer-events:none;min-height:0}.day-event{z-index:1;padding:1px 2px;overflow:hidden;min-height:0}.current-time-line{position:relative;z-index:2;pointer-events:none}.current-time-dot{width:8px;height:8px;background:var(--color-error, #ef4444);border-radius:50%;position:absolute;left:-4px;top:-4px}.current-time-rule{height:2px;background:var(--color-error, #ef4444);width:100%}\n"] }]
|
|
5852
5855
|
}], ctorParameters: () => [{ type: CalendarEventLayoutService }], propDecorators: { focusDay: [{
|
|
5853
5856
|
type: Input
|
|
5854
5857
|
}], eventsChanged: [{
|
|
@@ -5885,11 +5888,11 @@ class UpcomingEventRowComponent {
|
|
|
5885
5888
|
}
|
|
5886
5889
|
}
|
|
5887
5890
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UpcomingEventRowComponent, deps: [{ token: CALENDAR_DATE_FORMATTER, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
5888
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: UpcomingEventRowComponent, isStandalone: true, selector: "app-upcoming-event-row", inputs: { event: "event" }, outputs: { eventClicked: "eventClicked" }, ngImport: i0, template: "<div class=\"upcoming-event-row\" (click)=\"eventClicked.emit(event)\" [style.border-left-color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedDate }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".upcoming-event-row{padding:8px 12px;border-left:3px solid #3b82f6;margin-bottom:8px;cursor:pointer;border-radius:4px;transition:background .15s}.upcoming-event-row:hover{background
|
|
5891
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: UpcomingEventRowComponent, isStandalone: true, selector: "app-upcoming-event-row", inputs: { event: "event" }, outputs: { eventClicked: "eventClicked" }, ngImport: i0, template: "<div class=\"upcoming-event-row\" (click)=\"eventClicked.emit(event)\" [style.border-left-color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedDate }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".upcoming-event-row{padding:8px 12px;border-left:3px solid var(--color-primary, #3b82f6);margin-bottom:8px;cursor:pointer;border-radius:4px;transition:background .15s}.upcoming-event-row:hover{background:var(--color-base-200)}.event-title{font-weight:600;font-size:13px}.event-time{font-size:12px;color:var(--color-base-content, #6b7280);opacity:.7}.event-description{font-size:12px;color:var(--color-base-content, #9ca3af);opacity:.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
5889
5892
|
}
|
|
5890
5893
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UpcomingEventRowComponent, decorators: [{
|
|
5891
5894
|
type: Component,
|
|
5892
|
-
args: [{ selector: 'app-upcoming-event-row', standalone: true, imports: [CommonModule], template: "<div class=\"upcoming-event-row\" (click)=\"eventClicked.emit(event)\" [style.border-left-color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedDate }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".upcoming-event-row{padding:8px 12px;border-left:3px solid #3b82f6;margin-bottom:8px;cursor:pointer;border-radius:4px;transition:background .15s}.upcoming-event-row:hover{background
|
|
5895
|
+
args: [{ selector: 'app-upcoming-event-row', standalone: true, imports: [CommonModule], template: "<div class=\"upcoming-event-row\" (click)=\"eventClicked.emit(event)\" [style.border-left-color]=\"event.color.primaryColor\">\n <div class=\"event-title\">{{ event.title }}</div>\n <div class=\"event-time\">{{ formattedDate }}</div>\n @if (event.description) {\n <div class=\"event-description\">{{ event.description }}</div>\n }\n</div>\n", styles: [".upcoming-event-row{padding:8px 12px;border-left:3px solid var(--color-primary, #3b82f6);margin-bottom:8px;cursor:pointer;border-radius:4px;transition:background .15s}.upcoming-event-row:hover{background:var(--color-base-200)}.event-title{font-weight:600;font-size:13px}.event-time{font-size:12px;color:var(--color-base-content, #6b7280);opacity:.7}.event-description{font-size:12px;color:var(--color-base-content, #9ca3af);opacity:.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
|
|
5893
5896
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
5894
5897
|
type: Optional
|
|
5895
5898
|
}, {
|
|
@@ -5940,11 +5943,11 @@ class UpcomingEventsComponent {
|
|
|
5940
5943
|
return event.id;
|
|
5941
5944
|
}
|
|
5942
5945
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UpcomingEventsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5943
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: UpcomingEventsComponent, isStandalone: true, selector: "app-upcoming-events", inputs: { eventsChanged: "eventsChanged", config: "config" }, outputs: { eventClicked: "eventClicked" }, ngImport: i0, template: "<div class=\"upcoming-events\" role=\"complementary\" aria-label=\"Upcoming events\">\n <div class=\"upcoming-title\">{{ title }}</div>\n @for (event of upcomingEvents; track event.id) {\n <app-upcoming-event-row\n [event]=\"event\"\n (eventClicked)=\"eventClicked.emit($event)\">\n </app-upcoming-event-row>\n }\n @if (upcomingEvents.length === 0) {\n <div class=\"no-events\">No upcoming events</div>\n }\n</div>\n", styles: [".upcoming-events{padding:16px}.upcoming-title{font-size:16px;font-weight:600;margin-bottom:12px}.no-events{color
|
|
5946
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: UpcomingEventsComponent, isStandalone: true, selector: "app-upcoming-events", inputs: { eventsChanged: "eventsChanged", config: "config" }, outputs: { eventClicked: "eventClicked" }, ngImport: i0, template: "<div class=\"upcoming-events\" role=\"complementary\" aria-label=\"Upcoming events\">\n <div class=\"upcoming-title\">{{ title }}</div>\n @for (event of upcomingEvents; track event.id) {\n <app-upcoming-event-row\n [event]=\"event\"\n (eventClicked)=\"eventClicked.emit($event)\">\n </app-upcoming-event-row>\n }\n @if (upcomingEvents.length === 0) {\n <div class=\"no-events\">No upcoming events</div>\n }\n</div>\n", styles: [".upcoming-events{padding:16px}.upcoming-title{font-size:16px;font-weight:600;margin-bottom:12px}.no-events{color:var(--color-base-content, #9ca3af);opacity:.5;font-size:14px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: UpcomingEventRowComponent, selector: "app-upcoming-event-row", inputs: ["event"], outputs: ["eventClicked"] }] });
|
|
5944
5947
|
}
|
|
5945
5948
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UpcomingEventsComponent, decorators: [{
|
|
5946
5949
|
type: Component,
|
|
5947
|
-
args: [{ selector: 'app-upcoming-events', standalone: true, imports: [CommonModule, UpcomingEventRowComponent], template: "<div class=\"upcoming-events\" role=\"complementary\" aria-label=\"Upcoming events\">\n <div class=\"upcoming-title\">{{ title }}</div>\n @for (event of upcomingEvents; track event.id) {\n <app-upcoming-event-row\n [event]=\"event\"\n (eventClicked)=\"eventClicked.emit($event)\">\n </app-upcoming-event-row>\n }\n @if (upcomingEvents.length === 0) {\n <div class=\"no-events\">No upcoming events</div>\n }\n</div>\n", styles: [".upcoming-events{padding:16px}.upcoming-title{font-size:16px;font-weight:600;margin-bottom:12px}.no-events{color
|
|
5950
|
+
args: [{ selector: 'app-upcoming-events', standalone: true, imports: [CommonModule, UpcomingEventRowComponent], template: "<div class=\"upcoming-events\" role=\"complementary\" aria-label=\"Upcoming events\">\n <div class=\"upcoming-title\">{{ title }}</div>\n @for (event of upcomingEvents; track event.id) {\n <app-upcoming-event-row\n [event]=\"event\"\n (eventClicked)=\"eventClicked.emit($event)\">\n </app-upcoming-event-row>\n }\n @if (upcomingEvents.length === 0) {\n <div class=\"no-events\">No upcoming events</div>\n }\n</div>\n", styles: [".upcoming-events{padding:16px}.upcoming-title{font-size:16px;font-weight:600;margin-bottom:12px}.no-events{color:var(--color-base-content, #9ca3af);opacity:.5;font-size:14px}\n"] }]
|
|
5948
5951
|
}], ctorParameters: () => [], propDecorators: { eventsChanged: [{
|
|
5949
5952
|
type: Input
|
|
5950
5953
|
}], config: [{
|
|
@@ -6127,7 +6130,7 @@ class CalendarViewComponent {
|
|
|
6127
6130
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarViewComponent, deps: [{ token: CALENDAR_DATE_FORMATTER, optional: true }, { token: MN_CALENDAR_CONFIG, optional: true }, { token: CALENDAR_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
6128
6131
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CalendarViewComponent, isStandalone: true, selector: "app-calendar-view", inputs: { showButton: "showButton", buttonTitle: "buttonTitle", CalendarEventComponent: "CalendarEventComponent", NewCalendarItemsEvent: "NewCalendarItemsEvent" }, outputs: { RequestNewCalendarItemsEvent: "RequestNewCalendarItemsEvent", CalendarItemClickedEvent: "CalendarItemClickedEvent", ButtonClickedEvent: "ButtonClickedEvent" }, host: { listeners: { "window:resize": "onResize()" } }, providers: [
|
|
6129
6132
|
provideMnCalendarConfig(DEFAULT_CALENDAR_CONFIG),
|
|
6130
|
-
], ngImport: i0, template: "<div class=\"calendar-view\" role=\"application\" aria-label=\"Calendar\">\n <div class=\"calendar-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"view-switcher\" role=\"tablist\" aria-label=\"Calendar view\">\n @for (view of viewOptions; track view.value) {\n <button\n class=\"view-btn\"\n role=\"tab\"\n [attr.aria-selected]=\"currentView === view.value\"\n [class.active]=\"currentView === view.value\"\n (click)=\"switchView(view.value)\">\n {{ view.label }}\n </button>\n }\n </div>\n <div class=\"date-nav\">\n <button class=\"nav-btn\" (click)=\"navigatePrevious()\" aria-label=\"Previous\">‹</button>\n <input type=\"date\" [value]=\"dateInputValue\" (change)=\"onDateInputChange($event)\" class=\"date-input\" aria-label=\"Select date\" />\n <button class=\"nav-btn\" (click)=\"navigateNext()\" aria-label=\"Next\">›</button>\n <button class=\"today-btn\" (click)=\"goToToday()\">{{ config.todayLabel }}</button>\n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (showButton) {\n <button class=\"action-btn\" (click)=\"ButtonClickedEvent.emit()\">\n {{ buttonTitle }}\n </button>\n }\n </div>\n </div>\n <div class=\"calendar-content\">\n <div class=\"calendar-main\">\n @if (currentView === CalendarView.MONTH) {\n <app-calendar-month\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n (dayClicked)=\"onMonthDayClick($event)\">\n </app-calendar-month>\n }\n @if (currentView === CalendarView.WEEK) {\n <app-calendar-week\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-week>\n }\n @if (currentView === CalendarView.DAY) {\n <app-calendar-day\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-day>\n }\n </div>\n <div class=\"calendar-sidebar\">\n <app-upcoming-events\n [eventsChanged]=\"internalEventsChanged\"\n [config]=\"config\"\n (eventClicked)=\"onEventClick($event)\">\n </app-upcoming-events>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%}.calendar-view{width:100%;height:100%;font-family:inherit;display:flex;flex-direction:column}.calendar-toolbar{display:flex;justify-content:space-between;align-items:center;padding:12px 0;gap:12px;flex-wrap:wrap}.toolbar-left{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.view-switcher{display:flex;border:1px solid
|
|
6133
|
+
], ngImport: i0, template: "<div class=\"calendar-view\" role=\"application\" aria-label=\"Calendar\">\n <div class=\"calendar-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"view-switcher\" role=\"tablist\" aria-label=\"Calendar view\">\n @for (view of viewOptions; track view.value) {\n <button\n class=\"view-btn\"\n role=\"tab\"\n [attr.aria-selected]=\"currentView === view.value\"\n [class.active]=\"currentView === view.value\"\n (click)=\"switchView(view.value)\">\n {{ view.label }}\n </button>\n }\n </div>\n <div class=\"date-nav\">\n <button class=\"nav-btn\" (click)=\"navigatePrevious()\" aria-label=\"Previous\">‹</button>\n <input type=\"date\" [value]=\"dateInputValue\" (change)=\"onDateInputChange($event)\" class=\"date-input\" aria-label=\"Select date\" />\n <button class=\"nav-btn\" (click)=\"navigateNext()\" aria-label=\"Next\">›</button>\n <button class=\"today-btn\" (click)=\"goToToday()\">{{ config.todayLabel }}</button>\n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (showButton) {\n <button class=\"action-btn\" (click)=\"ButtonClickedEvent.emit()\">\n {{ buttonTitle }}\n </button>\n }\n </div>\n </div>\n <div class=\"calendar-content\">\n <div class=\"calendar-main\">\n @if (currentView === CalendarView.MONTH) {\n <app-calendar-month\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n (dayClicked)=\"onMonthDayClick($event)\">\n </app-calendar-month>\n }\n @if (currentView === CalendarView.WEEK) {\n <app-calendar-week\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-week>\n }\n @if (currentView === CalendarView.DAY) {\n <app-calendar-day\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-day>\n }\n </div>\n <div class=\"calendar-sidebar\">\n <app-upcoming-events\n [eventsChanged]=\"internalEventsChanged\"\n [config]=\"config\"\n (eventClicked)=\"onEventClick($event)\">\n </app-upcoming-events>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%}.calendar-view{width:100%;height:100%;font-family:inherit;display:flex;flex-direction:column}.calendar-toolbar{display:flex;justify-content:space-between;align-items:center;padding:12px 0;gap:12px;flex-wrap:wrap}.toolbar-left{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.view-switcher{display:flex;border:1px solid var(--color-base-300);border-radius:6px;overflow:hidden}.view-btn{padding:6px 14px;border:none;background:var(--color-base-100);cursor:pointer;font-size:13px;transition:background .15s}.view-btn:hover{background:var(--color-base-200)}.view-btn.active{background:var(--color-primary);color:var(--color-primary-content, white)}.date-nav{display:flex;align-items:center;gap:4px}.nav-btn{width:32px;height:32px;border:1px solid var(--color-base-300);border-radius:6px;background:var(--color-base-100);cursor:pointer;font-size:18px;display:flex;align-items:center;justify-content:center}.nav-btn:hover{background:var(--color-base-200)}.date-input{padding:4px 8px;border:1px solid var(--color-base-300);border-radius:6px;background:var(--color-base-100);color:var(--color-base-content);font-size:13px}.today-btn{padding:6px 12px;border:1px solid var(--color-base-300);border-radius:6px;background:var(--color-base-100);cursor:pointer;font-size:13px;color:var(--color-base-content)}.today-btn:hover{background:var(--color-base-200)}.action-btn{padding:8px 16px;border:none;border-radius:6px;background:var(--color-primary);color:var(--color-primary-content, white);cursor:pointer;font-size:13px}.action-btn:hover{opacity:.85}.calendar-content{display:grid;grid-template-columns:1fr 220px;gap:12px;flex:1;min-height:0}.calendar-main{min-width:0;min-height:0;overflow:hidden}.calendar-sidebar{border-left:1px solid var(--color-base-300);overflow:auto}@media(max-width:767px){.calendar-toolbar{padding:8px 0}.toolbar-left{flex-direction:column;align-items:flex-start;gap:8px}.view-switcher{display:none}.calendar-content{grid-template-columns:1fr}.calendar-sidebar{display:none}.calendar-main{overflow-y:auto}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: CalendarMonthComponent, selector: "app-calendar-month", inputs: ["focusDay", "eventsChanged", "focusDayChanged", "config"], outputs: ["dayClicked"] }, { kind: "component", type: CalendarWeekComponent, selector: "app-calendar-week", inputs: ["focusDay", "eventsChanged", "focusDayChanged", "config", "calendarEventComponent"], outputs: ["eventClicked"] }, { kind: "component", type: CalendarDayComponent, selector: "app-calendar-day", inputs: ["focusDay", "eventsChanged", "focusDayChanged", "config", "calendarEventComponent"], outputs: ["eventClicked"] }, { kind: "component", type: UpcomingEventsComponent, selector: "app-upcoming-events", inputs: ["eventsChanged", "config"], outputs: ["eventClicked"] }] });
|
|
6131
6134
|
}
|
|
6132
6135
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CalendarViewComponent, decorators: [{
|
|
6133
6136
|
type: Component,
|
|
@@ -6139,7 +6142,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
6139
6142
|
UpcomingEventsComponent
|
|
6140
6143
|
], providers: [
|
|
6141
6144
|
provideMnCalendarConfig(DEFAULT_CALENDAR_CONFIG),
|
|
6142
|
-
], template: "<div class=\"calendar-view\" role=\"application\" aria-label=\"Calendar\">\n <div class=\"calendar-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"view-switcher\" role=\"tablist\" aria-label=\"Calendar view\">\n @for (view of viewOptions; track view.value) {\n <button\n class=\"view-btn\"\n role=\"tab\"\n [attr.aria-selected]=\"currentView === view.value\"\n [class.active]=\"currentView === view.value\"\n (click)=\"switchView(view.value)\">\n {{ view.label }}\n </button>\n }\n </div>\n <div class=\"date-nav\">\n <button class=\"nav-btn\" (click)=\"navigatePrevious()\" aria-label=\"Previous\">‹</button>\n <input type=\"date\" [value]=\"dateInputValue\" (change)=\"onDateInputChange($event)\" class=\"date-input\" aria-label=\"Select date\" />\n <button class=\"nav-btn\" (click)=\"navigateNext()\" aria-label=\"Next\">›</button>\n <button class=\"today-btn\" (click)=\"goToToday()\">{{ config.todayLabel }}</button>\n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (showButton) {\n <button class=\"action-btn\" (click)=\"ButtonClickedEvent.emit()\">\n {{ buttonTitle }}\n </button>\n }\n </div>\n </div>\n <div class=\"calendar-content\">\n <div class=\"calendar-main\">\n @if (currentView === CalendarView.MONTH) {\n <app-calendar-month\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n (dayClicked)=\"onMonthDayClick($event)\">\n </app-calendar-month>\n }\n @if (currentView === CalendarView.WEEK) {\n <app-calendar-week\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-week>\n }\n @if (currentView === CalendarView.DAY) {\n <app-calendar-day\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-day>\n }\n </div>\n <div class=\"calendar-sidebar\">\n <app-upcoming-events\n [eventsChanged]=\"internalEventsChanged\"\n [config]=\"config\"\n (eventClicked)=\"onEventClick($event)\">\n </app-upcoming-events>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%}.calendar-view{width:100%;height:100%;font-family:inherit;display:flex;flex-direction:column}.calendar-toolbar{display:flex;justify-content:space-between;align-items:center;padding:12px 0;gap:12px;flex-wrap:wrap}.toolbar-left{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.view-switcher{display:flex;border:1px solid
|
|
6145
|
+
], template: "<div class=\"calendar-view\" role=\"application\" aria-label=\"Calendar\">\n <div class=\"calendar-toolbar\">\n <div class=\"toolbar-left\">\n <div class=\"view-switcher\" role=\"tablist\" aria-label=\"Calendar view\">\n @for (view of viewOptions; track view.value) {\n <button\n class=\"view-btn\"\n role=\"tab\"\n [attr.aria-selected]=\"currentView === view.value\"\n [class.active]=\"currentView === view.value\"\n (click)=\"switchView(view.value)\">\n {{ view.label }}\n </button>\n }\n </div>\n <div class=\"date-nav\">\n <button class=\"nav-btn\" (click)=\"navigatePrevious()\" aria-label=\"Previous\">‹</button>\n <input type=\"date\" [value]=\"dateInputValue\" (change)=\"onDateInputChange($event)\" class=\"date-input\" aria-label=\"Select date\" />\n <button class=\"nav-btn\" (click)=\"navigateNext()\" aria-label=\"Next\">›</button>\n <button class=\"today-btn\" (click)=\"goToToday()\">{{ config.todayLabel }}</button>\n </div>\n </div>\n <div class=\"toolbar-right\">\n @if (showButton) {\n <button class=\"action-btn\" (click)=\"ButtonClickedEvent.emit()\">\n {{ buttonTitle }}\n </button>\n }\n </div>\n </div>\n <div class=\"calendar-content\">\n <div class=\"calendar-main\">\n @if (currentView === CalendarView.MONTH) {\n <app-calendar-month\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n (dayClicked)=\"onMonthDayClick($event)\">\n </app-calendar-month>\n }\n @if (currentView === CalendarView.WEEK) {\n <app-calendar-week\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-week>\n }\n @if (currentView === CalendarView.DAY) {\n <app-calendar-day\n [focusDay]=\"focusDay\"\n [eventsChanged]=\"internalEventsChanged\"\n [focusDayChanged]=\"internalFocusDayChanged\"\n [config]=\"config\"\n [calendarEventComponent]=\"CalendarEventComponent\"\n (eventClicked)=\"onEventClick($event)\">\n </app-calendar-day>\n }\n </div>\n <div class=\"calendar-sidebar\">\n <app-upcoming-events\n [eventsChanged]=\"internalEventsChanged\"\n [config]=\"config\"\n (eventClicked)=\"onEventClick($event)\">\n </app-upcoming-events>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;width:100%;height:100%}.calendar-view{width:100%;height:100%;font-family:inherit;display:flex;flex-direction:column}.calendar-toolbar{display:flex;justify-content:space-between;align-items:center;padding:12px 0;gap:12px;flex-wrap:wrap}.toolbar-left{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.view-switcher{display:flex;border:1px solid var(--color-base-300);border-radius:6px;overflow:hidden}.view-btn{padding:6px 14px;border:none;background:var(--color-base-100);cursor:pointer;font-size:13px;transition:background .15s}.view-btn:hover{background:var(--color-base-200)}.view-btn.active{background:var(--color-primary);color:var(--color-primary-content, white)}.date-nav{display:flex;align-items:center;gap:4px}.nav-btn{width:32px;height:32px;border:1px solid var(--color-base-300);border-radius:6px;background:var(--color-base-100);cursor:pointer;font-size:18px;display:flex;align-items:center;justify-content:center}.nav-btn:hover{background:var(--color-base-200)}.date-input{padding:4px 8px;border:1px solid var(--color-base-300);border-radius:6px;background:var(--color-base-100);color:var(--color-base-content);font-size:13px}.today-btn{padding:6px 12px;border:1px solid var(--color-base-300);border-radius:6px;background:var(--color-base-100);cursor:pointer;font-size:13px;color:var(--color-base-content)}.today-btn:hover{background:var(--color-base-200)}.action-btn{padding:8px 16px;border:none;border-radius:6px;background:var(--color-primary);color:var(--color-primary-content, white);cursor:pointer;font-size:13px}.action-btn:hover{opacity:.85}.calendar-content{display:grid;grid-template-columns:1fr 220px;gap:12px;flex:1;min-height:0}.calendar-main{min-width:0;min-height:0;overflow:hidden}.calendar-sidebar{border-left:1px solid var(--color-base-300);overflow:auto}@media(max-width:767px){.calendar-toolbar{padding:8px 0}.toolbar-left{flex-direction:column;align-items:flex-start;gap:8px}.view-switcher{display:none}.calendar-content{grid-template-columns:1fr}.calendar-sidebar{display:none}.calendar-main{overflow-y:auto}}\n"] }]
|
|
6143
6146
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
6144
6147
|
type: Optional
|
|
6145
6148
|
}, {
|