feat(explore): adhoc column expressions [ID-3] (#17379)

* add support for adhoc columns to api and sqla model

* fix some types

* fix duplicates in column names

* fix more lint

* fix schema and dedup

* clean up some logic

* first pass at fixing viz.py

* Add frontend support for adhoc columns

* Add title edit

* Fix showing custom title

* Use column name as default value in sql editor

* fix: Adds a loading message when needed in the Select component (#16531)

* fix(tests): make parquet select deterministic with order by (#16570)

* bump emotion to help with cache clobbering (#16559)

* fix: Support Jinja template functions in global async queries (#16412)

* Support Jinja template functions in async queries

* Pylint

* Add tests for async tasks

* Remove redundant has_request_context check

* fix: impersonate user label/tooltip (#16573)

* docs: update for small typos (#16568)

* feat: Add Aurora Data API engine spec (#16535)

* feat: Add Aurora Data API engine spec

* Fix lint

* refactor: sql_json view endpoint: encapsulate ctas parameters (#16548)

* refactor sql_json view endpoint: encapsulate ctas parameters

* fix failed tests

* fix failed tests and ci issues

* refactor sql_json view endpoint: separate concern into ad hod method (#16595)

* feat: Experimental cross-filter plugins (#16594)

* fix:fix get permission function

* feat: add cross filter chart in charts gallery under FF

* chore(deps): bump superset-ui to 0.18.2 (#16601)

* update type guard references

* fix imports

* update series_columns schema

* Add changes that got lost in rebase

* Use current columns name or expression as sql editor init value

* add integration test and do minor fixes

* Bump superset-ui

* fix linting issue

* bump superset-ui to 0.18.22

* resolve merge conflict

* lint

* fix select filter infinite loop

* bump superset-ui to 0.18.23

* Fix auto setting column popover title

* Enable adhoc columns only if UX_BETA enabled

* put back removed test

* Move popover height and width to constants

* Refactor big ternary expression

Co-authored-by: Kamil Gabryjelski <kamil.gabryjelski@gmail.com>
Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
Co-authored-by: Elizabeth Thompson <eschutho@gmail.com>
Co-authored-by: Rob DiCiuccio <rob.diciuccio@gmail.com>
Co-authored-by: Beto Dealmeida <roberto@dealmeida.net>
Co-authored-by: joeADSP <75027008+joeADSP@users.noreply.github.com>
Co-authored-by: ofekisr <35701650+ofekisr@users.noreply.github.com>
Co-authored-by: simcha90 <56388545+simcha90@users.noreply.github.com>
This commit is contained in:
Ville Brofeldt
2021-11-15 12:50:08 +02:00
committed by GitHub
parent 5d3e1b5c2c
commit e2a429b0c8
27 changed files with 1122 additions and 606 deletions

View File

@@ -16,11 +16,25 @@
* specific language governing permissions and limitations
* under the License.
*/
import { ColumnMeta } from '@superset-ui/chart-controls';
import { ensureIsArray } from '@superset-ui/core';
import { ColumnMeta, isColumnMeta } from '@superset-ui/chart-controls';
import {
AdhocColumn,
ensureIsArray,
QueryFormColumn,
isPhysicalColumn,
} from '@superset-ui/core';
const getColumnNameOrAdhocColumn = (
column: ColumnMeta | AdhocColumn,
): QueryFormColumn => {
if (isColumnMeta(column)) {
return column.column_name;
}
return column as AdhocColumn;
};
export class OptionSelector {
values: ColumnMeta[];
values: (ColumnMeta | AdhocColumn)[];
options: Record<string, ColumnMeta>;
@@ -29,23 +43,28 @@ export class OptionSelector {
constructor(
options: Record<string, ColumnMeta>,
multi: boolean,
initialValues?: string[] | string | null,
initialValues?: QueryFormColumn[] | QueryFormColumn | null,
) {
this.options = options;
this.multi = multi;
this.values = ensureIsArray(initialValues)
.map(value => {
if (value && value in options) {
if (value && isPhysicalColumn(value) && value in options) {
return options[value];
}
if (!isPhysicalColumn(value)) {
return value;
}
return null;
})
.filter(Boolean) as ColumnMeta[];
}
add(value: string) {
if (value in this.options) {
add(value: QueryFormColumn) {
if (isPhysicalColumn(value) && value in this.options) {
this.values.push(this.options[value]);
} else if (!isPhysicalColumn(value)) {
this.values.push(value as AdhocColumn);
}
}
@@ -53,9 +72,9 @@ export class OptionSelector {
this.values.splice(idx, 1);
}
replace(idx: number, value: string) {
replace(idx: number, value: QueryFormColumn) {
if (this.values[idx]) {
this.values[idx] = this.options[value];
this.values[idx] = isPhysicalColumn(value) ? this.options[value] : value;
}
}
@@ -63,14 +82,27 @@ export class OptionSelector {
[this.values[a], this.values[b]] = [this.values[b], this.values[a]];
}
has(value: string): boolean {
return ensureIsArray(this.getValues()).includes(value);
has(value: QueryFormColumn): boolean {
return this.values.some(col => {
if (isPhysicalColumn(value)) {
return (
(col as ColumnMeta).column_name === value ||
(col as AdhocColumn).label === value
);
}
return (
(col as ColumnMeta).column_name === value.label ||
(col as AdhocColumn).label === value.label
);
});
}
getValues(): string[] | string | undefined {
getValues(): QueryFormColumn[] | QueryFormColumn | undefined {
if (!this.multi) {
return this.values.length > 0 ? this.values[0].column_name : undefined;
return this.values.length > 0
? getColumnNameOrAdhocColumn(this.values[0])
: undefined;
}
return this.values.map(option => option.column_name);
return this.values.map(getColumnNameOrAdhocColumn);
}
}