@sisense/sdk-data 1.13.0 → 1.14.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.
Files changed (32) hide show
  1. package/dist/cjs/dimensional-model/attributes.js +20 -1
  2. package/dist/cjs/dimensional-model/dimensions.d.ts +8 -0
  3. package/dist/cjs/dimensional-model/dimensions.js +4 -0
  4. package/dist/cjs/dimensional-model/dimensions.test.js +30 -0
  5. package/dist/cjs/dimensional-model/filters/factory.d.ts +1 -1
  6. package/dist/cjs/dimensional-model/filters/factory.js +2 -2
  7. package/dist/cjs/dimensional-model/filters/filters.d.ts +13 -1
  8. package/dist/cjs/dimensional-model/filters/filters.js +38 -3
  9. package/dist/cjs/dimensional-model/filters/filters.test.js +16 -0
  10. package/dist/cjs/dimensional-model/interfaces.d.ts +14 -0
  11. package/dist/cjs/dimensional-model/types.d.ts +2 -0
  12. package/dist/cjs/dimensional-model/types.js +4 -0
  13. package/dist/cjs/interfaces.d.ts +1 -1
  14. package/dist/cjs/translation/resources/en.js +1 -1
  15. package/dist/cjs/translation/resources/uk.js +1 -1
  16. package/dist/cjs/utils.js +6 -2
  17. package/dist/cjs/utils.test.js +24 -0
  18. package/dist/dimensional-model/attributes.js +20 -1
  19. package/dist/dimensional-model/dimensions.d.ts +8 -0
  20. package/dist/dimensional-model/dimensions.js +4 -0
  21. package/dist/dimensional-model/filters/factory.d.ts +1 -1
  22. package/dist/dimensional-model/filters/factory.js +2 -2
  23. package/dist/dimensional-model/filters/filters.d.ts +13 -1
  24. package/dist/dimensional-model/filters/filters.js +38 -3
  25. package/dist/dimensional-model/interfaces.d.ts +14 -0
  26. package/dist/dimensional-model/types.d.ts +2 -0
  27. package/dist/dimensional-model/types.js +4 -0
  28. package/dist/interfaces.d.ts +1 -1
  29. package/dist/translation/resources/en.js +1 -1
  30. package/dist/translation/resources/uk.js +1 -1
  31. package/dist/utils.js +6 -2
  32. package/package.json +3 -3
@@ -163,6 +163,7 @@ class DimensionalLevelAttribute extends DimensionalAttribute {
163
163
  */
164
164
  translateGranularityToJaql() {
165
165
  const MINUTES_LEVEL = 'minutes';
166
+ const SECONDS_LEVEL = 'seconds';
166
167
  switch (this.granularity) {
167
168
  case types_js_1.DateLevels.Years:
168
169
  case types_js_1.DateLevels.Quarters:
@@ -185,6 +186,16 @@ class DimensionalLevelAttribute extends DimensionalAttribute {
185
186
  dateTimeLevel: MINUTES_LEVEL,
186
187
  bucket: '15',
187
188
  };
189
+ case types_js_1.DateLevels.Minutes:
190
+ return {
191
+ dateTimeLevel: MINUTES_LEVEL,
192
+ bucket: '1',
193
+ };
194
+ case types_js_1.DateLevels.Seconds:
195
+ return {
196
+ dateTimeLevel: SECONDS_LEVEL,
197
+ bucket: '0',
198
+ };
188
199
  case types_js_1.DateLevels.AggHours:
189
200
  return {
190
201
  level: MINUTES_LEVEL,
@@ -216,7 +227,7 @@ class DimensionalLevelAttribute extends DimensionalAttribute {
216
227
  return lvl;
217
228
  };
218
229
  if (json.dateTimeLevel) {
219
- if (json.dateTimeLevel !== 'minutes') {
230
+ if (json.dateTimeLevel !== 'minutes' && json.dateTimeLevel !== 'seconds') {
220
231
  return returnUnsupported(json.dateTimeLevel);
221
232
  }
222
233
  switch (json.bucket) {
@@ -226,6 +237,10 @@ class DimensionalLevelAttribute extends DimensionalAttribute {
226
237
  return types_js_1.DateLevels.MinutesRoundTo30;
227
238
  case '15':
228
239
  return types_js_1.DateLevels.MinutesRoundTo15;
240
+ case '1':
241
+ return types_js_1.DateLevels.Minutes;
242
+ case '0':
243
+ return types_js_1.DateLevels.Seconds;
229
244
  default:
230
245
  return returnUnsupported(json.dateTimeLevel);
231
246
  }
@@ -277,6 +292,10 @@ class DimensionalLevelAttribute extends DimensionalAttribute {
277
292
  return 'yyyy-MM-dd HH:mm';
278
293
  case types_js_1.DateLevels.MinutesRoundTo15:
279
294
  return 'yyyy-MM-dd HH:mm';
295
+ case types_js_1.DateLevels.Minutes:
296
+ return 'yyyy-MM-dd HH:mm';
297
+ case types_js_1.DateLevels.Seconds:
298
+ return 'yyyy-MM-dd HH:mm:ss';
280
299
  case types_js_1.DateLevels.AggHours:
281
300
  return 'HH:mm';
282
301
  case types_js_1.DateLevels.AggMinutesRoundTo30:
@@ -94,6 +94,14 @@ export declare class DimensionalDateDimension extends DimensionalDimension imple
94
94
  * Minutes (round to 15) level
95
95
  */
96
96
  readonly MinutesRoundTo15: LevelAttribute;
97
+ /**
98
+ * Minutes level (for Live Models)
99
+ */
100
+ readonly Minutes: LevelAttribute;
101
+ /**
102
+ * Seconds level (for Live Models)
103
+ */
104
+ readonly Seconds: LevelAttribute;
97
105
  /**
98
106
  * Aggregated Hours level
99
107
  */
@@ -164,6 +164,8 @@ class DimensionalDateDimension extends DimensionalDimension {
164
164
  this.Hours = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.Hours, expression, types_js_1.DateLevels.Hours, 'yyyy-MM-dd HH:mm');
165
165
  this.MinutesRoundTo30 = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.MinutesRoundTo30, expression, types_js_1.DateLevels.MinutesRoundTo30, 'yyyy-MM-dd HH:mm');
166
166
  this.MinutesRoundTo15 = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.MinutesRoundTo15, expression, types_js_1.DateLevels.MinutesRoundTo15, 'yyyy-MM-dd HH:mm');
167
+ this.Minutes = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.Minutes, expression, types_js_1.DateLevels.Minutes, 'yyyy-MM-dd HH:mm');
168
+ this.Seconds = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.Seconds, expression, types_js_1.DateLevels.Seconds, 'yyyy-MM-dd HH:mm:ss');
167
169
  this.AggHours = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.AggHours, expression, types_js_1.DateLevels.AggHours, 'HH:mm');
168
170
  this.AggMinutesRoundTo30 = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.AggMinutesRoundTo30, expression, types_js_1.DateLevels.AggMinutesRoundTo30, 'HH:mm');
169
171
  this.AggMinutesRoundTo15 = new attributes_js_1.DimensionalLevelAttribute(types_js_1.DateLevels.AggMinutesRoundTo15, expression, types_js_1.DateLevels.AggMinutesRoundTo15, 'HH:mm');
@@ -177,6 +179,8 @@ class DimensionalDateDimension extends DimensionalDimension {
177
179
  this.Hours,
178
180
  this.MinutesRoundTo30,
179
181
  this.MinutesRoundTo15,
182
+ this.Minutes,
183
+ this.Seconds,
180
184
  this.AggHours,
181
185
  this.AggMinutesRoundTo30,
182
186
  this.AggMinutesRoundTo15,
@@ -43,6 +43,36 @@ describe('Dimension jaql preparations', () => {
43
43
  const jaql = dimension.jaql();
44
44
  expect(jaql).toStrictEqual(result);
45
45
  });
46
+ it('must prepare jaql for date dimension with "seconds" level', () => {
47
+ const result = {
48
+ jaql: {
49
+ title: 'Seconds',
50
+ dim: '[Commerce.Date (Calendar)]',
51
+ bucket: '0',
52
+ dateTimeLevel: 'seconds',
53
+ datatype: 'datetime',
54
+ },
55
+ format: { mask: { seconds: 'yyyy-MM-dd HH:mm:ss' } },
56
+ };
57
+ const dimension = new dimensions_js_1.DimensionalDateDimension('Date', '[Commerce.Date (Calendar)]');
58
+ const jaql = dimension.Seconds.jaql();
59
+ expect(jaql).toStrictEqual(result);
60
+ });
61
+ it('must prepare jaql for date dimension with "minutes" level', () => {
62
+ const result = {
63
+ jaql: {
64
+ title: 'Minutes',
65
+ dim: '[Commerce.Date (Calendar)]',
66
+ bucket: '1',
67
+ dateTimeLevel: 'minutes',
68
+ datatype: 'datetime',
69
+ },
70
+ format: { mask: { minutes: 'yyyy-MM-dd HH:mm' } },
71
+ };
72
+ const dimension = new dimensions_js_1.DimensionalDateDimension('Date', '[Commerce.Date (Calendar)]');
73
+ const jaql = dimension.Minutes.jaql();
74
+ expect(jaql).toStrictEqual(result);
75
+ });
46
76
  it('must handle sort', () => {
47
77
  const dimensionAscSort = new dimensions_js_1.DimensionalDimension('Brand', '[Brand.Brand]', [new attributes_js_1.DimensionalAttribute('Brand', '[Brand.Brand]')], [], 'textdimension', '', types_js_1.Sort.Ascending);
48
78
  const dimensionDescSort = new dimensions_js_1.DimensionalDimension('Brand', '[Brand.Brand]', [new attributes_js_1.DimensionalAttribute('Brand', '[Brand.Brand]')], [], 'textdimension', '', types_js_1.Sort.Descending);
@@ -377,7 +377,7 @@ export declare function numeric(attribute: Attribute, operatorA?: string, valueA
377
377
  * @param guid - Optional GUID for the filter
378
378
  * @returns A filter instance
379
379
  */
380
- export declare function members(attribute: Attribute, members: string[], _deactivatedMembers?: string[], guid?: string): Filter;
380
+ export declare function members(attribute: Attribute, members: string[], _deactivatedMembers?: string[], guid?: string, backgroundFilter?: Filter): Filter;
381
381
  /**
382
382
  * Creates a filter to isolate date values starting from and including the given date and level.
383
383
  *
@@ -449,8 +449,8 @@ exports.numeric = numeric;
449
449
  * @param guid - Optional GUID for the filter
450
450
  * @returns A filter instance
451
451
  */
452
- function members(attribute, members, _deactivatedMembers, guid) {
453
- return new filters_js_1.MembersFilter(attribute, members, _deactivatedMembers, guid);
452
+ function members(attribute, members, _deactivatedMembers, guid, backgroundFilter) {
453
+ return new filters_js_1.MembersFilter(attribute, members, _deactivatedMembers, guid, backgroundFilter);
454
454
  }
455
455
  exports.members = members;
456
456
  // DATE FILTERS
@@ -95,6 +95,7 @@ declare abstract class AbstractFilter extends DimensionalElement implements Filt
95
95
  */
96
96
  readonly guid: string;
97
97
  private _disabled;
98
+ private _locked;
98
99
  /**
99
100
  * Boolean flag whether the filter is disabled
100
101
  *
@@ -102,6 +103,13 @@ declare abstract class AbstractFilter extends DimensionalElement implements Filt
102
103
  */
103
104
  get disabled(): boolean;
104
105
  set disabled(value: boolean);
106
+ /**
107
+ * Boolean flag whether the filter is locked
108
+ *
109
+ * @internal
110
+ */
111
+ get locked(): boolean;
112
+ set locked(value: boolean);
105
113
  constructor(att: Attribute, filterType: string, guid?: string);
106
114
  get name(): string;
107
115
  /**
@@ -156,7 +164,9 @@ export declare class MembersFilter extends AbstractFilter {
156
164
  readonly members: any[];
157
165
  /** @internal */
158
166
  _deactivatedMembers: any[];
159
- constructor(attribute: Attribute, members?: any[], _deactivatedMembers?: any[], guid?: string);
167
+ /** @internal */
168
+ backgroundFilter?: Filter;
169
+ constructor(attribute: Attribute, members?: any[], _deactivatedMembers?: any[], guid?: string, backgroundFilter?: Filter);
160
170
  /**
161
171
  * gets the element's ID
162
172
  */
@@ -182,6 +192,8 @@ export declare class CascadingFilter extends AbstractFilter {
182
192
  get id(): string;
183
193
  get disabled(): boolean;
184
194
  set disabled(value: boolean);
195
+ get locked(): boolean;
196
+ set locked(value: boolean);
185
197
  /**
186
198
  * Gets a serializable representation of the element
187
199
  */
@@ -108,6 +108,7 @@ class AbstractFilter extends base_js_1.DimensionalElement {
108
108
  this.attribute = att;
109
109
  this.guid = guid || (0, utils_js_1.guidFast)(13);
110
110
  this.disabled = false;
111
+ this.locked = false;
111
112
  }
112
113
  /**
113
114
  * Boolean flag whether the filter is disabled
@@ -120,6 +121,17 @@ class AbstractFilter extends base_js_1.DimensionalElement {
120
121
  set disabled(value) {
121
122
  this._disabled = value;
122
123
  }
124
+ /**
125
+ * Boolean flag whether the filter is locked
126
+ *
127
+ * @internal
128
+ */
129
+ get locked() {
130
+ return this._locked;
131
+ }
132
+ set locked(value) {
133
+ this._locked = value;
134
+ }
123
135
  get name() {
124
136
  return (0, object_hash_1.default)(this.jaql());
125
137
  }
@@ -161,7 +173,9 @@ class AbstractFilter extends base_js_1.DimensionalElement {
161
173
  const { granularity } = attribute;
162
174
  if (granularity === types_js_1.DateLevels.Hours ||
163
175
  granularity === types_js_1.DateLevels.MinutesRoundTo30 ||
164
- granularity === types_js_1.DateLevels.MinutesRoundTo15) {
176
+ granularity === types_js_1.DateLevels.MinutesRoundTo15 ||
177
+ granularity === types_js_1.DateLevels.Minutes ||
178
+ granularity === types_js_1.DateLevels.Seconds) {
165
179
  throw new translatable_error_js_1.TranslatableError('errors.filter.unsupportedDatetimeLevel');
166
180
  }
167
181
  }
@@ -207,10 +221,11 @@ exports.LogicalAttributeFilter = LogicalAttributeFilter;
207
221
  * @internal
208
222
  */
209
223
  class MembersFilter extends AbstractFilter {
210
- constructor(attribute, members, _deactivatedMembers, guid) {
224
+ constructor(attribute, members, _deactivatedMembers, guid, backgroundFilter) {
211
225
  super(attribute, exports.FilterTypes.members, guid);
212
226
  this.members = members !== null && members !== void 0 ? members : [];
213
227
  this._deactivatedMembers = _deactivatedMembers !== null && _deactivatedMembers !== void 0 ? _deactivatedMembers : [];
228
+ this.backgroundFilter = backgroundFilter;
214
229
  if (this.members.filter((m) => m === null || m === undefined).length > 0) {
215
230
  throw new translatable_error_js_1.TranslatableError('errors.filter.membersFilterNullMember', {
216
231
  attributeId: attribute.id,
@@ -229,15 +244,24 @@ class MembersFilter extends AbstractFilter {
229
244
  serializable() {
230
245
  const result = super.serializable();
231
246
  result.members = this.members;
247
+ if (this.backgroundFilter) {
248
+ result.backgroundFilter = this.backgroundFilter.serializable();
249
+ }
232
250
  return result;
233
251
  }
234
252
  /**
235
253
  * Gets JAQL representing this Filter instance
236
254
  */
237
255
  filterJaql() {
238
- return {
256
+ const filterJaql = {
239
257
  members: this.members.map((m) => m.toString()),
240
258
  };
259
+ if (this.backgroundFilter) {
260
+ return {
261
+ and: [filterJaql, this.backgroundFilter.filterJaql()],
262
+ };
263
+ }
264
+ return filterJaql;
241
265
  }
242
266
  }
243
267
  exports.MembersFilter = MembersFilter;
@@ -266,6 +290,17 @@ class CascadingFilter extends AbstractFilter {
266
290
  });
267
291
  }
268
292
  }
293
+ get locked() {
294
+ return super.locked;
295
+ }
296
+ set locked(value) {
297
+ super.locked = value;
298
+ if (this.filters) {
299
+ this.filters.forEach((filter) => {
300
+ filter.locked = value;
301
+ });
302
+ }
303
+ }
269
304
  /**
270
305
  * Gets a serializable representation of the element
271
306
  */
@@ -206,6 +206,22 @@ describe('Filters jaql preparations', () => {
206
206
  const jaql = filter.jaql();
207
207
  expect(jaql).toStrictEqual(result);
208
208
  });
209
+ it('must prepare members filter jaql with inner background filter', () => {
210
+ const result = {
211
+ jaql: {
212
+ title: 'CommerceGender',
213
+ dim: '[Commerce.Gender]',
214
+ datatype: 'text',
215
+ filter: { and: [{ members: ['Female'] }, { members: ['Female', 'Male'] }] },
216
+ },
217
+ };
218
+ const attribute = new attributes_js_1.DimensionalAttribute('[Commerce.Gender]', '[Commerce.Gender]');
219
+ const backgroundFilter = new filters_js_1.MembersFilter(attribute, ['Female', 'Male']);
220
+ const filter = new filters_js_1.MembersFilter(attribute, ['Female'], undefined, undefined, backgroundFilter);
221
+ expect(filter.backgroundFilter).toBe(backgroundFilter);
222
+ const jaql = filter.jaql();
223
+ expect(jaql).toStrictEqual(result);
224
+ });
209
225
  });
210
226
  describe('Disabled Filter', () => {
211
227
  it('must prepare empty jaql for attribute filter', () => {
@@ -249,6 +249,14 @@ export interface DateDimension extends Dimension {
249
249
  * Minutes (round to 15) level (for Live Models)
250
250
  */
251
251
  readonly MinutesRoundTo15: LevelAttribute;
252
+ /**
253
+ * Minutes level (for Live Models)
254
+ */
255
+ readonly Minutes: LevelAttribute;
256
+ /**
257
+ * Seconds level (for Live Models)
258
+ */
259
+ readonly Seconds: LevelAttribute;
252
260
  /**
253
261
  * Aggregated Hours level (for Live Models)
254
262
  */
@@ -346,6 +354,12 @@ export interface Filter extends Element {
346
354
  * @internal
347
355
  */
348
356
  disabled: boolean;
357
+ /**
358
+ * Boolean flag whether the filter is locked
359
+ *
360
+ * @internal
361
+ */
362
+ locked: boolean;
349
363
  /**
350
364
  * Gets JAQL representing this Filter instance
351
365
  *
@@ -144,6 +144,8 @@ export declare const DateLevels: {
144
144
  Hours: string;
145
145
  MinutesRoundTo30: string;
146
146
  MinutesRoundTo15: string;
147
+ Minutes: string;
148
+ Seconds: string;
147
149
  AggHours: string;
148
150
  AggMinutesRoundTo30: string;
149
151
  AggMinutesRoundTo15: string;
@@ -261,6 +261,8 @@ exports.DateLevels = {
261
261
  Hours: 'Hours',
262
262
  MinutesRoundTo30: 'MinutesRoundTo30',
263
263
  MinutesRoundTo15: 'MinutesRoundTo15',
264
+ Minutes: 'Minutes',
265
+ Seconds: 'Seconds',
264
266
  AggHours: 'AggHours',
265
267
  AggMinutesRoundTo30: 'AggMinutesRoundTo30',
266
268
  AggMinutesRoundTo15: 'AggMinutesRoundTo15',
@@ -276,6 +278,8 @@ exports.DateLevels = {
276
278
  exports.DateLevels.Hours,
277
279
  exports.DateLevels.MinutesRoundTo30,
278
280
  exports.DateLevels.MinutesRoundTo15,
281
+ exports.DateLevels.Minutes,
282
+ exports.DateLevels.Seconds,
279
283
  exports.DateLevels.AggHours,
280
284
  exports.DateLevels.AggMinutesRoundTo30,
281
285
  exports.DateLevels.AggMinutesRoundTo15,
@@ -288,7 +288,7 @@ export declare const EMPTY_PIVOT_QUERY_RESULT_DATA: PivotQueryResultData;
288
288
  * @param arg
289
289
  * @internal
290
290
  */
291
- export declare function isDataSource(arg: DataSource | Data | undefined): arg is DataSource;
291
+ export declare function isDataSource(arg: DataSource | Data | undefined): arg is DataSource | undefined;
292
292
  /**
293
293
  * Trend formula options.
294
294
  */
@@ -22,7 +22,7 @@ exports.translation = {
22
22
  },
23
23
  filter: {
24
24
  unsupportedType: 'Unsupported filter type: {{filterType}}',
25
- unsupportedDatetimeLevel: 'Filters do not support the next "datetime" levels: Hours, MinutesRoundTo30, MinutesRoundTo15',
25
+ unsupportedDatetimeLevel: 'Filters do not support the next "datetime" levels: Hours, MinutesRoundTo30, MinutesRoundTo15, Minutes, Seconds',
26
26
  membersFilterNullMember: 'MembersFilter of {{attributeId}} - member cannot be null',
27
27
  },
28
28
  unsupportedDimensionalElement: 'Unsupported dimensional element type',
@@ -22,7 +22,7 @@ exports.translation = {
22
22
  },
23
23
  filter: {
24
24
  unsupportedType: 'Непідтримуваний тип фільтра: {{filterType}}',
25
- unsupportedDatetimeLevel: 'Фільтри не підтримують наступні рівні "datetime": Hours, MinutesRoundTo30, MinutesRoundTo15',
25
+ unsupportedDatetimeLevel: 'Фільтри не підтримують наступні рівні "datetime": Hours, MinutesRoundTo30, MinutesRoundTo15, Minutes, Seconds',
26
26
  membersFilterNullMember: 'MembersFilter у {{attributeId}} - member не може бути нульовим',
27
27
  },
28
28
  unsupportedDimensionalElement: 'Непідтримуваний тип елемента',
package/dist/cjs/utils.js CHANGED
@@ -99,7 +99,11 @@ exports.isDataSourceInfo = isDataSourceInfo;
99
99
  const createFilterFromJaql = (jaql, instanceid) => {
100
100
  // translation logic is based on FilterJaqlInternal type (from internal modern-analytics-filters)
101
101
  // TODO reconcile FilterJaql and FilterJaqlInternal
102
- const jaqlInternal = jaql;
103
- return (0, filter_from_jaql_util_js_1.createFilterFromJaqlInternal)(jaqlInternal, instanceid);
102
+ const hasBackgroundFilter = jaql.filter.filter && !('turnedOff' in jaql.filter.filter);
103
+ const filter = (0, filter_from_jaql_util_js_1.createFilterFromJaqlInternal)(jaql, instanceid);
104
+ if (hasBackgroundFilter) {
105
+ filter.backgroundFilter = (0, filter_from_jaql_util_js_1.createFilterFromJaqlInternal)(Object.assign(Object.assign({}, jaql), { filter: jaql.filter.filter }), `${instanceid}-bg`);
106
+ }
107
+ return filter;
104
108
  };
105
109
  exports.createFilterFromJaql = createFilterFromJaql;
@@ -154,5 +154,29 @@ const nestedFilterRelationsResult = {
154
154
  const expectedFilter = filterFactory.members(attribute, jaql.filter.members);
155
155
  expect(filter.jaql().jaql).toEqual(expectedFilter.jaql().jaql);
156
156
  });
157
+ test('should creact MembersFilter with inner background filter', () => {
158
+ const jaql = {
159
+ table: 'Category',
160
+ column: 'Category',
161
+ dim: '[Category.Category]',
162
+ datatype: 'text',
163
+ filter: {
164
+ explicit: true,
165
+ multiSelection: true,
166
+ members: ['Cell Phones'],
167
+ filter: {
168
+ members: ['Cell Phones', 'GPS Devices'],
169
+ },
170
+ },
171
+ title: 'Category',
172
+ };
173
+ const filter = (0, index_js_1.createFilterFromJaql)(jaql, instanceid);
174
+ const attribute = (0, attribute_measure_util_js_1.createAttributeFromFilterJaql)(jaql);
175
+ const backgroundFilter = filterFactory.members(attribute, jaql.filter.filter.members);
176
+ const expectedFilter = filterFactory.members(attribute, jaql.filter.members, undefined, undefined, backgroundFilter);
177
+ expect(filter.jaql().jaql).toEqual(expectedFilter.jaql().jaql);
178
+ expect(filter.backgroundFilter).toBeDefined();
179
+ expect(expectedFilter.backgroundFilter).toBeDefined();
180
+ });
157
181
  });
158
182
  });
@@ -158,6 +158,7 @@ export class DimensionalLevelAttribute extends DimensionalAttribute {
158
158
  */
159
159
  translateGranularityToJaql() {
160
160
  const MINUTES_LEVEL = 'minutes';
161
+ const SECONDS_LEVEL = 'seconds';
161
162
  switch (this.granularity) {
162
163
  case DateLevels.Years:
163
164
  case DateLevels.Quarters:
@@ -180,6 +181,16 @@ export class DimensionalLevelAttribute extends DimensionalAttribute {
180
181
  dateTimeLevel: MINUTES_LEVEL,
181
182
  bucket: '15',
182
183
  };
184
+ case DateLevels.Minutes:
185
+ return {
186
+ dateTimeLevel: MINUTES_LEVEL,
187
+ bucket: '1',
188
+ };
189
+ case DateLevels.Seconds:
190
+ return {
191
+ dateTimeLevel: SECONDS_LEVEL,
192
+ bucket: '0',
193
+ };
183
194
  case DateLevels.AggHours:
184
195
  return {
185
196
  level: MINUTES_LEVEL,
@@ -211,7 +222,7 @@ export class DimensionalLevelAttribute extends DimensionalAttribute {
211
222
  return lvl;
212
223
  };
213
224
  if (json.dateTimeLevel) {
214
- if (json.dateTimeLevel !== 'minutes') {
225
+ if (json.dateTimeLevel !== 'minutes' && json.dateTimeLevel !== 'seconds') {
215
226
  return returnUnsupported(json.dateTimeLevel);
216
227
  }
217
228
  switch (json.bucket) {
@@ -221,6 +232,10 @@ export class DimensionalLevelAttribute extends DimensionalAttribute {
221
232
  return DateLevels.MinutesRoundTo30;
222
233
  case '15':
223
234
  return DateLevels.MinutesRoundTo15;
235
+ case '1':
236
+ return DateLevels.Minutes;
237
+ case '0':
238
+ return DateLevels.Seconds;
224
239
  default:
225
240
  return returnUnsupported(json.dateTimeLevel);
226
241
  }
@@ -272,6 +287,10 @@ export class DimensionalLevelAttribute extends DimensionalAttribute {
272
287
  return 'yyyy-MM-dd HH:mm';
273
288
  case DateLevels.MinutesRoundTo15:
274
289
  return 'yyyy-MM-dd HH:mm';
290
+ case DateLevels.Minutes:
291
+ return 'yyyy-MM-dd HH:mm';
292
+ case DateLevels.Seconds:
293
+ return 'yyyy-MM-dd HH:mm:ss';
275
294
  case DateLevels.AggHours:
276
295
  return 'HH:mm';
277
296
  case DateLevels.AggMinutesRoundTo30:
@@ -94,6 +94,14 @@ export declare class DimensionalDateDimension extends DimensionalDimension imple
94
94
  * Minutes (round to 15) level
95
95
  */
96
96
  readonly MinutesRoundTo15: LevelAttribute;
97
+ /**
98
+ * Minutes level (for Live Models)
99
+ */
100
+ readonly Minutes: LevelAttribute;
101
+ /**
102
+ * Seconds level (for Live Models)
103
+ */
104
+ readonly Seconds: LevelAttribute;
97
105
  /**
98
106
  * Aggregated Hours level
99
107
  */
@@ -160,6 +160,8 @@ export class DimensionalDateDimension extends DimensionalDimension {
160
160
  this.Hours = new DimensionalLevelAttribute(DateLevels.Hours, expression, DateLevels.Hours, 'yyyy-MM-dd HH:mm');
161
161
  this.MinutesRoundTo30 = new DimensionalLevelAttribute(DateLevels.MinutesRoundTo30, expression, DateLevels.MinutesRoundTo30, 'yyyy-MM-dd HH:mm');
162
162
  this.MinutesRoundTo15 = new DimensionalLevelAttribute(DateLevels.MinutesRoundTo15, expression, DateLevels.MinutesRoundTo15, 'yyyy-MM-dd HH:mm');
163
+ this.Minutes = new DimensionalLevelAttribute(DateLevels.Minutes, expression, DateLevels.Minutes, 'yyyy-MM-dd HH:mm');
164
+ this.Seconds = new DimensionalLevelAttribute(DateLevels.Seconds, expression, DateLevels.Seconds, 'yyyy-MM-dd HH:mm:ss');
163
165
  this.AggHours = new DimensionalLevelAttribute(DateLevels.AggHours, expression, DateLevels.AggHours, 'HH:mm');
164
166
  this.AggMinutesRoundTo30 = new DimensionalLevelAttribute(DateLevels.AggMinutesRoundTo30, expression, DateLevels.AggMinutesRoundTo30, 'HH:mm');
165
167
  this.AggMinutesRoundTo15 = new DimensionalLevelAttribute(DateLevels.AggMinutesRoundTo15, expression, DateLevels.AggMinutesRoundTo15, 'HH:mm');
@@ -173,6 +175,8 @@ export class DimensionalDateDimension extends DimensionalDimension {
173
175
  this.Hours,
174
176
  this.MinutesRoundTo30,
175
177
  this.MinutesRoundTo15,
178
+ this.Minutes,
179
+ this.Seconds,
176
180
  this.AggHours,
177
181
  this.AggMinutesRoundTo30,
178
182
  this.AggMinutesRoundTo15,
@@ -377,7 +377,7 @@ export declare function numeric(attribute: Attribute, operatorA?: string, valueA
377
377
  * @param guid - Optional GUID for the filter
378
378
  * @returns A filter instance
379
379
  */
380
- export declare function members(attribute: Attribute, members: string[], _deactivatedMembers?: string[], guid?: string): Filter;
380
+ export declare function members(attribute: Attribute, members: string[], _deactivatedMembers?: string[], guid?: string, backgroundFilter?: Filter): Filter;
381
381
  /**
382
382
  * Creates a filter to isolate date values starting from and including the given date and level.
383
383
  *
@@ -427,8 +427,8 @@ export function numeric(attribute, operatorA, valueA, operatorB, valueB, guid) {
427
427
  * @param guid - Optional GUID for the filter
428
428
  * @returns A filter instance
429
429
  */
430
- export function members(attribute, members, _deactivatedMembers, guid) {
431
- return new MembersFilter(attribute, members, _deactivatedMembers, guid);
430
+ export function members(attribute, members, _deactivatedMembers, guid, backgroundFilter) {
431
+ return new MembersFilter(attribute, members, _deactivatedMembers, guid, backgroundFilter);
432
432
  }
433
433
  // DATE FILTERS
434
434
  /**
@@ -95,6 +95,7 @@ declare abstract class AbstractFilter extends DimensionalElement implements Filt
95
95
  */
96
96
  readonly guid: string;
97
97
  private _disabled;
98
+ private _locked;
98
99
  /**
99
100
  * Boolean flag whether the filter is disabled
100
101
  *
@@ -102,6 +103,13 @@ declare abstract class AbstractFilter extends DimensionalElement implements Filt
102
103
  */
103
104
  get disabled(): boolean;
104
105
  set disabled(value: boolean);
106
+ /**
107
+ * Boolean flag whether the filter is locked
108
+ *
109
+ * @internal
110
+ */
111
+ get locked(): boolean;
112
+ set locked(value: boolean);
105
113
  constructor(att: Attribute, filterType: string, guid?: string);
106
114
  get name(): string;
107
115
  /**
@@ -156,7 +164,9 @@ export declare class MembersFilter extends AbstractFilter {
156
164
  readonly members: any[];
157
165
  /** @internal */
158
166
  _deactivatedMembers: any[];
159
- constructor(attribute: Attribute, members?: any[], _deactivatedMembers?: any[], guid?: string);
167
+ /** @internal */
168
+ backgroundFilter?: Filter;
169
+ constructor(attribute: Attribute, members?: any[], _deactivatedMembers?: any[], guid?: string, backgroundFilter?: Filter);
160
170
  /**
161
171
  * gets the element's ID
162
172
  */
@@ -182,6 +192,8 @@ export declare class CascadingFilter extends AbstractFilter {
182
192
  get id(): string;
183
193
  get disabled(): boolean;
184
194
  set disabled(value: boolean);
195
+ get locked(): boolean;
196
+ set locked(value: boolean);
185
197
  /**
186
198
  * Gets a serializable representation of the element
187
199
  */
@@ -102,6 +102,7 @@ class AbstractFilter extends DimensionalElement {
102
102
  this.attribute = att;
103
103
  this.guid = guid || guidFast(13);
104
104
  this.disabled = false;
105
+ this.locked = false;
105
106
  }
106
107
  /**
107
108
  * Boolean flag whether the filter is disabled
@@ -114,6 +115,17 @@ class AbstractFilter extends DimensionalElement {
114
115
  set disabled(value) {
115
116
  this._disabled = value;
116
117
  }
118
+ /**
119
+ * Boolean flag whether the filter is locked
120
+ *
121
+ * @internal
122
+ */
123
+ get locked() {
124
+ return this._locked;
125
+ }
126
+ set locked(value) {
127
+ this._locked = value;
128
+ }
117
129
  get name() {
118
130
  return hash(this.jaql());
119
131
  }
@@ -155,7 +167,9 @@ class AbstractFilter extends DimensionalElement {
155
167
  const { granularity } = attribute;
156
168
  if (granularity === DateLevels.Hours ||
157
169
  granularity === DateLevels.MinutesRoundTo30 ||
158
- granularity === DateLevels.MinutesRoundTo15) {
170
+ granularity === DateLevels.MinutesRoundTo15 ||
171
+ granularity === DateLevels.Minutes ||
172
+ granularity === DateLevels.Seconds) {
159
173
  throw new TranslatableError('errors.filter.unsupportedDatetimeLevel');
160
174
  }
161
175
  }
@@ -200,10 +214,11 @@ export class LogicalAttributeFilter extends AbstractFilter {
200
214
  * @internal
201
215
  */
202
216
  export class MembersFilter extends AbstractFilter {
203
- constructor(attribute, members, _deactivatedMembers, guid) {
217
+ constructor(attribute, members, _deactivatedMembers, guid, backgroundFilter) {
204
218
  super(attribute, FilterTypes.members, guid);
205
219
  this.members = members !== null && members !== void 0 ? members : [];
206
220
  this._deactivatedMembers = _deactivatedMembers !== null && _deactivatedMembers !== void 0 ? _deactivatedMembers : [];
221
+ this.backgroundFilter = backgroundFilter;
207
222
  if (this.members.filter((m) => m === null || m === undefined).length > 0) {
208
223
  throw new TranslatableError('errors.filter.membersFilterNullMember', {
209
224
  attributeId: attribute.id,
@@ -222,15 +237,24 @@ export class MembersFilter extends AbstractFilter {
222
237
  serializable() {
223
238
  const result = super.serializable();
224
239
  result.members = this.members;
240
+ if (this.backgroundFilter) {
241
+ result.backgroundFilter = this.backgroundFilter.serializable();
242
+ }
225
243
  return result;
226
244
  }
227
245
  /**
228
246
  * Gets JAQL representing this Filter instance
229
247
  */
230
248
  filterJaql() {
231
- return {
249
+ const filterJaql = {
232
250
  members: this.members.map((m) => m.toString()),
233
251
  };
252
+ if (this.backgroundFilter) {
253
+ return {
254
+ and: [filterJaql, this.backgroundFilter.filterJaql()],
255
+ };
256
+ }
257
+ return filterJaql;
234
258
  }
235
259
  }
236
260
  /**
@@ -258,6 +282,17 @@ export class CascadingFilter extends AbstractFilter {
258
282
  });
259
283
  }
260
284
  }
285
+ get locked() {
286
+ return super.locked;
287
+ }
288
+ set locked(value) {
289
+ super.locked = value;
290
+ if (this.filters) {
291
+ this.filters.forEach((filter) => {
292
+ filter.locked = value;
293
+ });
294
+ }
295
+ }
261
296
  /**
262
297
  * Gets a serializable representation of the element
263
298
  */
@@ -249,6 +249,14 @@ export interface DateDimension extends Dimension {
249
249
  * Minutes (round to 15) level (for Live Models)
250
250
  */
251
251
  readonly MinutesRoundTo15: LevelAttribute;
252
+ /**
253
+ * Minutes level (for Live Models)
254
+ */
255
+ readonly Minutes: LevelAttribute;
256
+ /**
257
+ * Seconds level (for Live Models)
258
+ */
259
+ readonly Seconds: LevelAttribute;
252
260
  /**
253
261
  * Aggregated Hours level (for Live Models)
254
262
  */
@@ -346,6 +354,12 @@ export interface Filter extends Element {
346
354
  * @internal
347
355
  */
348
356
  disabled: boolean;
357
+ /**
358
+ * Boolean flag whether the filter is locked
359
+ *
360
+ * @internal
361
+ */
362
+ locked: boolean;
349
363
  /**
350
364
  * Gets JAQL representing this Filter instance
351
365
  *
@@ -144,6 +144,8 @@ export declare const DateLevels: {
144
144
  Hours: string;
145
145
  MinutesRoundTo30: string;
146
146
  MinutesRoundTo15: string;
147
+ Minutes: string;
148
+ Seconds: string;
147
149
  AggHours: string;
148
150
  AggMinutesRoundTo30: string;
149
151
  AggMinutesRoundTo15: string;
@@ -258,6 +258,8 @@ export const DateLevels = {
258
258
  Hours: 'Hours',
259
259
  MinutesRoundTo30: 'MinutesRoundTo30',
260
260
  MinutesRoundTo15: 'MinutesRoundTo15',
261
+ Minutes: 'Minutes',
262
+ Seconds: 'Seconds',
261
263
  AggHours: 'AggHours',
262
264
  AggMinutesRoundTo30: 'AggMinutesRoundTo30',
263
265
  AggMinutesRoundTo15: 'AggMinutesRoundTo15',
@@ -273,6 +275,8 @@ export const DateLevels = {
273
275
  DateLevels.Hours,
274
276
  DateLevels.MinutesRoundTo30,
275
277
  DateLevels.MinutesRoundTo15,
278
+ DateLevels.Minutes,
279
+ DateLevels.Seconds,
276
280
  DateLevels.AggHours,
277
281
  DateLevels.AggMinutesRoundTo30,
278
282
  DateLevels.AggMinutesRoundTo15,
@@ -288,7 +288,7 @@ export declare const EMPTY_PIVOT_QUERY_RESULT_DATA: PivotQueryResultData;
288
288
  * @param arg
289
289
  * @internal
290
290
  */
291
- export declare function isDataSource(arg: DataSource | Data | undefined): arg is DataSource;
291
+ export declare function isDataSource(arg: DataSource | Data | undefined): arg is DataSource | undefined;
292
292
  /**
293
293
  * Trend formula options.
294
294
  */
@@ -19,7 +19,7 @@ export const translation = {
19
19
  },
20
20
  filter: {
21
21
  unsupportedType: 'Unsupported filter type: {{filterType}}',
22
- unsupportedDatetimeLevel: 'Filters do not support the next "datetime" levels: Hours, MinutesRoundTo30, MinutesRoundTo15',
22
+ unsupportedDatetimeLevel: 'Filters do not support the next "datetime" levels: Hours, MinutesRoundTo30, MinutesRoundTo15, Minutes, Seconds',
23
23
  membersFilterNullMember: 'MembersFilter of {{attributeId}} - member cannot be null',
24
24
  },
25
25
  unsupportedDimensionalElement: 'Unsupported dimensional element type',
@@ -19,7 +19,7 @@ export const translation = {
19
19
  },
20
20
  filter: {
21
21
  unsupportedType: 'Непідтримуваний тип фільтра: {{filterType}}',
22
- unsupportedDatetimeLevel: 'Фільтри не підтримують наступні рівні "datetime": Hours, MinutesRoundTo30, MinutesRoundTo15',
22
+ unsupportedDatetimeLevel: 'Фільтри не підтримують наступні рівні "datetime": Hours, MinutesRoundTo30, MinutesRoundTo15, Minutes, Seconds',
23
23
  membersFilterNullMember: 'MembersFilter у {{attributeId}} - member не може бути нульовим',
24
24
  },
25
25
  unsupportedDimensionalElement: 'Непідтримуваний тип елемента',
package/dist/utils.js CHANGED
@@ -89,6 +89,10 @@ export function isDataSourceInfo(dataSource) {
89
89
  export const createFilterFromJaql = (jaql, instanceid) => {
90
90
  // translation logic is based on FilterJaqlInternal type (from internal modern-analytics-filters)
91
91
  // TODO reconcile FilterJaql and FilterJaqlInternal
92
- const jaqlInternal = jaql;
93
- return createFilterFromJaqlInternal(jaqlInternal, instanceid);
92
+ const hasBackgroundFilter = jaql.filter.filter && !('turnedOff' in jaql.filter.filter);
93
+ const filter = createFilterFromJaqlInternal(jaql, instanceid);
94
+ if (hasBackgroundFilter) {
95
+ filter.backgroundFilter = createFilterFromJaqlInternal(Object.assign(Object.assign({}, jaql), { filter: jaql.filter.filter }), `${instanceid}-bg`);
96
+ }
97
+ return filter;
94
98
  };
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "Sisense",
12
12
  "Compose SDK"
13
13
  ],
14
- "version": "1.13.0",
14
+ "version": "1.14.0",
15
15
  "type": "module",
16
16
  "main": "./dist/cjs/index.js",
17
17
  "module": "./dist/index.js",
@@ -32,8 +32,8 @@
32
32
  "author": "Sisense",
33
33
  "license": "SEE LICENSE IN LICENSE.md",
34
34
  "dependencies": {
35
- "@sisense/sdk-common": "^1.13.0",
36
- "@sisense/sdk-rest-client": "^1.13.0",
35
+ "@sisense/sdk-common": "^1.14.0",
36
+ "@sisense/sdk-rest-client": "^1.14.0",
37
37
  "guid-typescript": "^1.0.9",
38
38
  "lodash": "^4.17.21",
39
39
  "numeral": "^2.0.6",