A VA parameter can now carry a transform on the column side of a mapping: va_parmap=SELECTED_DATE-D_DATE:ADD(QUARTER_START,-1) which filters D_DATE on the report value AND the same point one quarter earlier, as a single IN clause - so the AND rule, the clause signature, saveQuery and the reload loop are untouched. Transforms resolve to one clause with these operations: - ADD(<ANCHOR>,<offset>) the value plus one anchor beside it -> IN - RANGE(<PERIOD>,<offset>) a closed period -> BETWEEN Anchors: QUARTER_START/END, MONTH_START/END, YEAR_START/END. Periods: QUARTER, MONTH, YEAR. Offset is a whole number of periods, defaulting to 0. The names describe the result rather than mirroring SAS intnx: the arithmetic runs in the browser, so mirroring intnx would mean reimplementing its alignment letters and their corners (week alignment, 's' and 'm') with no guarantee of matching SAS. A report author can read ADD(QUARTER_START,-1) without knowing intnx. Resolution is anchored on the parameter value, never on today, so a saved report reproduces the same rows. A transform that cannot run where it is used - a non-temporal column, a value that is not a date - is skipped and reported in the existing warning banner rather than silently filtering on the raw value.
182 lines
4.7 KiB
TypeScript
182 lines
4.7 KiB
TypeScript
import { QueryClause } from './models/TableData'
|
|
import { VaParmapTarget } from './shared/utils/parse-va-parmap'
|
|
|
|
/**
|
|
* Filtering cache info, to be reused when filtering modal is re-open
|
|
*/
|
|
interface FilterCache {
|
|
cols: any[]
|
|
vals: any[]
|
|
groupLogic: string
|
|
whereClause: string
|
|
libds: string
|
|
clauses: any[]
|
|
query: QueryClause[]
|
|
}
|
|
|
|
/**
|
|
* Filtering cache info in the open viewboxes, to be reused when filtering modal is re-open
|
|
*/
|
|
interface ViewboxCache {
|
|
[key: number]: {
|
|
filter: FilterCache
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initial values when no cached values stored
|
|
*/
|
|
export const initFilter: { filter: FilterCache } = {
|
|
filter: {
|
|
cols: <any[]>[],
|
|
vals: <any[]>[],
|
|
groupLogic: <string>'',
|
|
whereClause: <string>'',
|
|
libds: <string>'',
|
|
clauses: <any>[],
|
|
query: <QueryClause[]>[]
|
|
}
|
|
}
|
|
|
|
export interface XLMapListItem {
|
|
id: string
|
|
description: string
|
|
targetDS: string
|
|
}
|
|
|
|
export interface HandsontableStaticConfig {
|
|
darkTableHeaderClass: string
|
|
}
|
|
|
|
/**
|
|
* Cached filtering values across whole app (editor, viewer, viewboxes)
|
|
* Cached lineage libraries, tables
|
|
* Cached metadata tree
|
|
* Cached usernav tree
|
|
* Cached viyaApi collections, search and selected endpoint
|
|
*/
|
|
export const globals: {
|
|
embed: boolean | 'va'
|
|
/**
|
|
* VA embed filter behavior: 'live' = auto-apply, 'confirm' = manual Apply.
|
|
* Defaults to 'live'; toggled by the Auto-apply checkbox in the editor.
|
|
*/
|
|
vaApplyMode: 'live' | 'confirm'
|
|
/**
|
|
* Explicit VA parameter -> DC column mappings, parsed from the `va_parmap`
|
|
* URL parameter (see parseVaParmap). Empty unless configured; entries override
|
|
* VA's default same-name (parameter label -> column) resolution, so two DC
|
|
* instances over one table can filter the same column from differently-named
|
|
* VA parameters.
|
|
*/
|
|
vaParamMap: Map<string, VaParmapTarget>
|
|
/**
|
|
* `va_parmap` entries that could not be used at all (not a plain SAS column
|
|
* name, or missing a side of the `-`). Surfaced to the report author, because
|
|
* these are hand-written in the report's URL and a typo otherwise looks like
|
|
* a working, unfiltered view.
|
|
*/
|
|
vaParmapProblems: string[]
|
|
rootParam: string
|
|
dcLib: string
|
|
xlmaps: XLMapListItem[]
|
|
editor: any
|
|
viewer: any
|
|
viewboxes: ViewboxCache
|
|
lineage: any
|
|
metadata: any
|
|
viyaApi: any
|
|
usernav: any
|
|
operators: any
|
|
handsontable: HandsontableStaticConfig
|
|
[key: string]: any
|
|
} = {
|
|
embed: false,
|
|
vaApplyMode: 'live',
|
|
vaParamMap: new Map(),
|
|
vaParmapProblems: [],
|
|
rootParam: <string>'',
|
|
dcLib: '',
|
|
xlmaps: [],
|
|
editor: {
|
|
startupSet: <boolean>false,
|
|
treeNodeLibraries: <any[] | null>[],
|
|
libsAndTables: <any[]>[],
|
|
libraries: <string[] | undefined>[],
|
|
library: <string>'',
|
|
table: <string>'',
|
|
filter: <FilterCache>{
|
|
cols: <any[]>[],
|
|
vals: <any[]>[],
|
|
groupLogic: <string>'',
|
|
whereClause: <string>'',
|
|
libds: <string>'',
|
|
clauses: <any>[],
|
|
query: <QueryClause[]>[]
|
|
}
|
|
},
|
|
viewer: {
|
|
startupSet: <boolean>false,
|
|
tablesSet: <boolean>false,
|
|
libraries: <any[]>[],
|
|
tables: <any>null,
|
|
library: '',
|
|
table: '',
|
|
libinfo: [],
|
|
librariesSearch: <string>'',
|
|
filter: <FilterCache>{
|
|
cols: <any[]>[],
|
|
vals: <any[]>[],
|
|
groupLogic: <string>'',
|
|
whereClause: <string>'',
|
|
libds: <string>'',
|
|
clauses: <any>[],
|
|
query: <QueryClause[]>[]
|
|
},
|
|
currentSelection: <string>''
|
|
},
|
|
viewboxes: {},
|
|
lineage: {
|
|
libraryList: <any[] | undefined>[],
|
|
tablesList: <any[] | undefined>[],
|
|
columnsList: <any[] | undefined>[],
|
|
librariesSearch: <string>'',
|
|
lib: <String | null>'',
|
|
table: <String | undefined>'',
|
|
column: <String | undefined>'',
|
|
currentLineagePathLibTable: <String>'',
|
|
currentLineagePathColumn: <String>''
|
|
},
|
|
metadata: {
|
|
metaDataList: <any[] | undefined>undefined,
|
|
metaDataSearch: <string>'',
|
|
metaObjectList: <any[] | undefined>[],
|
|
metaObjectSearch: <string>'',
|
|
metaRepositories: <any[] | undefined>undefined,
|
|
selectedRepository: <string>''
|
|
},
|
|
viyaApi: {
|
|
collectionsList: <any[] | undefined>undefined,
|
|
collectionsSearch: <string>'',
|
|
selectedRepository: <string>''
|
|
},
|
|
usernav: {
|
|
userList: <any[] | undefined>undefined,
|
|
userSearch: <string>'',
|
|
groupList: <any[] | undefined>undefined,
|
|
groupSearch: <string>'',
|
|
roleList: <any[] | undefined>undefined,
|
|
roleSearch: <string>''
|
|
},
|
|
operators: {
|
|
numOperators: ['=', '<', '>', '<=', '>=', 'BETWEEN', 'IN', 'NOT IN', 'NE'],
|
|
charOperators: ['=', '<', '>', '<=', '>=', 'CONTAINS', 'IN', 'NOT IN', 'NE']
|
|
},
|
|
handsontable: {
|
|
darkTableHeaderClass: 'darkTH'
|
|
},
|
|
userDropdownConfig: {
|
|
closeOnDebugClick: false
|
|
}
|
|
}
|