@memberjunction/ng-filter-builder 0.0.1 → 2.123.1
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/lib/filter-builder/filter-builder.component.d.ts +155 -0
- package/dist/lib/filter-builder/filter-builder.component.d.ts.map +1 -0
- package/dist/lib/filter-builder/filter-builder.component.js +482 -0
- package/dist/lib/filter-builder/filter-builder.component.js.map +1 -0
- package/dist/lib/filter-builder.module.d.ts +39 -0
- package/dist/lib/filter-builder.module.d.ts.map +1 -0
- package/dist/lib/filter-builder.module.js +66 -0
- package/dist/lib/filter-builder.module.js.map +1 -0
- package/dist/lib/filter-group/filter-group.component.d.ts +102 -0
- package/dist/lib/filter-group/filter-group.component.d.ts.map +1 -0
- package/dist/lib/filter-group/filter-group.component.js +328 -0
- package/dist/lib/filter-group/filter-group.component.js.map +1 -0
- package/dist/lib/filter-rule/filter-rule.component.d.ts +165 -0
- package/dist/lib/filter-rule/filter-rule.component.d.ts.map +1 -0
- package/dist/lib/filter-rule/filter-rule.component.js +682 -0
- package/dist/lib/filter-rule/filter-rule.component.js.map +1 -0
- package/dist/lib/types/filter.types.d.ts +142 -0
- package/dist/lib/types/filter.types.d.ts.map +1 -0
- package/dist/lib/types/filter.types.js +82 -0
- package/dist/lib/types/filter.types.js.map +1 -0
- package/dist/lib/types/operators.d.ts +49 -0
- package/dist/lib/types/operators.d.ts.map +1 -0
- package/dist/lib/types/operators.js +99 -0
- package/dist/lib/types/operators.js.map +1 -0
- package/dist/public-api.d.ts +15 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +19 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +38 -6
- package/README.md +0 -45
|
@@ -0,0 +1,682 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ViewEncapsulation, HostListener } from '@angular/core';
|
|
2
|
+
import { getOperatorsForType, operatorRequiresValue } from '../types/operators';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
const _forTrack0 = ($index, $item) => $item.name;
|
|
5
|
+
const _forTrack1 = ($index, $item) => $item.value;
|
|
6
|
+
function FilterRuleComponent_Conditional_6_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
7
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
8
|
+
i0.ɵɵelementStart(0, "div", 11);
|
|
9
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_6_For_2_Template_div_click_0_listener() { const field_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.selectField(field_r2.name)); });
|
|
10
|
+
i0.ɵɵtext(1);
|
|
11
|
+
i0.ɵɵelementEnd();
|
|
12
|
+
} if (rf & 2) {
|
|
13
|
+
const field_r2 = ctx.$implicit;
|
|
14
|
+
const ɵ$index_15_r4 = ctx.$index;
|
|
15
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
16
|
+
i0.ɵɵclassProp("selected", field_r2.name === ctx_r2.filter.field)("highlighted", ɵ$index_15_r4 === ctx_r2.fieldHighlightIndex);
|
|
17
|
+
i0.ɵɵadvance();
|
|
18
|
+
i0.ɵɵtextInterpolate1(" ", field_r2.displayName, " ");
|
|
19
|
+
} }
|
|
20
|
+
function FilterRuleComponent_Conditional_6_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
21
|
+
i0.ɵɵelementStart(0, "div", 10);
|
|
22
|
+
i0.ɵɵtext(1, "No fields available");
|
|
23
|
+
i0.ɵɵelementEnd();
|
|
24
|
+
} }
|
|
25
|
+
function FilterRuleComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
26
|
+
i0.ɵɵelementStart(0, "div", 5);
|
|
27
|
+
i0.ɵɵrepeaterCreate(1, FilterRuleComponent_Conditional_6_For_2_Template, 2, 5, "div", 9, _forTrack0);
|
|
28
|
+
i0.ɵɵtemplate(3, FilterRuleComponent_Conditional_6_Conditional_3_Template, 2, 0, "div", 10);
|
|
29
|
+
i0.ɵɵelementEnd();
|
|
30
|
+
} if (rf & 2) {
|
|
31
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
32
|
+
i0.ɵɵadvance();
|
|
33
|
+
i0.ɵɵrepeater(ctx_r2.fields);
|
|
34
|
+
i0.ɵɵadvance(2);
|
|
35
|
+
i0.ɵɵconditional(ctx_r2.fields.length === 0 ? 3 : -1);
|
|
36
|
+
} }
|
|
37
|
+
function FilterRuleComponent_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
38
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
39
|
+
i0.ɵɵelementStart(0, "div", 11);
|
|
40
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_12_For_2_Template_div_click_0_listener() { const op_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.selectOperator(op_r6.value)); });
|
|
41
|
+
i0.ɵɵtext(1);
|
|
42
|
+
i0.ɵɵelementEnd();
|
|
43
|
+
} if (rf & 2) {
|
|
44
|
+
const op_r6 = ctx.$implicit;
|
|
45
|
+
const ɵ$index_35_r7 = ctx.$index;
|
|
46
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
47
|
+
i0.ɵɵclassProp("selected", op_r6.value === ctx_r2.filter.operator)("highlighted", ɵ$index_35_r7 === ctx_r2.operatorHighlightIndex);
|
|
48
|
+
i0.ɵɵadvance();
|
|
49
|
+
i0.ɵɵtextInterpolate1(" ", op_r6.label, " ");
|
|
50
|
+
} }
|
|
51
|
+
function FilterRuleComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
52
|
+
i0.ɵɵelementStart(0, "div", 5);
|
|
53
|
+
i0.ɵɵrepeaterCreate(1, FilterRuleComponent_Conditional_12_For_2_Template, 2, 5, "div", 9, _forTrack1);
|
|
54
|
+
i0.ɵɵelementEnd();
|
|
55
|
+
} if (rf & 2) {
|
|
56
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵrepeater(ctx_r2.availableOperators);
|
|
59
|
+
} }
|
|
60
|
+
function FilterRuleComponent_Conditional_13_Conditional_0_Conditional_5_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
61
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
62
|
+
i0.ɵɵelementStart(0, "div", 11);
|
|
63
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_13_Conditional_0_Conditional_5_For_4_Template_div_click_0_listener() { const option_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.selectValue(option_r11.value)); });
|
|
64
|
+
i0.ɵɵtext(1);
|
|
65
|
+
i0.ɵɵelementEnd();
|
|
66
|
+
} if (rf & 2) {
|
|
67
|
+
const option_r11 = ctx.$implicit;
|
|
68
|
+
const ɵ$index_56_r12 = ctx.$index;
|
|
69
|
+
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
70
|
+
i0.ɵɵclassProp("selected", option_r11.value === ctx_r2.filter.value)("highlighted", ɵ$index_56_r12 + 1 === ctx_r2.valueHighlightIndex);
|
|
71
|
+
i0.ɵɵadvance();
|
|
72
|
+
i0.ɵɵtextInterpolate1(" ", option_r11.label, " ");
|
|
73
|
+
} }
|
|
74
|
+
function FilterRuleComponent_Conditional_13_Conditional_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
75
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
76
|
+
i0.ɵɵelementStart(0, "div", 5)(1, "div", 11);
|
|
77
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_13_Conditional_0_Conditional_5_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.selectValue("")); });
|
|
78
|
+
i0.ɵɵtext(2, " Select... ");
|
|
79
|
+
i0.ɵɵelementEnd();
|
|
80
|
+
i0.ɵɵrepeaterCreate(3, FilterRuleComponent_Conditional_13_Conditional_0_Conditional_5_For_4_Template, 2, 5, "div", 9, _forTrack1);
|
|
81
|
+
i0.ɵɵelementEnd();
|
|
82
|
+
} if (rf & 2) {
|
|
83
|
+
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
84
|
+
i0.ɵɵadvance();
|
|
85
|
+
i0.ɵɵclassProp("selected", !ctx_r2.filter.value)("highlighted", 0 === ctx_r2.valueHighlightIndex);
|
|
86
|
+
i0.ɵɵadvance(2);
|
|
87
|
+
i0.ɵɵrepeater(ctx_r2.selectedField.valueList);
|
|
88
|
+
} }
|
|
89
|
+
function FilterRuleComponent_Conditional_13_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
90
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
91
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "button", 2);
|
|
92
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_13_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleValueDropdown()); })("keydown", function FilterRuleComponent_Conditional_13_Conditional_0_Template_button_keydown_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onValueKeydown($event)); });
|
|
93
|
+
i0.ɵɵelementStart(2, "span", 3);
|
|
94
|
+
i0.ɵɵtext(3);
|
|
95
|
+
i0.ɵɵelementEnd();
|
|
96
|
+
i0.ɵɵelement(4, "i", 4);
|
|
97
|
+
i0.ɵɵelementEnd();
|
|
98
|
+
i0.ɵɵtemplate(5, FilterRuleComponent_Conditional_13_Conditional_0_Conditional_5_Template, 5, 4, "div", 5);
|
|
99
|
+
i0.ɵɵelementEnd();
|
|
100
|
+
} if (rf & 2) {
|
|
101
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
102
|
+
i0.ɵɵclassProp("open", ctx_r2.valueDropdownOpen)("disabled", ctx_r2.disabled);
|
|
103
|
+
i0.ɵɵadvance();
|
|
104
|
+
i0.ɵɵproperty("disabled", ctx_r2.disabled);
|
|
105
|
+
i0.ɵɵadvance(2);
|
|
106
|
+
i0.ɵɵtextInterpolate(ctx_r2.getSelectedValueLabel());
|
|
107
|
+
i0.ɵɵadvance(2);
|
|
108
|
+
i0.ɵɵconditional(ctx_r2.valueDropdownOpen ? 5 : -1);
|
|
109
|
+
} }
|
|
110
|
+
function FilterRuleComponent_Conditional_13_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
111
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
112
|
+
i0.ɵɵelementStart(0, "input", 19);
|
|
113
|
+
i0.ɵɵlistener("input", function FilterRuleComponent_Conditional_13_Conditional_1_Template_input_input_0_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onValueChange($event.target.value)); });
|
|
114
|
+
i0.ɵɵelementEnd();
|
|
115
|
+
} if (rf & 2) {
|
|
116
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
117
|
+
i0.ɵɵproperty("value", ctx_r2.filter.value || "")("disabled", ctx_r2.disabled);
|
|
118
|
+
} }
|
|
119
|
+
function FilterRuleComponent_Conditional_13_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
120
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
121
|
+
i0.ɵɵelementStart(0, "input", 20);
|
|
122
|
+
i0.ɵɵlistener("input", function FilterRuleComponent_Conditional_13_Conditional_2_Template_input_input_0_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onValueChange($event.target.valueAsNumber)); });
|
|
123
|
+
i0.ɵɵelementEnd();
|
|
124
|
+
} if (rf & 2) {
|
|
125
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
126
|
+
i0.ɵɵproperty("value", ctx_r2.filter.value)("disabled", ctx_r2.disabled);
|
|
127
|
+
} }
|
|
128
|
+
function FilterRuleComponent_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
129
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
130
|
+
i0.ɵɵelementStart(0, "div", 15)(1, "button", 21);
|
|
131
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_13_Conditional_3_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onBooleanChange(true)); });
|
|
132
|
+
i0.ɵɵtext(2, " True ");
|
|
133
|
+
i0.ɵɵelementEnd();
|
|
134
|
+
i0.ɵɵelementStart(3, "button", 22);
|
|
135
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_13_Conditional_3_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onBooleanChange(false)); });
|
|
136
|
+
i0.ɵɵtext(4, " False ");
|
|
137
|
+
i0.ɵɵelementEnd()();
|
|
138
|
+
} if (rf & 2) {
|
|
139
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
140
|
+
i0.ɵɵadvance();
|
|
141
|
+
i0.ɵɵclassProp("active", ctx_r2.filter.value === true);
|
|
142
|
+
i0.ɵɵproperty("disabled", ctx_r2.disabled);
|
|
143
|
+
i0.ɵɵadvance(2);
|
|
144
|
+
i0.ɵɵclassProp("active", ctx_r2.filter.value === false);
|
|
145
|
+
i0.ɵɵproperty("disabled", ctx_r2.disabled);
|
|
146
|
+
} }
|
|
147
|
+
function FilterRuleComponent_Conditional_13_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
148
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
149
|
+
i0.ɵɵelementStart(0, "input", 23);
|
|
150
|
+
i0.ɵɵlistener("change", function FilterRuleComponent_Conditional_13_Conditional_4_Template_input_change_0_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onDateChange($event)); });
|
|
151
|
+
i0.ɵɵelementEnd();
|
|
152
|
+
} if (rf & 2) {
|
|
153
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
154
|
+
i0.ɵɵproperty("value", ctx_r2.getDateInputValue())("disabled", ctx_r2.disabled);
|
|
155
|
+
} }
|
|
156
|
+
function FilterRuleComponent_Conditional_13_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
157
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
158
|
+
i0.ɵɵelementStart(0, "input", 24);
|
|
159
|
+
i0.ɵɵlistener("input", function FilterRuleComponent_Conditional_13_Conditional_5_Template_input_input_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onValueChange($event.target.value)); });
|
|
160
|
+
i0.ɵɵelementEnd();
|
|
161
|
+
} if (rf & 2) {
|
|
162
|
+
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
163
|
+
i0.ɵɵproperty("value", ctx_r2.filter.value || "")("disabled", ctx_r2.disabled);
|
|
164
|
+
} }
|
|
165
|
+
function FilterRuleComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
166
|
+
i0.ɵɵtemplate(0, FilterRuleComponent_Conditional_13_Conditional_0_Template, 6, 7, "div", 12)(1, FilterRuleComponent_Conditional_13_Conditional_1_Template, 1, 2, "input", 13)(2, FilterRuleComponent_Conditional_13_Conditional_2_Template, 1, 2, "input", 14)(3, FilterRuleComponent_Conditional_13_Conditional_3_Template, 5, 6, "div", 15)(4, FilterRuleComponent_Conditional_13_Conditional_4_Template, 1, 2, "input", 16)(5, FilterRuleComponent_Conditional_13_Conditional_5_Template, 1, 2, "input", 17);
|
|
167
|
+
} if (rf & 2) {
|
|
168
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
169
|
+
i0.ɵɵconditional(ctx_r2.selectedField.type === "string" && ctx_r2.hasValueList() ? 0 : ctx_r2.selectedField.type === "string" ? 1 : ctx_r2.selectedField.type === "number" ? 2 : ctx_r2.selectedField.type === "boolean" ? 3 : ctx_r2.selectedField.type === "date" ? 4 : ctx_r2.selectedField.type === "lookup" ? 5 : -1);
|
|
170
|
+
} }
|
|
171
|
+
function FilterRuleComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
172
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
173
|
+
i0.ɵɵelementStart(0, "button", 25);
|
|
174
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onDelete()); });
|
|
175
|
+
i0.ɵɵelement(1, "i", 26);
|
|
176
|
+
i0.ɵɵelementEnd();
|
|
177
|
+
} if (rf & 2) {
|
|
178
|
+
const ctx_r2 = i0.ɵɵnextContext();
|
|
179
|
+
i0.ɵɵproperty("disabled", ctx_r2.disabled);
|
|
180
|
+
} }
|
|
181
|
+
/**
|
|
182
|
+
* FilterRuleComponent - A single filter condition row
|
|
183
|
+
*
|
|
184
|
+
* Displays field selector, operator selector, and value editor
|
|
185
|
+
* based on the field type.
|
|
186
|
+
*/
|
|
187
|
+
export class FilterRuleComponent {
|
|
188
|
+
elementRef;
|
|
189
|
+
/**
|
|
190
|
+
* The filter descriptor for this rule
|
|
191
|
+
*/
|
|
192
|
+
filter;
|
|
193
|
+
/**
|
|
194
|
+
* Available fields to filter on
|
|
195
|
+
*/
|
|
196
|
+
fields = [];
|
|
197
|
+
/**
|
|
198
|
+
* Whether the component is disabled
|
|
199
|
+
*/
|
|
200
|
+
disabled = false;
|
|
201
|
+
/**
|
|
202
|
+
* Whether to show the delete button
|
|
203
|
+
*/
|
|
204
|
+
showDelete = true;
|
|
205
|
+
/**
|
|
206
|
+
* Emitted when the filter changes
|
|
207
|
+
*/
|
|
208
|
+
filterChange = new EventEmitter();
|
|
209
|
+
/**
|
|
210
|
+
* Emitted when the delete button is clicked
|
|
211
|
+
*/
|
|
212
|
+
delete = new EventEmitter();
|
|
213
|
+
/**
|
|
214
|
+
* Currently selected field info
|
|
215
|
+
*/
|
|
216
|
+
selectedField = null;
|
|
217
|
+
/**
|
|
218
|
+
* Available operators for the selected field type
|
|
219
|
+
*/
|
|
220
|
+
availableOperators = [];
|
|
221
|
+
/**
|
|
222
|
+
* Whether the current operator requires a value
|
|
223
|
+
*/
|
|
224
|
+
requiresValue = true;
|
|
225
|
+
// Dropdown state
|
|
226
|
+
fieldDropdownOpen = false;
|
|
227
|
+
operatorDropdownOpen = false;
|
|
228
|
+
valueDropdownOpen = false;
|
|
229
|
+
// Keyboard navigation state
|
|
230
|
+
fieldHighlightIndex = -1;
|
|
231
|
+
operatorHighlightIndex = -1;
|
|
232
|
+
valueHighlightIndex = -1;
|
|
233
|
+
constructor(elementRef) {
|
|
234
|
+
this.elementRef = elementRef;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Close dropdowns when clicking outside the component
|
|
238
|
+
*/
|
|
239
|
+
onDocumentClick(event) {
|
|
240
|
+
if (!this.elementRef.nativeElement.contains(event.target)) {
|
|
241
|
+
this.closeAllDropdowns();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
ngOnInit() {
|
|
245
|
+
this.updateFieldSelection();
|
|
246
|
+
}
|
|
247
|
+
ngOnChanges(changes) {
|
|
248
|
+
if (changes['filter'] || changes['fields']) {
|
|
249
|
+
this.updateFieldSelection();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Update the selected field and available operators
|
|
254
|
+
*/
|
|
255
|
+
updateFieldSelection() {
|
|
256
|
+
if (!this.filter || !this.fields.length)
|
|
257
|
+
return;
|
|
258
|
+
this.selectedField = this.fields.find(f => f.name === this.filter.field) || null;
|
|
259
|
+
if (this.selectedField) {
|
|
260
|
+
this.availableOperators = getOperatorsForType(this.selectedField.type);
|
|
261
|
+
this.requiresValue = operatorRequiresValue(this.filter.operator);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
this.availableOperators = [];
|
|
265
|
+
this.requiresValue = true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// ========================================
|
|
269
|
+
// DROPDOWN TOGGLE METHODS
|
|
270
|
+
// ========================================
|
|
271
|
+
toggleFieldDropdown() {
|
|
272
|
+
if (this.disabled)
|
|
273
|
+
return;
|
|
274
|
+
const wasOpen = this.fieldDropdownOpen;
|
|
275
|
+
this.closeAllDropdowns();
|
|
276
|
+
this.fieldDropdownOpen = !wasOpen;
|
|
277
|
+
}
|
|
278
|
+
toggleOperatorDropdown() {
|
|
279
|
+
if (this.disabled || !this.selectedField)
|
|
280
|
+
return;
|
|
281
|
+
const wasOpen = this.operatorDropdownOpen;
|
|
282
|
+
this.closeAllDropdowns();
|
|
283
|
+
this.operatorDropdownOpen = !wasOpen;
|
|
284
|
+
}
|
|
285
|
+
toggleValueDropdown() {
|
|
286
|
+
if (this.disabled)
|
|
287
|
+
return;
|
|
288
|
+
const wasOpen = this.valueDropdownOpen;
|
|
289
|
+
this.closeAllDropdowns();
|
|
290
|
+
this.valueDropdownOpen = !wasOpen;
|
|
291
|
+
}
|
|
292
|
+
closeFieldDropdown() {
|
|
293
|
+
this.fieldDropdownOpen = false;
|
|
294
|
+
}
|
|
295
|
+
closeOperatorDropdown() {
|
|
296
|
+
this.operatorDropdownOpen = false;
|
|
297
|
+
}
|
|
298
|
+
closeValueDropdown() {
|
|
299
|
+
this.valueDropdownOpen = false;
|
|
300
|
+
}
|
|
301
|
+
closeAllDropdowns() {
|
|
302
|
+
this.fieldDropdownOpen = false;
|
|
303
|
+
this.operatorDropdownOpen = false;
|
|
304
|
+
this.valueDropdownOpen = false;
|
|
305
|
+
this.resetHighlightIndices();
|
|
306
|
+
}
|
|
307
|
+
resetHighlightIndices() {
|
|
308
|
+
this.fieldHighlightIndex = -1;
|
|
309
|
+
this.operatorHighlightIndex = -1;
|
|
310
|
+
this.valueHighlightIndex = -1;
|
|
311
|
+
}
|
|
312
|
+
// ========================================
|
|
313
|
+
// KEYBOARD NAVIGATION
|
|
314
|
+
// ========================================
|
|
315
|
+
/**
|
|
316
|
+
* Handle keyboard events on the field dropdown trigger
|
|
317
|
+
*/
|
|
318
|
+
onFieldKeydown(event) {
|
|
319
|
+
if (this.disabled)
|
|
320
|
+
return;
|
|
321
|
+
if (!this.fieldDropdownOpen) {
|
|
322
|
+
// Open dropdown on Enter, Space, or arrow keys
|
|
323
|
+
if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
324
|
+
event.preventDefault();
|
|
325
|
+
this.toggleFieldDropdown();
|
|
326
|
+
this.fieldHighlightIndex = this.fields.findIndex(f => f.name === this.filter.field);
|
|
327
|
+
if (this.fieldHighlightIndex < 0)
|
|
328
|
+
this.fieldHighlightIndex = 0;
|
|
329
|
+
}
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
this.handleDropdownKeydown(event, this.fields, this.fieldHighlightIndex, (index) => this.fieldHighlightIndex = index, (item) => this.selectField(item.name), (item) => item.displayName, () => this.closeFieldDropdown());
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Handle keyboard events on the operator dropdown trigger
|
|
336
|
+
*/
|
|
337
|
+
onOperatorKeydown(event) {
|
|
338
|
+
if (this.disabled || !this.selectedField)
|
|
339
|
+
return;
|
|
340
|
+
if (!this.operatorDropdownOpen) {
|
|
341
|
+
if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
342
|
+
event.preventDefault();
|
|
343
|
+
this.toggleOperatorDropdown();
|
|
344
|
+
this.operatorHighlightIndex = this.availableOperators.findIndex(o => o.value === this.filter.operator);
|
|
345
|
+
if (this.operatorHighlightIndex < 0)
|
|
346
|
+
this.operatorHighlightIndex = 0;
|
|
347
|
+
}
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
this.handleDropdownKeydown(event, this.availableOperators, this.operatorHighlightIndex, (index) => this.operatorHighlightIndex = index, (item) => this.selectOperator(item.value), (item) => item.label, () => this.closeOperatorDropdown());
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Handle keyboard events on the value dropdown trigger
|
|
354
|
+
*/
|
|
355
|
+
onValueKeydown(event) {
|
|
356
|
+
if (this.disabled || !this.selectedField?.valueList)
|
|
357
|
+
return;
|
|
358
|
+
if (!this.valueDropdownOpen) {
|
|
359
|
+
if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
360
|
+
event.preventDefault();
|
|
361
|
+
this.toggleValueDropdown();
|
|
362
|
+
const valueList = this.selectedField.valueList;
|
|
363
|
+
this.valueHighlightIndex = valueList.findIndex(v => v.value === this.filter.value);
|
|
364
|
+
if (this.valueHighlightIndex < 0)
|
|
365
|
+
this.valueHighlightIndex = 0;
|
|
366
|
+
}
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
this.handleDropdownKeydown(event, this.selectedField.valueList, this.valueHighlightIndex, (index) => this.valueHighlightIndex = index, (item) => this.selectValueFromOption(item.value), (item) => item.label, () => this.closeValueDropdown());
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Generic handler for dropdown keyboard navigation
|
|
373
|
+
*/
|
|
374
|
+
handleDropdownKeydown(event, items, currentIndex, setIndex, onSelect, getLabel, onClose) {
|
|
375
|
+
switch (event.key) {
|
|
376
|
+
case 'ArrowDown':
|
|
377
|
+
event.preventDefault();
|
|
378
|
+
setIndex(Math.min(currentIndex + 1, items.length - 1));
|
|
379
|
+
this.scrollHighlightedItemIntoView();
|
|
380
|
+
break;
|
|
381
|
+
case 'ArrowUp':
|
|
382
|
+
event.preventDefault();
|
|
383
|
+
setIndex(Math.max(currentIndex - 1, 0));
|
|
384
|
+
this.scrollHighlightedItemIntoView();
|
|
385
|
+
break;
|
|
386
|
+
case 'Enter':
|
|
387
|
+
case ' ':
|
|
388
|
+
event.preventDefault();
|
|
389
|
+
if (currentIndex >= 0 && currentIndex < items.length) {
|
|
390
|
+
onSelect(items[currentIndex]);
|
|
391
|
+
}
|
|
392
|
+
break;
|
|
393
|
+
case 'Escape':
|
|
394
|
+
case 'Tab':
|
|
395
|
+
event.preventDefault();
|
|
396
|
+
onClose();
|
|
397
|
+
break;
|
|
398
|
+
case 'Home':
|
|
399
|
+
event.preventDefault();
|
|
400
|
+
setIndex(0);
|
|
401
|
+
this.scrollHighlightedItemIntoView();
|
|
402
|
+
break;
|
|
403
|
+
case 'End':
|
|
404
|
+
event.preventDefault();
|
|
405
|
+
setIndex(items.length - 1);
|
|
406
|
+
this.scrollHighlightedItemIntoView();
|
|
407
|
+
break;
|
|
408
|
+
default:
|
|
409
|
+
// Type-ahead: jump to first item starting with typed character
|
|
410
|
+
if (event.key.length === 1 && /[a-zA-Z0-9]/.test(event.key)) {
|
|
411
|
+
const char = event.key.toLowerCase();
|
|
412
|
+
const startIndex = currentIndex + 1;
|
|
413
|
+
// Search from current position to end, then from start
|
|
414
|
+
for (let i = 0; i < items.length; i++) {
|
|
415
|
+
const idx = (startIndex + i) % items.length;
|
|
416
|
+
const label = getLabel(items[idx]).toLowerCase();
|
|
417
|
+
if (label.startsWith(char)) {
|
|
418
|
+
setIndex(idx);
|
|
419
|
+
this.scrollHighlightedItemIntoView();
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Scroll the highlighted dropdown item into view
|
|
429
|
+
*/
|
|
430
|
+
scrollHighlightedItemIntoView() {
|
|
431
|
+
// Use setTimeout to let Angular update the DOM first
|
|
432
|
+
setTimeout(() => {
|
|
433
|
+
const highlightedEl = this.elementRef.nativeElement.querySelector('.dropdown-item.highlighted');
|
|
434
|
+
if (highlightedEl) {
|
|
435
|
+
highlightedEl.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
436
|
+
}
|
|
437
|
+
}, 0);
|
|
438
|
+
}
|
|
439
|
+
// ========================================
|
|
440
|
+
// DISPLAY HELPERS
|
|
441
|
+
// ========================================
|
|
442
|
+
/**
|
|
443
|
+
* Get the display name for the currently selected field
|
|
444
|
+
*/
|
|
445
|
+
getSelectedFieldDisplayName() {
|
|
446
|
+
if (!this.filter.field)
|
|
447
|
+
return 'Select field...';
|
|
448
|
+
const field = this.fields.find(f => f.name === this.filter.field);
|
|
449
|
+
return field?.displayName || this.filter.field;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Get the label for the currently selected operator
|
|
453
|
+
*/
|
|
454
|
+
getSelectedOperatorLabel() {
|
|
455
|
+
if (!this.filter.operator)
|
|
456
|
+
return 'Select...';
|
|
457
|
+
const op = this.availableOperators.find(o => o.value === this.filter.operator);
|
|
458
|
+
return op?.label || this.filter.operator;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Get the label for the currently selected value (for value list dropdowns)
|
|
462
|
+
*/
|
|
463
|
+
getSelectedValueLabel() {
|
|
464
|
+
if (!this.filter.value || !this.selectedField?.valueList)
|
|
465
|
+
return 'Select...';
|
|
466
|
+
const option = this.selectedField.valueList.find(o => o.value === this.filter.value);
|
|
467
|
+
return option?.label || String(this.filter.value);
|
|
468
|
+
}
|
|
469
|
+
// ========================================
|
|
470
|
+
// SELECTION HANDLERS
|
|
471
|
+
// ========================================
|
|
472
|
+
/**
|
|
473
|
+
* Handle field selection from custom dropdown
|
|
474
|
+
*/
|
|
475
|
+
selectField(fieldName) {
|
|
476
|
+
this.closeFieldDropdown();
|
|
477
|
+
this.onFieldChange(fieldName);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Handle operator selection from custom dropdown
|
|
481
|
+
*/
|
|
482
|
+
selectOperator(operator) {
|
|
483
|
+
this.closeOperatorDropdown();
|
|
484
|
+
this.onOperatorChange(operator);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Handle value selection from custom dropdown
|
|
488
|
+
*/
|
|
489
|
+
selectValue(value) {
|
|
490
|
+
this.closeValueDropdown();
|
|
491
|
+
this.onValueChange(value);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Handle value selection from value list option (supports union type)
|
|
495
|
+
*/
|
|
496
|
+
selectValueFromOption(value) {
|
|
497
|
+
this.closeValueDropdown();
|
|
498
|
+
this.onValueChange(value);
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Handle field selection change
|
|
502
|
+
*/
|
|
503
|
+
onFieldChange(fieldName) {
|
|
504
|
+
const field = this.fields.find(f => f.name === fieldName);
|
|
505
|
+
if (!field)
|
|
506
|
+
return;
|
|
507
|
+
this.selectedField = field;
|
|
508
|
+
this.availableOperators = getOperatorsForType(field.type);
|
|
509
|
+
// Get default operator for the new field type
|
|
510
|
+
const defaultOperator = this.availableOperators[0]?.value || 'eq';
|
|
511
|
+
this.requiresValue = operatorRequiresValue(defaultOperator);
|
|
512
|
+
// Emit updated filter with new field and reset value
|
|
513
|
+
this.emitChange({
|
|
514
|
+
field: fieldName,
|
|
515
|
+
operator: defaultOperator,
|
|
516
|
+
value: this.getDefaultValue(field.type)
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Handle operator selection change
|
|
521
|
+
*/
|
|
522
|
+
onOperatorChange(operator) {
|
|
523
|
+
this.requiresValue = operatorRequiresValue(operator);
|
|
524
|
+
// If operator doesn't require value, clear it
|
|
525
|
+
const value = this.requiresValue ? this.filter.value : null;
|
|
526
|
+
this.emitChange({
|
|
527
|
+
...this.filter,
|
|
528
|
+
operator,
|
|
529
|
+
value
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Handle value change
|
|
534
|
+
*/
|
|
535
|
+
onValueChange(value) {
|
|
536
|
+
this.emitChange({
|
|
537
|
+
...this.filter,
|
|
538
|
+
value
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Handle boolean toggle
|
|
543
|
+
*/
|
|
544
|
+
onBooleanChange(value) {
|
|
545
|
+
this.emitChange({
|
|
546
|
+
...this.filter,
|
|
547
|
+
value
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Handle date change
|
|
552
|
+
*/
|
|
553
|
+
onDateChange(event) {
|
|
554
|
+
const input = event.target;
|
|
555
|
+
const value = input.value ? new Date(input.value).toISOString() : null;
|
|
556
|
+
this.emitChange({
|
|
557
|
+
...this.filter,
|
|
558
|
+
value
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Handle delete button click
|
|
563
|
+
*/
|
|
564
|
+
onDelete() {
|
|
565
|
+
this.delete.emit();
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Emit the filter change event
|
|
569
|
+
*/
|
|
570
|
+
emitChange(filter) {
|
|
571
|
+
this.filterChange.emit(filter);
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Get default value for a field type
|
|
575
|
+
*/
|
|
576
|
+
getDefaultValue(type) {
|
|
577
|
+
switch (type) {
|
|
578
|
+
case 'string':
|
|
579
|
+
return '';
|
|
580
|
+
case 'number':
|
|
581
|
+
return null;
|
|
582
|
+
case 'boolean':
|
|
583
|
+
return true;
|
|
584
|
+
case 'date':
|
|
585
|
+
return null;
|
|
586
|
+
case 'lookup':
|
|
587
|
+
return null;
|
|
588
|
+
default:
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Get the date value formatted for the date input
|
|
594
|
+
*/
|
|
595
|
+
getDateInputValue() {
|
|
596
|
+
if (!this.filter.value)
|
|
597
|
+
return '';
|
|
598
|
+
try {
|
|
599
|
+
const date = new Date(this.filter.value);
|
|
600
|
+
return date.toISOString().split('T')[0];
|
|
601
|
+
}
|
|
602
|
+
catch {
|
|
603
|
+
return '';
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Check if the current field has a value list (dropdown options)
|
|
608
|
+
*/
|
|
609
|
+
hasValueList() {
|
|
610
|
+
return !!(this.selectedField?.valueList && this.selectedField.valueList.length > 0);
|
|
611
|
+
}
|
|
612
|
+
static ɵfac = function FilterRuleComponent_Factory(t) { return new (t || FilterRuleComponent)(i0.ɵɵdirectiveInject(i0.ElementRef)); };
|
|
613
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FilterRuleComponent, selectors: [["mj-filter-rule"]], hostBindings: function FilterRuleComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
614
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_click_HostBindingHandler($event) { return ctx.onDocumentClick($event); }, false, i0.ɵɵresolveDocument);
|
|
615
|
+
} }, inputs: { filter: "filter", fields: "fields", disabled: "disabled", showDelete: "showDelete" }, outputs: { filterChange: "filterChange", delete: "delete" }, features: [i0.ɵɵNgOnChangesFeature], decls: 16, vars: 18, consts: [[1, "filter-rule"], [1, "custom-dropdown", "field-dropdown"], ["type", "button", 1, "dropdown-trigger", 3, "click", "keydown", "disabled"], [1, "dropdown-value"], [1, "fa-solid", "fa-chevron-down", "dropdown-arrow"], [1, "dropdown-menu"], [1, "custom-dropdown", "operator-dropdown"], [1, "rule-actions"], ["type", "button", "title", "Remove filter", 1, "action-btn", "delete", 3, "disabled"], [1, "dropdown-item", 3, "selected", "highlighted"], [1, "dropdown-empty"], [1, "dropdown-item", 3, "click"], [1, "custom-dropdown", "value-dropdown", 3, "open", "disabled"], ["type", "text", "placeholder", "Enter value...", 1, "value-input", 3, "value", "disabled"], ["type", "number", "placeholder", "Enter number...", 1, "value-input", 3, "value", "disabled"], [1, "value-toggle"], ["type", "date", 1, "value-input", "value-date", 3, "value", "disabled"], ["type", "text", "placeholder", "Enter ID...", 1, "value-input", 3, "value", "disabled"], [1, "custom-dropdown", "value-dropdown"], ["type", "text", "placeholder", "Enter value...", 1, "value-input", 3, "input", "value", "disabled"], ["type", "number", "placeholder", "Enter number...", 1, "value-input", 3, "input", "value", "disabled"], ["type", "button", 1, "toggle-btn", "true", 3, "click", "disabled"], ["type", "button", 1, "toggle-btn", "false", 3, "click", "disabled"], ["type", "date", 1, "value-input", "value-date", 3, "change", "value", "disabled"], ["type", "text", "placeholder", "Enter ID...", 1, "value-input", 3, "input", "value", "disabled"], ["type", "button", "title", "Remove filter", 1, "action-btn", "delete", 3, "click", "disabled"], [1, "fa-solid", "fa-times"]], template: function FilterRuleComponent_Template(rf, ctx) { if (rf & 1) {
|
|
616
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
|
|
617
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Template_button_click_2_listener() { return ctx.toggleFieldDropdown(); })("keydown", function FilterRuleComponent_Template_button_keydown_2_listener($event) { return ctx.onFieldKeydown($event); });
|
|
618
|
+
i0.ɵɵelementStart(3, "span", 3);
|
|
619
|
+
i0.ɵɵtext(4);
|
|
620
|
+
i0.ɵɵelementEnd();
|
|
621
|
+
i0.ɵɵelement(5, "i", 4);
|
|
622
|
+
i0.ɵɵelementEnd();
|
|
623
|
+
i0.ɵɵtemplate(6, FilterRuleComponent_Conditional_6_Template, 4, 1, "div", 5);
|
|
624
|
+
i0.ɵɵelementEnd();
|
|
625
|
+
i0.ɵɵelementStart(7, "div", 6)(8, "button", 2);
|
|
626
|
+
i0.ɵɵlistener("click", function FilterRuleComponent_Template_button_click_8_listener() { return ctx.toggleOperatorDropdown(); })("keydown", function FilterRuleComponent_Template_button_keydown_8_listener($event) { return ctx.onOperatorKeydown($event); });
|
|
627
|
+
i0.ɵɵelementStart(9, "span", 3);
|
|
628
|
+
i0.ɵɵtext(10);
|
|
629
|
+
i0.ɵɵelementEnd();
|
|
630
|
+
i0.ɵɵelement(11, "i", 4);
|
|
631
|
+
i0.ɵɵelementEnd();
|
|
632
|
+
i0.ɵɵtemplate(12, FilterRuleComponent_Conditional_12_Template, 3, 0, "div", 5);
|
|
633
|
+
i0.ɵɵelementEnd();
|
|
634
|
+
i0.ɵɵtemplate(13, FilterRuleComponent_Conditional_13_Template, 6, 1);
|
|
635
|
+
i0.ɵɵelementStart(14, "div", 7);
|
|
636
|
+
i0.ɵɵtemplate(15, FilterRuleComponent_Conditional_15_Template, 2, 1, "button", 8);
|
|
637
|
+
i0.ɵɵelementEnd()();
|
|
638
|
+
} if (rf & 2) {
|
|
639
|
+
i0.ɵɵclassProp("disabled", ctx.disabled);
|
|
640
|
+
i0.ɵɵadvance();
|
|
641
|
+
i0.ɵɵclassProp("open", ctx.fieldDropdownOpen)("disabled", ctx.disabled);
|
|
642
|
+
i0.ɵɵadvance();
|
|
643
|
+
i0.ɵɵproperty("disabled", ctx.disabled);
|
|
644
|
+
i0.ɵɵadvance(2);
|
|
645
|
+
i0.ɵɵtextInterpolate(ctx.getSelectedFieldDisplayName());
|
|
646
|
+
i0.ɵɵadvance(2);
|
|
647
|
+
i0.ɵɵconditional(ctx.fieldDropdownOpen ? 6 : -1);
|
|
648
|
+
i0.ɵɵadvance();
|
|
649
|
+
i0.ɵɵclassProp("open", ctx.operatorDropdownOpen)("disabled", ctx.disabled || !ctx.selectedField);
|
|
650
|
+
i0.ɵɵadvance();
|
|
651
|
+
i0.ɵɵproperty("disabled", ctx.disabled || !ctx.selectedField);
|
|
652
|
+
i0.ɵɵadvance(2);
|
|
653
|
+
i0.ɵɵtextInterpolate(ctx.getSelectedOperatorLabel());
|
|
654
|
+
i0.ɵɵadvance(2);
|
|
655
|
+
i0.ɵɵconditional(ctx.operatorDropdownOpen ? 12 : -1);
|
|
656
|
+
i0.ɵɵadvance();
|
|
657
|
+
i0.ɵɵconditional(ctx.requiresValue && ctx.selectedField ? 13 : -1);
|
|
658
|
+
i0.ɵɵadvance(2);
|
|
659
|
+
i0.ɵɵconditional(ctx.showDelete ? 15 : -1);
|
|
660
|
+
} }, styles: ["/* Scoped to mj-filter-rule to prevent style leakage with ViewEncapsulation.None */\nmj-filter-rule .filter-rule {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: linear-gradient(to bottom, #ffffff, #fafafa);\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\nmj-filter-rule .filter-rule:hover {\n border-color: #d1d5db;\n background: linear-gradient(to bottom, #ffffff, #f5f5f5);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);\n}\n\nmj-filter-rule .filter-rule.disabled {\n opacity: 0.6;\n pointer-events: none;\n box-shadow: none;\n}\n\n/* ========================================\n CUSTOM DROPDOWN STYLES\n ======================================== */\n\nmj-filter-rule .custom-dropdown {\n position: relative;\n min-width: 160px;\n}\n\nmj-filter-rule .custom-dropdown.field-dropdown {\n min-width: 180px;\n}\n\nmj-filter-rule .custom-dropdown.operator-dropdown {\n min-width: 160px;\n}\n\nmj-filter-rule .custom-dropdown.value-dropdown {\n min-width: 160px;\n flex: 1;\n}\n\nmj-filter-rule .custom-dropdown.disabled {\n opacity: 0.6;\n pointer-events: none;\n}\n\n/* Dropdown Trigger Button */\nmj-filter-rule .dropdown-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 10px 14px;\n border: 1px solid #d4d4d8;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n background: white;\n color: #374151;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n text-align: left;\n}\n\nmj-filter-rule .dropdown-trigger:hover:not(:disabled) {\n border-color: #a1a1aa;\n background: #fafafa;\n}\n\nmj-filter-rule .dropdown-trigger:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n background: white;\n}\n\nmj-filter-rule .dropdown-trigger:disabled {\n background-color: #f4f4f5;\n color: #a1a1aa;\n cursor: not-allowed;\n box-shadow: none;\n}\n\nmj-filter-rule .custom-dropdown.open .dropdown-trigger {\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n}\n\nmj-filter-rule .dropdown-value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\nmj-filter-rule .dropdown-arrow {\n font-size: 10px;\n color: #6b7280;\n margin-left: 8px;\n transition: transform 0.2s ease;\n}\n\nmj-filter-rule .custom-dropdown.open .dropdown-arrow {\n transform: rotate(180deg);\n}\n\n/* Dropdown Menu */\nmj-filter-rule .dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n min-width: 100%;\n max-height: 280px;\n overflow-y: auto;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.04);\n z-index: 9999;\n animation: dropdownFadeIn 0.15s ease;\n}\n\n@keyframes dropdownFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Dropdown Items */\nmj-filter-rule .dropdown-item {\n padding: 10px 14px;\n font-size: 14px;\n color: #374151;\n cursor: pointer;\n transition: all 0.15s ease;\n border-bottom: 1px solid #f3f4f6;\n}\n\nmj-filter-rule .dropdown-item:last-child {\n border-bottom: none;\n}\n\nmj-filter-rule .dropdown-item:hover,\nmj-filter-rule .dropdown-item.highlighted {\n background: #f0f9ff;\n color: #1d4ed8;\n}\n\nmj-filter-rule .dropdown-item.highlighted {\n outline: 2px solid #3b82f6;\n outline-offset: -2px;\n}\n\nmj-filter-rule .dropdown-item.selected {\n background: #eff6ff;\n color: #1d4ed8;\n font-weight: 600;\n}\n\nmj-filter-rule .dropdown-item.selected::before {\n content: '\\f00c';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n font-size: 10px;\n margin-right: 8px;\n color: #3b82f6;\n}\n\nmj-filter-rule .dropdown-empty {\n padding: 16px;\n text-align: center;\n color: #9ca3af;\n font-size: 13px;\n font-style: italic;\n}\n\n/* Scrollbar styling for dropdown */\nmj-filter-rule .dropdown-menu::-webkit-scrollbar {\n width: 6px;\n}\n\nmj-filter-rule .dropdown-menu::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 3px;\n}\n\nmj-filter-rule .dropdown-menu::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 3px;\n}\n\nmj-filter-rule .dropdown-menu::-webkit-scrollbar-thumb:hover {\n background: #a1a1a1;\n}\n\n/* ========================================\n VALUE INPUT STYLES\n ======================================== */\n\nmj-filter-rule .value-input {\n padding: 10px 14px;\n border: 1px solid #d4d4d8;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n background-color: white;\n color: #374151;\n transition: all 0.2s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n flex: 1;\n min-width: 150px;\n}\n\nmj-filter-rule .value-input:hover:not(:disabled) {\n border-color: #a1a1aa;\n background-color: #fafafa;\n}\n\nmj-filter-rule .value-input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n background-color: white;\n}\n\nmj-filter-rule .value-input:disabled {\n background-color: #f4f4f5;\n color: #a1a1aa;\n cursor: not-allowed;\n box-shadow: none;\n}\n\nmj-filter-rule .value-input::placeholder {\n color: #9ca3af;\n font-weight: 400;\n}\n\nmj-filter-rule .value-date {\n min-width: 160px;\n}\n\n/* ========================================\n BOOLEAN TOGGLE STYLES\n ======================================== */\n\nmj-filter-rule .value-toggle {\n display: flex;\n background: #f4f4f5;\n border-radius: 8px;\n padding: 3px;\n border: 1px solid #e5e7eb;\n}\n\nmj-filter-rule .toggle-btn {\n padding: 8px 18px;\n border: none;\n background: transparent;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #71717a;\n}\n\nmj-filter-rule .toggle-btn:hover:not(:disabled) {\n color: #3f3f46;\n background: rgba(255, 255, 255, 0.5);\n}\n\nmj-filter-rule .toggle-btn:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\nmj-filter-rule .toggle-btn.active {\n background: white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n color: #18181b;\n}\n\nmj-filter-rule .toggle-btn.true.active {\n color: #16a34a;\n}\n\nmj-filter-rule .toggle-btn.false.active {\n color: #dc2626;\n}\n\n/* ========================================\n RULE ACTIONS\n ======================================== */\n\nmj-filter-rule .rule-actions {\n display: flex;\n gap: 4px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\nmj-filter-rule .action-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #a1a1aa;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n}\n\nmj-filter-rule .action-btn:hover:not(:disabled) {\n background: #f4f4f5;\n color: #71717a;\n}\n\nmj-filter-rule .action-btn:disabled {\n cursor: not-allowed;\n opacity: 0.3;\n}\n\nmj-filter-rule .action-btn.delete:hover:not(:disabled) {\n background: #fef2f2;\n color: #ef4444;\n}\n\n/* ========================================\n RESPONSIVE\n ======================================== */\n\n@media (max-width: 768px) {\n mj-filter-rule .filter-rule {\n flex-wrap: wrap;\n }\n\n mj-filter-rule .custom-dropdown,\n mj-filter-rule .value-input {\n min-width: 100%;\n flex: 1 1 100%;\n }\n\n mj-filter-rule .custom-dropdown.field-dropdown,\n mj-filter-rule .custom-dropdown.operator-dropdown,\n mj-filter-rule .custom-dropdown.value-dropdown {\n min-width: 100%;\n }\n}\n"], encapsulation: 2 });
|
|
661
|
+
}
|
|
662
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FilterRuleComponent, [{
|
|
663
|
+
type: Component,
|
|
664
|
+
args: [{ selector: 'mj-filter-rule', encapsulation: ViewEncapsulation.None, template: "<div class=\"filter-rule\" [class.disabled]=\"disabled\">\n <!-- Field Selector - Custom Dropdown -->\n <div class=\"custom-dropdown field-dropdown\" [class.open]=\"fieldDropdownOpen\" [class.disabled]=\"disabled\">\n <button\n type=\"button\"\n class=\"dropdown-trigger\"\n (click)=\"toggleFieldDropdown()\"\n (keydown)=\"onFieldKeydown($event)\"\n [disabled]=\"disabled\">\n <span class=\"dropdown-value\">{{ getSelectedFieldDisplayName() }}</span>\n <i class=\"fa-solid fa-chevron-down dropdown-arrow\"></i>\n </button>\n @if (fieldDropdownOpen) {\n <div class=\"dropdown-menu\">\n @for (field of fields; track field.name; let i = $index) {\n <div\n class=\"dropdown-item\"\n [class.selected]=\"field.name === filter.field\"\n [class.highlighted]=\"i === fieldHighlightIndex\"\n (click)=\"selectField(field.name)\">\n {{ field.displayName }}\n </div>\n }\n @if (fields.length === 0) {\n <div class=\"dropdown-empty\">No fields available</div>\n }\n </div>\n }\n </div>\n\n <!-- Operator Selector - Custom Dropdown -->\n <div class=\"custom-dropdown operator-dropdown\" [class.open]=\"operatorDropdownOpen\" [class.disabled]=\"disabled || !selectedField\">\n <button\n type=\"button\"\n class=\"dropdown-trigger\"\n (click)=\"toggleOperatorDropdown()\"\n (keydown)=\"onOperatorKeydown($event)\"\n [disabled]=\"disabled || !selectedField\">\n <span class=\"dropdown-value\">{{ getSelectedOperatorLabel() }}</span>\n <i class=\"fa-solid fa-chevron-down dropdown-arrow\"></i>\n </button>\n @if (operatorDropdownOpen) {\n <div class=\"dropdown-menu\">\n @for (op of availableOperators; track op.value; let i = $index) {\n <div\n class=\"dropdown-item\"\n [class.selected]=\"op.value === filter.operator\"\n [class.highlighted]=\"i === operatorHighlightIndex\"\n (click)=\"selectOperator(op.value)\">\n {{ op.label }}\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Value Editor - varies by field type -->\n @if (requiresValue && selectedField) {\n <!-- String with value list (custom dropdown) -->\n @if (selectedField.type === 'string' && hasValueList()) {\n <div class=\"custom-dropdown value-dropdown\" [class.open]=\"valueDropdownOpen\" [class.disabled]=\"disabled\">\n <button\n type=\"button\"\n class=\"dropdown-trigger\"\n (click)=\"toggleValueDropdown()\"\n (keydown)=\"onValueKeydown($event)\"\n [disabled]=\"disabled\">\n <span class=\"dropdown-value\">{{ getSelectedValueLabel() }}</span>\n <i class=\"fa-solid fa-chevron-down dropdown-arrow\"></i>\n </button>\n @if (valueDropdownOpen) {\n <div class=\"dropdown-menu\">\n <div\n class=\"dropdown-item\"\n [class.selected]=\"!filter.value\"\n [class.highlighted]=\"0 === valueHighlightIndex\"\n (click)=\"selectValue('')\">\n Select...\n </div>\n @for (option of selectedField.valueList; track option.value; let i = $index) {\n <div\n class=\"dropdown-item\"\n [class.selected]=\"option.value === filter.value\"\n [class.highlighted]=\"(i + 1) === valueHighlightIndex\"\n (click)=\"selectValue(option.value)\">\n {{ option.label }}\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- String (text input) -->\n @else if (selectedField.type === 'string') {\n <input\n type=\"text\"\n class=\"value-input\"\n [value]=\"filter.value || ''\"\n (input)=\"onValueChange($any($event.target).value)\"\n [disabled]=\"disabled\"\n placeholder=\"Enter value...\">\n }\n <!-- Number -->\n @else if (selectedField.type === 'number') {\n <input\n type=\"number\"\n class=\"value-input\"\n [value]=\"filter.value\"\n (input)=\"onValueChange($any($event.target).valueAsNumber)\"\n [disabled]=\"disabled\"\n placeholder=\"Enter number...\">\n }\n <!-- Boolean -->\n @else if (selectedField.type === 'boolean') {\n <div class=\"value-toggle\">\n <button\n type=\"button\"\n class=\"toggle-btn true\"\n [class.active]=\"filter.value === true\"\n (click)=\"onBooleanChange(true)\"\n [disabled]=\"disabled\">\n True\n </button>\n <button\n type=\"button\"\n class=\"toggle-btn false\"\n [class.active]=\"filter.value === false\"\n (click)=\"onBooleanChange(false)\"\n [disabled]=\"disabled\">\n False\n </button>\n </div>\n }\n <!-- Date -->\n @else if (selectedField.type === 'date') {\n <input\n type=\"date\"\n class=\"value-input value-date\"\n [value]=\"getDateInputValue()\"\n (change)=\"onDateChange($event)\"\n [disabled]=\"disabled\">\n }\n <!-- Lookup (for now, simple text input - can be enhanced with record selector) -->\n @else if (selectedField.type === 'lookup') {\n <input\n type=\"text\"\n class=\"value-input\"\n [value]=\"filter.value || ''\"\n (input)=\"onValueChange($any($event.target).value)\"\n [disabled]=\"disabled\"\n placeholder=\"Enter ID...\">\n }\n }\n\n <!-- Actions -->\n <div class=\"rule-actions\">\n @if (showDelete) {\n <button\n type=\"button\"\n class=\"action-btn delete\"\n (click)=\"onDelete()\"\n [disabled]=\"disabled\"\n title=\"Remove filter\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n</div>\n", styles: ["/* Scoped to mj-filter-rule to prevent style leakage with ViewEncapsulation.None */\nmj-filter-rule .filter-rule {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: linear-gradient(to bottom, #ffffff, #fafafa);\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\nmj-filter-rule .filter-rule:hover {\n border-color: #d1d5db;\n background: linear-gradient(to bottom, #ffffff, #f5f5f5);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);\n}\n\nmj-filter-rule .filter-rule.disabled {\n opacity: 0.6;\n pointer-events: none;\n box-shadow: none;\n}\n\n/* ========================================\n CUSTOM DROPDOWN STYLES\n ======================================== */\n\nmj-filter-rule .custom-dropdown {\n position: relative;\n min-width: 160px;\n}\n\nmj-filter-rule .custom-dropdown.field-dropdown {\n min-width: 180px;\n}\n\nmj-filter-rule .custom-dropdown.operator-dropdown {\n min-width: 160px;\n}\n\nmj-filter-rule .custom-dropdown.value-dropdown {\n min-width: 160px;\n flex: 1;\n}\n\nmj-filter-rule .custom-dropdown.disabled {\n opacity: 0.6;\n pointer-events: none;\n}\n\n/* Dropdown Trigger Button */\nmj-filter-rule .dropdown-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 10px 14px;\n border: 1px solid #d4d4d8;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n background: white;\n color: #374151;\n cursor: pointer;\n transition: all 0.2s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n text-align: left;\n}\n\nmj-filter-rule .dropdown-trigger:hover:not(:disabled) {\n border-color: #a1a1aa;\n background: #fafafa;\n}\n\nmj-filter-rule .dropdown-trigger:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n background: white;\n}\n\nmj-filter-rule .dropdown-trigger:disabled {\n background-color: #f4f4f5;\n color: #a1a1aa;\n cursor: not-allowed;\n box-shadow: none;\n}\n\nmj-filter-rule .custom-dropdown.open .dropdown-trigger {\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n}\n\nmj-filter-rule .dropdown-value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\nmj-filter-rule .dropdown-arrow {\n font-size: 10px;\n color: #6b7280;\n margin-left: 8px;\n transition: transform 0.2s ease;\n}\n\nmj-filter-rule .custom-dropdown.open .dropdown-arrow {\n transform: rotate(180deg);\n}\n\n/* Dropdown Menu */\nmj-filter-rule .dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n min-width: 100%;\n max-height: 280px;\n overflow-y: auto;\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.04);\n z-index: 9999;\n animation: dropdownFadeIn 0.15s ease;\n}\n\n@keyframes dropdownFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Dropdown Items */\nmj-filter-rule .dropdown-item {\n padding: 10px 14px;\n font-size: 14px;\n color: #374151;\n cursor: pointer;\n transition: all 0.15s ease;\n border-bottom: 1px solid #f3f4f6;\n}\n\nmj-filter-rule .dropdown-item:last-child {\n border-bottom: none;\n}\n\nmj-filter-rule .dropdown-item:hover,\nmj-filter-rule .dropdown-item.highlighted {\n background: #f0f9ff;\n color: #1d4ed8;\n}\n\nmj-filter-rule .dropdown-item.highlighted {\n outline: 2px solid #3b82f6;\n outline-offset: -2px;\n}\n\nmj-filter-rule .dropdown-item.selected {\n background: #eff6ff;\n color: #1d4ed8;\n font-weight: 600;\n}\n\nmj-filter-rule .dropdown-item.selected::before {\n content: '\\f00c';\n font-family: 'Font Awesome 6 Free';\n font-weight: 900;\n font-size: 10px;\n margin-right: 8px;\n color: #3b82f6;\n}\n\nmj-filter-rule .dropdown-empty {\n padding: 16px;\n text-align: center;\n color: #9ca3af;\n font-size: 13px;\n font-style: italic;\n}\n\n/* Scrollbar styling for dropdown */\nmj-filter-rule .dropdown-menu::-webkit-scrollbar {\n width: 6px;\n}\n\nmj-filter-rule .dropdown-menu::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 3px;\n}\n\nmj-filter-rule .dropdown-menu::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 3px;\n}\n\nmj-filter-rule .dropdown-menu::-webkit-scrollbar-thumb:hover {\n background: #a1a1a1;\n}\n\n/* ========================================\n VALUE INPUT STYLES\n ======================================== */\n\nmj-filter-rule .value-input {\n padding: 10px 14px;\n border: 1px solid #d4d4d8;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n background-color: white;\n color: #374151;\n transition: all 0.2s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n flex: 1;\n min-width: 150px;\n}\n\nmj-filter-rule .value-input:hover:not(:disabled) {\n border-color: #a1a1aa;\n background-color: #fafafa;\n}\n\nmj-filter-rule .value-input:focus {\n outline: none;\n border-color: #3b82f6;\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);\n background-color: white;\n}\n\nmj-filter-rule .value-input:disabled {\n background-color: #f4f4f5;\n color: #a1a1aa;\n cursor: not-allowed;\n box-shadow: none;\n}\n\nmj-filter-rule .value-input::placeholder {\n color: #9ca3af;\n font-weight: 400;\n}\n\nmj-filter-rule .value-date {\n min-width: 160px;\n}\n\n/* ========================================\n BOOLEAN TOGGLE STYLES\n ======================================== */\n\nmj-filter-rule .value-toggle {\n display: flex;\n background: #f4f4f5;\n border-radius: 8px;\n padding: 3px;\n border: 1px solid #e5e7eb;\n}\n\nmj-filter-rule .toggle-btn {\n padding: 8px 18px;\n border: none;\n background: transparent;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #71717a;\n}\n\nmj-filter-rule .toggle-btn:hover:not(:disabled) {\n color: #3f3f46;\n background: rgba(255, 255, 255, 0.5);\n}\n\nmj-filter-rule .toggle-btn:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\nmj-filter-rule .toggle-btn.active {\n background: white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n color: #18181b;\n}\n\nmj-filter-rule .toggle-btn.true.active {\n color: #16a34a;\n}\n\nmj-filter-rule .toggle-btn.false.active {\n color: #dc2626;\n}\n\n/* ========================================\n RULE ACTIONS\n ======================================== */\n\nmj-filter-rule .rule-actions {\n display: flex;\n gap: 4px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\nmj-filter-rule .action-btn {\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: #a1a1aa;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n}\n\nmj-filter-rule .action-btn:hover:not(:disabled) {\n background: #f4f4f5;\n color: #71717a;\n}\n\nmj-filter-rule .action-btn:disabled {\n cursor: not-allowed;\n opacity: 0.3;\n}\n\nmj-filter-rule .action-btn.delete:hover:not(:disabled) {\n background: #fef2f2;\n color: #ef4444;\n}\n\n/* ========================================\n RESPONSIVE\n ======================================== */\n\n@media (max-width: 768px) {\n mj-filter-rule .filter-rule {\n flex-wrap: wrap;\n }\n\n mj-filter-rule .custom-dropdown,\n mj-filter-rule .value-input {\n min-width: 100%;\n flex: 1 1 100%;\n }\n\n mj-filter-rule .custom-dropdown.field-dropdown,\n mj-filter-rule .custom-dropdown.operator-dropdown,\n mj-filter-rule .custom-dropdown.value-dropdown {\n min-width: 100%;\n }\n}\n"] }]
|
|
665
|
+
}], () => [{ type: i0.ElementRef }], { filter: [{
|
|
666
|
+
type: Input
|
|
667
|
+
}], fields: [{
|
|
668
|
+
type: Input
|
|
669
|
+
}], disabled: [{
|
|
670
|
+
type: Input
|
|
671
|
+
}], showDelete: [{
|
|
672
|
+
type: Input
|
|
673
|
+
}], filterChange: [{
|
|
674
|
+
type: Output
|
|
675
|
+
}], delete: [{
|
|
676
|
+
type: Output
|
|
677
|
+
}], onDocumentClick: [{
|
|
678
|
+
type: HostListener,
|
|
679
|
+
args: ['document:click', ['$event']]
|
|
680
|
+
}] }); })();
|
|
681
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FilterRuleComponent, { className: "FilterRuleComponent", filePath: "src/lib/filter-rule/filter-rule.component.ts", lineNumber: 22 }); })();
|
|
682
|
+
//# sourceMappingURL=filter-rule.component.js.map
|