fluentui-extended 2026.2.5 → 2026.2.6

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/README.md CHANGED
@@ -29,6 +29,8 @@ A searchable dropdown component styled after Dynamics 365 lookup fields. Support
29
29
 
30
30
  ### QueryBuilder
31
31
 
32
+ > **🚧 Beta** - This component is in beta. Please report any issues on [GitHub](https://github.com/garethcheyne/npm-fluentui-extended/issues).
33
+
32
34
  An Advanced Find-style query builder for Dynamics 365. Build complex filter conditions with AND/OR logic, serialize to FetchXML or OData, and validate queries against the Dynamics 365 API.
33
35
 
34
36
  ![QueryBuilder Component](assets/screenshot-querybuilder.png)
package/dist/index.d.mts CHANGED
@@ -63,23 +63,60 @@ interface QueryBuilderOption {
63
63
  label: string;
64
64
  value: string | number;
65
65
  }
66
+ /** Target entity for lookup fields */
67
+ interface QueryBuilderLookupTarget {
68
+ /** Logical name of the target entity (e.g., "contact") */
69
+ entityLogicalName: string;
70
+ /** Entity set name for OData queries (e.g., "contacts") */
71
+ entitySetName?: string;
72
+ /** Display name of the entity (e.g., "Contact") */
73
+ displayName?: string;
74
+ /** Primary name attribute for searching (e.g., "fullname") */
75
+ primaryNameAttribute?: string;
76
+ }
66
77
  interface QueryBuilderField {
67
78
  id: string;
68
79
  label: string;
69
80
  dataType: QueryBuilderDataType;
70
81
  options?: QueryBuilderOption[];
82
+ /** Schema name (PascalCase attribute name, e.g., "CreatedOn") */
83
+ schemaName?: string;
84
+ /** Target entities for lookup fields (which entities can be referenced) */
85
+ targets?: QueryBuilderLookupTarget[];
71
86
  }
72
- type QueryBuilderOperator = 'eq' | 'ne' | 'gt' | 'ge' | 'lt' | 'le' | 'between' | 'contains' | 'notcontains' | 'startswith' | 'endswith' | 'containsdata' | 'null' | 'notnull';
87
+ /**
88
+ * FetchXML condition operators.
89
+ *
90
+ * Common operators are explicitly listed for IDE autocomplete.
91
+ * Additional FetchXML operators are supported via the string type.
92
+ *
93
+ * @see QueryBuilder.operators.ts for full list of operators
94
+ */
95
+ type QueryBuilderOperator = 'eq' | 'ne' | 'gt' | 'ge' | 'lt' | 'le' | 'null' | 'not-null' | 'notnull' | 'contains' | 'not-contain' | 'begins-with' | 'not-begin-with' | 'ends-with' | 'not-end-with' | 'like' | 'not-like' | 'notcontains' | 'startswith' | 'endswith' | 'containsdata' | 'in' | 'not-in' | 'between' | 'not-between' | 'contain-values' | 'not-contain-values' | 'on' | 'on-or-before' | 'on-or-after' | 'not-on' | 'today' | 'yesterday' | 'tomorrow' | 'this-week' | 'last-week' | 'next-week' | 'this-month' | 'last-month' | 'next-month' | 'this-year' | 'last-year' | 'next-year' | 'last-seven-days' | 'next-seven-days' | 'last-x-hours' | 'next-x-hours' | 'last-x-days' | 'next-x-days' | 'last-x-weeks' | 'next-x-weeks' | 'last-x-months' | 'next-x-months' | 'last-x-years' | 'next-x-years' | 'olderthan-x-minutes' | 'olderthan-x-hours' | 'olderthan-x-days' | 'olderthan-x-weeks' | 'olderthan-x-months' | 'olderthan-x-years' | 'this-fiscal-year' | 'this-fiscal-period' | 'last-fiscal-year' | 'last-fiscal-period' | 'next-fiscal-year' | 'next-fiscal-period' | 'last-x-fiscal-years' | 'last-x-fiscal-periods' | 'next-x-fiscal-years' | 'next-x-fiscal-periods' | 'in-fiscal-year' | 'in-fiscal-period' | 'in-fiscal-period-and-year' | 'in-or-before-fiscal-period-and-year' | 'in-or-after-fiscal-period-and-year' | 'eq-userid' | 'ne-userid' | 'eq-userteams' | 'eq-useroruserteams' | 'eq-useroruserhierarchy' | 'eq-useroruserhierarchyandteams' | 'eq-businessid' | 'ne-businessid' | 'eq-userlanguage' | 'above' | 'eq-or-above' | 'under' | 'eq-or-under' | 'not-under' | (string & {});
73
96
  interface QueryBuilderCondition {
74
97
  id: string;
75
98
  kind?: 'field' | 'relatedEntity';
76
99
  fieldId: string;
77
100
  operator: QueryBuilderOperator;
78
- value?: string | number | boolean;
101
+ /** Single value or array of values (for in/not-in operators) */
102
+ value?: string | number | boolean | (string | number)[];
79
103
  value2?: string | number | boolean;
80
104
  /** Display name for lookup values (the GUID is stored in value) */
81
105
  valueDisplayName?: string;
106
+ /** Entity alias when condition references a link-entity (e.g., entityname="S" in FetchXML) */
107
+ entityAlias?: string;
108
+ /** The lookup field ID that creates this relationship (e.g., "ownerid") - used as "to" in link-entity */
82
109
  relatedEntityName?: string;
110
+ /** The target entity logical name (e.g., "systemuser") - used as "name" in link-entity */
111
+ relatedEntityTarget?: string;
112
+ /** Alias for the link-entity (e.g., "S" in alias="S") */
113
+ relatedEntityAlias?: string;
114
+ /** Nested conditions for related entity (link-entity filter) */
115
+ nestedConditions?: QueryBuilderCondition[];
116
+ /** Logic operator for nested conditions */
117
+ nestedLogic?: 'and' | 'or';
118
+ /** Fields available for the related entity (loaded dynamically) */
119
+ nestedFields?: QueryBuilderField[];
83
120
  }
84
121
  interface QueryBuilderGroup {
85
122
  id: string;
@@ -94,10 +131,20 @@ interface QueryBuilderApplyResult {
94
131
  fetchXmlFilter: string;
95
132
  fetchXml: string;
96
133
  odataFilter: string;
134
+ /** Full OData query URL (e.g., "accounts?$filter=...") - requires entitySetName */
135
+ odataQuery?: string;
97
136
  }
98
137
  interface QueryBuilderRelatedEntity {
138
+ /** Unique identifier - typically the lookup field name (e.g., "primarycontactid") */
99
139
  id: string;
140
+ /** Display label for the relationship (e.g., "Primary Contact (Contact)") */
100
141
  label: string;
142
+ /** The lookup field that creates this relationship */
143
+ lookupField?: string;
144
+ /** The target entity logical name (e.g., "contact") */
145
+ targetEntity?: string;
146
+ /** The target entity set name for OData (e.g., "contacts") */
147
+ targetEntitySetName?: string;
101
148
  }
102
149
  interface QueryBuilderLookupOption {
103
150
  /** Unique identifier (typically a GUID) */
@@ -109,8 +156,11 @@ interface QueryBuilderLookupOption {
109
156
  }
110
157
  interface QueryBuilderProps {
111
158
  entityName: string;
159
+ /** Entity set name for OData queries (e.g., "accounts"). If not provided, will be fetched from Xrm metadata. */
160
+ entitySetName?: string;
112
161
  entityDisplayName?: string;
113
162
  fields?: QueryBuilderField[];
163
+ /** Related entities for filtering. If not provided, will be auto-detected from lookup fields. */
114
164
  relatedEntities?: QueryBuilderRelatedEntity[];
115
165
  /** Initial query state object */
116
166
  initialState?: QueryBuilderState;
@@ -141,7 +191,17 @@ interface QueryBuilderProps {
141
191
  onLookupSearch?: (fieldId: string, searchText: string) => Promise<QueryBuilderLookupOption[]> | QueryBuilderLookupOption[];
142
192
  }
143
193
 
144
- declare const serializeQueryBuilderState: (state: QueryBuilderState, fields: QueryBuilderField[], entityName: string) => QueryBuilderApplyResult;
194
+ /**
195
+ * QueryBuilder Serializer
196
+ *
197
+ * Converts QueryBuilder state to FetchXML and OData formats.
198
+ */
199
+
200
+ /**
201
+ * Serialize QueryBuilder state to FetchXML and OData
202
+ */
203
+ declare const serializeQueryBuilderState: (state: QueryBuilderState, fields: QueryBuilderField[], entityName: string, entitySetName?: string) => QueryBuilderApplyResult;
204
+
145
205
  declare const QueryBuilder: React.FC<QueryBuilderProps>;
146
206
 
147
207
  export { Lookup, type LookupOption, type LookupOptionDetail, type LookupProps, QueryBuilder, type QueryBuilderApplyResult, type QueryBuilderCondition, type QueryBuilderDataType, type QueryBuilderField, type QueryBuilderGroup, type QueryBuilderOperator, type QueryBuilderOption, type QueryBuilderProps, type QueryBuilderRelatedEntity, type QueryBuilderState, serializeQueryBuilderState };
package/dist/index.d.ts CHANGED
@@ -63,23 +63,60 @@ interface QueryBuilderOption {
63
63
  label: string;
64
64
  value: string | number;
65
65
  }
66
+ /** Target entity for lookup fields */
67
+ interface QueryBuilderLookupTarget {
68
+ /** Logical name of the target entity (e.g., "contact") */
69
+ entityLogicalName: string;
70
+ /** Entity set name for OData queries (e.g., "contacts") */
71
+ entitySetName?: string;
72
+ /** Display name of the entity (e.g., "Contact") */
73
+ displayName?: string;
74
+ /** Primary name attribute for searching (e.g., "fullname") */
75
+ primaryNameAttribute?: string;
76
+ }
66
77
  interface QueryBuilderField {
67
78
  id: string;
68
79
  label: string;
69
80
  dataType: QueryBuilderDataType;
70
81
  options?: QueryBuilderOption[];
82
+ /** Schema name (PascalCase attribute name, e.g., "CreatedOn") */
83
+ schemaName?: string;
84
+ /** Target entities for lookup fields (which entities can be referenced) */
85
+ targets?: QueryBuilderLookupTarget[];
71
86
  }
72
- type QueryBuilderOperator = 'eq' | 'ne' | 'gt' | 'ge' | 'lt' | 'le' | 'between' | 'contains' | 'notcontains' | 'startswith' | 'endswith' | 'containsdata' | 'null' | 'notnull';
87
+ /**
88
+ * FetchXML condition operators.
89
+ *
90
+ * Common operators are explicitly listed for IDE autocomplete.
91
+ * Additional FetchXML operators are supported via the string type.
92
+ *
93
+ * @see QueryBuilder.operators.ts for full list of operators
94
+ */
95
+ type QueryBuilderOperator = 'eq' | 'ne' | 'gt' | 'ge' | 'lt' | 'le' | 'null' | 'not-null' | 'notnull' | 'contains' | 'not-contain' | 'begins-with' | 'not-begin-with' | 'ends-with' | 'not-end-with' | 'like' | 'not-like' | 'notcontains' | 'startswith' | 'endswith' | 'containsdata' | 'in' | 'not-in' | 'between' | 'not-between' | 'contain-values' | 'not-contain-values' | 'on' | 'on-or-before' | 'on-or-after' | 'not-on' | 'today' | 'yesterday' | 'tomorrow' | 'this-week' | 'last-week' | 'next-week' | 'this-month' | 'last-month' | 'next-month' | 'this-year' | 'last-year' | 'next-year' | 'last-seven-days' | 'next-seven-days' | 'last-x-hours' | 'next-x-hours' | 'last-x-days' | 'next-x-days' | 'last-x-weeks' | 'next-x-weeks' | 'last-x-months' | 'next-x-months' | 'last-x-years' | 'next-x-years' | 'olderthan-x-minutes' | 'olderthan-x-hours' | 'olderthan-x-days' | 'olderthan-x-weeks' | 'olderthan-x-months' | 'olderthan-x-years' | 'this-fiscal-year' | 'this-fiscal-period' | 'last-fiscal-year' | 'last-fiscal-period' | 'next-fiscal-year' | 'next-fiscal-period' | 'last-x-fiscal-years' | 'last-x-fiscal-periods' | 'next-x-fiscal-years' | 'next-x-fiscal-periods' | 'in-fiscal-year' | 'in-fiscal-period' | 'in-fiscal-period-and-year' | 'in-or-before-fiscal-period-and-year' | 'in-or-after-fiscal-period-and-year' | 'eq-userid' | 'ne-userid' | 'eq-userteams' | 'eq-useroruserteams' | 'eq-useroruserhierarchy' | 'eq-useroruserhierarchyandteams' | 'eq-businessid' | 'ne-businessid' | 'eq-userlanguage' | 'above' | 'eq-or-above' | 'under' | 'eq-or-under' | 'not-under' | (string & {});
73
96
  interface QueryBuilderCondition {
74
97
  id: string;
75
98
  kind?: 'field' | 'relatedEntity';
76
99
  fieldId: string;
77
100
  operator: QueryBuilderOperator;
78
- value?: string | number | boolean;
101
+ /** Single value or array of values (for in/not-in operators) */
102
+ value?: string | number | boolean | (string | number)[];
79
103
  value2?: string | number | boolean;
80
104
  /** Display name for lookup values (the GUID is stored in value) */
81
105
  valueDisplayName?: string;
106
+ /** Entity alias when condition references a link-entity (e.g., entityname="S" in FetchXML) */
107
+ entityAlias?: string;
108
+ /** The lookup field ID that creates this relationship (e.g., "ownerid") - used as "to" in link-entity */
82
109
  relatedEntityName?: string;
110
+ /** The target entity logical name (e.g., "systemuser") - used as "name" in link-entity */
111
+ relatedEntityTarget?: string;
112
+ /** Alias for the link-entity (e.g., "S" in alias="S") */
113
+ relatedEntityAlias?: string;
114
+ /** Nested conditions for related entity (link-entity filter) */
115
+ nestedConditions?: QueryBuilderCondition[];
116
+ /** Logic operator for nested conditions */
117
+ nestedLogic?: 'and' | 'or';
118
+ /** Fields available for the related entity (loaded dynamically) */
119
+ nestedFields?: QueryBuilderField[];
83
120
  }
84
121
  interface QueryBuilderGroup {
85
122
  id: string;
@@ -94,10 +131,20 @@ interface QueryBuilderApplyResult {
94
131
  fetchXmlFilter: string;
95
132
  fetchXml: string;
96
133
  odataFilter: string;
134
+ /** Full OData query URL (e.g., "accounts?$filter=...") - requires entitySetName */
135
+ odataQuery?: string;
97
136
  }
98
137
  interface QueryBuilderRelatedEntity {
138
+ /** Unique identifier - typically the lookup field name (e.g., "primarycontactid") */
99
139
  id: string;
140
+ /** Display label for the relationship (e.g., "Primary Contact (Contact)") */
100
141
  label: string;
142
+ /** The lookup field that creates this relationship */
143
+ lookupField?: string;
144
+ /** The target entity logical name (e.g., "contact") */
145
+ targetEntity?: string;
146
+ /** The target entity set name for OData (e.g., "contacts") */
147
+ targetEntitySetName?: string;
101
148
  }
102
149
  interface QueryBuilderLookupOption {
103
150
  /** Unique identifier (typically a GUID) */
@@ -109,8 +156,11 @@ interface QueryBuilderLookupOption {
109
156
  }
110
157
  interface QueryBuilderProps {
111
158
  entityName: string;
159
+ /** Entity set name for OData queries (e.g., "accounts"). If not provided, will be fetched from Xrm metadata. */
160
+ entitySetName?: string;
112
161
  entityDisplayName?: string;
113
162
  fields?: QueryBuilderField[];
163
+ /** Related entities for filtering. If not provided, will be auto-detected from lookup fields. */
114
164
  relatedEntities?: QueryBuilderRelatedEntity[];
115
165
  /** Initial query state object */
116
166
  initialState?: QueryBuilderState;
@@ -141,7 +191,17 @@ interface QueryBuilderProps {
141
191
  onLookupSearch?: (fieldId: string, searchText: string) => Promise<QueryBuilderLookupOption[]> | QueryBuilderLookupOption[];
142
192
  }
143
193
 
144
- declare const serializeQueryBuilderState: (state: QueryBuilderState, fields: QueryBuilderField[], entityName: string) => QueryBuilderApplyResult;
194
+ /**
195
+ * QueryBuilder Serializer
196
+ *
197
+ * Converts QueryBuilder state to FetchXML and OData formats.
198
+ */
199
+
200
+ /**
201
+ * Serialize QueryBuilder state to FetchXML and OData
202
+ */
203
+ declare const serializeQueryBuilderState: (state: QueryBuilderState, fields: QueryBuilderField[], entityName: string, entitySetName?: string) => QueryBuilderApplyResult;
204
+
145
205
  declare const QueryBuilder: React.FC<QueryBuilderProps>;
146
206
 
147
207
  export { Lookup, type LookupOption, type LookupOptionDetail, type LookupProps, QueryBuilder, type QueryBuilderApplyResult, type QueryBuilderCondition, type QueryBuilderDataType, type QueryBuilderField, type QueryBuilderGroup, type QueryBuilderOperator, type QueryBuilderOption, type QueryBuilderProps, type QueryBuilderRelatedEntity, type QueryBuilderState, serializeQueryBuilderState };