Skip to content

Commit

Permalink
Merge branch 'master' into chore/logo-width
Browse files Browse the repository at this point in the history
  • Loading branch information
rusackas authored Mar 21, 2022
2 parents 62e1d43 + 88029e2 commit 8c926f4
Show file tree
Hide file tree
Showing 91 changed files with 1,089 additions and 430 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,5 @@ release.json
messages.mo

docker/requirements-local.txt

cache/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ A modern, enterprise-ready business intelligence web application.

## Why Superset?

Superset is a modern data exploration and data visualization platform. Superset can replace or augment proprietary business intelligence tools for many teams.
Superset is a modern data exploration and data visualization platform. Superset can replace or augment proprietary business intelligence tools for many teams. Superset integrates well with a variety of data sources.

Superset provides:

Expand Down
7 changes: 6 additions & 1 deletion UPDATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ assists people when migrating to a new version.
### Breaking Changes

- [19049](https://github.com/apache/superset/pull/19049): APP_ICON_WIDTH has been removed from the config. Superset should now be able to handle different logo sizes without having to explicitly set an APP_ICON_WIDTH. This might affect the size of existing custom logos as the UI will now resize them according to the specified space of maximum 148px and not according to the value of APP_ICON_WIDTH.
- [19274](https://github.com/apache/superset/pull/19274): The `PUBLIC_ROLE_LIKE_GAMMA` config key has been removed, set `PUBLIC_ROLE_LIKE` = "Gamma" to have the same functionality.
- [19273](https://github.com/apache/superset/pull/19273): The `SUPERSET_CELERY_WORKERS` and `SUPERSET_WORKERS` config keys has been removed. Configure celery directly using `CELERY_CONFIG` on Superset
- [19231](https://github.com/apache/superset/pull/19231): The `ENABLE_REACT_CRUD_VIEWS` feature flag has been removed (permanently enabled). Any deployments which had set this flag to false will need to verify that the React views support their use case.
- [17556](https://github.com/apache/superset/pull/17556): Bumps mysqlclient from v1 to v2
- [19113](https://github.com/apache/superset/pull/19113): The `ENABLE_JAVASCRIPT_CONTROLS` setting has moved from app config to a feature flag. Any deployments who overrode this setting will now need to override the feature flag from here onward.
Expand All @@ -38,10 +40,13 @@ assists people when migrating to a new version.
- [17984](https://github.com/apache/superset/pull/17984): Default Flask SECRET_KEY has changed for security reasons. You should always override with your own secret. Set `PREVIOUS_SECRET_KEY` (ex: PREVIOUS_SECRET_KEY = "\2\1thisismyscretkey\1\2\\e\\y\\y\\h") with your previous key and use `superset re-encrypt-secrets` to rotate you current secrets
- [15254](https://github.com/apache/superset/pull/15254): Previously `QUERY_COST_FORMATTERS_BY_ENGINE`, `SQL_VALIDATORS_BY_ENGINE` and `SCHEDULED_QUERIES` were expected to be defined in the feature flag dictionary in the `config.py` file. These should now be defined as a top-level config, with the feature flag dictionary being reserved for boolean only values.
- [17539](https://github.com/apache/superset/pull/17539): all Superset CLI commands (init, load_examples and etc) require setting the FLASK_APP environment variable (which is set by default when `.flaskenv` is loaded)
- [18970](https://github.com/apache/superset/pull/18970): Changes feature flag for the legacy datasource editor (DISABLE_LEGACY_DATASOURCE_EDITOR) in config.py to True, thus disabling the feature from being shown in the client.
- [18970](https://github.com/apache/superset/pull/18970): Changes feature
flag for the legacy datasource editor (DISABLE_LEGACY_DATASOURCE_EDITOR) in config.py to True, thus disabling the feature from being shown in the client.
- [19083](https://github.com/apache/superset/pull/19083): Updates the mutator function in the config file to take a sql argument and a list of kwargs. Any `SQL_QUERY_MUTATOR` config function overrides will need to be updated to match the new set of params. It is advised regardless of the dictionary args that you list in your function arguments, to keep **kwargs as the last argument to allow for any new kwargs to be passed in.
- [19017](https://github.com/apache/superset/pull/19017): Removes Python 3.7 support.
- [19142](https://github.com/apache/superset/pull/19142): Changes feature flag for versioned export(VERSIONED_EXPORT) to be true.
- [19107](https://github.com/apache/superset/pull/19107): Feature flag `SQLLAB_BACKEND_PERSISTENCE` is now on by default, which enables persisting SQL Lab tabs in the backend instead of the browser's `localStorage`.
- [19262](https://github.com/apache/superset/pull/19262): As per SIPs 11 and 68, the native NoSQL Druid connector is deprecated as of 2.0 and will no longer be supported. Druid is still supported through SQLAlchemy via pydruid.

### Potential Downtime

Expand Down
26 changes: 20 additions & 6 deletions superset-frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions superset-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
"rison": "^0.1.1",
"scroll-into-view-if-needed": "^2.2.28",
"shortid": "^2.2.6",
"tinycolor2": "^1.4.2",
"urijs": "^1.19.8",
"use-immer": "^0.6.0",
"use-query-params": "^1.1.9",
Expand Down Expand Up @@ -261,6 +262,7 @@
"@types/rison": "0.0.6",
"@types/shortid": "^0.0.29",
"@types/sinon": "^9.0.5",
"@types/tinycolor2": "^1.4.3",
"@types/yargs": "12 - 15",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ const linear_color_scheme: SharedControlConfig<'ColorSchemeControl'> = {
renderTrigger: true,
schemes: () => sequentialSchemeRegistry.getMap(),
isLinear: true,
mapStateToProps: state => ({
dashboardId: state?.form_data?.dashboardId,
}),
};

const secondary_metric: SharedControlConfig<'MetricsControl'> = {
Expand Down
1 change: 1 addition & 0 deletions superset-frontend/packages/superset-ui-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@types/math-expression-evaluator": "^1.2.1",
"@types/rison": "0.0.6",
"@types/seedrandom": "^2.4.28",
"@types/tinycolor2": "^1.4.3",
"@types/fetch-mock": "^7.3.3",
"@types/enzyme": "^3.10.5",
"@types/prop-types": "^15.7.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ import { scaleOrdinal, ScaleOrdinal } from 'd3-scale';
import { ExtensibleFunction } from '../models';
import { ColorsLookup } from './types';
import stringifyAndTrim from './stringifyAndTrim';
import getSharedLabelColor from './SharedLabelColorSingleton';

// Use type augmentation to correct the fact that
// an instance of CategoricalScale is also a function

interface CategoricalColorScale {
(x: { toString(): string }): string;
(x: { toString(): string }, y?: number): string;
}

class CategoricalColorScale extends ExtensibleFunction {
Expand All @@ -46,7 +46,7 @@ class CategoricalColorScale extends ExtensibleFunction {
* (usually CategoricalColorNamespace) and supersede this.forcedColors
*/
constructor(colors: string[], parentForcedColors?: ColorsLookup) {
super((value: string) => this.getColor(value));
super((value: string, sliceId?: number) => this.getColor(value, sliceId));

this.colors = colors;
this.scale = scaleOrdinal<{ toString(): string }, string>();
Expand All @@ -55,20 +55,27 @@ class CategoricalColorScale extends ExtensibleFunction {
this.forcedColors = {};
}

getColor(value?: string) {
getColor(value?: string, sliceId?: number) {
const cleanedValue = stringifyAndTrim(value);
const sharedLabelColor = getSharedLabelColor();

const parentColor =
this.parentForcedColors && this.parentForcedColors[cleanedValue];
if (parentColor) {
sharedLabelColor.addSlice(cleanedValue, parentColor, sliceId);
return parentColor;
}

const forcedColor = this.forcedColors[cleanedValue];
if (forcedColor) {
sharedLabelColor.addSlice(cleanedValue, forcedColor, sliceId);
return forcedColor;
}

return this.scale(cleanedValue);
const color = this.scale(cleanedValue);
sharedLabelColor.addSlice(cleanedValue, color, sliceId);

return color;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import tinycolor from 'tinycolor2';
import { CategoricalColorNamespace } from '.';
import makeSingleton from '../utils/makeSingleton';

export class SharedLabelColor {
sliceLabelColorMap: Record<number, Record<string, string | undefined>>;

constructor() {
// { sliceId1: { label1: color1 }, sliceId2: { label2: color2 } }
this.sliceLabelColorMap = {};
}

getColorMap(
colorNamespace?: string,
colorScheme?: string,
updateColorScheme?: boolean,
) {
if (colorScheme) {
const categoricalNamespace =
CategoricalColorNamespace.getNamespace(colorNamespace);
const colors = categoricalNamespace.getScale(colorScheme).range();
const sharedLabels = this.getSharedLabels();
const generatedColors: tinycolor.Instance[] = [];
let sharedLabelMap;

if (sharedLabels.length) {
const multiple = Math.ceil(sharedLabels.length / colors.length);
const ext = 5;
const analogousColors = colors.map(color => {
const result = tinycolor(color).analogous(multiple + ext);
return result.slice(ext);
});

// [[A, AA, AAA], [B, BB, BBB]] => [A, B, AA, BB, AAA, BBB]
while (analogousColors[analogousColors.length - 1]?.length) {
analogousColors.forEach(colors =>
generatedColors.push(colors.shift() as tinycolor.Instance),
);
}
sharedLabelMap = sharedLabels.reduce(
(res, label, index) => ({
...res,
[label.toString()]: generatedColors[index]?.toHexString(),
}),
{},
);
}

const labelMap = Object.keys(this.sliceLabelColorMap).reduce(
(res, sliceId) => {
const colorScale = categoricalNamespace.getScale(colorScheme);
return {
...res,
...Object.keys(this.sliceLabelColorMap[sliceId]).reduce(
(res, label) => ({
...res,
[label]: updateColorScheme
? colorScale(label)
: this.sliceLabelColorMap[sliceId][label],
}),
{},
),
};
},
{},
);

return {
...labelMap,
...sharedLabelMap,
};
}
return undefined;
}

addSlice(label: string, color: string, sliceId?: number) {
if (!sliceId) return;
this.sliceLabelColorMap[sliceId] = {
...this.sliceLabelColorMap[sliceId],
[label]: color,
};
}

removeSlice(sliceId: number) {
delete this.sliceLabelColorMap[sliceId];
}

clear() {
this.sliceLabelColorMap = {};
}

getSharedLabels() {
const tempLabels = new Set<string>();
const result = new Set<string>();
Object.keys(this.sliceLabelColorMap).forEach(sliceId => {
const colorMap = this.sliceLabelColorMap[sliceId];
Object.keys(colorMap).forEach(label => {
if (tempLabels.has(label) && !result.has(label)) {
result.add(label);
} else {
tempLabels.add(label);
}
});
});
return [...result];
}
}

const getInstance = makeSingleton(SharedLabelColor);

export default getInstance;
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,9 @@ export * from './SequentialScheme';
export { default as ColorSchemeRegistry } from './ColorSchemeRegistry';
export * from './colorSchemes';
export * from './utils';
export {
default as getSharedLabelColor,
SharedLabelColor,
} from './SharedLabelColorSingleton';

export const BRAND_COLOR = '#00A699';
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ import { QueryObjectFilterClause } from './types/Query';
import { isSimpleAdhocFilter } from './types/Filter';
import convertFilter from './convertFilter';

function sanitizeClause(clause: string): string {
let sanitizedClause = clause;
if (clause.includes('--')) {
sanitizedClause = `${clause}\n`;
}
return `(${sanitizedClause})`;
}

/** Logic formerly in viz.py's process_query_filters */
export default function processFilters(
formData: Partial<QueryFormData>,
Expand Down Expand Up @@ -60,9 +68,9 @@ export default function processFilters(
});

// some filter-related fields need to go in `extras`
extras.having = freeformHaving.map(exp => `(${exp})`).join(' AND ');
extras.having = freeformHaving.map(sanitizeClause).join(' AND ');
extras.having_druid = simpleHaving;
extras.where = freeformWhere.map(exp => `(${exp})`).join(' AND ');
extras.where = freeformWhere.map(sanitizeClause).join(' AND ');

return {
filters: simpleWhere,
Expand Down
Loading

0 comments on commit 8c926f4

Please sign in to comment.