mirror of https://github.com/apache/druid.git
Web console: make it possible to namespace local storage, auto flatten spec generator should deal better with bad data (#12238)
* improve computeFlattenExprsForData * allow local storage namespacing * add test
This commit is contained in:
parent
ced1389d4c
commit
090c429c8c
|
@ -49,6 +49,7 @@ describe('spec-utils', () => {
|
|||
],
|
||||
value: 2,
|
||||
},
|
||||
'Curveball' as any,
|
||||
];
|
||||
|
||||
it('works for path, ignore-arrays', () => {
|
||||
|
|
|
@ -82,13 +82,15 @@ export function computeFlattenExprsForData(
|
|||
data: Record<string, any>[],
|
||||
exprType: ExprType,
|
||||
arrayHandling: ArrayHandling,
|
||||
includeTopLevel = false,
|
||||
): string[] {
|
||||
const seenPaths: Record<string, boolean> = {};
|
||||
for (const datum of data) {
|
||||
if (!datum || typeof datum !== 'object') continue;
|
||||
const datumKeys = Object.keys(datum);
|
||||
for (const datumKey of datumKeys) {
|
||||
const datumValue = datum[datumKey];
|
||||
if (isNested(datumValue)) {
|
||||
if (includeTopLevel || isNested(datumValue)) {
|
||||
addPath(
|
||||
seenPaths,
|
||||
exprType === 'path' ? `$.${datumKey}` : `.${datumKey}`,
|
||||
|
|
|
@ -29,6 +29,7 @@ import { bootstrapReactTable } from './bootstrap/react-table-defaults';
|
|||
import { ConsoleApplication } from './console-application';
|
||||
import { Links, setLinkOverrides } from './links';
|
||||
import { Api, UrlBaser } from './singletons';
|
||||
import { setLocalStorageNamespace } from './utils';
|
||||
|
||||
import './entry.scss';
|
||||
|
||||
|
@ -63,6 +64,9 @@ interface ConsoleConfig {
|
|||
|
||||
// Allow for link overriding to different docs
|
||||
linkOverrides?: Links;
|
||||
|
||||
// Allow for namespacing the local storage in case multiple clusters share a URL due to proxying
|
||||
localStorageNamespace?: string;
|
||||
}
|
||||
|
||||
const consoleConfig: ConsoleConfig = (window as any).consoleConfig;
|
||||
|
@ -89,6 +93,10 @@ if (consoleConfig.linkOverrides) {
|
|||
setLinkOverrides(consoleConfig.linkOverrides);
|
||||
}
|
||||
|
||||
if (consoleConfig.localStorageNamespace) {
|
||||
setLocalStorageNamespace(consoleConfig.localStorageNamespace);
|
||||
}
|
||||
|
||||
QueryRunner.defaultQueryExecutor = (payload, isSql, cancelToken) => {
|
||||
return Api.instance.post(`/druid/v2${isSql ? '/sql' : ''}`, payload, { cancelToken });
|
||||
};
|
||||
|
|
|
@ -16,28 +16,22 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as JSONBig from 'json-bigint-native';
|
||||
import { Dispatch, SetStateAction, useState } from 'react';
|
||||
|
||||
import { localStorageGetJson, LocalStorageKeys, localStorageSetJson } from '../utils';
|
||||
|
||||
export function useLocalStorageState<T>(
|
||||
key: string,
|
||||
key: LocalStorageKeys,
|
||||
initialValue?: T,
|
||||
): [T, Dispatch<SetStateAction<T>>] {
|
||||
const [state, setState] = useState(() => {
|
||||
try {
|
||||
const item = window.localStorage.getItem(key);
|
||||
return item ? JSONBig.parse(item) : initialValue;
|
||||
} catch {
|
||||
return initialValue;
|
||||
}
|
||||
return localStorageGetJson(key) || initialValue;
|
||||
});
|
||||
|
||||
const setValue: Dispatch<SetStateAction<T>> = (value: T | ((prevState: T) => T)) => {
|
||||
const valueToStore = value instanceof Function ? value(state) : value;
|
||||
setState(valueToStore);
|
||||
try {
|
||||
window.localStorage.setItem(key, JSONBig.stringify(valueToStore));
|
||||
} catch {}
|
||||
localStorageSetJson(key, valueToStore);
|
||||
};
|
||||
return [state, setValue];
|
||||
}
|
||||
|
|
|
@ -44,10 +44,20 @@ export type LocalStorageKeys = typeof LocalStorageKeys[keyof typeof LocalStorage
|
|||
|
||||
// ----------------------------
|
||||
|
||||
let localStorageNamespace: string | undefined;
|
||||
|
||||
export function setLocalStorageNamespace(namespace: string) {
|
||||
localStorageNamespace = namespace;
|
||||
}
|
||||
|
||||
function prependNamespace(key: string): string {
|
||||
return localStorageNamespace ? `${localStorageNamespace}:${key}` : key;
|
||||
}
|
||||
|
||||
export function localStorageSet(key: LocalStorageKeys, value: string): void {
|
||||
if (typeof localStorage === 'undefined') return;
|
||||
try {
|
||||
localStorage.setItem(key, value);
|
||||
localStorage.setItem(prependNamespace(key), value);
|
||||
} catch (e) {
|
||||
console.error('Issue setting local storage key', e);
|
||||
}
|
||||
|
@ -60,7 +70,7 @@ export function localStorageSetJson(key: LocalStorageKeys, value: any): void {
|
|||
export function localStorageGet(key: LocalStorageKeys): string | undefined {
|
||||
if (typeof localStorage === 'undefined') return;
|
||||
try {
|
||||
return localStorage.getItem(key) || undefined;
|
||||
return localStorage.getItem(prependNamespace(key)) || localStorage.getItem(key) || undefined;
|
||||
} catch (e) {
|
||||
console.error('Issue getting local storage key', e);
|
||||
return;
|
||||
|
@ -80,7 +90,7 @@ export function localStorageGetJson(key: LocalStorageKeys): any {
|
|||
export function localStorageRemove(key: LocalStorageKeys): void {
|
||||
if (typeof localStorage === 'undefined') return;
|
||||
try {
|
||||
localStorage.removeItem(key);
|
||||
localStorage.removeItem(prependNamespace(key));
|
||||
} catch (e) {
|
||||
console.error('Issue removing local storage key', e);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue