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 branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,8 @@ import {
resetTestTable,
resyncDatabase,
getTableId,
visitPublicQuestion,
visitPublicDashboard,
} from "e2e/support/helpers";
import { WRITABLE_DB_ID, SAMPLE_DB_ID } from "e2e/support/cypress_data";
......@@ -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 { connect } from "react-redux";
import _ from "underscore";
import { useMount, usePrevious } from "react-use";
import { State } from "metabase-types/store";
......@@ -31,6 +32,7 @@ import {
getCanZoomPreviousRow,
getCanZoomNextRow,
} from "metabase/query_builder/selectors";
import { getUser } from "metabase/selectors/user";
import { isVirtualCardId } from "metabase-lib/metadata/utils/saved-questions";
import { isPK } from "metabase-lib/types/utils/isa";
......@@ -61,6 +63,12 @@ import {
} from "./ObjectDetail.styled";
const mapStateToProps = (state: State, { data }: ObjectDetailProps) => {
const isLoggedIn = !!getUser(state);
if (!isLoggedIn) {
return {};
}
const table = getTableMetadata(state);
let zoomedRowID = getZoomedObjectId(state);
const isZooming = zoomedRowID != null;
......@@ -194,7 +202,9 @@ export function ObjectDetailFn({
const onFollowForeignKey = useCallback(
(fk: ForeignKey) => {
followForeignKey({ objectId: zoomedRowID, fk });
zoomedRowID !== undefined
? followForeignKey({ objectId: zoomedRowID, fk })
: _.noop();
},
[zoomedRowID, followForeignKey],
);
......@@ -250,10 +260,12 @@ export function ObjectDetailFn({
>
{showHeader && (
<ObjectDetailHeader
canZoom={canZoom && (canZoomNextRow || canZoomPreviousRow)}
canZoom={Boolean(
canZoom && (canZoomNextRow || canZoomPreviousRow),
)}
objectName={objectName}
objectId={displayId}
canZoomPreviousRow={canZoomPreviousRow}
canZoomPreviousRow={!!canZoomPreviousRow}
canZoomNextRow={canZoomNextRow}
showActions={showActions}
viewPreviousObjectDetail={viewPreviousObjectDetail}
......@@ -330,6 +342,7 @@ export function ObjectDetailWrapper({
/>
{hasPagination && (
<PaginationFooter
data-testid="pagination-footer"
start={currentObjectIndex}
end={currentObjectIndex}
total={data.rows.length}
......@@ -424,11 +437,11 @@ export interface ObjectDetailBodyProps {
hasRelationships: boolean;
onVisualizationClick: OnVisualizationClickType;
visualizationIsClickable: (clicked: unknown) => boolean;
tableForeignKeys: ForeignKey[];
tableForeignKeyReferences: {
tableForeignKeys?: ForeignKey[];
tableForeignKeyReferences?: {
[key: number]: { status: number; value: number };
};
followForeignKey: (fk: ForeignKey) => void;
followForeignKey?: (fk: ForeignKey) => void;
}
export function ObjectDetailBody({
......@@ -443,6 +456,12 @@ export function ObjectDetailBody({
tableForeignKeyReferences,
followForeignKey,
}: ObjectDetailBodyProps): JSX.Element {
const showRelationships =
hasRelationships &&
tableForeignKeys &&
tableForeignKeyReferences &&
followForeignKey;
return (
<ObjectDetailBodyWrapper>
<DetailsTable
......@@ -452,7 +471,7 @@ export function ObjectDetailBody({
onVisualizationClick={onVisualizationClick}
visualizationIsClickable={visualizationIsClickable}
/>
{hasRelationships && (
{showRelationships && (
<Relationships
objectName={objectName}
tableForeignKeys={tableForeignKeys}
......
......@@ -21,20 +21,20 @@ export type OnVisualizationClickType =
export interface ObjectDetailProps {
data: DatasetData;
question: Question;
question?: Question;
card?: SavedCard;
dashcard?: DashboardOrderedCard;
isObjectDetail?: boolean; // whether this should be shown in a modal
table: Table | null;
zoomedRow: unknown[] | undefined;
zoomedRowID: ObjectId;
tableForeignKeys: ForeignKey[];
tableForeignKeyReferences: {
table?: Table | null;
zoomedRow?: unknown[] | undefined;
zoomedRowID?: ObjectId;
tableForeignKeys?: ForeignKey[];
tableForeignKeyReferences?: {
[key: number]: { status: number; value: number };
};
settings: any;
canZoom: boolean;
canZoomPreviousRow: boolean;
canZoom?: boolean;
canZoomPreviousRow?: boolean;
canZoomNextRow?: boolean;
isDataApp?: boolean;
showActions?: boolean;
......
......@@ -15,8 +15,8 @@ import Table from "metabase-lib/metadata/Table";
import { ObjectId } from "./types";
export interface GetObjectNameArgs {
table: Table | null;
question: Question;
table?: Table | null;
question?: Question;
cols: Column[];
zoomedRow: unknown[] | undefined;
}
......
......@@ -14,6 +14,7 @@ import {
interface TableFooterProps {
className?: string;
"data-testid"?: string;
start: number;
end: number;
total: number;
......@@ -27,6 +28,7 @@ const TableFooter = React.forwardRef<HTMLDivElement, TableFooterProps>(
function TableFooter(
{
className,
"data-testid": dataTestId = "TableFooter",
start,
end,
limit,
......@@ -73,6 +75,7 @@ const TableFooter = React.forwardRef<HTMLDivElement, TableFooterProps>(
className,
"fullscreen-normal-text fullscreen-night-text",
)}
data-testid={dataTestId}
ref={ref}
>
<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