@genesislcap/foundation-ui 14.428.2-alpha-257ebec.0 → 14.429.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import { AIProvider } from '@genesislcap/foundation-ai';
2
2
  import type { MetadataDetail } from '@genesislcap/foundation-comms';
3
3
  import { FoundationElement } from '@microsoft/fast-foundation';
4
+ import type { CriteriaChip, CriteriaGroup } from './validation/criteria-ir';
4
5
  /**
5
6
  * Natural-language criteria search input with AI interpretation.
6
7
  *
@@ -13,17 +14,22 @@ export declare class AiCriteriaSearch extends FoundationElement {
13
14
  aiProvider: AIProvider;
14
15
  placeholder: string;
15
16
  disabled: boolean;
16
- mode: 'append' | 'replace';
17
17
  inputValue: string;
18
18
  isInterpreting: boolean;
19
19
  lastValidCriteria: string | null;
20
+ activeGroups: CriteriaGroup[];
21
+ showingChips: boolean;
20
22
  fieldMetadata: MetadataDetail[] | string[];
21
23
  isRecording: boolean;
22
24
  textAreaRef: HTMLTextAreaElement;
23
25
  private stopRecording;
24
26
  private speechApplyDebounceTimer;
25
- private baseInputForAppend;
26
27
  get speechAvailable(): boolean;
28
+ get criteriaChips(): CriteriaChip[];
29
+ private getFieldLabel;
30
+ toggleCriteriaView(): void;
31
+ removeChip(groupIndex: number, clauseIndex: number): void;
32
+ clearChips(): void;
27
33
  handleSubmit(): Promise<void>;
28
34
  handleBlur(): void;
29
35
  clear(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"ai-criteria-search.d.ts","sourceRoot":"","sources":["../../../src/ai-criteria-search/ai-criteria-search.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAGX,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAW/D;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,iBAAiB;IACzC,UAAU,EAAE,UAAU,CAAC;IAE7B,WAAW,EAAE,MAAM,CAA0D;IACxD,QAAQ,EAAE,OAAO,CAAC;IACvC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAa;IAEjC,UAAU,EAAE,MAAM,CAAM;IACxB,cAAc,EAAE,OAAO,CAAS;IAChC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC,aAAa,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAAM;IAChD,WAAW,EAAE,OAAO,CAAS;IAElC,WAAW,EAAE,mBAAmB,CAAC;IAExC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,wBAAwB,CAA8C;IAC9E,OAAO,CAAC,kBAAkB,CAAc;IAExC,IACI,eAAe,IAAI,OAAO,CAE7B;IAEK,YAAY;IAsDlB,UAAU;IAUV,KAAK;IAML,iBAAiB;IA+CjB,OAAO,CAAC,wBAAwB;CAMjC;AAED,eAAO,MAAM,uCAAuC,EAAE,cAA0B,CAAC;AACjF,eAAO,MAAM,6BAA6B,IAAK,CAAC;AAEhD,eAAO,MAAM,0BAA0B;;;;;;;;;;2BAMrC,CAAC"}
1
+ {"version":3,"file":"ai-criteria-search.d.ts","sourceRoot":"","sources":["../../../src/ai-criteria-search/ai-criteria-search.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAGX,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAI/D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAc,MAAM,0BAA0B,CAAC;AAOxF;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,iBAAiB;IACzC,UAAU,EAAE,UAAU,CAAC;IAE7B,WAAW,EAAE,MAAM,CAA0D;IACxD,QAAQ,EAAE,OAAO,CAAC;IAEjC,UAAU,EAAE,MAAM,CAAM;IACxB,cAAc,EAAE,OAAO,CAAS;IAChC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,YAAY,EAAE,aAAa,EAAE,CAAM;IACnC,YAAY,EAAE,OAAO,CAAS;IAE9B,aAAa,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAAM;IAChD,WAAW,EAAE,OAAO,CAAS;IAElC,WAAW,EAAE,mBAAmB,CAAC;IAExC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,wBAAwB,CAA8C;IAE9E,IACI,eAAe,IAAI,OAAO,CAE7B;IAED,IACI,aAAa,IAAI,YAAY,EAAE,CAUlC;IAED,OAAO,CAAC,aAAa;IAQrB,kBAAkB,IAAI,IAAI;IAS1B,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAmBzD,UAAU,IAAI,IAAI;IAOZ,YAAY;IA0DlB,UAAU;IAUV,KAAK;IAQL,iBAAiB;IAwCjB,OAAO,CAAC,wBAAwB;CAMjC;AAED,eAAO,MAAM,uCAAuC,EAAE,cAA0B,CAAC;AACjF,eAAO,MAAM,6BAA6B,IAAK,CAAC;AAEhD,eAAO,MAAM,0BAA0B;;;;;;;;;;2BAMrC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ai-criteria-search.styles.d.ts","sourceRoot":"","sources":["../../../src/ai-criteria-search/ai-criteria-search.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gCAAgC,iDAiC5C,CAAC"}
1
+ {"version":3,"file":"ai-criteria-search.styles.d.ts","sourceRoot":"","sources":["../../../src/ai-criteria-search/ai-criteria-search.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gCAAgC,iDAkG5C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ai-criteria-search.template.d.ts","sourceRoot":"","sources":["../../../src/ai-criteria-search/ai-criteria-search.template.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAExE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA8C7D,eAAO,MAAM,kCAAkC,EAAE,YAAY,CAAC,gBAAgB,CAE7E,CAAC"}
1
+ {"version":3,"file":"ai-criteria-search.template.d.ts","sourceRoot":"","sources":["../../../src/ai-criteria-search/ai-criteria-search.template.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA+F7D,eAAO,MAAM,kCAAkC,EAAE,YAAY,CAAC,gBAAgB,CAE7E,CAAC"}
@@ -33,4 +33,11 @@ export type GroupsValidationResult = {
33
33
  valid: CriteriaGroup[];
34
34
  invalid: ValidationError[];
35
35
  };
36
+ export type CriteriaChip = {
37
+ groupIndex: number;
38
+ clauseIndex: number;
39
+ fieldLabel: string;
40
+ operatorLabel: string;
41
+ valueLabel: string;
42
+ };
36
43
  //# sourceMappingURL=criteria-ir.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"criteria-ir.d.ts","sourceRoot":"","sources":["../../../../src/ai-criteria-search/validation/criteria-ir.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,UAAU,GACV,aAAa,GACb,UAAU,GACV,oBAAoB,GACpB,iBAAiB,GACjB,UAAU,GACV,aAAa,GACb,aAAa,GACb,cAAc,GACd,aAAa,GACb,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,wBAAwB,GACxB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC"}
1
+ {"version":3,"file":"criteria-ir.d.ts","sourceRoot":"","sources":["../../../../src/ai-criteria-search/validation/criteria-ir.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,UAAU,GACV,aAAa,GACb,UAAU,GACV,oBAAoB,GACpB,iBAAiB,GACjB,UAAU,GACV,aAAa,GACb,aAAa,GACb,cAAc,GACd,aAAa,GACb,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,wBAAwB,GACxB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC"}
@@ -14,4 +14,5 @@ export declare const STRING_OPERATORS: CriteriaOperator[];
14
14
  export declare const NUMERIC_OPERATORS: CriteriaOperator[];
15
15
  export declare const DATE_OPERATORS: CriteriaOperator[];
16
16
  export declare const DATETIME_OPERATORS: CriteriaOperator[];
17
+ export declare const OPERATOR_DISPLAY_LABEL: Record<CriteriaOperator, string>;
17
18
  //# sourceMappingURL=operator-map.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"operator-map.d.ts","sourceRoot":"","sources":["../../../../src/ai-criteria-search/validation/operator-map.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAkB,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA6CrF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAqBhE;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAAgB,EAM9C,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,EAO/C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,gBAAgB,EAO5C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAKhD,CAAC"}
1
+ {"version":3,"file":"operator-map.d.ts","sourceRoot":"","sources":["../../../../src/ai-criteria-search/validation/operator-map.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAkB,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AA6CrF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAqBhE;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAAgB,EAM9C,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,EAO/C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,gBAAgB,EAO5C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAKhD,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAoBnE,CAAC"}
@@ -129,6 +129,15 @@ export declare const AccordionItem: React.ForwardRefExoticComponent<
129
129
  >;
130
130
  export type AccordionItemRef = AccordionItemWC;
131
131
 
132
+ export declare const Accordion: React.ForwardRefExoticComponent<
133
+ React.PropsWithChildren<
134
+ Omit<PublicOf<AccordionWC>, 'children' | 'style'> &
135
+ HTMLWCProps & {
136
+ }
137
+ > & React.RefAttributes<AccordionWC>
138
+ >;
139
+ export type AccordionRef = AccordionWC;
140
+
132
141
  export declare const ActionsMenu: React.ForwardRefExoticComponent<
133
142
  React.PropsWithChildren<
134
143
  Omit<PublicOf<ActionsMenuWC>, 'children' | 'style'> &
@@ -158,15 +167,6 @@ export declare const AiCriteriaSearch: React.ForwardRefExoticComponent<
158
167
  >;
159
168
  export type AiCriteriaSearchRef = AiCriteriaSearchWC;
160
169
 
161
- export declare const Accordion: React.ForwardRefExoticComponent<
162
- React.PropsWithChildren<
163
- Omit<PublicOf<AccordionWC>, 'children' | 'style'> &
164
- HTMLWCProps & {
165
- }
166
- > & React.RefAttributes<AccordionWC>
167
- >;
168
- export type AccordionRef = AccordionWC;
169
-
170
170
  export declare const Anchor: React.ForwardRefExoticComponent<
171
171
  React.PropsWithChildren<
172
172
  Omit<PublicOf<AnchorWC>, 'children' | 'style'> &
@@ -5,7 +5,7 @@ import { FoundationElement } from '@microsoft/fast-foundation';
5
5
  import { getPrefix } from '../utils';
6
6
  import { foundationAiCriteriaSearchStyles as styles } from './ai-criteria-search.styles';
7
7
  import { foundationAiCriteriaSearchTemplate as template } from './ai-criteria-search.template';
8
- import { groupsToCriteria } from './validation/operator-map';
8
+ import { groupsToCriteria, OPERATOR_DISPLAY_LABEL } from './validation/operator-map';
9
9
  import { validateGroups } from './validation/schema-validator';
10
10
  import { showCriteriaError, formatValidationErrors } from './validation-error-notification';
11
11
  const SPEECH_APPLY_DEBOUNCE_MS = 700;
@@ -21,19 +21,73 @@ export class AiCriteriaSearch extends FoundationElement {
21
21
  constructor() {
22
22
  super(...arguments);
23
23
  this.placeholder = 'Describe your search criteria in natural language...';
24
- this.mode = 'replace';
25
24
  this.inputValue = '';
26
25
  this.isInterpreting = false;
27
26
  this.lastValidCriteria = null;
27
+ this.activeGroups = [];
28
+ this.showingChips = false;
28
29
  this.fieldMetadata = [];
29
30
  this.isRecording = false;
30
31
  this.stopRecording = null;
31
32
  this.speechApplyDebounceTimer = null;
32
- this.baseInputForAppend = '';
33
33
  }
34
34
  get speechAvailable() {
35
35
  return isSpeechRecognitionAvailable();
36
36
  }
37
+ get criteriaChips() {
38
+ return this.activeGroups.flatMap((group, groupIndex) => group.clauses.map((clause, clauseIndex) => {
39
+ var _a, _b;
40
+ return ({
41
+ groupIndex,
42
+ clauseIndex,
43
+ fieldLabel: this.getFieldLabel(clause.field),
44
+ operatorLabel: (_a = OPERATOR_DISPLAY_LABEL[clause.operator]) !== null && _a !== void 0 ? _a : clause.operator,
45
+ valueLabel: clause.operator === 'dateIsToday' ? '' : String((_b = clause.value) !== null && _b !== void 0 ? _b : ''),
46
+ });
47
+ }));
48
+ }
49
+ getFieldLabel(fieldName) {
50
+ var _a, _b;
51
+ if (!Array.isArray(this.fieldMetadata) || this.fieldMetadata.length === 0)
52
+ return fieldName;
53
+ const first = this.fieldMetadata[0];
54
+ if (typeof first === 'string')
55
+ return fieldName;
56
+ const meta = this.fieldMetadata.find((m) => m.NAME === fieldName);
57
+ return (_b = (_a = meta === null || meta === void 0 ? void 0 : meta.UI_LABEL) !== null && _a !== void 0 ? _a : meta === null || meta === void 0 ? void 0 : meta.NAME) !== null && _b !== void 0 ? _b : fieldName;
58
+ }
59
+ toggleCriteriaView() {
60
+ if (this.showingChips) {
61
+ this.inputValue = '';
62
+ this.showingChips = false;
63
+ }
64
+ else {
65
+ this.showingChips = true;
66
+ }
67
+ }
68
+ removeChip(groupIndex, clauseIndex) {
69
+ var _a;
70
+ const groups = this.activeGroups.map((g) => (Object.assign(Object.assign({}, g), { clauses: [...g.clauses] })));
71
+ (_a = groups[groupIndex]) === null || _a === void 0 ? void 0 : _a.clauses.splice(clauseIndex, 1);
72
+ const pruned = groups.filter((g) => g.clauses.length > 0);
73
+ this.activeGroups = pruned;
74
+ if (pruned.length === 0) {
75
+ this.showingChips = false;
76
+ this.lastValidCriteria = null;
77
+ this.$emit('criteria-changed', null);
78
+ }
79
+ else {
80
+ const criteria = groupsToCriteria(pruned);
81
+ this.lastValidCriteria = criteria;
82
+ this.$emit('criteria-changed', criteria);
83
+ }
84
+ }
85
+ clearChips() {
86
+ this.activeGroups = [];
87
+ this.showingChips = false;
88
+ this.lastValidCriteria = null;
89
+ this.$emit('criteria-changed', null);
90
+ }
37
91
  handleSubmit() {
38
92
  return __awaiter(this, void 0, void 0, function* () {
39
93
  var _a, _b, _c;
@@ -61,8 +115,12 @@ export class AiCriteriaSearch extends FoundationElement {
61
115
  this.$emit('validation-errors', invalid);
62
116
  }
63
117
  if (valid.length > 0) {
64
- const criteria = groupsToCriteria(valid);
118
+ const accumulated = [...this.activeGroups, ...valid];
119
+ const criteria = groupsToCriteria(accumulated);
65
120
  this.lastValidCriteria = criteria;
121
+ this.activeGroups = accumulated;
122
+ this.inputValue = '';
123
+ this.showingChips = true;
66
124
  this.$emit('criteria-changed', criteria);
67
125
  }
68
126
  }
@@ -82,42 +140,35 @@ export class AiCriteriaSearch extends FoundationElement {
82
140
  if (text) {
83
141
  this.handleSubmit();
84
142
  }
85
- else {
86
- this.clear();
143
+ else if (this.activeGroups.length > 0) {
144
+ this.showingChips = true;
87
145
  }
88
146
  }
89
147
  clear() {
90
148
  this.inputValue = '';
91
149
  this.lastValidCriteria = null;
150
+ this.activeGroups = [];
151
+ this.showingChips = false;
92
152
  this.$emit('criteria-changed', null);
93
153
  }
94
154
  toggleSpeechInput() {
95
- var _a, _b;
96
155
  if (this.isRecording && this.stopRecording) {
97
156
  this.clearSpeechApplyDebounce();
98
157
  this.stopRecording();
99
158
  this.stopRecording = null;
100
159
  this.isRecording = false;
101
- this.baseInputForAppend = '';
102
160
  return;
103
161
  }
104
- this.baseInputForAppend = this.mode === 'append' ? ((_b = (_a = this.inputValue) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '') : '';
162
+ this.inputValue = '';
163
+ this.showingChips = false;
105
164
  this.stopRecording = startSpeechRecognition((transcript, isFinal) => {
106
- if (this.mode === 'append') {
107
- this.inputValue = this.baseInputForAppend
108
- ? `${this.baseInputForAppend} ${transcript}`.trim()
109
- : transcript;
110
- }
111
- else {
112
- this.inputValue = transcript;
113
- }
165
+ this.inputValue = transcript;
114
166
  if (isFinal && (transcript === null || transcript === void 0 ? void 0 : transcript.trim())) {
115
167
  this.clearSpeechApplyDebounce();
116
168
  if (this.stopRecording) {
117
169
  this.stopRecording();
118
170
  this.stopRecording = null;
119
171
  this.isRecording = false;
120
- this.baseInputForAppend = '';
121
172
  }
122
173
  this.speechApplyDebounceTimer = setTimeout(() => {
123
174
  this.speechApplyDebounceTimer = null;
@@ -128,7 +179,6 @@ export class AiCriteriaSearch extends FoundationElement {
128
179
  this.clearSpeechApplyDebounce();
129
180
  this.isRecording = false;
130
181
  this.stopRecording = null;
131
- this.baseInputForAppend = '';
132
182
  });
133
183
  if (this.stopRecording) {
134
184
  this.isRecording = true;
@@ -150,9 +200,6 @@ __decorate([
150
200
  __decorate([
151
201
  attr({ mode: 'boolean' })
152
202
  ], AiCriteriaSearch.prototype, "disabled", void 0);
153
- __decorate([
154
- attr
155
- ], AiCriteriaSearch.prototype, "mode", void 0);
156
203
  __decorate([
157
204
  observable
158
205
  ], AiCriteriaSearch.prototype, "inputValue", void 0);
@@ -162,6 +209,12 @@ __decorate([
162
209
  __decorate([
163
210
  observable
164
211
  ], AiCriteriaSearch.prototype, "lastValidCriteria", void 0);
212
+ __decorate([
213
+ observable
214
+ ], AiCriteriaSearch.prototype, "activeGroups", void 0);
215
+ __decorate([
216
+ observable
217
+ ], AiCriteriaSearch.prototype, "showingChips", void 0);
165
218
  __decorate([
166
219
  observable
167
220
  ], AiCriteriaSearch.prototype, "fieldMetadata", void 0);
@@ -171,6 +224,9 @@ __decorate([
171
224
  __decorate([
172
225
  volatile
173
226
  ], AiCriteriaSearch.prototype, "speechAvailable", null);
227
+ __decorate([
228
+ volatile
229
+ ], AiCriteriaSearch.prototype, "criteriaChips", null);
174
230
  export const foundationAiCriteriaSearchShadowOptions = undefined;
175
231
  export const defaultAiCriteriaSearchConfig = {};
176
232
  export const foundationAiCriteriaSearch = AiCriteriaSearch.compose(Object.assign({ baseName: 'ai-criteria-search', template,
@@ -25,12 +25,77 @@ export const foundationAiCriteriaSearchStyles = css `
25
25
  min-width: 0;
26
26
  }
27
27
 
28
+ .criteria-chips-inline {
29
+ height: calc(((var(--base-height-multiplier) + var(--density)) * var(--design-unit) - 4) * 1px);
30
+ flex: 1;
31
+ min-width: 0;
32
+ display: flex;
33
+ align-items: center;
34
+ gap: calc(${designUnit} * 1px);
35
+ overflow-x: auto;
36
+ padding: 0 calc(${designUnit} * 2px);
37
+ background: var(--neutral-fill-input-rest);
38
+ border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-rest);
39
+ border-radius: calc(var(--control-corner-radius) * 1px);
40
+ scrollbar-width: none;
41
+ }
42
+
43
+ .criteria-chips-inline::-webkit-scrollbar {
44
+ display: none;
45
+ }
46
+
28
47
  .mic-icon {
29
48
  color: var(--neutral-foreground-rest);
30
49
  fill: currentColor;
31
50
  }
32
51
 
33
- .mode-control {
52
+ .criteria-toggle-button,
53
+ .criteria-clear-button {
54
+ flex-shrink: 0;
55
+ }
56
+
57
+ .criteria-chip {
58
+ display: inline-flex;
59
+ align-items: center;
34
60
  flex-shrink: 0;
61
+ gap: calc(${designUnit} * 1px);
62
+ padding: calc(${designUnit} * 0.5px) calc(${designUnit} * 2px);
63
+ background: var(--neutral-fill-rest);
64
+ border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-rest);
65
+ border-radius: calc(${designUnit} * 4px);
66
+ font-size: var(--type-ramp-minus-1-font-size);
67
+ color: var(--neutral-foreground-rest);
68
+ white-space: nowrap;
69
+ }
70
+
71
+ .criteria-chip-field {
72
+ font-weight: 600;
73
+ }
74
+
75
+ .criteria-chip-operator {
76
+ color: var(--neutral-foreground-hint, var(--neutral-foreground-rest));
77
+ font-style: italic;
78
+ }
79
+
80
+ .criteria-chip-remove {
81
+ display: inline-flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ width: 14px;
85
+ height: 14px;
86
+ padding: 0;
87
+ margin-left: calc(${designUnit} * 0.5px);
88
+ background: none;
89
+ border: none;
90
+ cursor: pointer;
91
+ color: var(--neutral-foreground-hint, var(--neutral-foreground-rest));
92
+ font-size: 10px;
93
+ border-radius: 50%;
94
+ line-height: 1;
95
+ }
96
+
97
+ .criteria-chip-remove:hover {
98
+ background: var(--neutral-fill-hover);
99
+ color: var(--neutral-foreground-rest);
35
100
  }
36
101
  `;
@@ -1,40 +1,76 @@
1
1
  import { isAIFeatureEnabled } from '@genesislcap/foundation-ai';
2
2
  import { sync } from '@genesislcap/foundation-utils';
3
- import { html, ref, when } from '@microsoft/fast-element';
3
+ import { html, ref, repeat, when } from '@microsoft/fast-element';
4
4
  import { getPrefix } from '../utils';
5
5
  const aiCriteriaSearchTemplate = (prefix) => html `
6
6
  ${when(() => isAIFeatureEnabled(), html `
7
7
  <div class="ai-criteria-search">
8
8
  <div class="ai-criteria-search-row">
9
- <${prefix}-text-area
10
- ${ref('textAreaRef')}
11
- class="criteria-input"
12
- placeholder="${(x) => x.placeholder}"
13
- ?disabled=${(x) => x.disabled || x.isInterpreting}
14
- :value=${sync((x) => x.inputValue, 'string', 'input')}
15
- @blur=${(x) => x.handleBlur()}
16
- rows="1"
17
- ></${prefix}-text-area>
18
- ${when((x) => x.speechAvailable, html `
19
- <${prefix}-button
20
- class="mic-button"
21
- appearance="${(x) => (x.isRecording ? 'accent' : 'outline')}"
22
- ?disabled=${(x) => x.disabled || x.isInterpreting}
23
- @click=${(x) => x.toggleSpeechInput()}
24
- title=${(x) => (x.isRecording ? 'Stop recording' : 'Start voice input')}
25
- >
26
- <${prefix}-icon
27
- class="mic-icon"
28
- name="microphone"
29
- size="lg"
30
- variant="solid"
31
- ></${prefix}-icon>
32
- </${prefix}-button>
33
- `)}
34
- <${prefix}-segmented-control class="mode-control" :value=${sync((x) => x.mode)}>
35
- <${prefix}-segmented-item value="append">Append</${prefix}-segmented-item>
36
- <${prefix}-segmented-item value="replace">Replace</${prefix}-segmented-item>
37
- </${prefix}-segmented-control>
9
+ ${when((x) => !x.showingChips, html `
10
+ <${prefix}-text-area
11
+ ${ref('textAreaRef')}
12
+ class="criteria-input"
13
+ placeholder="${(x) => x.placeholder}"
14
+ ?disabled=${(x) => x.disabled || x.isInterpreting}
15
+ :value=${sync((x) => x.inputValue, 'string', 'input')}
16
+ @blur=${(x) => x.handleBlur()}
17
+ rows="1"
18
+ ></${prefix}-text-area>
19
+ `)}
20
+ ${when((x) => x.showingChips, html `
21
+ <div class="criteria-chips-inline">
22
+ ${repeat((x) => x.criteriaChips, html `
23
+ <span class="criteria-chip">
24
+ <span class="criteria-chip-field">${(chip) => chip.fieldLabel}</span>
25
+ <span class="criteria-chip-operator">${(chip) => chip.operatorLabel}</span>
26
+ ${when((chip) => !!chip.valueLabel, html `
27
+ <span class="criteria-chip-value">${(chip) => chip.valueLabel}</span>
28
+ `)}
29
+ <button
30
+ class="criteria-chip-remove"
31
+ aria-label="Remove filter"
32
+ @click=${(chip, c) => c.parent.removeChip(chip.groupIndex, chip.clauseIndex)}
33
+ >
34
+ &#x2715;
35
+ </button>
36
+ </span>
37
+ `)}
38
+ </div>
39
+ `)}
40
+ <${prefix}-button
41
+ class="criteria-toggle-button"
42
+ appearance="outline"
43
+ title=${(x) => (x.showingChips ? 'Add more criteria' : 'View active filters')}
44
+ ?disabled=${(x) => x.activeGroups.length === 0 || x.isInterpreting}
45
+ @click=${(x) => x.toggleCriteriaView()}
46
+ >
47
+ <${prefix}-icon name="pen" size="sm"></${prefix}-icon>
48
+ </${prefix}-button>
49
+ <${prefix}-button
50
+ class="criteria-clear-button"
51
+ appearance="outline"
52
+ title="Clear all filters"
53
+ ?disabled=${(x) => x.activeGroups.length === 0 || x.isInterpreting}
54
+ @click=${(x) => x.clearChips()}
55
+ >
56
+ <${prefix}-icon name="trash-alt" size="sm"></${prefix}-icon>
57
+ </${prefix}-button>
58
+ ${when((x) => x.speechAvailable, html `
59
+ <${prefix}-button
60
+ class="mic-button"
61
+ appearance="${(x) => (x.isRecording ? 'accent' : 'outline')}"
62
+ ?disabled=${(x) => x.disabled || x.isInterpreting}
63
+ @click=${(x) => x.toggleSpeechInput()}
64
+ title=${(x) => (x.isRecording ? 'Stop recording' : 'Start voice input')}
65
+ >
66
+ <${prefix}-icon
67
+ class="mic-icon"
68
+ name="microphone"
69
+ size="lg"
70
+ variant="solid"
71
+ ></${prefix}-icon>
72
+ </${prefix}-button>
73
+ `)}
38
74
  </div>
39
75
  </div>
40
76
  `)}
@@ -95,3 +95,24 @@ export const DATETIME_OPERATORS = [
95
95
  'dateTimeIsGreaterEqual',
96
96
  'dateTimeIsLessEqual',
97
97
  ];
98
+ export const OPERATOR_DISPLAY_LABEL = {
99
+ contains: 'contains',
100
+ equals: '=',
101
+ startsWith: 'starts with',
102
+ endsWith: 'ends with',
103
+ notEqual: '≠',
104
+ greaterThan: '>',
105
+ lessThan: '<',
106
+ greaterThanOrEqual: '≥',
107
+ lessThanOrEqual: '≤',
108
+ dateIsToday: 'is today',
109
+ dateIsAfter: 'after',
110
+ dateIsBefore: 'before',
111
+ dateIsEqual: '=',
112
+ dateIsGreaterEqual: '≥',
113
+ dateIsLessEqual: '≤',
114
+ dateTimeIsAfter: 'after',
115
+ dateTimeIsBefore: 'before',
116
+ dateTimeIsGreaterEqual: '≥',
117
+ dateTimeIsLessEqual: '≤',
118
+ };
package/dist/react.cjs CHANGED
@@ -107,6 +107,11 @@ const AccordionItem = React.forwardRef(function AccordionItem(props, ref) {
107
107
  return React.createElement(customElements.getName(AccordionItemWC) ?? '%%prefix%%-accordion-item', { ...rest, ref }, children);
108
108
  });
109
109
 
110
+ const Accordion = React.forwardRef(function Accordion(props, ref) {
111
+ const { children, ...rest } = props;
112
+ return React.createElement(customElements.getName(AccordionWC) ?? '%%prefix%%-accordion', { ...rest, ref }, children);
113
+ });
114
+
110
115
  const ActionsMenu = React.forwardRef(function ActionsMenu(props, ref) {
111
116
  const { children, ...rest } = props;
112
117
  return React.createElement(customElements.getName(ActionsMenuWC) ?? '%%prefix%%-actions-menu', { ...rest, ref }, children);
@@ -139,11 +144,6 @@ const AiCriteriaSearch = React.forwardRef(function AiCriteriaSearch(props, ref)
139
144
  return React.createElement(customElements.getName(AiCriteriaSearchWC) ?? '%%prefix%%-ai-criteria-search', { ...rest, ref: _mergeRefs(_innerRef, ref) }, children);
140
145
  });
141
146
 
142
- const Accordion = React.forwardRef(function Accordion(props, ref) {
143
- const { children, ...rest } = props;
144
- return React.createElement(customElements.getName(AccordionWC) ?? '%%prefix%%-accordion', { ...rest, ref }, children);
145
- });
146
-
147
147
  const Anchor = React.forwardRef(function Anchor(props, ref) {
148
148
  const { children, ...rest } = props;
149
149
  return React.createElement(customElements.getName(AnchorWC) ?? '%%prefix%%-anchor', { ...rest, ref }, children);
@@ -878,10 +878,10 @@ const UrlInput = React.forwardRef(function UrlInput(props, ref) {
878
878
 
879
879
  module.exports = {
880
880
  AccordionItem,
881
+ Accordion,
881
882
  ActionsMenu,
882
883
  AiIndicator,
883
884
  AiCriteriaSearch,
884
- Accordion,
885
885
  Anchor,
886
886
  AnchoredRegion,
887
887
  Avatar,
package/dist/react.mjs CHANGED
@@ -105,6 +105,11 @@ export const AccordionItem = React.forwardRef(function AccordionItem(props, ref)
105
105
  return React.createElement(customElements.getName(AccordionItemWC) ?? '%%prefix%%-accordion-item', { ...rest, ref }, children);
106
106
  });
107
107
 
108
+ export const Accordion = React.forwardRef(function Accordion(props, ref) {
109
+ const { children, ...rest } = props;
110
+ return React.createElement(customElements.getName(AccordionWC) ?? '%%prefix%%-accordion', { ...rest, ref }, children);
111
+ });
112
+
108
113
  export const ActionsMenu = React.forwardRef(function ActionsMenu(props, ref) {
109
114
  const { children, ...rest } = props;
110
115
  return React.createElement(customElements.getName(ActionsMenuWC) ?? '%%prefix%%-actions-menu', { ...rest, ref }, children);
@@ -137,11 +142,6 @@ export const AiCriteriaSearch = React.forwardRef(function AiCriteriaSearch(props
137
142
  return React.createElement(customElements.getName(AiCriteriaSearchWC) ?? '%%prefix%%-ai-criteria-search', { ...rest, ref: _mergeRefs(_innerRef, ref) }, children);
138
143
  });
139
144
 
140
- export const Accordion = React.forwardRef(function Accordion(props, ref) {
141
- const { children, ...rest } = props;
142
- return React.createElement(customElements.getName(AccordionWC) ?? '%%prefix%%-accordion', { ...rest, ref }, children);
143
- });
144
-
145
145
  export const Anchor = React.forwardRef(function Anchor(props, ref) {
146
146
  const { children, ...rest } = props;
147
147
  return React.createElement(customElements.getName(AnchorWC) ?? '%%prefix%%-anchor', { ...rest, ref }, children);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/foundation-ui",
3
3
  "description": "Genesis Foundation UI",
4
- "version": "14.428.2-alpha-257ebec.0",
4
+ "version": "14.429.0",
5
5
  "sideEffects": false,
6
6
  "license": "SEE LICENSE IN license.txt",
7
7
  "main": "dist/esm/index.js",
@@ -85,13 +85,13 @@
85
85
  }
86
86
  },
87
87
  "devDependencies": {
88
- "@genesislcap/foundation-testing": "14.428.2-alpha-257ebec.0",
89
- "@genesislcap/genx": "14.428.2-alpha-257ebec.0",
90
- "@genesislcap/rollup-builder": "14.428.2-alpha-257ebec.0",
91
- "@genesislcap/ts-builder": "14.428.2-alpha-257ebec.0",
92
- "@genesislcap/uvu-playwright-builder": "14.428.2-alpha-257ebec.0",
93
- "@genesislcap/vite-builder": "14.428.2-alpha-257ebec.0",
94
- "@genesislcap/webpack-builder": "14.428.2-alpha-257ebec.0",
88
+ "@genesislcap/foundation-testing": "14.429.0",
89
+ "@genesislcap/genx": "14.429.0",
90
+ "@genesislcap/rollup-builder": "14.429.0",
91
+ "@genesislcap/ts-builder": "14.429.0",
92
+ "@genesislcap/uvu-playwright-builder": "14.429.0",
93
+ "@genesislcap/vite-builder": "14.429.0",
94
+ "@genesislcap/webpack-builder": "14.429.0",
95
95
  "copyfiles": "^2.4.1"
96
96
  },
97
97
  "dependencies": {
@@ -100,16 +100,16 @@
100
100
  "@fortawesome/free-regular-svg-icons": "^6.2.1",
101
101
  "@fortawesome/free-solid-svg-icons": "^6.2.1",
102
102
  "@genesiscommunitysuccess/analyzer-import-alias-plugin": "^5.0.3",
103
- "@genesislcap/expression-builder": "14.428.2-alpha-257ebec.0",
104
- "@genesislcap/foundation-ai": "14.428.2-alpha-257ebec.0",
105
- "@genesislcap/foundation-comms": "14.428.2-alpha-257ebec.0",
106
- "@genesislcap/foundation-criteria": "14.428.2-alpha-257ebec.0",
107
- "@genesislcap/foundation-errors": "14.428.2-alpha-257ebec.0",
108
- "@genesislcap/foundation-events": "14.428.2-alpha-257ebec.0",
109
- "@genesislcap/foundation-logger": "14.428.2-alpha-257ebec.0",
110
- "@genesislcap/foundation-notifications": "14.428.2-alpha-257ebec.0",
111
- "@genesislcap/foundation-user": "14.428.2-alpha-257ebec.0",
112
- "@genesislcap/foundation-utils": "14.428.2-alpha-257ebec.0",
103
+ "@genesislcap/expression-builder": "14.429.0",
104
+ "@genesislcap/foundation-ai": "14.429.0",
105
+ "@genesislcap/foundation-comms": "14.429.0",
106
+ "@genesislcap/foundation-criteria": "14.429.0",
107
+ "@genesislcap/foundation-errors": "14.429.0",
108
+ "@genesislcap/foundation-events": "14.429.0",
109
+ "@genesislcap/foundation-logger": "14.429.0",
110
+ "@genesislcap/foundation-notifications": "14.429.0",
111
+ "@genesislcap/foundation-user": "14.429.0",
112
+ "@genesislcap/foundation-utils": "14.429.0",
113
113
  "@microsoft/fast-colors": "5.3.1",
114
114
  "@microsoft/fast-components": "2.30.6",
115
115
  "@microsoft/fast-element": "1.14.0",
@@ -142,5 +142,5 @@
142
142
  "require": "./dist/react.cjs"
143
143
  }
144
144
  },
145
- "gitHead": "1bc9af761d734595aac8173e23d623e25459f9c3"
145
+ "gitHead": "3584bc77da10f9c2b4207d690ef088d2c8a12496"
146
146
  }