@oneuptime/common 10.0.68 → 10.0.70
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/Models/DatabaseModels/KubernetesCluster.ts +5 -0
- package/Models/DatabaseModels/KubernetesResource.ts +19 -0
- package/Server/API/KubernetesResourceAPI.ts +2 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1776865086264-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1776881254913-DedupeKubernetesClustersAndAddUniqueIndex.ts +134 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/DatabaseService.ts +19 -4
- package/Server/Services/KubernetesResourceService.ts +323 -8
- package/Server/Types/Database/QueryHelper.ts +127 -0
- package/Server/Types/Database/QueryUtil.ts +244 -0
- package/Server/Utils/VM/VMRunner.ts +39 -22
- package/Types/BaseDatabase/EndsWith.ts +41 -0
- package/Types/BaseDatabase/IncludesAll.ts +45 -0
- package/Types/BaseDatabase/IncludesNone.ts +48 -0
- package/Types/BaseDatabase/NotContains.ts +41 -0
- package/Types/BaseDatabase/StartsWith.ts +41 -0
- package/Types/IsolatedVM/ReturnResult.ts +6 -0
- package/Types/JSON.ts +20 -0
- package/Types/Kubernetes/KubernetesInventoryExtractor.ts +15 -1
- package/Types/SerializableObjectDictionary.ts +10 -0
- package/UI/Components/Filters/BooleanFilter.tsx +1 -0
- package/UI/Components/Filters/DateFilter.tsx +212 -25
- package/UI/Components/Filters/DropdownFilter.tsx +1 -0
- package/UI/Components/Filters/EntityFilter.tsx +214 -41
- package/UI/Components/Filters/FilterViewer.tsx +228 -146
- package/UI/Components/Filters/FilterViewerItem.tsx +1 -11
- package/UI/Components/Filters/FiltersForm.tsx +148 -97
- package/UI/Components/Filters/NumberFilter.tsx +219 -34
- package/UI/Components/Filters/OperatorSelector.tsx +91 -0
- package/UI/Components/Filters/TextFilter.tsx +182 -71
- package/UI/Components/Filters/Types/FilterOperator.ts +73 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +8 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +7 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesResource.js +20 -0
- package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
- package/build/dist/Server/API/KubernetesResourceAPI.js +2 -0
- package/build/dist/Server/API/KubernetesResourceAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776865086264-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776865086264-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776881254913-DedupeKubernetesClustersAndAddUniqueIndex.js +123 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1776881254913-DedupeKubernetesClustersAndAddUniqueIndex.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +18 -4
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesResourceService.js +204 -8
- package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +110 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryUtil.js +180 -0
- package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +33 -19
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Types/BaseDatabase/EndsWith.js +31 -0
- package/build/dist/Types/BaseDatabase/EndsWith.js.map +1 -0
- package/build/dist/Types/BaseDatabase/IncludesAll.js +34 -0
- package/build/dist/Types/BaseDatabase/IncludesAll.js.map +1 -0
- package/build/dist/Types/BaseDatabase/IncludesNone.js +34 -0
- package/build/dist/Types/BaseDatabase/IncludesNone.js.map +1 -0
- package/build/dist/Types/BaseDatabase/NotContains.js +31 -0
- package/build/dist/Types/BaseDatabase/NotContains.js.map +1 -0
- package/build/dist/Types/BaseDatabase/StartsWith.js +31 -0
- package/build/dist/Types/BaseDatabase/StartsWith.js.map +1 -0
- package/build/dist/Types/JSON.js +5 -0
- package/build/dist/Types/JSON.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesInventoryExtractor.js +7 -1
- package/build/dist/Types/Kubernetes/KubernetesInventoryExtractor.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +10 -0
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/UI/Components/Filters/BooleanFilter.js +1 -1
- package/build/dist/UI/Components/Filters/BooleanFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/DateFilter.js +158 -14
- package/build/dist/UI/Components/Filters/DateFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/DropdownFilter.js +1 -1
- package/build/dist/UI/Components/Filters/DropdownFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/EntityFilter.js +174 -30
- package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/FilterViewer.js +188 -97
- package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
- package/build/dist/UI/Components/Filters/FilterViewerItem.js +1 -6
- package/build/dist/UI/Components/Filters/FilterViewerItem.js.map +1 -1
- package/build/dist/UI/Components/Filters/FiltersForm.js +46 -38
- package/build/dist/UI/Components/Filters/FiltersForm.js.map +1 -1
- package/build/dist/UI/Components/Filters/NumberFilter.js +165 -23
- package/build/dist/UI/Components/Filters/NumberFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/OperatorSelector.js +41 -0
- package/build/dist/UI/Components/Filters/OperatorSelector.js.map +1 -0
- package/build/dist/UI/Components/Filters/TextFilter.js +130 -53
- package/build/dist/UI/Components/Filters/TextFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/Types/FilterOperator.js +63 -0
- package/build/dist/UI/Components/Filters/Types/FilterOperator.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +7 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,18 @@
|
|
|
1
|
+
import Icon from "../Icon/Icon";
|
|
1
2
|
import Includes from "../../../Types/BaseDatabase/Includes";
|
|
3
|
+
import IncludesAll from "../../../Types/BaseDatabase/IncludesAll";
|
|
4
|
+
import IncludesNone from "../../../Types/BaseDatabase/IncludesNone";
|
|
5
|
+
import StartsWith from "../../../Types/BaseDatabase/StartsWith";
|
|
6
|
+
import EndsWith from "../../../Types/BaseDatabase/EndsWith";
|
|
7
|
+
import NotContains from "../../../Types/BaseDatabase/NotContains";
|
|
8
|
+
import EqualTo from "../../../Types/BaseDatabase/EqualTo";
|
|
9
|
+
import NotEqual from "../../../Types/BaseDatabase/NotEqual";
|
|
10
|
+
import GreaterThan from "../../../Types/BaseDatabase/GreaterThan";
|
|
11
|
+
import LessThan from "../../../Types/BaseDatabase/LessThan";
|
|
12
|
+
import GreaterThanOrEqual from "../../../Types/BaseDatabase/GreaterThanOrEqual";
|
|
13
|
+
import LessThanOrEqual from "../../../Types/BaseDatabase/LessThanOrEqual";
|
|
14
|
+
import IsNull from "../../../Types/BaseDatabase/IsNull";
|
|
15
|
+
import NotNull from "../../../Types/BaseDatabase/NotNull";
|
|
2
16
|
import Button, { ButtonStyleType } from "../Button/Button";
|
|
3
17
|
import { DropdownOption } from "../Dropdown/Dropdown";
|
|
4
18
|
import ErrorMessage from "../ErrorMessage/ErrorMessage";
|
|
@@ -151,13 +165,12 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
151
165
|
|
|
152
166
|
if (data.filter.type === FieldType.Boolean) {
|
|
153
167
|
filterText = (
|
|
154
|
-
<
|
|
155
|
-
{" "}
|
|
168
|
+
<span>
|
|
156
169
|
<span className="font-medium">{data.filter.title}</span> is{" "}
|
|
157
170
|
<span className="font-medium">
|
|
158
171
|
{data.filterData[data.filter.key] ? "Yes" : "No"}
|
|
159
|
-
</span>
|
|
160
|
-
</
|
|
172
|
+
</span>
|
|
173
|
+
</span>
|
|
161
174
|
);
|
|
162
175
|
return filterText;
|
|
163
176
|
}
|
|
@@ -168,34 +181,82 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
168
181
|
data.filter.type === FieldType.Email ||
|
|
169
182
|
data.filter.type === FieldType.Phone ||
|
|
170
183
|
data.filter.type === FieldType.URL ||
|
|
171
|
-
data.filter.type === FieldType.Hostname
|
|
184
|
+
data.filter.type === FieldType.Hostname ||
|
|
185
|
+
data.filter.type === FieldType.LongText ||
|
|
186
|
+
data.filter.type === FieldType.Name ||
|
|
187
|
+
data.filter.type === FieldType.Port ||
|
|
188
|
+
data.filter.type === FieldType.ObjectID
|
|
172
189
|
) {
|
|
173
190
|
const key: keyof T = data.filter.key;
|
|
191
|
+
const value: unknown = data.filterData[key];
|
|
174
192
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
<span className="font-medium">
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
</div>
|
|
193
|
+
type RenderFunction = (verb: string, display: string) => ReactElement;
|
|
194
|
+
const render: RenderFunction = (
|
|
195
|
+
verb: string,
|
|
196
|
+
display: string,
|
|
197
|
+
): ReactElement => {
|
|
198
|
+
return (
|
|
199
|
+
<span>
|
|
200
|
+
<span className="font-medium">{data.filter.title}</span> {verb}{" "}
|
|
201
|
+
<span className="font-medium">{display}</span>
|
|
202
|
+
</span>
|
|
186
203
|
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
<span className="font-medium">
|
|
193
|
-
|
|
194
|
-
</span>{" "}
|
|
195
|
-
</div>
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
if (value instanceof IsNull) {
|
|
207
|
+
return (
|
|
208
|
+
<span>
|
|
209
|
+
<span className="font-medium">{data.filter.title}</span> is empty
|
|
210
|
+
</span>
|
|
196
211
|
);
|
|
197
212
|
}
|
|
198
|
-
|
|
213
|
+
if (value instanceof NotNull) {
|
|
214
|
+
return (
|
|
215
|
+
<span>
|
|
216
|
+
<span className="font-medium">{data.filter.title}</span> is not empty
|
|
217
|
+
</span>
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
if (value instanceof Search) {
|
|
221
|
+
return render("contains", value.toString());
|
|
222
|
+
}
|
|
223
|
+
if (value instanceof NotContains) {
|
|
224
|
+
return render("does not contain", value.toString());
|
|
225
|
+
}
|
|
226
|
+
if (value instanceof StartsWith) {
|
|
227
|
+
return render("starts with", value.toString());
|
|
228
|
+
}
|
|
229
|
+
if (value instanceof EndsWith) {
|
|
230
|
+
return render("ends with", value.toString());
|
|
231
|
+
}
|
|
232
|
+
if (value instanceof InBetween) {
|
|
233
|
+
return render(
|
|
234
|
+
"is between",
|
|
235
|
+
`${value.startValue} and ${value.endValue}`,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
if (value instanceof GreaterThanOrEqual) {
|
|
239
|
+
return render("is ≥", value.toString());
|
|
240
|
+
}
|
|
241
|
+
if (value instanceof LessThanOrEqual) {
|
|
242
|
+
return render("is ≤", value.toString());
|
|
243
|
+
}
|
|
244
|
+
if (value instanceof GreaterThan) {
|
|
245
|
+
return render("is greater than", value.toString());
|
|
246
|
+
}
|
|
247
|
+
if (value instanceof LessThan) {
|
|
248
|
+
return render("is less than", value.toString());
|
|
249
|
+
}
|
|
250
|
+
if (value instanceof NotEqual) {
|
|
251
|
+
return render("does not equal", value.toString());
|
|
252
|
+
}
|
|
253
|
+
if (value instanceof EqualTo) {
|
|
254
|
+
return render("equals", value.toString());
|
|
255
|
+
}
|
|
256
|
+
if (value !== undefined && value !== null && value !== "") {
|
|
257
|
+
return render("is", (value as any).toString());
|
|
258
|
+
}
|
|
259
|
+
return null;
|
|
199
260
|
}
|
|
200
261
|
|
|
201
262
|
if (
|
|
@@ -203,62 +264,66 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
203
264
|
data.filter.type === FieldType.DateTime
|
|
204
265
|
) {
|
|
205
266
|
const key: keyof T = data.filter.key;
|
|
206
|
-
|
|
207
|
-
const startAndEndDates: InBetween<Date> = data.filterData[
|
|
208
|
-
key
|
|
209
|
-
] as InBetween<Date>;
|
|
267
|
+
const value: unknown = data.filterData[key];
|
|
210
268
|
|
|
211
269
|
const shouldOnlyShowDate: boolean = data.filter.type === FieldType.Date;
|
|
212
270
|
const shouldShowSeconds: boolean =
|
|
213
271
|
data.filter.type === FieldType.DateTime;
|
|
214
272
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
273
|
+
type FormatFunction = (d: Date) => string;
|
|
274
|
+
const format: FormatFunction = (d: Date): string => {
|
|
275
|
+
return OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(
|
|
276
|
+
d,
|
|
218
277
|
shouldOnlyShowDate,
|
|
219
278
|
shouldShowSeconds,
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
279
|
+
);
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
type RenderFunction = (verb: string, display: string) => ReactElement;
|
|
283
|
+
const render: RenderFunction = (
|
|
284
|
+
verb: string,
|
|
285
|
+
display: string,
|
|
286
|
+
): ReactElement => {
|
|
227
287
|
return (
|
|
228
|
-
<
|
|
229
|
-
{" "}
|
|
230
|
-
<span className="font-medium">{
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
288
|
+
<span>
|
|
289
|
+
<span className="font-medium">{data.filter.title}</span> {verb}{" "}
|
|
290
|
+
<span className="font-medium">{display}</span>
|
|
291
|
+
</span>
|
|
292
|
+
);
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
if (value instanceof IsNull) {
|
|
296
|
+
return (
|
|
297
|
+
<span>
|
|
298
|
+
<span className="font-medium">{data.filter.title}</span> is empty
|
|
299
|
+
</span>
|
|
239
300
|
);
|
|
240
301
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
302
|
+
if (value instanceof NotNull) {
|
|
303
|
+
return (
|
|
304
|
+
<span>
|
|
305
|
+
<span className="font-medium">{data.filter.title}</span> is not empty
|
|
306
|
+
</span>
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
if (value instanceof InBetween) {
|
|
310
|
+
const start: Date = value.startValue as unknown as Date;
|
|
311
|
+
const end: Date = value.endValue as unknown as Date;
|
|
312
|
+
if (format(start) === format(end)) {
|
|
313
|
+
return render("is", format(start));
|
|
314
|
+
}
|
|
315
|
+
return render("is between", `${format(start)} and ${format(end)}`);
|
|
316
|
+
}
|
|
317
|
+
if (value instanceof GreaterThan) {
|
|
318
|
+
return render("is after", format(value.value as unknown as Date));
|
|
319
|
+
}
|
|
320
|
+
if (value instanceof LessThan) {
|
|
321
|
+
return render("is before", format(value.value as unknown as Date));
|
|
322
|
+
}
|
|
323
|
+
if (value instanceof EqualTo) {
|
|
324
|
+
return render("is", format(value.value as unknown as Date));
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
262
327
|
}
|
|
263
328
|
|
|
264
329
|
if (data.filter.type === FieldType.JSON) {
|
|
@@ -277,14 +342,11 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
277
342
|
const isPlural: boolean = Object.keys(json).length > 1;
|
|
278
343
|
|
|
279
344
|
return (
|
|
280
|
-
<
|
|
281
|
-
|
|
282
|
-
<
|
|
283
|
-
<
|
|
284
|
-
|
|
285
|
-
</div>
|
|
286
|
-
<div className="font-medium">{formatJson(json)}</div>{" "}
|
|
287
|
-
</div>
|
|
345
|
+
<span className="inline-flex items-center space-x-1">
|
|
346
|
+
<span className="font-medium">{data.filter.title}</span>
|
|
347
|
+
<span>{isPlural ? "are" : "is"}</span>
|
|
348
|
+
<span className="font-medium">{formatJson(json)}</span>
|
|
349
|
+
</span>
|
|
288
350
|
);
|
|
289
351
|
}
|
|
290
352
|
|
|
@@ -295,56 +357,82 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
295
357
|
data.filter.type === FieldType.EntityArray
|
|
296
358
|
) {
|
|
297
359
|
const key: keyof T = data.filter.key;
|
|
360
|
+
const rawValue: unknown = data.filterData[key];
|
|
298
361
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
362
|
+
if (rawValue instanceof IsNull) {
|
|
363
|
+
return (
|
|
364
|
+
<span>
|
|
365
|
+
<span className="font-medium">{data.filter.title}</span> is empty
|
|
366
|
+
</span>
|
|
367
|
+
);
|
|
303
368
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
369
|
+
if (rawValue instanceof NotNull) {
|
|
370
|
+
return (
|
|
371
|
+
<span>
|
|
372
|
+
<span className="font-medium">{data.filter.title}</span> is not empty
|
|
373
|
+
</span>
|
|
374
|
+
);
|
|
307
375
|
}
|
|
308
376
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
return null;
|
|
328
|
-
})
|
|
329
|
-
.filter((item: string | null) => {
|
|
330
|
-
return item !== null;
|
|
331
|
-
})
|
|
332
|
-
.join(", ");
|
|
377
|
+
let items: Array<string> = [];
|
|
378
|
+
type MatchMode = "any" | "all" | "none";
|
|
379
|
+
let matchMode: MatchMode = "any";
|
|
380
|
+
|
|
381
|
+
if (rawValue instanceof IncludesAll) {
|
|
382
|
+
items = rawValue.values as Array<string>;
|
|
383
|
+
matchMode = "all";
|
|
384
|
+
} else if (rawValue instanceof IncludesNone) {
|
|
385
|
+
items = rawValue.values as Array<string>;
|
|
386
|
+
matchMode = "none";
|
|
387
|
+
} else if (rawValue instanceof Includes) {
|
|
388
|
+
items = rawValue.values as Array<string>;
|
|
389
|
+
} else if (Array.isArray(rawValue)) {
|
|
390
|
+
items = rawValue as Array<string>;
|
|
391
|
+
} else if (typeof rawValue === "string") {
|
|
392
|
+
items = [rawValue];
|
|
393
|
+
}
|
|
333
394
|
|
|
334
|
-
|
|
395
|
+
const entityNames: string = items
|
|
396
|
+
.map((item: string) => {
|
|
397
|
+
const entity: DropdownOption | undefined =
|
|
398
|
+
data.filter.filterDropdownOptions?.find(
|
|
399
|
+
(e: DropdownOption | undefined) => {
|
|
400
|
+
return e?.value.toString() === item.toString();
|
|
401
|
+
},
|
|
402
|
+
);
|
|
403
|
+
if (entity) {
|
|
404
|
+
return entity.label.toString();
|
|
405
|
+
}
|
|
335
406
|
return null;
|
|
336
|
-
}
|
|
407
|
+
})
|
|
408
|
+
.filter((name: string | null) => {
|
|
409
|
+
return name !== null;
|
|
410
|
+
})
|
|
411
|
+
.join(", ");
|
|
337
412
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
<span className="font-medium">{data.filter.title}</span>
|
|
341
|
-
{isMoreItems ? " is any of these values: " : " is "}
|
|
342
|
-
<span className="font-medium">{entityNames}</span>
|
|
343
|
-
</div>
|
|
344
|
-
);
|
|
413
|
+
if (!entityNames) {
|
|
414
|
+
return null;
|
|
345
415
|
}
|
|
346
416
|
|
|
347
|
-
|
|
417
|
+
const isMoreItems: boolean = items.length > 1;
|
|
418
|
+
let joiner: string;
|
|
419
|
+
if (matchMode === "all") {
|
|
420
|
+
joiner = " has all of: ";
|
|
421
|
+
} else if (matchMode === "none") {
|
|
422
|
+
joiner = " has none of: ";
|
|
423
|
+
} else if (isMoreItems) {
|
|
424
|
+
joiner = " is any of: ";
|
|
425
|
+
} else {
|
|
426
|
+
joiner = " is ";
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return (
|
|
430
|
+
<span>
|
|
431
|
+
<span className="font-medium">{data.filter.title}</span>
|
|
432
|
+
{joiner}
|
|
433
|
+
<span className="font-medium">{entityNames}</span>
|
|
434
|
+
</span>
|
|
435
|
+
);
|
|
348
436
|
}
|
|
349
437
|
|
|
350
438
|
return filterText;
|
|
@@ -365,36 +453,30 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
365
453
|
<div>
|
|
366
454
|
{showViewer && (
|
|
367
455
|
<div>
|
|
368
|
-
<div className="mt-
|
|
369
|
-
<div className="flex
|
|
370
|
-
<div className="flex-
|
|
456
|
+
<div className="mt-4 mb-4 bg-gray-50 rounded-xl p-4 border border-gray-200">
|
|
457
|
+
<div className="flex items-center justify-between mb-3">
|
|
458
|
+
<div className="flex items-center gap-2 text-sm text-gray-700">
|
|
459
|
+
<Icon icon={IconProp.Filter} size={SizeProp.Smaller} />
|
|
371
460
|
<span className="font-semibold">
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
</span>{" "}
|
|
461
|
+
Showing {props.pluralLabel || "results"} that match
|
|
462
|
+
</span>
|
|
375
463
|
</div>
|
|
376
464
|
</div>
|
|
377
465
|
|
|
378
|
-
<
|
|
466
|
+
<div className="flex flex-wrap gap-2">
|
|
379
467
|
{filterTexts.map((filterText: ReactElement, index: number) => {
|
|
380
|
-
const isLastItem: boolean = index === filterTexts.length - 1;
|
|
381
468
|
return (
|
|
382
|
-
<
|
|
383
|
-
{
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
<div className="relative flex h-6 w-6 flex-none items-center justify-center bg-gray-50">
|
|
389
|
-
<div className="h-1.5 w-1.5 rounded-full bg-gray-100 ring-1 ring-gray-300"></div>
|
|
390
|
-
</div>
|
|
391
|
-
<FilterViewerItem key={index} text={filterText} />{" "}
|
|
392
|
-
</li>
|
|
469
|
+
<div
|
|
470
|
+
key={index}
|
|
471
|
+
className="inline-flex items-center rounded-full bg-white border border-gray-200 px-3 py-1 text-sm text-gray-700 shadow-sm whitespace-nowrap"
|
|
472
|
+
>
|
|
473
|
+
<FilterViewerItem key={index} text={filterText} />
|
|
474
|
+
</div>
|
|
393
475
|
);
|
|
394
476
|
})}
|
|
395
|
-
</
|
|
477
|
+
</div>
|
|
396
478
|
|
|
397
|
-
<div className="flex -ml-3 mt-3 -mb-
|
|
479
|
+
<div className="flex -ml-3 mt-3 -mb-1">
|
|
398
480
|
{/** Edit Filter Button */}
|
|
399
481
|
<Button
|
|
400
482
|
className="font-medium text-gray-900"
|
|
@@ -425,10 +507,10 @@ const FilterComponent: FilterComponentFunction = <T extends GenericObject>(
|
|
|
425
507
|
<Modal
|
|
426
508
|
modalWidth={ModalWidth.Large}
|
|
427
509
|
isLoading={props.isModalLoading}
|
|
428
|
-
title={
|
|
429
|
-
description={`
|
|
430
|
-
props.pluralLabel || ""
|
|
431
|
-
} by
|
|
510
|
+
title={`Filter ${props.pluralLabel || props.singularLabel || "results"}`}
|
|
511
|
+
description={`Narrow down ${
|
|
512
|
+
props.pluralLabel || "results"
|
|
513
|
+
} by one or more criteria below.`}
|
|
432
514
|
submitButtonText={`Apply Filters`}
|
|
433
515
|
onClose={() => {
|
|
434
516
|
props.onFilterModalClose?.();
|
|
@@ -11,17 +11,7 @@ type FilterViewerItemComponentFunction = (
|
|
|
11
11
|
const FilterViewerItem: FilterViewerItemComponentFunction = (
|
|
12
12
|
props: ComponentProps,
|
|
13
13
|
): ReactElement => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<div className="flex w-full -ml-3">
|
|
18
|
-
<div className="flex">
|
|
19
|
-
<div className="ml-1 flex-auto py-0.5 text-sm leading-5 text-gray-500">
|
|
20
|
-
<span className="text-gray-900">{text}</span>{" "}
|
|
21
|
-
</div>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
);
|
|
14
|
+
return <span className="text-gray-800 leading-5">{props.text}</span>;
|
|
25
15
|
};
|
|
26
16
|
|
|
27
17
|
export default FilterViewerItem;
|