@alaarab/ogrid-angular-material 2.0.9 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/column-chooser/column-chooser.component.js +20 -42
- package/dist/esm/column-header-filter/column-header-filter.component.js +88 -228
- package/dist/esm/column-header-menu/column-header-menu.component.js +91 -58
- package/dist/esm/datagrid-table/datagrid-table.component.js +179 -68
- package/dist/esm/datagrid-table/inline-cell-editor.component.js +48 -20
- package/dist/esm/datagrid-table/popover-cell-editor.component.js +39 -20
- package/dist/esm/index.js +2 -0
- package/dist/esm/ogrid/ogrid.component.js +26 -17
- package/dist/esm/pagination-controls/pagination-controls.component.js +23 -36
- package/dist/types/column-chooser/column-chooser.component.d.ts +2 -20
- package/dist/types/column-header-filter/column-header-filter.component.d.ts +6 -68
- package/dist/types/column-header-menu/column-header-menu.component.d.ts +13 -13
- package/dist/types/datagrid-table/datagrid-table.component.d.ts +16 -3
- package/dist/types/datagrid-table/inline-cell-editor.component.d.ts +13 -10
- package/dist/types/datagrid-table/popover-cell-editor.component.d.ts +9 -9
- package/dist/types/index.d.ts +0 -2
- package/dist/types/ogrid/ogrid.component.d.ts +7 -4
- package/dist/types/pagination-controls/pagination-controls.component.d.ts +2 -10
- package/package.json +13 -4
|
@@ -4,43 +4,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Component,
|
|
7
|
+
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
|
8
|
+
import { BaseColumnChooserComponent } from '@alaarab/ogrid-angular';
|
|
8
9
|
/**
|
|
9
10
|
* Column visibility chooser dropdown using Angular Material styling.
|
|
10
11
|
* Standalone component with inline template.
|
|
11
12
|
*/
|
|
12
|
-
let ColumnChooserComponent = class ColumnChooserComponent {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.columns = input.required();
|
|
15
|
-
this.visibleColumns = input.required();
|
|
16
|
-
this.visibilityChange = output();
|
|
17
|
-
this.isOpen = signal(false);
|
|
18
|
-
this.visibleCount = computed(() => this.visibleColumns().size);
|
|
19
|
-
this.totalCount = computed(() => this.columns().length);
|
|
20
|
-
}
|
|
21
|
-
toggle() {
|
|
22
|
-
this.isOpen.update((v) => !v);
|
|
23
|
-
}
|
|
24
|
-
onCheckboxChange(columnKey, event) {
|
|
25
|
-
const checked = event.target.checked;
|
|
26
|
-
this.visibilityChange.emit({ columnKey, visible: checked });
|
|
27
|
-
}
|
|
28
|
-
selectAll() {
|
|
29
|
-
for (const col of this.columns()) {
|
|
30
|
-
if (!this.visibleColumns().has(col.columnId)) {
|
|
31
|
-
this.visibilityChange.emit({ columnKey: col.columnId, visible: true });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
clearAll() {
|
|
36
|
-
for (const col of this.columns()) {
|
|
37
|
-
if (this.visibleColumns().has(col.columnId)) {
|
|
38
|
-
this.visibilityChange.emit({ columnKey: col.columnId, visible: false });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
13
|
+
let ColumnChooserComponent = class ColumnChooserComponent extends BaseColumnChooserComponent {
|
|
42
14
|
onDocumentClick(event) {
|
|
43
|
-
// Close dropdown when clicking outside
|
|
44
15
|
const el = event.target;
|
|
45
16
|
if (!el.closest('ogrid-column-chooser')) {
|
|
46
17
|
this.isOpen.set(false);
|
|
@@ -71,11 +42,11 @@ ColumnChooserComponent = __decorate([
|
|
|
71
42
|
</div>
|
|
72
43
|
|
|
73
44
|
<div class="ogrid-column-chooser__list">
|
|
74
|
-
@for (col of columns
|
|
45
|
+
@for (col of columns; track col.columnId) {
|
|
75
46
|
<label class="ogrid-column-chooser__item">
|
|
76
47
|
<input
|
|
77
48
|
type="checkbox"
|
|
78
|
-
[checked]="visibleColumns
|
|
49
|
+
[checked]="visibleColumns.has(col.columnId)"
|
|
79
50
|
(change)="onCheckboxChange(col.columnId, $event)"
|
|
80
51
|
/>
|
|
81
52
|
<span>{{ col.name }}</span>
|
|
@@ -96,20 +67,24 @@ ColumnChooserComponent = __decorate([
|
|
|
96
67
|
.ogrid-column-chooser { position: relative; }
|
|
97
68
|
.ogrid-column-chooser__trigger {
|
|
98
69
|
display: inline-flex; align-items: center; gap: 6px;
|
|
99
|
-
padding: 6px 12px; border: 1px solid rgba(0,0,0,0.23); border-radius: 4px;
|
|
70
|
+
padding: 6px 12px; border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.23)); border-radius: 4px;
|
|
100
71
|
background: transparent; cursor: pointer; font-size: 14px; font-weight: 600;
|
|
101
72
|
text-transform: none; white-space: nowrap;
|
|
73
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
102
74
|
}
|
|
75
|
+
.ogrid-column-chooser__trigger:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
|
|
103
76
|
.ogrid-column-chooser__caret { font-size: 10px; }
|
|
104
77
|
.ogrid-column-chooser__dropdown {
|
|
105
78
|
position: absolute; top: 100%; right: 0; z-index: 10;
|
|
106
79
|
min-width: 220px; margin-top: 4px;
|
|
107
|
-
background: #
|
|
108
|
-
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
80
|
+
background: var(--ogrid-bg, #ffffff); border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12)); border-radius: 4px;
|
|
81
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
109
82
|
}
|
|
110
83
|
.ogrid-column-chooser__header {
|
|
111
84
|
padding: 8px 12px; font-size: 14px; font-weight: 600;
|
|
112
|
-
border-bottom: 1px solid rgba(0,0,0,0.12);
|
|
85
|
+
border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
|
|
86
|
+
background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
|
|
87
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
113
88
|
}
|
|
114
89
|
.ogrid-column-chooser__list {
|
|
115
90
|
max-height: 320px; overflow-y: auto; padding: 4px 0;
|
|
@@ -117,22 +92,25 @@ ColumnChooserComponent = __decorate([
|
|
|
117
92
|
.ogrid-column-chooser__item {
|
|
118
93
|
display: flex; align-items: center; gap: 8px;
|
|
119
94
|
padding: 4px 12px; min-height: 32px; cursor: pointer; font-size: 14px;
|
|
95
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
120
96
|
}
|
|
121
|
-
.ogrid-column-chooser__item:hover { background: rgba(0,0,0,0.04); }
|
|
97
|
+
.ogrid-column-chooser__item:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
|
|
122
98
|
.ogrid-column-chooser__footer {
|
|
123
99
|
display: flex; justify-content: flex-end; gap: 8px;
|
|
124
|
-
padding: 8px 12px; border-top: 1px solid rgba(0,0,0,0.12);
|
|
100
|
+
padding: 8px 12px; border-top: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
|
|
101
|
+
background: var(--ogrid-header-bg, rgba(0, 0, 0, 0.04));
|
|
125
102
|
}
|
|
126
103
|
.ogrid-column-chooser__btn {
|
|
127
104
|
padding: 4px 12px; border: none; border-radius: 4px;
|
|
128
105
|
background: transparent; cursor: pointer; font-size: 13px; text-transform: none;
|
|
106
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
129
107
|
}
|
|
130
|
-
.ogrid-column-chooser__btn:hover { background: rgba(0,0,0,0.04); }
|
|
108
|
+
.ogrid-column-chooser__btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
|
|
131
109
|
.ogrid-column-chooser__btn--primary {
|
|
132
110
|
background: var(--mat-sys-primary, #1976d2); color: #fff;
|
|
133
111
|
}
|
|
134
112
|
.ogrid-column-chooser__btn--primary:hover {
|
|
135
|
-
|
|
113
|
+
opacity: 0.9;
|
|
136
114
|
}
|
|
137
115
|
`],
|
|
138
116
|
host: {
|
|
@@ -4,195 +4,23 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Component,
|
|
7
|
+
import { Component, ChangeDetectionStrategy, ViewChild } from '@angular/core';
|
|
8
|
+
import { BaseColumnHeaderFilterComponent } from '@alaarab/ogrid-angular';
|
|
8
9
|
/**
|
|
9
10
|
* Column header filter component with sort + filter icon + popover.
|
|
10
11
|
* Standalone component with inline template.
|
|
11
12
|
*/
|
|
12
|
-
let ColumnHeaderFilterComponent = class ColumnHeaderFilterComponent {
|
|
13
|
-
|
|
14
|
-
this.
|
|
15
|
-
this.columnName = input.required();
|
|
16
|
-
this.filterType = input.required();
|
|
17
|
-
this.isSorted = input(false);
|
|
18
|
-
this.isSortedDescending = input(false);
|
|
19
|
-
this.onSort = input(undefined);
|
|
20
|
-
this.selectedValues = input(undefined);
|
|
21
|
-
this.onFilterChange = input(undefined);
|
|
22
|
-
this.options = input(undefined);
|
|
23
|
-
this.isLoadingOptions = input(false);
|
|
24
|
-
this.textValue = input('');
|
|
25
|
-
this.onTextChange = input(undefined);
|
|
26
|
-
this.selectedUser = input(undefined);
|
|
27
|
-
this.onUserChange = input(undefined);
|
|
28
|
-
this.peopleSearch = input(undefined);
|
|
29
|
-
this.dateValue = input(undefined);
|
|
30
|
-
this.onDateChange = input(undefined);
|
|
31
|
-
this.headerEl = viewChild('headerEl');
|
|
32
|
-
// Internal state
|
|
33
|
-
this.isFilterOpen = signal(false);
|
|
34
|
-
this.tempTextValue = signal('');
|
|
35
|
-
this.searchText = signal('');
|
|
36
|
-
this.tempSelected = signal(new Set());
|
|
37
|
-
this.peopleSearchText = signal('');
|
|
38
|
-
this.peopleSuggestions = signal([]);
|
|
39
|
-
this.isPeopleLoading = signal(false);
|
|
40
|
-
this.tempDateFrom = signal('');
|
|
41
|
-
this.tempDateTo = signal('');
|
|
42
|
-
// Popover position
|
|
43
|
-
this.popoverTop = signal(0);
|
|
44
|
-
this.popoverLeft = signal(0);
|
|
45
|
-
this.peopleDebounceTimer = null;
|
|
46
|
-
this.hasActiveFilter = computed(() => {
|
|
47
|
-
const ft = this.filterType();
|
|
48
|
-
if (ft === 'text')
|
|
49
|
-
return !!this.textValue();
|
|
50
|
-
if (ft === 'multiSelect')
|
|
51
|
-
return (this.selectedValues()?.length ?? 0) > 0;
|
|
52
|
-
if (ft === 'people')
|
|
53
|
-
return this.selectedUser() != null;
|
|
54
|
-
if (ft === 'date')
|
|
55
|
-
return this.dateValue() != null;
|
|
56
|
-
return false;
|
|
57
|
-
});
|
|
58
|
-
this.filteredOptions = computed(() => {
|
|
59
|
-
const opts = this.options() ?? [];
|
|
60
|
-
const search = this.searchText().toLowerCase().trim();
|
|
61
|
-
if (!search)
|
|
62
|
-
return opts;
|
|
63
|
-
return opts.filter((o) => o.toLowerCase().includes(search));
|
|
64
|
-
});
|
|
13
|
+
let ColumnHeaderFilterComponent = class ColumnHeaderFilterComponent extends BaseColumnHeaderFilterComponent {
|
|
14
|
+
getHeaderEl() {
|
|
15
|
+
return this.headerEl;
|
|
65
16
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
toggleFilter(event) {
|
|
70
|
-
event.stopPropagation();
|
|
71
|
-
if (this.isFilterOpen()) {
|
|
72
|
-
this.isFilterOpen.set(false);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
// Initialize temp state from current values
|
|
76
|
-
this.tempTextValue.set(this.textValue());
|
|
77
|
-
this.tempSelected.set(new Set(this.selectedValues() ?? []));
|
|
78
|
-
this.searchText.set('');
|
|
79
|
-
this.peopleSearchText.set('');
|
|
80
|
-
this.peopleSuggestions.set([]);
|
|
81
|
-
const dv = this.dateValue();
|
|
82
|
-
this.tempDateFrom.set(dv?.from ?? '');
|
|
83
|
-
this.tempDateTo.set(dv?.to ?? '');
|
|
84
|
-
// Compute popover position
|
|
85
|
-
const el = this.headerEl()?.nativeElement;
|
|
86
|
-
if (el) {
|
|
87
|
-
const rect = el.getBoundingClientRect();
|
|
88
|
-
this.popoverTop.set(rect.bottom + 4);
|
|
89
|
-
this.popoverLeft.set(rect.left);
|
|
90
|
-
}
|
|
91
|
-
this.isFilterOpen.set(true);
|
|
92
|
-
}
|
|
93
|
-
// --- Text filter ---
|
|
94
|
-
onTextKeydown(event) {
|
|
95
|
-
event.stopPropagation();
|
|
96
|
-
if (event.key === 'Enter') {
|
|
97
|
-
event.preventDefault();
|
|
98
|
-
this.handleTextApply();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
handleTextApply() {
|
|
102
|
-
this.onTextChange()(this.tempTextValue());
|
|
103
|
-
this.isFilterOpen.set(false);
|
|
104
|
-
}
|
|
105
|
-
handleTextClear() {
|
|
106
|
-
this.tempTextValue.set('');
|
|
107
|
-
this.onTextChange()('');
|
|
108
|
-
this.isFilterOpen.set(false);
|
|
109
|
-
}
|
|
110
|
-
// --- MultiSelect filter ---
|
|
111
|
-
handleCheckboxChange(option, event) {
|
|
112
|
-
const checked = event.target.checked;
|
|
113
|
-
this.tempSelected.update((s) => {
|
|
114
|
-
const next = new Set(s);
|
|
115
|
-
if (checked)
|
|
116
|
-
next.add(option);
|
|
117
|
-
else
|
|
118
|
-
next.delete(option);
|
|
119
|
-
return next;
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
handleSelectAllFiltered() {
|
|
123
|
-
this.tempSelected.update((s) => {
|
|
124
|
-
const next = new Set(s);
|
|
125
|
-
for (const opt of this.filteredOptions())
|
|
126
|
-
next.add(opt);
|
|
127
|
-
return next;
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
handleClearSelection() {
|
|
131
|
-
this.tempSelected.set(new Set());
|
|
132
|
-
}
|
|
133
|
-
handleApplyMultiSelect() {
|
|
134
|
-
this.onFilterChange()(Array.from(this.tempSelected()));
|
|
135
|
-
this.isFilterOpen.set(false);
|
|
136
|
-
}
|
|
137
|
-
// --- People filter ---
|
|
138
|
-
onPeopleSearchInput(event) {
|
|
139
|
-
const value = event.target.value;
|
|
140
|
-
this.peopleSearchText.set(value);
|
|
141
|
-
if (this.peopleDebounceTimer)
|
|
142
|
-
clearTimeout(this.peopleDebounceTimer);
|
|
143
|
-
const query = value.trim();
|
|
144
|
-
if (!query) {
|
|
145
|
-
this.peopleSuggestions.set([]);
|
|
146
|
-
this.isPeopleLoading.set(false);
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
this.isPeopleLoading.set(true);
|
|
150
|
-
this.peopleDebounceTimer = setTimeout(() => {
|
|
151
|
-
const fn = this.peopleSearch();
|
|
152
|
-
if (!fn)
|
|
153
|
-
return;
|
|
154
|
-
fn(query).then((results) => {
|
|
155
|
-
this.peopleSuggestions.set(results);
|
|
156
|
-
this.isPeopleLoading.set(false);
|
|
157
|
-
}).catch(() => {
|
|
158
|
-
this.peopleSuggestions.set([]);
|
|
159
|
-
this.isPeopleLoading.set(false);
|
|
160
|
-
});
|
|
161
|
-
}, 300);
|
|
162
|
-
}
|
|
163
|
-
handleUserSelect(user) {
|
|
164
|
-
this.onUserChange()(user);
|
|
165
|
-
this.isFilterOpen.set(false);
|
|
166
|
-
}
|
|
167
|
-
handleClearUser() {
|
|
168
|
-
this.onUserChange()(undefined);
|
|
169
|
-
this.isFilterOpen.set(false);
|
|
170
|
-
}
|
|
171
|
-
// --- Date filter ---
|
|
172
|
-
handleDateApply() {
|
|
173
|
-
const from = this.tempDateFrom();
|
|
174
|
-
const to = this.tempDateTo();
|
|
175
|
-
if (!from && !to) {
|
|
176
|
-
this.onDateChange()(undefined);
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
this.onDateChange()({ from: from || undefined, to: to || undefined });
|
|
180
|
-
}
|
|
181
|
-
this.isFilterOpen.set(false);
|
|
182
|
-
}
|
|
183
|
-
handleDateClear() {
|
|
184
|
-
this.tempDateFrom.set('');
|
|
185
|
-
this.tempDateTo.set('');
|
|
186
|
-
this.onDateChange()(undefined);
|
|
187
|
-
this.isFilterOpen.set(false);
|
|
188
|
-
}
|
|
189
|
-
onDocumentClick(event) {
|
|
190
|
-
const el = event.target;
|
|
191
|
-
if (!el.closest('ogrid-column-header-filter') && !el.closest('.ogrid-header-filter__popover')) {
|
|
192
|
-
this.isFilterOpen.set(false);
|
|
193
|
-
}
|
|
17
|
+
onDocumentClickWrapper(event) {
|
|
18
|
+
this.onDocumentClick(event, 'ogrid-column-header-filter');
|
|
194
19
|
}
|
|
195
20
|
};
|
|
21
|
+
__decorate([
|
|
22
|
+
ViewChild('headerEl')
|
|
23
|
+
], ColumnHeaderFilterComponent.prototype, "headerEl", void 0);
|
|
196
24
|
ColumnHeaderFilterComponent = __decorate([
|
|
197
25
|
Component({
|
|
198
26
|
selector: 'ogrid-column-header-filter',
|
|
@@ -201,23 +29,23 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
201
29
|
template: `
|
|
202
30
|
<div class="ogrid-header-filter" #headerEl>
|
|
203
31
|
<div class="ogrid-header-filter__label">
|
|
204
|
-
<span class="ogrid-header-filter__name" [title]="columnName
|
|
205
|
-
{{ columnName
|
|
32
|
+
<span class="ogrid-header-filter__name" [title]="columnName" data-header-label>
|
|
33
|
+
{{ columnName }}
|
|
206
34
|
</span>
|
|
207
35
|
</div>
|
|
208
36
|
|
|
209
37
|
<div class="ogrid-header-filter__actions">
|
|
210
|
-
@if (onSort
|
|
38
|
+
@if (onSort) {
|
|
211
39
|
<button
|
|
212
40
|
class="ogrid-header-filter__btn"
|
|
213
|
-
[class.ogrid-header-filter__btn--active]="isSorted
|
|
214
|
-
(click)="onSort
|
|
215
|
-
[attr.aria-label]="'Sort by ' + columnName
|
|
216
|
-
[title]="isSorted
|
|
41
|
+
[class.ogrid-header-filter__btn--active]="isSorted"
|
|
42
|
+
(click)="onSort!()"
|
|
43
|
+
[attr.aria-label]="'Sort by ' + columnName"
|
|
44
|
+
[title]="isSorted ? (isSortedDescending ? 'Sorted descending' : 'Sorted ascending') : 'Sort'"
|
|
217
45
|
>
|
|
218
|
-
@if (isSorted
|
|
46
|
+
@if (isSorted && isSortedDescending) {
|
|
219
47
|
▼
|
|
220
|
-
} @else if (isSorted
|
|
48
|
+
} @else if (isSorted) {
|
|
221
49
|
▲
|
|
222
50
|
} @else {
|
|
223
51
|
↕
|
|
@@ -225,15 +53,15 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
225
53
|
</button>
|
|
226
54
|
}
|
|
227
55
|
|
|
228
|
-
@if (filterType
|
|
56
|
+
@if (filterType !== 'none') {
|
|
229
57
|
<button
|
|
230
|
-
class="ogrid-header-
|
|
231
|
-
[class.ogrid-header-
|
|
58
|
+
class="ogrid-header-filter__filter-btn"
|
|
59
|
+
[class.ogrid-header-filter__filter-btn--active]="hasActiveFilter() || isFilterOpen()"
|
|
232
60
|
(click)="toggleFilter($event)"
|
|
233
|
-
[attr.aria-label]="'Filter ' + columnName
|
|
234
|
-
[title]="'Filter ' + columnName
|
|
61
|
+
[attr.aria-label]="'Filter ' + columnName"
|
|
62
|
+
[title]="'Filter ' + columnName"
|
|
235
63
|
>
|
|
236
|
-
|
|
64
|
+
<span class="ogrid-header-filter__funnel"></span>
|
|
237
65
|
@if (hasActiveFilter()) {
|
|
238
66
|
<span class="ogrid-header-filter__dot"></span>
|
|
239
67
|
}
|
|
@@ -242,7 +70,7 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
242
70
|
</div>
|
|
243
71
|
</div>
|
|
244
72
|
|
|
245
|
-
@if (isFilterOpen() && filterType
|
|
73
|
+
@if (isFilterOpen() && filterType !== 'none') {
|
|
246
74
|
<div
|
|
247
75
|
class="ogrid-header-filter__popover"
|
|
248
76
|
[style.top.px]="popoverTop()"
|
|
@@ -250,10 +78,10 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
250
78
|
(click)="$event.stopPropagation()"
|
|
251
79
|
>
|
|
252
80
|
<div class="ogrid-header-filter__popover-header">
|
|
253
|
-
Filter: {{ columnName
|
|
81
|
+
Filter: {{ columnName }}
|
|
254
82
|
</div>
|
|
255
83
|
|
|
256
|
-
@switch (filterType
|
|
84
|
+
@switch (filterType) {
|
|
257
85
|
@case ('text') {
|
|
258
86
|
<div class="ogrid-header-filter__popover-body" style="width: 260px;">
|
|
259
87
|
<div style="padding: 12px;">
|
|
@@ -286,7 +114,7 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
286
114
|
autocomplete="off"
|
|
287
115
|
/>
|
|
288
116
|
<div class="ogrid-header-filter__options-info">
|
|
289
|
-
{{ filteredOptions().length }} of {{ (options
|
|
117
|
+
{{ filteredOptions().length }} of {{ (options ?? []).length }} options
|
|
290
118
|
</div>
|
|
291
119
|
</div>
|
|
292
120
|
<div class="ogrid-header-filter__select-actions">
|
|
@@ -296,7 +124,7 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
296
124
|
<button class="ogrid-header-filter__action-btn" (click)="handleClearSelection()">Clear</button>
|
|
297
125
|
</div>
|
|
298
126
|
<div class="ogrid-header-filter__options-list">
|
|
299
|
-
@if (isLoadingOptions
|
|
127
|
+
@if (isLoadingOptions) {
|
|
300
128
|
<div class="ogrid-header-filter__loading">Loading...</div>
|
|
301
129
|
} @else if (filteredOptions().length === 0) {
|
|
302
130
|
<div class="ogrid-header-filter__empty">No options found</div>
|
|
@@ -321,14 +149,14 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
321
149
|
}
|
|
322
150
|
@case ('people') {
|
|
323
151
|
<div class="ogrid-header-filter__popover-body" style="width: 300px;">
|
|
324
|
-
@if (selectedUser
|
|
152
|
+
@if (selectedUser) {
|
|
325
153
|
<div class="ogrid-header-filter__people-selected">
|
|
326
154
|
<div class="ogrid-header-filter__people-info-label">Currently filtered by:</div>
|
|
327
155
|
<div class="ogrid-header-filter__people-card">
|
|
328
|
-
<div class="ogrid-header-filter__people-avatar">{{ selectedUser
|
|
156
|
+
<div class="ogrid-header-filter__people-avatar">{{ selectedUser!.displayName?.[0] ?? '?' }}</div>
|
|
329
157
|
<div class="ogrid-header-filter__people-details">
|
|
330
|
-
<div>{{ selectedUser
|
|
331
|
-
<div class="ogrid-header-filter__people-email">{{ selectedUser
|
|
158
|
+
<div>{{ selectedUser!.displayName }}</div>
|
|
159
|
+
<div class="ogrid-header-filter__people-email">{{ selectedUser!.email }}</div>
|
|
332
160
|
</div>
|
|
333
161
|
<button class="ogrid-header-filter__btn" (click)="handleClearUser()" aria-label="Remove filter">×</button>
|
|
334
162
|
</div>
|
|
@@ -364,7 +192,7 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
364
192
|
<div class="ogrid-header-filter__empty">Type to search...</div>
|
|
365
193
|
}
|
|
366
194
|
</div>
|
|
367
|
-
@if (selectedUser
|
|
195
|
+
@if (selectedUser) {
|
|
368
196
|
<div style="padding: 8px 12px; border-top: 1px solid rgba(0,0,0,0.12);">
|
|
369
197
|
<button class="ogrid-header-filter__action-btn" style="width: 100%;" (click)="handleClearUser()">Clear Filter</button>
|
|
370
198
|
</div>
|
|
@@ -392,7 +220,7 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
392
220
|
}
|
|
393
221
|
`,
|
|
394
222
|
styles: [`
|
|
395
|
-
:host { display: flex; align-items: center;
|
|
223
|
+
:host { display: flex; align-items: center; flex: 1; min-width: 0; position: relative; }
|
|
396
224
|
.ogrid-header-filter { display: flex; align-items: center; width: 100%; min-width: 0; }
|
|
397
225
|
.ogrid-header-filter__label { flex: 1; min-width: 0; overflow: hidden; }
|
|
398
226
|
.ogrid-header-filter__name {
|
|
@@ -404,35 +232,63 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
404
232
|
width: 24px; height: 24px; padding: 2px; border: none; border-radius: 4px;
|
|
405
233
|
background: transparent; cursor: pointer; font-size: 12px; line-height: 1;
|
|
406
234
|
display: inline-flex; align-items: center; justify-content: center; position: relative;
|
|
407
|
-
color: rgba(0,0,0,0.54);
|
|
235
|
+
color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.54));
|
|
408
236
|
}
|
|
409
|
-
.ogrid-header-filter__btn:hover { background: rgba(0,0,0,0.
|
|
237
|
+
.ogrid-header-filter__btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.08)); }
|
|
410
238
|
.ogrid-header-filter__btn--active { color: var(--mat-sys-primary, #1976d2); }
|
|
239
|
+
.ogrid-header-filter__filter-btn {
|
|
240
|
+
width: 24px; height: 24px; padding: 2px; border: none; border-radius: 4px;
|
|
241
|
+
background: transparent; cursor: pointer; line-height: 1;
|
|
242
|
+
display: inline-flex; align-items: center; justify-content: center; position: relative;
|
|
243
|
+
opacity: 0.6; transition: opacity 0.15s;
|
|
244
|
+
}
|
|
245
|
+
.ogrid-header-filter:hover .ogrid-header-filter__filter-btn { opacity: 0.8; }
|
|
246
|
+
.ogrid-header-filter__filter-btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.08)); opacity: 1 !important; }
|
|
247
|
+
.ogrid-header-filter__filter-btn--active { opacity: 1 !important; }
|
|
248
|
+
.ogrid-header-filter__funnel {
|
|
249
|
+
display: block; width: 0; height: 0;
|
|
250
|
+
border-left: 5px solid transparent; border-right: 5px solid transparent;
|
|
251
|
+
border-top: 6px solid var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.65));
|
|
252
|
+
position: relative;
|
|
253
|
+
}
|
|
254
|
+
.ogrid-header-filter__funnel::after {
|
|
255
|
+
content: ''; display: block; width: 2px; height: 4px;
|
|
256
|
+
background: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.65)); position: absolute;
|
|
257
|
+
top: -1px; left: -1px;
|
|
258
|
+
}
|
|
259
|
+
.ogrid-header-filter__filter-btn--active .ogrid-header-filter__funnel {
|
|
260
|
+
border-top-color: var(--mat-sys-primary, #1976d2);
|
|
261
|
+
}
|
|
262
|
+
.ogrid-header-filter__filter-btn--active .ogrid-header-filter__funnel::after {
|
|
263
|
+
background: var(--mat-sys-primary, #1976d2);
|
|
264
|
+
}
|
|
411
265
|
.ogrid-header-filter__dot {
|
|
412
266
|
position: absolute; top: 2px; right: 2px;
|
|
413
267
|
width: 6px; height: 6px; border-radius: 50%;
|
|
414
268
|
background: var(--mat-sys-primary, #1976d2);
|
|
415
269
|
}
|
|
416
270
|
.ogrid-header-filter__popover {
|
|
417
|
-
position: fixed; z-index:
|
|
418
|
-
background: #
|
|
419
|
-
border-radius:
|
|
420
|
-
margin-top: 4px;
|
|
271
|
+
position: fixed; z-index: 10000;
|
|
272
|
+
background: var(--ogrid-bg, #ffffff); border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.2));
|
|
273
|
+
border-radius: 8px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.1);
|
|
274
|
+
margin-top: 4px; color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
421
275
|
}
|
|
422
276
|
.ogrid-header-filter__popover-header {
|
|
423
277
|
padding: 8px 12px; font-size: 14px; font-weight: 600;
|
|
424
|
-
border-bottom: 1px solid rgba(0,0,0,0.12);
|
|
278
|
+
border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
|
|
279
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
425
280
|
}
|
|
426
281
|
.ogrid-header-filter__popover-body { }
|
|
427
282
|
.ogrid-header-filter__popover-actions {
|
|
428
283
|
display: flex; justify-content: flex-end; gap: 8px; padding: 8px 12px;
|
|
429
284
|
}
|
|
430
285
|
.ogrid-header-filter__input {
|
|
431
|
-
width: 100%; padding: 8px 12px; border: 1px solid rgba(0,0,0,0.23);
|
|
286
|
+
width: 100%; padding: 8px 12px; border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.23));
|
|
432
287
|
border-radius: 4px; font-size: 14px; box-sizing: border-box;
|
|
288
|
+
background: var(--ogrid-bg, #ffffff); color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
433
289
|
}
|
|
434
290
|
.ogrid-header-filter__input:focus { outline: 2px solid var(--mat-sys-primary, #1976d2); outline-offset: -1px; }
|
|
435
|
-
.ogrid-header-filter__options-info { margin-top: 4px; font-size: 12px; color: rgba(0,0,0,0.6); }
|
|
291
|
+
.ogrid-header-filter__options-info { margin-top: 4px; font-size: 12px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
|
|
436
292
|
.ogrid-header-filter__select-actions {
|
|
437
293
|
display: flex; justify-content: space-between; padding: 4px 12px;
|
|
438
294
|
}
|
|
@@ -440,43 +296,47 @@ ColumnHeaderFilterComponent = __decorate([
|
|
|
440
296
|
.ogrid-header-filter__option {
|
|
441
297
|
display: flex; align-items: center; gap: 8px;
|
|
442
298
|
padding: 4px 8px; cursor: pointer; font-size: 14px;
|
|
299
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
443
300
|
}
|
|
444
|
-
.ogrid-header-filter__option:hover { background: rgba(0,0,0,0.04); }
|
|
301
|
+
.ogrid-header-filter__option:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
|
|
445
302
|
.ogrid-header-filter__loading, .ogrid-header-filter__empty {
|
|
446
|
-
padding: 16px; text-align: center; font-size: 14px; color: rgba(0,0,0,0.6);
|
|
303
|
+
padding: 16px; text-align: center; font-size: 14px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6));
|
|
447
304
|
}
|
|
448
305
|
.ogrid-header-filter__action-btn {
|
|
449
306
|
padding: 4px 12px; border: none; border-radius: 4px;
|
|
450
307
|
background: transparent; cursor: pointer; font-size: 13px;
|
|
308
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
451
309
|
}
|
|
452
|
-
.ogrid-header-filter__action-btn:hover { background: rgba(0,0,0,0.04); }
|
|
310
|
+
.ogrid-header-filter__action-btn:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
|
|
453
311
|
.ogrid-header-filter__action-btn:disabled { opacity: 0.38; cursor: default; }
|
|
454
312
|
.ogrid-header-filter__action-btn--primary {
|
|
455
313
|
background: var(--mat-sys-primary, #1976d2); color: #fff;
|
|
456
314
|
}
|
|
457
|
-
.ogrid-header-filter__action-btn--primary:hover {
|
|
315
|
+
.ogrid-header-filter__action-btn--primary:hover { opacity: 0.9; }
|
|
458
316
|
.ogrid-header-filter__people-selected {
|
|
459
|
-
padding: 12px; border-bottom: 1px solid rgba(0,0,0,0.12);
|
|
317
|
+
padding: 12px; border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
|
|
460
318
|
}
|
|
461
|
-
.ogrid-header-filter__people-info-label { font-size: 12px; color: rgba(0,0,0,0.6); }
|
|
319
|
+
.ogrid-header-filter__people-info-label { font-size: 12px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
|
|
462
320
|
.ogrid-header-filter__people-card {
|
|
463
321
|
display: flex; align-items: center; gap: 8px; margin-top: 4px;
|
|
464
322
|
}
|
|
465
323
|
.ogrid-header-filter__people-avatar {
|
|
466
|
-
width: 32px; height: 32px; border-radius: 50%; background: rgba(0,0,0,0.08);
|
|
324
|
+
width: 32px; height: 32px; border-radius: 50%; background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.08));
|
|
467
325
|
display: flex; align-items: center; justify-content: center;
|
|
468
326
|
font-size: 14px; font-weight: 600; flex-shrink: 0;
|
|
327
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
469
328
|
}
|
|
470
|
-
.ogrid-header-filter__people-details { flex: 1; min-width: 0; font-size: 14px; }
|
|
329
|
+
.ogrid-header-filter__people-details { flex: 1; min-width: 0; font-size: 14px; color: var(--ogrid-fg, rgba(0, 0, 0, 0.87)); }
|
|
471
330
|
.ogrid-header-filter__people-details > div { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
472
|
-
.ogrid-header-filter__people-email { font-size: 12px; color: rgba(0,0,0,0.6); }
|
|
331
|
+
.ogrid-header-filter__people-email { font-size: 12px; color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6)); }
|
|
473
332
|
.ogrid-header-filter__people-option {
|
|
474
333
|
display: flex; align-items: center; gap: 8px; padding: 8px 12px; cursor: pointer;
|
|
334
|
+
color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
|
|
475
335
|
}
|
|
476
|
-
.ogrid-header-filter__people-option:hover { background: rgba(0,0,0,0.04); }
|
|
336
|
+
.ogrid-header-filter__people-option:hover { background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)); }
|
|
477
337
|
`],
|
|
478
338
|
host: {
|
|
479
|
-
'(document:click)': '
|
|
339
|
+
'(document:click)': 'onDocumentClickWrapper($event)',
|
|
480
340
|
},
|
|
481
341
|
})
|
|
482
342
|
], ColumnHeaderFilterComponent);
|