Skip to content
Snippets Groups Projects
Unverified Commit f2970c51 authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Show back button only when there are multiple timelines in a collection (#21516)

parent f4421f22
Branches
Tags
No related merge requests found
Showing
with 58 additions and 11 deletions
......@@ -17,6 +17,7 @@ const propTypes = {
wrapped: PropTypes.bool,
debounced: PropTypes.bool,
loadingAndErrorWrapper: PropTypes.bool,
LoadingAndErrorWrapper: PropTypes.elementType,
keepListWhileLoading: PropTypes.bool,
listName: PropTypes.string,
selectorName: PropTypes.string,
......@@ -41,6 +42,7 @@ const propTypes = {
const defaultProps = {
loadingAndErrorWrapper: true,
LoadingAndErrorWrapper: LoadingAndErrorWrapper,
keepListWhileLoading: false,
reload: false,
wrapped: false,
......@@ -56,6 +58,7 @@ const CONSUMED_PROPS = [
"wrapped",
"debounced",
"loadingAndErrorWrapper",
"LoadingAndErrorWrapper",
"selectorName",
];
......@@ -245,7 +248,12 @@ class EntityListLoader extends React.Component {
};
render() {
const { allFetched, allError, loadingAndErrorWrapper } = this.props;
const {
allFetched,
allError,
loadingAndErrorWrapper,
LoadingAndErrorWrapper,
} = this.props;
const { isReloading } = this.state;
return loadingAndErrorWrapper ? (
......
......@@ -25,7 +25,7 @@ export interface TimelineDetailsModalProps {
timeline: Timeline;
collection: Collection;
isArchive?: boolean;
isDefault?: boolean;
isOnlyTimeline?: boolean;
onArchive?: (event: TimelineEvent) => void;
onUnarchive?: (event: TimelineEvent) => void;
onClose?: () => void;
......@@ -36,7 +36,7 @@ const TimelineDetailsModal = ({
timeline,
collection,
isArchive = false,
isDefault = false,
isOnlyTimeline = false,
onArchive,
onUnarchive,
onClose,
......@@ -55,8 +55,8 @@ const TimelineDetailsModal = ({
}, [timeline, searchText, isArchive]);
const menuItems = useMemo(() => {
return getMenuItems(timeline, collection, isArchive, isDefault);
}, [timeline, collection, isArchive, isDefault]);
return getMenuItems(timeline, collection, isArchive, isOnlyTimeline);
}, [timeline, collection, isArchive, isOnlyTimeline]);
const handleGoBack = useCallback(() => {
onGoBack?.(timeline, collection);
......@@ -65,13 +65,14 @@ const TimelineDetailsModal = ({
const isNotEmpty = events.length > 0;
const isSearching = searchText.length > 0;
const canWrite = timeline.collection?.can_write;
const canGoBack = isArchive || !isOnlyTimeline;
return (
<ModalRoot>
<ModalHeader
title={title}
onClose={onClose}
onGoBack={!isDefault ? handleGoBack : undefined}
onGoBack={canGoBack ? handleGoBack : undefined}
>
{menuItems.length > 0 && (
<EntityMenu items={menuItems} triggerIcon="ellipsis" />
......@@ -139,7 +140,7 @@ const getMenuItems = (
timeline: Timeline,
collection: Collection,
isArchive: boolean,
isDefault: boolean,
isOnlyTimeline: boolean,
) => {
const items: MenuItem[] = [];
......@@ -163,7 +164,7 @@ const getMenuItems = (
});
}
if (isDefault) {
if (isOnlyTimeline) {
items.push({
title: t`View archived timelines`,
link: Urls.timelinesArchiveInCollection(collection),
......
......@@ -19,7 +19,6 @@ const TimelineIndexModal = ({
return (
<TimelineDetailsModal
params={{ ...params, timelineId: timelines[0].id }}
isDefault={true}
onClose={onClose}
/>
);
......
......@@ -27,6 +27,7 @@ const timelineEventProps = {
const collectionProps = {
id: (state: State, props: ModalProps) =>
Urls.extractCollectionId(props.params.slug),
LoadingAndErrorWrapper,
};
const mapDispatchToProps = (dispatch: any) => ({
......
......@@ -20,6 +20,7 @@ const timelineProps = {
const collectionProps = {
id: (state: State, props: ModalProps) =>
Urls.extractCollectionId(props.params.slug),
LoadingAndErrorWrapper,
};
const mapDispatchToProps = (dispatch: any) => ({
......
......@@ -21,6 +21,7 @@ const timelineProps = {
const collectionProps = {
id: (state: State, props: ModalProps) =>
Urls.extractCollectionId(props.params.slug),
LoadingAndErrorWrapper,
};
const mapDispatchToProps = (dispatch: any) => ({
......
......@@ -21,6 +21,7 @@ const timelineProps = {
const collectionProps = {
id: (state: State, props: ModalProps) =>
Urls.extractCollectionId(props.params.slug),
LoadingAndErrorWrapper,
};
const mapStateToProps = () => ({
......
......@@ -9,7 +9,12 @@ import { Collection, Timeline, TimelineEvent } from "metabase-types/api";
import { State } from "metabase-types/store";
import TimelineDetailsModal from "../../components/TimelineDetailsModal";
import LoadingAndErrorWrapper from "../../components/LoadingAndErrorWrapper";
import { ModalProps } from "../../types";
import { ModalParams } from "../../types";
interface ModalProps {
params: ModalParams;
timelines: Timeline[];
}
const timelineProps = {
id: (state: State, props: ModalProps) =>
......@@ -18,6 +23,15 @@ const timelineProps = {
LoadingAndErrorWrapper,
};
const timelinesProps = {
query: { include: "events" },
LoadingAndErrorWrapper,
};
const mapStateToProps = (state: State, { timelines }: ModalProps) => ({
isOnlyTimeline: timelines.length === 1,
});
const collectionProps = {
id: (state: State, props: ModalProps) =>
Urls.extractCollectionId(props.params.slug),
......@@ -34,6 +48,7 @@ const mapDispatchToProps = (dispatch: any) => ({
export default _.compose(
Timelines.load(timelineProps),
Timelines.loadList(timelinesProps),
Collections.load(collectionProps),
connect(null, mapDispatchToProps),
connect(mapStateToProps, mapDispatchToProps),
)(TimelineDetailsModal);
......@@ -233,6 +233,26 @@ describe("scenarios > collections > timelines", () => {
cy.findByText("No events found").should("be.visible");
});
it("should allow navigating back to the list of timelines", () => {
cy.createTimeline({ name: "Releases" });
cy.createTimeline({ name: "Metrics" });
cy.visit(`/collection/root/timelines/1`);
cy.findByText("Releases");
cy.icon("chevronleft").click();
cy.findByText("Releases");
cy.findByText("Metrics");
});
it("should not allow navigating back when there is only one timeline in a collection", () => {
cy.createTimeline({ name: "Releases" });
cy.visit(`/collection/root/timelines/1`);
cy.findByText("Releases");
cy.icon("chevronleft").should("not.exist");
});
it("should create an additional timeline", () => {
cy.createTimelineWithEvents({
timeline: { name: "Releases" },
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment