@vuu-ui/vuu-filters 3.5.16 → 3.5.18-beta.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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.5.16",
2
+ "version": "3.5.18-beta.1",
3
3
  "main": "./src/index.js",
4
4
  "author": "heswell",
5
5
  "license": "Apache-2.0",
@@ -10,19 +10,19 @@
10
10
  "type-defs": "node ../../scripts/build-type-defs.mjs"
11
11
  },
12
12
  "devDependencies": {
13
- "@vuu-ui/vuu-data-types": "3.5.16",
14
- "@vuu-ui/vuu-protocol-types": "3.5.16",
15
- "@vuu-ui/vuu-table-types": "3.5.16",
16
- "@vuu-ui/vuu-filter-types": "3.5.16"
13
+ "@vuu-ui/vuu-data-types": "3.5.18-beta.1",
14
+ "@vuu-ui/vuu-protocol-types": "3.5.18-beta.1",
15
+ "@vuu-ui/vuu-table-types": "3.5.18-beta.1",
16
+ "@vuu-ui/vuu-filter-types": "3.5.18-beta.1"
17
17
  },
18
18
  "dependencies": {
19
- "@vuu-ui/vuu-context-menu": "3.5.16",
20
- "@vuu-ui/vuu-data-react": "3.5.16",
21
- "@vuu-ui/vuu-filter-parser": "3.5.16",
22
- "@vuu-ui/vuu-popups": "3.5.16",
23
- "@vuu-ui/vuu-ui-controls": "3.5.16",
24
- "@vuu-ui/vuu-table": "3.5.16",
25
- "@vuu-ui/vuu-utils": "3.5.16",
19
+ "@vuu-ui/vuu-context-menu": "3.5.18-beta.1",
20
+ "@vuu-ui/vuu-data-react": "3.5.18-beta.1",
21
+ "@vuu-ui/vuu-filter-parser": "3.5.18-beta.1",
22
+ "@vuu-ui/vuu-popups": "3.5.18-beta.1",
23
+ "@vuu-ui/vuu-ui-controls": "3.5.18-beta.1",
24
+ "@vuu-ui/vuu-table": "3.5.18-beta.1",
25
+ "@vuu-ui/vuu-utils": "3.5.18-beta.1",
26
26
  "@salt-ds/core": "1.54.1",
27
27
  "@salt-ds/lab": "1.0.0-alpha.83",
28
28
  "@salt-ds/styles": "0.2.1",
@@ -1,4 +1,4 @@
1
- import { EpochTimestamp, getTemporalInfo, getTypedValueForDescriptor, isAndFilter, isBetweenFilter, isBetweenOperator, isExtendedFilter, isMultiClauseFilter, isSingleValueFilter } from "@vuu-ui/vuu-utils";
1
+ import { DataValidationError, EpochTimestamp, getScaledDecimalFilterOptions, getTemporalInfo, getTypedValueForDescriptor, isAndFilter, isBetweenFilter, isBetweenOperator, isExtendedFilter, isMultiClauseFilter, isScaledDecimalFilterOptions, isSingleValueFilter, isValidDecimalString } from "@vuu-ui/vuu-utils";
2
2
  import { ExtendedSingleValueFilterClause } from "./filter-container/ExtendedSingleValueFilterClause.js";
3
3
  function installExtendedFilters(filter, throwIfUndefined = false) {
4
4
  if (void 0 !== filter) if (isExtendedFilter(filter)) {
@@ -12,7 +12,9 @@ function installExtendedFilters(filter, throwIfUndefined = false) {
12
12
  else return filter;
13
13
  if (throwIfUndefined) throw Error("filter is undefined");
14
14
  }
15
- const getExtendedFilterOptions = (temporalInfo, extendedFilterOptions)=>{
15
+ const getExtendedFilterOptions = (column, temporalInfo, extendedFilterOptions)=>{
16
+ const scaledDecimalOptions = getScaledDecimalFilterOptions(column);
17
+ if (scaledDecimalOptions) return scaledDecimalOptions;
16
18
  if (temporalInfo?.kind === "time") return {
17
19
  type: "TimeString",
18
20
  date: "today",
@@ -28,8 +30,13 @@ const getFilterValue = (column, value, temporalInfo, options, throwIfInvalid)=>{
28
30
  return;
29
31
  }
30
32
  if (options?.type === "TimeString") return asFilterTimeString(value, temporalInfo, throwIfInvalid);
33
+ if (isScaledDecimalFilterOptions(options)) return asFilterDecimalString(value, throwIfInvalid);
31
34
  return getTypedValueForDescriptor(value, column, throwIfInvalid);
32
35
  };
36
+ const asFilterDecimalString = (value, throwIfInvalid)=>{
37
+ if (isValidDecimalString(value)) return value;
38
+ if (throwIfInvalid) throw new DataValidationError(`value ${value} is not a valid decimal`, "decimal", "string");
39
+ };
33
40
  const timeOfDayPattern = /^\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?$/;
34
41
  const asFilterTimeString = (value, temporalInfo, throwIfInvalid)=>{
35
42
  if (timeOfDayPattern.test(value)) return 5 === value.length ? `${value}:00` : value;
@@ -70,7 +77,7 @@ class FilterAggregator {
70
77
  }
71
78
  add(column, value, op = "=", extendedFilterOptions) {
72
79
  const temporalInfo = getTemporalInfo(column);
73
- const options = getExtendedFilterOptions(temporalInfo, extendedFilterOptions);
80
+ const options = getExtendedFilterOptions(column, temporalInfo, extendedFilterOptions);
74
81
  const isInclusive = "between-inclusive" === op;
75
82
  const createClause = (op, value)=>options ? new ExtendedSingleValueFilterClause(column.name, op, value, options) : {
76
83
  column: column.name,
@@ -61,7 +61,11 @@ const ColumnFilter_ColumnFilter = /*#__PURE__*/ external_react_forwardRef(functi
61
61
  onSelect: (event, operator)=>{
62
62
  onOperatorSelect(event, operator);
63
63
  requestAnimationFrame(()=>{
64
- rootRef.current?.querySelector("input:not(:disabled)")?.focus();
64
+ const root = rootRef.current;
65
+ if (!root) return;
66
+ const { activeElement, body } = root.ownerDocument;
67
+ if (activeElement && activeElement !== body && !root.contains(activeElement)) return;
68
+ root.querySelector("input:not(:disabled)")?.focus();
65
69
  });
66
70
  },
67
71
  value: operator,
@@ -1,4 +1,4 @@
1
- import { getDefaultTimeZone, isValidTimeString, temporalFilterAsQuery } from "@vuu-ui/vuu-utils";
1
+ import { getDefaultTimeZone, isScaledDecimalFilterOptions, isValidTimeString, scaledDecimalFilterAsQuery, temporalFilterAsQuery } from "@vuu-ui/vuu-utils";
2
2
  const isTimeToday = (options)=>"TimeString" === options.type && "today" === options.date;
3
3
  const timeStringWithFraction = /^\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?$/;
4
4
  class ExtendedSingleValueFilterClause {
@@ -18,22 +18,30 @@ class ExtendedSingleValueFilterClause {
18
18
  }
19
19
  asQuery() {
20
20
  const { column, op, value } = this;
21
- const { date, encoding = "epochMillis", timeZone } = this.#options;
22
- if ("TimeString" === this.#options.type) if ("string" == typeof value && (isValidTimeString(value) || timeStringWithFraction.test(value))) {
23
- const temporalInfo = {
24
- kind: "time",
25
- encoding,
26
- precision: "epochNanos" === encoding ? "ns" : "ms",
27
- timeZone: timeZone ?? getDefaultTimeZone()
28
- };
29
- return temporalFilterAsQuery({
30
- column,
31
- op,
32
- value
33
- }, temporalInfo, {
34
- date: date
35
- });
36
- } else throw Error(`[ExtendedSingleValueFilterClause] invalid TimeString ${value}`);
21
+ if (isScaledDecimalFilterOptions(this.#options)) return scaledDecimalFilterAsQuery({
22
+ column,
23
+ op,
24
+ value
25
+ }, this.#options);
26
+ if ("TimeString" === this.#options.type) {
27
+ const { date, encoding = "epochMillis", timeZone } = this.#options;
28
+ if ("string" == typeof value && (isValidTimeString(value) || timeStringWithFraction.test(value))) {
29
+ const temporalInfo = {
30
+ kind: "time",
31
+ encoding,
32
+ precision: "epochNanos" === encoding ? "ns" : "ms",
33
+ timeZone: timeZone ?? getDefaultTimeZone()
34
+ };
35
+ return temporalFilterAsQuery({
36
+ column,
37
+ op,
38
+ value
39
+ }, temporalInfo, {
40
+ date: date
41
+ });
42
+ }
43
+ throw Error(`[ExtendedSingleValueFilterClause] invalid TimeString ${value}`);
44
+ }
37
45
  throw Error("[ExtendedSingleValueFilterClause] unhandled extended filter type");
38
46
  }
39
47
  toJSON() {
@@ -1,4 +1,4 @@
1
- import { filtersAreEqual, getTemporalCellFilter, getTemporalInfo, withDateTimePattern } from "@vuu-ui/vuu-utils";
1
+ import { filtersAreEqual, getScaledDecimalCellFilter, getTemporalCellFilter, getTemporalInfo, withDateTimePattern } from "@vuu-ui/vuu-utils";
2
2
  import { useCallback, useMemo, useRef } from "react";
3
3
  import { useColumnFilterRegistry, useSavedFilters } from "../filter-provider/FilterContext.js";
4
4
  import { FilterAggregator } from "../FilterAggregator.js";
@@ -23,6 +23,11 @@ const useFilterContextMenu = ({ filterColumns = "*", filterPatterns, filterProvi
23
23
  ...temporalCellFilter
24
24
  };
25
25
  }
26
+ const scaledDecimalCellFilter = getScaledDecimalCellFilter(column, value);
27
+ if (scaledDecimalCellFilter) return {
28
+ column,
29
+ ...scaledDecimalCellFilter
30
+ };
26
31
  return {
27
32
  column,
28
33
  label: `${value}`,
@@ -5,9 +5,12 @@ export interface SerializableFilter {
5
5
  asQuery: () => string;
6
6
  }
7
7
  /**
8
- * A filter clause on a time of day value (TimeString). The time is resolved
9
- * against a date ('today' by default) only when the query is created, so a
10
- * persisted filter remains relative.
8
+ * A filter clause whose query depends on options beyond the column, op and value:
9
+ * - a time of day value (TimeString). The time is resolved against a date
10
+ * ('today' by default) only when the query is created, so a persisted filter
11
+ * remains relative.
12
+ * - a scaled decimal value, matched at the precision with which the column
13
+ * displays values (see scaledDecimalFilterAsQuery).
11
14
  */
12
15
  export declare class ExtendedSingleValueFilterClause implements SerializableSingleValueFilterClause {
13
16
  #private;