Skip to content
Snippets Groups Projects
Unverified Commit 3b69bba3 authored by Ryan Laurie's avatar Ryan Laurie Committed by GitHub
Browse files

Make object detail viz work for non-logged-in users (#29333)

* make object detail work for non-logged-in users

* update types to account for optional params

* test public object detail viz
parent 6f86f24e
No related merge requests found
...@@ -8,6 +8,8 @@ import { ...@@ -8,6 +8,8 @@ import {
resetTestTable, resetTestTable,
resyncDatabase, resyncDatabase,
getTableId, getTableId,
visitPublicQuestion,
visitPublicDashboard,
} from "e2e/support/helpers"; } from "e2e/support/helpers";
import { WRITABLE_DB_ID, SAMPLE_DB_ID } from "e2e/support/cypress_data"; import { WRITABLE_DB_ID, SAMPLE_DB_ID } from "e2e/support/cypress_data";
...@@ -325,3 +327,47 @@ function changeSorting(columnName, direction) { ...@@ -325,3 +327,47 @@ function changeSorting(columnName, direction) {
}); });
}); });
}); });
describe(`Object Detail > public`, () => {
beforeEach(() => {
restore();
cy.signInAsAdmin();
});
it('can view a public object detail question', () => {
cy.createQuestion({ ...TEST_QUESTION, display: 'object' }).then(
({ body: { id: questionId } }) => {
visitPublicQuestion(questionId);
},
);
cy.icon('warning').should('not.exist');
cy.findByTestId('object-detail').within(() => {
cy.findByText('User ID').should('be.visible');
cy.findByText('1283').should('be.visible');
});
cy.findByTestId('pagination-footer').within(() => {
cy.findByText("Item 1 of 3").should('be.visible');
});
});
it('can view an object detail question on a public dashboard', () => {
cy.createQuestionAndDashboard({ questionDetails: { ...TEST_QUESTION, display: 'object' } }).then(
({ body: { dashboard_id } }) => {
visitPublicDashboard(dashboard_id);
});
cy.icon('warning').should('not.exist');
cy.findByTestId('object-detail').within(() => {
cy.findByText('User ID').should('be.visible');
cy.findByText('1283').should('be.visible');
});
cy.findByTestId('pagination-footer').within(() => {
cy.findByText("Item 1 of 3").should('be.visible');
});
});
});
import React, { useState, useEffect, useCallback } from "react"; import React, { useState, useEffect, useCallback } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import _ from "underscore";
import { useMount, usePrevious } from "react-use"; import { useMount, usePrevious } from "react-use";
import { State } from "metabase-types/store"; import { State } from "metabase-types/store";
...@@ -31,6 +32,7 @@ import { ...@@ -31,6 +32,7 @@ import {
getCanZoomPreviousRow, getCanZoomPreviousRow,
getCanZoomNextRow, getCanZoomNextRow,
} from "metabase/query_builder/selectors"; } from "metabase/query_builder/selectors";
import { getUser } from "metabase/selectors/user";
import { isVirtualCardId } from "metabase-lib/metadata/utils/saved-questions"; import { isVirtualCardId } from "metabase-lib/metadata/utils/saved-questions";
import { isPK } from "metabase-lib/types/utils/isa"; import { isPK } from "metabase-lib/types/utils/isa";
...@@ -61,6 +63,12 @@ import { ...@@ -61,6 +63,12 @@ import {
} from "./ObjectDetail.styled"; } from "./ObjectDetail.styled";
const mapStateToProps = (state: State, { data }: ObjectDetailProps) => { const mapStateToProps = (state: State, { data }: ObjectDetailProps) => {
const isLoggedIn = !!getUser(state);
if (!isLoggedIn) {
return {};
}
const table = getTableMetadata(state); const table = getTableMetadata(state);
let zoomedRowID = getZoomedObjectId(state); let zoomedRowID = getZoomedObjectId(state);
const isZooming = zoomedRowID != null; const isZooming = zoomedRowID != null;
...@@ -194,7 +202,9 @@ export function ObjectDetailFn({ ...@@ -194,7 +202,9 @@ export function ObjectDetailFn({
const onFollowForeignKey = useCallback( const onFollowForeignKey = useCallback(
(fk: ForeignKey) => { (fk: ForeignKey) => {
followForeignKey({ objectId: zoomedRowID, fk }); zoomedRowID !== undefined
? followForeignKey({ objectId: zoomedRowID, fk })
: _.noop();
}, },
[zoomedRowID, followForeignKey], [zoomedRowID, followForeignKey],
); );
...@@ -250,10 +260,12 @@ export function ObjectDetailFn({ ...@@ -250,10 +260,12 @@ export function ObjectDetailFn({
> >
{showHeader && ( {showHeader && (
<ObjectDetailHeader <ObjectDetailHeader
canZoom={canZoom && (canZoomNextRow || canZoomPreviousRow)} canZoom={Boolean(
canZoom && (canZoomNextRow || canZoomPreviousRow),
)}
objectName={objectName} objectName={objectName}
objectId={displayId} objectId={displayId}
canZoomPreviousRow={canZoomPreviousRow} canZoomPreviousRow={!!canZoomPreviousRow}
canZoomNextRow={canZoomNextRow} canZoomNextRow={canZoomNextRow}
showActions={showActions} showActions={showActions}
viewPreviousObjectDetail={viewPreviousObjectDetail} viewPreviousObjectDetail={viewPreviousObjectDetail}
...@@ -330,6 +342,7 @@ export function ObjectDetailWrapper({ ...@@ -330,6 +342,7 @@ export function ObjectDetailWrapper({
/> />
{hasPagination && ( {hasPagination && (
<PaginationFooter <PaginationFooter
data-testid="pagination-footer"
start={currentObjectIndex} start={currentObjectIndex}
end={currentObjectIndex} end={currentObjectIndex}
total={data.rows.length} total={data.rows.length}
...@@ -424,11 +437,11 @@ export interface ObjectDetailBodyProps { ...@@ -424,11 +437,11 @@ export interface ObjectDetailBodyProps {
hasRelationships: boolean; hasRelationships: boolean;
onVisualizationClick: OnVisualizationClickType; onVisualizationClick: OnVisualizationClickType;
visualizationIsClickable: (clicked: unknown) => boolean; visualizationIsClickable: (clicked: unknown) => boolean;
tableForeignKeys: ForeignKey[]; tableForeignKeys?: ForeignKey[];
tableForeignKeyReferences: { tableForeignKeyReferences?: {
[key: number]: { status: number; value: number }; [key: number]: { status: number; value: number };
}; };
followForeignKey: (fk: ForeignKey) => void; followForeignKey?: (fk: ForeignKey) => void;
} }
export function ObjectDetailBody({ export function ObjectDetailBody({
...@@ -443,6 +456,12 @@ export function ObjectDetailBody({ ...@@ -443,6 +456,12 @@ export function ObjectDetailBody({
tableForeignKeyReferences, tableForeignKeyReferences,
followForeignKey, followForeignKey,
}: ObjectDetailBodyProps): JSX.Element { }: ObjectDetailBodyProps): JSX.Element {
const showRelationships =
hasRelationships &&
tableForeignKeys &&
tableForeignKeyReferences &&
followForeignKey;
return ( return (
<ObjectDetailBodyWrapper> <ObjectDetailBodyWrapper>
<DetailsTable <DetailsTable
...@@ -452,7 +471,7 @@ export function ObjectDetailBody({ ...@@ -452,7 +471,7 @@ export function ObjectDetailBody({
onVisualizationClick={onVisualizationClick} onVisualizationClick={onVisualizationClick}
visualizationIsClickable={visualizationIsClickable} visualizationIsClickable={visualizationIsClickable}
/> />
{hasRelationships && ( {showRelationships && (
<Relationships <Relationships
objectName={objectName} objectName={objectName}
tableForeignKeys={tableForeignKeys} tableForeignKeys={tableForeignKeys}
......
...@@ -21,20 +21,20 @@ export type OnVisualizationClickType = ...@@ -21,20 +21,20 @@ export type OnVisualizationClickType =
export interface ObjectDetailProps { export interface ObjectDetailProps {
data: DatasetData; data: DatasetData;
question: Question; question?: Question;
card?: SavedCard; card?: SavedCard;
dashcard?: DashboardOrderedCard; dashcard?: DashboardOrderedCard;
isObjectDetail?: boolean; // whether this should be shown in a modal isObjectDetail?: boolean; // whether this should be shown in a modal
table: Table | null; table?: Table | null;
zoomedRow: unknown[] | undefined; zoomedRow?: unknown[] | undefined;
zoomedRowID: ObjectId; zoomedRowID?: ObjectId;
tableForeignKeys: ForeignKey[]; tableForeignKeys?: ForeignKey[];
tableForeignKeyReferences: { tableForeignKeyReferences?: {
[key: number]: { status: number; value: number }; [key: number]: { status: number; value: number };
}; };
settings: any; settings: any;
canZoom: boolean; canZoom?: boolean;
canZoomPreviousRow: boolean; canZoomPreviousRow?: boolean;
canZoomNextRow?: boolean; canZoomNextRow?: boolean;
isDataApp?: boolean; isDataApp?: boolean;
showActions?: boolean; showActions?: boolean;
......
...@@ -15,8 +15,8 @@ import Table from "metabase-lib/metadata/Table"; ...@@ -15,8 +15,8 @@ import Table from "metabase-lib/metadata/Table";
import { ObjectId } from "./types"; import { ObjectId } from "./types";
export interface GetObjectNameArgs { export interface GetObjectNameArgs {
table: Table | null; table?: Table | null;
question: Question; question?: Question;
cols: Column[]; cols: Column[];
zoomedRow: unknown[] | undefined; zoomedRow: unknown[] | undefined;
} }
......
...@@ -14,6 +14,7 @@ import { ...@@ -14,6 +14,7 @@ import {
interface TableFooterProps { interface TableFooterProps {
className?: string; className?: string;
"data-testid"?: string;
start: number; start: number;
end: number; end: number;
total: number; total: number;
...@@ -27,6 +28,7 @@ const TableFooter = React.forwardRef<HTMLDivElement, TableFooterProps>( ...@@ -27,6 +28,7 @@ const TableFooter = React.forwardRef<HTMLDivElement, TableFooterProps>(
function TableFooter( function TableFooter(
{ {
className, className,
"data-testid": dataTestId = "TableFooter",
start, start,
end, end,
limit, limit,
...@@ -73,6 +75,7 @@ const TableFooter = React.forwardRef<HTMLDivElement, TableFooterProps>( ...@@ -73,6 +75,7 @@ const TableFooter = React.forwardRef<HTMLDivElement, TableFooterProps>(
className, className,
"fullscreen-normal-text fullscreen-night-text", "fullscreen-normal-text fullscreen-night-text",
)} )}
data-testid={dataTestId}
ref={ref} ref={ref}
> >
<PaginationMessage>{paginateMessage}</PaginationMessage> <PaginationMessage>{paginateMessage}</PaginationMessage>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment