You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by su...@apache.org on 2022/04/14 15:44:43 UTC
[superset] branch master updated: feat: UI override registry (#19671)
This is an automated email from the ASF dual-hosted git repository.
suddjian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 4927685c30 feat: UI override registry (#19671)
4927685c30 is described below
commit 4927685c3059c0207713bceeea7c60f1f3b75ec3
Author: David Aaron Suddjian <18...@users.noreply.github.com>
AuthorDate: Thu Apr 14 08:44:26 2022 -0700
feat: UI override registry (#19671)
* typed registry
* remove unintentional change
* lint
* fix
---
.../packages/superset-ui-core/src/index.ts | 1 +
.../superset-ui-core/src/models/Registry.ts | 4 ++
.../superset-ui-core/src/models/TypedRegistry.ts | 60 ++++++++++++++++++++++
.../packages/superset-ui-core/src/models/index.ts | 1 +
.../src/ui-overrides/UiOverrideRegistry.ts | 46 +++++++++++++++++
.../{models/index.ts => ui-overrides/index.tsx} | 7 +--
.../index.ts => test/models/TypedRegistry.test.ts} | 22 +++++---
.../components/DashboardEmbedControls.tsx | 27 +++++++---
8 files changed, 150 insertions(+), 18 deletions(-)
diff --git a/superset-frontend/packages/superset-ui-core/src/index.ts b/superset-frontend/packages/superset-ui-core/src/index.ts
index 23d972fc9a..2a53112f6f 100644
--- a/superset-frontend/packages/superset-ui-core/src/index.ts
+++ b/superset-frontend/packages/superset-ui-core/src/index.ts
@@ -35,3 +35,4 @@ export * from './chart';
export * from './chart-composition';
export * from './components';
export * from './math-expression';
+export * from './ui-overrides';
diff --git a/superset-frontend/packages/superset-ui-core/src/models/Registry.ts b/superset-frontend/packages/superset-ui-core/src/models/Registry.ts
index 7bf7f175cb..90a8065e29 100644
--- a/superset-frontend/packages/superset-ui-core/src/models/Registry.ts
+++ b/superset-frontend/packages/superset-ui-core/src/models/Registry.ts
@@ -59,6 +59,10 @@ export interface RegistryConfig {
/**
* Registry class
*
+ * !!!!!!!!
+ * IF YOU ARE ADDING A NEW REGISTRY TO SUPERSET, CONSIDER USING TypedRegistry
+ * !!!!!!!!
+ *
* Can use generic to specify type of item in the registry
* @type V Type of value
* @type W Type of value returned from loader function when using registerLoader().
diff --git a/superset-frontend/packages/superset-ui-core/src/models/TypedRegistry.ts b/superset-frontend/packages/superset-ui-core/src/models/TypedRegistry.ts
new file mode 100644
index 0000000000..80e32167f5
--- /dev/null
+++ b/superset-frontend/packages/superset-ui-core/src/models/TypedRegistry.ts
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ */
+
+/**
+ * A Registry which serves as a typed key:value store for Superset and for Plugins.
+ *
+ * Differences from the older Registry class:
+ *
+ * 1. The keys and values stored in this class are individually typed by TYPEMAP parameter.
+ * In the old Registry, all values are of the same type and keys are not enumerated.
+ * Though you can also use indexed or mapped types in a TYPEMAP.
+ *
+ * 2. This class does not have a separate async get and set methods or use loaders.
+ * Instead, TYPEMAP should specify async values and loaders explicitly when needed.
+ * The value can be anything! A string, a class, a function, an async function... anything!
+ *
+ * 3. This class does not implement Policies, that is a separate concern to be handled elsewhere.
+ *
+ *
+ * Removing or altering types in a type map could be a potential breaking change, be careful!
+ *
+ * Listener methods have not been added because there isn't a use case yet.
+ */
+class TypedRegistry<TYPEMAP extends {}> {
+ name = 'TypedRegistry';
+
+ private records: TYPEMAP;
+
+ constructor(initialRecords: TYPEMAP) {
+ this.records = initialRecords;
+ }
+
+ get<K extends keyof TYPEMAP>(key: K): TYPEMAP[K] {
+ // The type construction above means that when you call this function,
+ // you get a really specific type back.
+ return this.records[key];
+ }
+
+ set<K extends keyof TYPEMAP>(key: K, value: TYPEMAP[K]) {
+ this.records[key] = value;
+ }
+}
+
+export default TypedRegistry;
diff --git a/superset-frontend/packages/superset-ui-core/src/models/index.ts b/superset-frontend/packages/superset-ui-core/src/models/index.ts
index 10d46c2a7e..365ed391d3 100644
--- a/superset-frontend/packages/superset-ui-core/src/models/index.ts
+++ b/superset-frontend/packages/superset-ui-core/src/models/index.ts
@@ -21,3 +21,4 @@ export { default as Plugin } from './Plugin';
export { default as Preset } from './Preset';
export { default as Registry, OverwritePolicy } from './Registry';
export { default as RegistryWithDefaultKey } from './RegistryWithDefaultKey';
+export { default as TypedRegistry } from './TypedRegistry';
diff --git a/superset-frontend/packages/superset-ui-core/src/ui-overrides/UiOverrideRegistry.ts b/superset-frontend/packages/superset-ui-core/src/ui-overrides/UiOverrideRegistry.ts
new file mode 100644
index 0000000000..fb74ae1ece
--- /dev/null
+++ b/superset-frontend/packages/superset-ui-core/src/ui-overrides/UiOverrideRegistry.ts
@@ -0,0 +1,46 @@
+/**
+ * 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 React from 'react';
+import { TypedRegistry } from '../models';
+import { makeSingleton } from '../utils';
+
+/** A function (or component) which returns text (or marked-up text) */
+type UiGeneratorText<P = void> = (props: P) => string | React.ReactElement;
+
+/**
+ * This type defines all the UI override options which replace elements of Superset's default UI.
+ * Idea with the keys here is generally to namespace following the form of 'domain.functonality.item'
+ *
+ * When defining a new option here, take care to keep any parameters to functions (or components) minimal.
+ * Any removal or alteration to a parameter will be considered a breaking change.
+ */
+export type UiOverrides = Partial<{
+ 'embedded.documentation.description': UiGeneratorText;
+ 'embedded.documentation.url': string;
+}>;
+
+/**
+ * A registry containing UI customizations to replace elements of Superset's default UI.
+ */
+class UiOverrideRegistry extends TypedRegistry<UiOverrides> {
+ name = 'UiOverrideRegistry';
+}
+
+export const getUiOverrideRegistry = makeSingleton(UiOverrideRegistry, {});
diff --git a/superset-frontend/packages/superset-ui-core/src/models/index.ts b/superset-frontend/packages/superset-ui-core/src/ui-overrides/index.tsx
similarity index 72%
copy from superset-frontend/packages/superset-ui-core/src/models/index.ts
copy to superset-frontend/packages/superset-ui-core/src/ui-overrides/index.tsx
index 10d46c2a7e..d59afc216f 100644
--- a/superset-frontend/packages/superset-ui-core/src/models/index.ts
+++ b/superset-frontend/packages/superset-ui-core/src/ui-overrides/index.tsx
@@ -16,8 +16,5 @@
* specific language governing permissions and limitations
* under the License.
*/
-export { default as ExtensibleFunction } from './ExtensibleFunction';
-export { default as Plugin } from './Plugin';
-export { default as Preset } from './Preset';
-export { default as Registry, OverwritePolicy } from './Registry';
-export { default as RegistryWithDefaultKey } from './RegistryWithDefaultKey';
+
+export * from './UiOverrideRegistry';
diff --git a/superset-frontend/packages/superset-ui-core/src/models/index.ts b/superset-frontend/packages/superset-ui-core/test/models/TypedRegistry.test.ts
similarity index 68%
copy from superset-frontend/packages/superset-ui-core/src/models/index.ts
copy to superset-frontend/packages/superset-ui-core/test/models/TypedRegistry.test.ts
index 10d46c2a7e..7eb0d88f9d 100644
--- a/superset-frontend/packages/superset-ui-core/src/models/index.ts
+++ b/superset-frontend/packages/superset-ui-core/test/models/TypedRegistry.test.ts
@@ -1,4 +1,4 @@
-/**
+/*
* 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
@@ -16,8 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
-export { default as ExtensibleFunction } from './ExtensibleFunction';
-export { default as Plugin } from './Plugin';
-export { default as Preset } from './Preset';
-export { default as Registry, OverwritePolicy } from './Registry';
-export { default as RegistryWithDefaultKey } from './RegistryWithDefaultKey';
+
+import { TypedRegistry } from '@superset-ui/core';
+
+describe('TypedRegistry', () => {
+ it('gets a value', () => {
+ const reg = new TypedRegistry({ foo: 'bar' });
+ expect(reg.get('foo')).toBe('bar');
+ });
+
+ it('sets a value', () => {
+ const reg = new TypedRegistry({ foo: 'bar' });
+ reg.set('foo', 'blah');
+ expect(reg.get('foo')).toBe('blah');
+ });
+});
diff --git a/superset-frontend/src/dashboard/components/DashboardEmbedControls.tsx b/superset-frontend/src/dashboard/components/DashboardEmbedControls.tsx
index d20cc24600..a2c44f4902 100644
--- a/superset-frontend/src/dashboard/components/DashboardEmbedControls.tsx
+++ b/superset-frontend/src/dashboard/components/DashboardEmbedControls.tsx
@@ -17,7 +17,13 @@
* under the License.
*/
import React, { useCallback, useEffect, useState } from 'react';
-import { makeApi, styled, SupersetApiError, t } from '@superset-ui/core';
+import {
+ makeApi,
+ styled,
+ SupersetApiError,
+ t,
+ getUiOverrideRegistry,
+} from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import Modal from 'src/components/Modal';
import Loading from 'src/components/Loading';
@@ -27,6 +33,8 @@ import { useToasts } from 'src/components/MessageToasts/withToasts';
import { FormItem } from 'src/components/Form';
import { EmbeddedDashboard } from '../types';
+const uiOverrideRegistry = getUiOverrideRegistry();
+
type Props = {
dashboardId: string;
show: boolean;
@@ -140,6 +148,13 @@ export const DashboardEmbedControls = ({ dashboardId, onHide }: Props) => {
return <Loading />;
}
+ const docsDescription = uiOverrideRegistry.get(
+ 'embedded.documentation.description',
+ );
+ const docsUrl =
+ uiOverrideRegistry.get('embedded.documentation.url') ??
+ 'https://www.npmjs.com/package/@superset-ui/embedded-sdk';
+
return (
<>
<p>
@@ -159,12 +174,10 @@ export const DashboardEmbedControls = ({ dashboardId, onHide }: Props) => {
</p>
<p>
{t('For further instructions, consult the')}{' '}
- <a
- href="https://www.npmjs.com/package/@superset-ui/embedded-sdk"
- target="_blank"
- rel="noreferrer"
- >
- {t('Superset Embedded SDK documentation.')}
+ <a href={docsUrl} target="_blank" rel="noreferrer">
+ {docsDescription
+ ? docsDescription()
+ : t('Superset Embedded SDK documentation.')}
</a>
</p>
<h3>Settings</h3>