From 0e9c50933fbd790291004dbcf333d11d645c5aa2 Mon Sep 17 00:00:00 2001 From: Aleksandr Lesnenko <alxnddr@users.noreply.github.com> Date: Fri, 17 Mar 2023 19:00:40 -0300 Subject: [PATCH] fix how isCustomWidgetCheck detects if widgets are react components (#29334) --- .../models/models-metadata.cy.spec.js | 22 +++++++++++++++++++ frontend/src/metabase-types/guards/forms.ts | 3 ++- frontend/src/metabase-types/guards/react.ts | 12 ++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/e2e/test/scenarios/models/models-metadata.cy.spec.js b/e2e/test/scenarios/models/models-metadata.cy.spec.js index 12779aef0e3..53d94eb2465 100644 --- a/e2e/test/scenarios/models/models-metadata.cy.spec.js +++ b/e2e/test/scenarios/models/models-metadata.cy.spec.js @@ -152,6 +152,28 @@ describe("scenarios > models metadata", () => { cy.findByText("Pre-tax ($)"); }); + it("should allow setting column relations (metabase#29318)", () => { + cy.createNativeQuestion( + { + name: "Native Model", + dataset: true, + native: { + query: "SELECT * FROM ORDERS", + }, + }, + { visitQuestion: true }, + ); + openQuestionActions(); + cy.findByText("Edit metadata").click(); + openColumnOptions("USER_ID"); + setColumnType("No special type", "Foreign Key"); + cy.findByText("Select a target").click(); + cy.findByText("People → ID").click(); + cy.button("Save changes").click(); + // TODO: Not much to do with it at the moment beyond saving it. + // Check that the relation is automatically suggested in the notebook once it is implemented. + }); + it("should keep metadata in sync with the query", () => { cy.createNativeQuestion( { diff --git a/frontend/src/metabase-types/guards/forms.ts b/frontend/src/metabase-types/guards/forms.ts index e1ea0900b0c..99693221940 100644 --- a/frontend/src/metabase-types/guards/forms.ts +++ b/frontend/src/metabase-types/guards/forms.ts @@ -3,12 +3,13 @@ import type { CustomFormFieldDefinition, FormFieldDefinition, } from "metabase-types/forms"; +import { isReactComponent } from "./react"; export function isCustomWidget( formField: FormFieldDefinition, ): formField is CustomFormFieldDefinition { return ( !(formField as StandardFormFieldDefinition).type && - typeof (formField as CustomFormFieldDefinition).widget === "function" + isReactComponent((formField as CustomFormFieldDefinition).widget) ); } diff --git a/frontend/src/metabase-types/guards/react.ts b/frontend/src/metabase-types/guards/react.ts index 0fa5ae58f48..d31d9170155 100644 --- a/frontend/src/metabase-types/guards/react.ts +++ b/frontend/src/metabase-types/guards/react.ts @@ -8,3 +8,15 @@ export function isReactDOMTypeElement( ): element is React.ReactElement { return ReactIs.isElement(element) && typeof element.type === "string"; } + +export function isReactComponent( + component: any, +): component is React.FC | React.Component | React.ExoticComponent { + return ( + typeof component === "function" || + // Checking for "Exotic" components such as ones returned by memo, forwardRef + (typeof component === "object" && + "$$typeof" in component && + typeof component["$$typeof"] === "symbol") + ); +} -- GitLab