@ascentgl/ads-ui 21.78.0 → 21.80.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.
@@ -7265,6 +7265,7 @@ class AdsColumnSortFilterMenuComponent {
7265
7265
  allOptionKeys.every((key) => this.selectedFilterValues.includes(key));
7266
7266
  // Get the value formatter if provided
7267
7267
  const formatter = this.config.filterValueFormatter;
7268
+ const showDateOnly = this.config.showDateOnly ?? false;
7268
7269
  const options = this.config.filterOptions.map((rawValue) => {
7269
7270
  // Serialize raw value to stable string key for selection/persistence
7270
7271
  const key = this.serializeOptionValue(rawValue);
@@ -7279,8 +7280,17 @@ class AdsColumnSortFilterMenuComponent {
7279
7280
  }
7280
7281
  });
7281
7282
  this.optionSubscriptions.push(subscription);
7282
- // Use formatter with RAW VALUE if provided, otherwise convert to string
7283
- const label = formatter ? formatter(rawValue) : String(rawValue ?? '');
7283
+ // Build the label:
7284
+ // When showDateOnly is enabled, the rawValue is already a trimmed date-only string
7285
+ // from the table component — use it directly to avoid re-parsing and timezone shift.
7286
+ // Otherwise, use formatter if provided, or convert to string.
7287
+ let label;
7288
+ if (showDateOnly) {
7289
+ label = String(rawValue ?? '');
7290
+ }
7291
+ else {
7292
+ label = formatter ? formatter(rawValue) : String(rawValue ?? '');
7293
+ }
7284
7294
  return {
7285
7295
  value: key,
7286
7296
  rawValue,
@@ -8095,10 +8105,45 @@ class AdsTableComponent {
8095
8105
  }
8096
8106
  }
8097
8107
  // ============ Custom Sort/Filter Menu Methods ============
8098
- /** @ignore - Get the filterValueFormatter for a given column field */
8108
+ /**
8109
+ * @ignore - Get the effective filter formatter for a given column field.
8110
+ * When showDateOnly is true, wraps the base formatter to trim date-time output
8111
+ * to date-only. This ensures the dedup key, stored filter values, and
8112
+ * doesExternalFilterPass comparison all use date-only strings — so selecting
8113
+ * a date in the filter menu matches ALL rows for that date regardless of time.
8114
+ */
8099
8115
  getFilterValueFormatterForField(field) {
8100
8116
  const config = this.columnSortFilterConfigs.find(c => c.field === field);
8101
- return config?.filterValueFormatter;
8117
+ if (!config)
8118
+ return undefined;
8119
+ const baseFormatter = config.filterValueFormatter;
8120
+ if (!baseFormatter)
8121
+ return undefined;
8122
+ if (config.showDateOnly) {
8123
+ return (value) => {
8124
+ const formatted = baseFormatter(value);
8125
+ return this.trimToDateOnly(formatted);
8126
+ };
8127
+ }
8128
+ return baseFormatter;
8129
+ }
8130
+ /**
8131
+ * @ignore - Trim a formatted date-time string to date-only.
8132
+ * Handles: "01/15/2026, 21:00" → "01/15/2026"
8133
+ * "01/15/2026 21:00" → "01/15/2026"
8134
+ */
8135
+ trimToDateOnly(value) {
8136
+ if (!value)
8137
+ return value;
8138
+ const commaIdx = value.indexOf(',');
8139
+ if (commaIdx > 0) {
8140
+ return value.substring(0, commaIdx).trim();
8141
+ }
8142
+ const match = value.match(/^(\d{1,2}\/\d{1,2}\/\d{2,4})\s+\d/);
8143
+ if (match) {
8144
+ return match[1];
8145
+ }
8146
+ return value;
8102
8147
  }
8103
8148
  /**
8104
8149
  * @ignore - Serialize a cell value for filter key purposes.
@@ -8116,19 +8161,13 @@ class AdsTableComponent {
8116
8161
  if (!this.rowData || this.rowData.length === 0) {
8117
8162
  return [];
8118
8163
  }
8119
- const formatter = this.getFilterValueFormatterForField(field);
8120
- // Don't cache results when a filterValueFormatter is configured,
8121
- // because the formatter output may change over time (e.g., timezone service
8122
- // becoming ready, user changing timezone). Caching could cause stale values
8123
- // that mismatch with doesExternalFilterPass comparisons.
8124
- if (!formatter) {
8125
- // Check cache first (only for fields without formatter)
8126
- const cacheKey = `${field}_v${this.dataVersion}`;
8127
- const cached = this.uniqueColumnValuesCache.get(cacheKey);
8128
- if (cached) {
8129
- return cached;
8130
- }
8164
+ // Check cache first
8165
+ const cacheKey = `${field}_v${this.dataVersion}`;
8166
+ const cached = this.uniqueColumnValuesCache.get(cacheKey);
8167
+ if (cached) {
8168
+ return cached;
8131
8169
  }
8170
+ const formatter = this.getFilterValueFormatterForField(field);
8132
8171
  // Use a Map to dedupe by serialized key while preserving raw values
8133
8172
  const byKey = new Map();
8134
8173
  this.rowData.forEach(row => {
@@ -8146,11 +8185,8 @@ class AdsTableComponent {
8146
8185
  const result = Array.from(byKey.entries())
8147
8186
  .sort(([a], [b]) => a.localeCompare(b))
8148
8187
  .map(([, v]) => v);
8149
- // Cache the result only for fields without formatter
8150
- if (!formatter) {
8151
- const cacheKey = `${field}_v${this.dataVersion}`;
8152
- this.uniqueColumnValuesCache.set(cacheKey, result);
8153
- }
8188
+ // Cache the result
8189
+ this.uniqueColumnValuesCache.set(cacheKey, result);
8154
8190
  return result;
8155
8191
  }
8156
8192
  /**
@@ -8163,27 +8199,21 @@ class AdsTableComponent {
8163
8199
  if (!this.rowData || this.rowData.length === 0) {
8164
8200
  return [];
8165
8201
  }
8166
- const formatter = this.getFilterValueFormatterForField(field);
8167
- // Don't cache results when a filterValueFormatter is configured (same reason as getUniqueColumnValues)
8168
- if (!formatter) {
8169
- // Check cache first (only for fields without formatter)
8170
- const cacheKey = `${field}_v${this.filterCacheVersion}`;
8171
- const cached = this.filteredColumnValuesCache.get(cacheKey);
8172
- if (cached) {
8173
- return cached;
8174
- }
8202
+ // Check cache first
8203
+ const cacheKey = `${field}_v${this.filterCacheVersion}`;
8204
+ const cached = this.filteredColumnValuesCache.get(cacheKey);
8205
+ if (cached) {
8206
+ return cached;
8175
8207
  }
8176
8208
  // Check if any filter is active (excluding the current field)
8177
8209
  const hasOtherActiveFilters = this.hasActiveFiltersExcluding(field);
8178
8210
  // If no other filters are active, return all unique values
8179
8211
  if (!hasOtherActiveFilters) {
8180
8212
  const values = this.getUniqueColumnValues(field);
8181
- if (!formatter) {
8182
- const cacheKey = `${field}_v${this.filterCacheVersion}`;
8183
- this.filteredColumnValuesCache.set(cacheKey, values);
8184
- }
8213
+ this.filteredColumnValuesCache.set(cacheKey, values);
8185
8214
  return values;
8186
8215
  }
8216
+ const formatter = this.getFilterValueFormatterForField(field);
8187
8217
  // Use a Map to dedupe by serialized key while preserving raw values
8188
8218
  const byKey = new Map();
8189
8219
  // Iterate through all rows and check if they pass filters from OTHER columns
@@ -8209,11 +8239,8 @@ class AdsTableComponent {
8209
8239
  .sort(([a], [b]) => a.localeCompare(b))
8210
8240
  .map(([, v]) => v);
8211
8241
  }
8212
- // Cache the result only for fields without formatter
8213
- if (!formatter) {
8214
- const cacheKey = `${field}_v${this.filterCacheVersion}`;
8215
- this.filteredColumnValuesCache.set(cacheKey, result);
8216
- }
8242
+ // Cache the result
8243
+ this.filteredColumnValuesCache.set(cacheKey, result);
8217
8244
  return result;
8218
8245
  }
8219
8246
  /** @ignore - Invalidate the filtered column values cache */