Skip to content
Snippets Groups Projects
Commit 64d40f28 authored by Anton Kulyk's avatar Anton Kulyk
Browse files

Extract `ClickBehaviorSidebar` components (#25088)

* Extract straightforward styled components

* Extract `SidebarItem` bits

* Remove not used props

* Sort imports

* Extract `ValuesYouCanReference` component

* Extract `CustomLinkText` component

* Extract `LinkOption` component

* Extract `Column` component

* Extract utils

* Extract `TypeSelector` component

* Extract `ActionOptions` component

* Extract `QuestionDashboardPicker` component

* Extract `CrossfilterOptions` component

* Extract `LinkOptions` component

* Extract `TableClickBehaviorView` component

* Extract `ClickBehaviorSidebarHeader` component

* Extract `ClickBehaviorSidebarMainView` component

* Fix `this` references in functional components
parent 9c152124
Branches
Tags
No related merge requests found
Showing
with 1014 additions and 792 deletions
/* eslint-disable react/prop-types */
import React from "react";
import { t } from "ttag";
import _ from "underscore";
import Icon from "metabase/components/Icon";
import { color } from "metabase/lib/colors";
import Actions from "metabase/entities/actions";
import ClickMappings from "metabase/dashboard/components/ClickMappings";
import { SidebarItemWrapper, SidebarItemStyle } from "./SidebarItem";
import {
Heading,
SidebarContent,
SidebarIconWrapper,
} from "./ClickBehaviorSidebar.styled";
const ActionOption = ({ name, description, isSelected, onClick }) => {
return (
<SidebarItemWrapper
onClick={onClick}
style={{
...SidebarItemStyle,
backgroundColor: isSelected ? color("brand") : "transparent",
color: isSelected ? color("white") : "inherit",
alignItems: description ? "flex-start" : "center",
marginTop: "2px",
}}
>
<SidebarIconWrapper>
<Icon
name="bolt"
color={isSelected ? color("text-white") : color("brand")}
/>
</SidebarIconWrapper>
<div>
<h4>{name}</h4>
{description && (
<span
className={isSelected ? "text-white" : "text-medium"}
style={{ width: "95%", marginTop: "2px" }}
>
{description}
</span>
)}
</div>
</SidebarItemWrapper>
);
};
function ActionOptions({ dashcard, clickBehavior, updateSettings }) {
return (
<SidebarContent>
<Heading className="text-medium">{t`Pick an action`}</Heading>
<Actions.ListLoader>
{({ actions }) => {
const selectedAction = actions.find(
action => action.id === clickBehavior.action,
);
return (
<>
{actions.map(action => (
<ActionOption
key={action.id}
name={action.name}
description={action.description}
isSelected={clickBehavior.action === action.id}
onClick={() =>
updateSettings({
type: clickBehavior.type,
action: action.id,
emitter_id: clickBehavior.emitter_id,
})
}
/>
))}
{selectedAction && (
<ClickMappings
isAction
object={selectedAction}
dashcard={dashcard}
clickBehavior={clickBehavior}
updateSettings={updateSettings}
/>
)}
</>
);
}}
</Actions.ListLoader>
</SidebarContent>
);
}
export default ActionOptions;
import styled from "@emotion/styled";
import { darken } from "metabase/lib/colors";
import { color, darken } from "metabase/lib/colors";
export const SidebarItem = styled.div`
display: flex;
......@@ -12,3 +12,41 @@ export const CloseIconContainer = styled.span`
padding: 1rem;
border-left: 1px solid ${darken("brand", 0.2)};
`;
export const Heading = styled.h4`
color: ${color("text-dark")};
padding-top: 22px;
padding-bottom: 16px;
margin-bottom: 8px;
`;
export const SidebarContent = styled.div`
padding-left: 32px;
padding-right: 32px;
`;
export const SidebarContentBordered = styled(SidebarContent)`
padding-bottom: 2rem;
border-bottom: 1px solid ${color("border")};
`;
export const SidebarHeader = styled.div`
border-bottom: 1px solid ${color("border")};
padding-left: 32px;
padding-right: 36px;
margin-bottom: 16px;
`;
export const SidebarIconWrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
width: 36px;
height: 36px;
margin-right: 10px;
border: 1px solid #f2f2f2;
border-radius: 8px;
`;
/* eslint-disable react/prop-types */
import React from "react";
import { jt } from "ttag";
import Icon from "metabase/components/Icon";
import { Heading, SidebarHeader } from "./ClickBehaviorSidebar.styled";
function ClickBehaviorSidebarHeader({
dashcard,
selectedColumn,
hasSelectedColumn,
onUnsetColumn,
}) {
return (
<SidebarHeader>
{!hasSelectedColumn ? (
<Heading>{jt`Click behavior for ${(
<span className="text-brand">{dashcard.card.name}</span>
)}`}</Heading>
) : (
<div
onClick={onUnsetColumn}
className="flex align-center text-brand-hover cursor-pointer"
>
<div
className="bordered"
style={{
marginRight: 8,
paddingTop: 4,
paddingBottom: 4,
paddingRight: 6,
paddingLeft: 6,
borderRadius: 4,
}}
>
<Icon name="chevronleft" className="text-medium" size={12} />
</div>
<Heading>
{jt`Click behavior for ${(
<span className="text-brand">{selectedColumn.display_name}</span>
)}`}
</Heading>
</div>
)}
</SidebarHeader>
);
}
export default ClickBehaviorSidebarHeader;
/* eslint-disable react/prop-types */
import React from "react";
import Icon from "metabase/components/Icon";
import { color } from "metabase/lib/colors";
import { clickBehaviorOptions, getClickBehaviorOptionName } from "./utils";
import ActionOptions from "./ActionOptions";
import CrossfilterOptions from "./CrossfilterOptions";
import LinkOptions from "./LinkOptions";
import { SidebarItemWrapper } from "./SidebarItem";
import {
CloseIconContainer,
SidebarContentBordered,
SidebarIconWrapper,
} from "./ClickBehaviorSidebar.styled";
function ClickBehaviorSidebarMainView({
clickBehavior,
dashboard,
dashcard,
parameters,
handleShowTypeSelector,
updateSettings,
}) {
return (
<div>
<SidebarContentBordered>
<SidebarItemWrapper
onClick={handleShowTypeSelector}
style={{
backgroundColor: color("brand"),
color: color("white"),
}}
>
<SidebarIconWrapper
style={{ borderColor: "transparent", paddingLeft: 12 }}
>
<Icon
name={
clickBehaviorOptions.find(o => o.value === clickBehavior.type)
.icon
}
/>
</SidebarIconWrapper>
<div className="flex align-center full">
<h4>{getClickBehaviorOptionName(clickBehavior.type, dashcard)}</h4>
<CloseIconContainer>
<Icon name="close" size={12} />
</CloseIconContainer>
</div>
</SidebarItemWrapper>
</SidebarContentBordered>
{clickBehavior.type === "link" ? (
<LinkOptions
clickBehavior={clickBehavior}
dashcard={dashcard}
parameters={parameters}
updateSettings={updateSettings}
/>
) : clickBehavior.type === "crossfilter" ? (
<CrossfilterOptions
clickBehavior={clickBehavior}
dashboard={dashboard}
dashcard={dashcard}
updateSettings={updateSettings}
/>
) : clickBehavior.type === "action" ? (
<ActionOptions
clickBehavior={clickBehavior}
dashcard={dashcard}
parameters={parameters}
updateSettings={updateSettings}
/>
) : null}
</div>
);
}
export default ClickBehaviorSidebarMainView;
/* eslint-disable react/prop-types */
import React from "react";
import { t, jt, ngettext, msgid } from "ttag";
import _ from "underscore";
import Icon from "metabase/components/Icon";
import { color } from "metabase/lib/colors";
import { getIconForField } from "metabase/lib/schema_metadata";
import Dashboards from "metabase/entities/dashboards";
import Questions from "metabase/entities/questions";
import { SidebarItemWrapper, SidebarItemStyle } from "./SidebarItem";
import { SidebarIconWrapper } from "./ClickBehaviorSidebar.styled";
const LinkTargetName = ({ clickBehavior: { linkType, targetId } }) => (
<span>
{linkType === "url" ? (
t`URL`
) : linkType === "question" ? (
<span>
{'"'}
<Questions.Name id={targetId} />
{'"'}
</span>
) : linkType === "dashboard" ? (
<span>
{'"'}
<Dashboards.Name id={targetId} />
{'"'}
</span>
) : (
"Unknown"
)}
</span>
);
const Column = ({ column, clickBehavior, onClick }) => (
<SidebarItemWrapper onClick={onClick} style={{ ...SidebarItemStyle }}>
<SidebarIconWrapper>
<Icon name={getIconForField(column)} color={color("brand")} size={18} />
</SidebarIconWrapper>
<div>
<h4>
{clickBehavior && clickBehavior.type === "crossfilter"
? (n =>
ngettext(
msgid`${column.display_name} updates ${n} filter`,
`${column.display_name} updates ${n} filters`,
n,
))(Object.keys(clickBehavior.parameterMapping || {}).length)
: clickBehavior && clickBehavior.type === "link"
? jt`${column.display_name} goes to ${(
<LinkTargetName clickBehavior={clickBehavior} />
)}`
: column.display_name}
</h4>
</div>
</SidebarItemWrapper>
);
export default Column;
/* eslint-disable react/prop-types */
import React from "react";
import { t } from "ttag";
import ClickMappings from "metabase/dashboard/components/ClickMappings";
import { Heading, SidebarContent } from "./ClickBehaviorSidebar.styled";
function CrossfilterOptions({
clickBehavior,
dashboard,
dashcard,
updateSettings,
}) {
return (
<SidebarContent>
<Heading className="text-medium">{t`Pick one or more filters to update`}</Heading>
<ClickMappings
object={dashboard}
dashcard={dashcard}
isDash
clickBehavior={clickBehavior}
updateSettings={updateSettings}
excludeParametersSources
/>
</SidebarContent>
);
}
export default CrossfilterOptions;
/* eslint-disable react/prop-types */
import React from "react";
import { t } from "ttag";
import _ from "underscore";
import InputBlurChange from "metabase/components/InputBlurChange";
import { Heading } from "./ClickBehaviorSidebar.styled";
const CustomLinkText = ({ clickBehavior, updateSettings }) => {
return (
<div className="mt2 mb1">
<Heading>{t`Customize link text (optional)`}</Heading>
<InputBlurChange
className="input block full"
placeholder={t`E.x. Details for {{Column Name}}`}
value={clickBehavior.linkTextTemplate}
onBlurChange={e =>
updateSettings({
...clickBehavior,
linkTextTemplate: e.target.value,
})
}
/>
</div>
);
};
export default CustomLinkText;
/* eslint-disable react/prop-types */
import React from "react";
import _ from "underscore";
import Icon from "metabase/components/Icon";
import { color } from "metabase/lib/colors";
import { SidebarItemWrapper, SidebarItemStyle } from "./SidebarItem";
import { SidebarIconWrapper } from "./ClickBehaviorSidebar.styled";
const LinkOption = ({ option, icon, onClick }) => (
<SidebarItemWrapper onClick={onClick} style={{ ...SidebarItemStyle }}>
<SidebarIconWrapper>
<Icon name={icon} color={color("brand")} />
</SidebarIconWrapper>
<div>
<h4>{option}</h4>
</div>
</SidebarItemWrapper>
);
export default LinkOption;
/* eslint-disable react/prop-types */
import React from "react";
import { t } from "ttag";
import _ from "underscore";
import Button from "metabase/core/components/Button";
import Icon from "metabase/components/Icon";
import InputBlurChange from "metabase/components/InputBlurChange";
import ModalContent from "metabase/components/ModalContent";
import ModalWithTrigger from "metabase/components/ModalWithTrigger";
import { color } from "metabase/lib/colors";
import {
isTableDisplay,
clickBehaviorIsValid,
} from "metabase/lib/click-behavior";
import CustomLinkText from "./CustomLinkText";
import LinkOption from "./LinkOption";
import ValuesYouCanReference from "./ValuesYouCanReference";
import QuestionDashboardPicker from "./QuestionDashboardPicker";
import { SidebarItemWrapper } from "./SidebarItem";
import {
CloseIconContainer,
SidebarContent,
SidebarIconWrapper,
} from "./ClickBehaviorSidebar.styled";
function LinkOptions({ clickBehavior, updateSettings, dashcard, parameters }) {
const linkTypeOptions = [
{ type: "dashboard", icon: "dashboard", name: t`Dashboard` },
{ type: "question", icon: "bar", name: t`Saved question` },
{ type: "url", icon: "link", name: t`URL` },
];
return (
<SidebarContent>
<p className="text-medium mt3 mb1">{t`Link to`}</p>
<div>
{clickBehavior.linkType == null ? (
linkTypeOptions.map(({ type, icon, name }, index) => (
<LinkOption
key={name}
option={name}
icon={icon}
onClick={() =>
updateSettings({ type: clickBehavior.type, linkType: type })
}
/>
))
) : clickBehavior.linkType === "url" ? (
<ModalWithTrigger
isInitiallyOpen={clickBehavior.linkTemplate == null}
triggerElement={
<SidebarItemWrapper
style={{
backgroundColor: color("brand"),
color: color("white"),
}}
>
<SidebarIconWrapper
style={{ borderColor: "transparent", marginLeft: 8 }}
>
<Icon name="link" />
</SidebarIconWrapper>
<div className="flex align-center full">
<h4 className="pr1">
{clickBehavior.linkTemplate
? clickBehavior.linkTemplate
: t`URL`}
</h4>
<CloseIconContainer
onClick={() =>
updateSettings({
type: clickBehavior.type,
linkType: null,
})
}
>
<Icon name="close" size={12} />
</CloseIconContainer>
</div>
</SidebarItemWrapper>
}
>
{({ onClose }) => (
<ModalContent
title={t`Enter a URL to link to`}
onClose={clickBehavior.targetId != null ? onClose : null}
>
<div className="mb1">{t`You can insert the value of a column or dashboard filter using its name, like this: {{some_column}}`}</div>
<InputBlurChange
autoFocus
className="input block full"
placeholder={t`e.g. http://acme.com/id/\{\{user_id\}\}`}
value={clickBehavior.linkTemplate}
onChange={e =>
updateSettings({
...clickBehavior,
linkTemplate: e.target.value,
})
}
/>
{isTableDisplay(dashcard) && (
<CustomLinkText
updateSettings={updateSettings}
clickBehavior={clickBehavior}
/>
)}
<ValuesYouCanReference
dashcard={dashcard}
parameters={parameters}
/>
<div className="flex">
<Button
primary
onClick={() => onClose()}
className="ml-auto mt2"
disabled={!clickBehaviorIsValid(clickBehavior)}
>{t`Done`}</Button>
</div>
</ModalContent>
)}
</ModalWithTrigger>
) : (
<div></div>
)}
</div>
<div className="mt1">
{clickBehavior.linkType != null && clickBehavior.linkType !== "url" && (
<div>
<QuestionDashboardPicker
dashcard={dashcard}
clickBehavior={clickBehavior}
updateSettings={updateSettings}
/>
{isTableDisplay(dashcard) && (
<div>
<CustomLinkText
updateSettings={updateSettings}
clickBehavior={clickBehavior}
/>
<ValuesYouCanReference
dashcard={dashcard}
parameters={parameters}
/>
</div>
)}
</div>
)}
</div>
</SidebarContent>
);
}
export default LinkOptions;
/* eslint-disable react/prop-types */
import React from "react";
import { t } from "ttag";
import _ from "underscore";
import cx from "classnames";
import Icon from "metabase/components/Icon";
import ModalContent from "metabase/components/ModalContent";
import ModalWithTrigger from "metabase/components/ModalWithTrigger";
import { color } from "metabase/lib/colors";
import Dashboards from "metabase/entities/dashboards";
import Questions from "metabase/entities/questions";
import DashboardPicker from "metabase/containers/DashboardPicker";
import QuestionPicker from "metabase/containers/QuestionPicker";
import ClickMappings, {
clickTargetObjectType,
} from "metabase/dashboard/components/ClickMappings";
import { SidebarItemClasses, SidebarItemStyle } from "./SidebarItem";
import {
CloseIconContainer,
Heading,
SidebarIconWrapper,
SidebarItem,
} from "./ClickBehaviorSidebar.styled";
function QuestionDashboardPicker({ dashcard, clickBehavior, updateSettings }) {
const isDash = clickBehavior.linkType === "dashboard";
const Entity = isDash ? Dashboards : Questions;
const Picker = isDash ? DashboardPicker : QuestionPicker;
return (
<div>
<div className="pb1">
<ModalWithTrigger
triggerElement={
<div
className={cx(SidebarItemClasses, "overflow-hidden")}
style={{
marginLeft: SidebarItemStyle.marginLeft,
marginRight: SidebarItemStyle.marginRight,
backgroundColor: color("brand"),
color: color("white"),
}}
>
<SidebarItem
style={{
paddingLeft: SidebarItemStyle.paddingLeft,
paddingRight: SidebarItemStyle.paddingRight,
paddingTop: SidebarItemStyle.paddingTop,
paddingBottom: SidebarItemStyle.paddingBottom,
}}
>
<SidebarIconWrapper style={{ borderColor: "transparent" }}>
<Icon name={isDash ? "dashboard" : "bar"} />
</SidebarIconWrapper>
<div className="flex align-center full text-bold">
{clickBehavior.targetId == null ? (
isDash ? (
t`Pick a dashboard...`
) : (
t`Pick a question...`
)
) : (
<Entity.Name id={clickBehavior.targetId} />
)}
<Icon name="chevrondown" size={12} className="ml-auto" />
</div>
</SidebarItem>
<CloseIconContainer
onClick={() =>
updateSettings({
type: clickBehavior.type,
linkType: null,
})
}
>
<Icon name="close" size={12} />
</CloseIconContainer>
</div>
}
isInitiallyOpen={clickBehavior.targetId == null}
>
{({ onClose }) => (
<ModalContent
title={
isDash
? t`Pick a dashboard to link to`
: t`Pick a question to link to`
}
onClose={clickBehavior.targetId != null ? onClose : null}
>
<Picker
value={clickBehavior.targetId}
onChange={targetId => {
updateSettings({
...clickBehavior,
...(targetId !== clickBehavior.targetId
? { parameterMapping: {} }
: {}),
targetId,
});
onClose();
}}
/>
</ModalContent>
)}
</ModalWithTrigger>
</div>
{clickBehavior.targetId != null && (
<Entity.Loader id={clickBehavior.targetId}>
{({ object }) => (
<div className="pt1">
<Heading>
{
{
dashboard: t`Pass values to this dashboard's filters (optional)`,
native: t`Pass values to this question's variables (optional)`,
gui: t`Pass values to filter this question (optional)`,
}[clickTargetObjectType(object)]
}
</Heading>
<ClickMappings
object={object}
dashcard={dashcard}
isDash={isDash}
clickBehavior={clickBehavior}
updateSettings={updateSettings}
/>
</div>
)}
</Entity.Loader>
)}
</div>
);
}
export default QuestionDashboardPicker;
/* eslint-disable react/prop-types */
import React from "react";
import cx from "classnames";
export const SidebarItemClasses =
"border-brand-hover bordered border-transparent rounded flex align-center cursor-pointer overflow-hidden";
export const SidebarItemStyle = {
paddingTop: 8,
paddingBottom: 8,
paddingLeft: 12,
paddingRight: 12,
};
export const SidebarItemWrapper = ({ children, onClick, style, disabled }) => (
<div
className={cx(SidebarItemClasses, { disabled })}
onClick={!disabled && onClick}
style={{
...style,
}}
>
{children}
</div>
);
/* eslint-disable react/prop-types */
import React from "react";
import { t } from "ttag";
import _ from "underscore";
import { hasActionsMenu } from "metabase/lib/click-behavior";
import Sidebar from "metabase/dashboard/components/Sidebar";
import Column from "./Column";
import { Heading, SidebarHeader } from "./ClickBehaviorSidebar.styled";
function TableClickBehaviorView({
columns,
dashcard,
getClickBehaviorForColumn,
canClose,
onColumnClick,
onCancel,
onClose,
}) {
return (
<Sidebar onClose={onClose} onCancel={onCancel} closeIsDisabled={!canClose}>
<SidebarHeader>
<Heading className="text-paragraph">{t`On-click behavior for each column`}</Heading>
</SidebarHeader>
<div>
{_.chain(columns)
.map(column => ({
column,
clickBehavior: getClickBehaviorForColumn(column),
}))
.groupBy(({ clickBehavior }) => {
const { type = "actionMenu" } = clickBehavior || {};
return type;
})
.pairs()
.sortBy(([linkType]) =>
["link", "crossfilter", "actionMenu"].indexOf(linkType),
)
.map(([linkType, columnsWithClickBehavior]) => (
<div key={linkType} className="mb2 px4">
<h5 className="text-uppercase text-medium my1">
{
{
link: t`Go to custom destination`,
crossfilter: t`Update a dashboard filter`,
actionMenu: hasActionsMenu(dashcard)
? t`Open the actions menu`
: t`Do nothing`,
}[linkType]
}
</h5>
{columnsWithClickBehavior.map(
({ column, clickBehavior }, index) => (
<Column
key={index}
column={column}
clickBehavior={clickBehavior}
onClick={() => onColumnClick(column)}
/>
),
)}
</div>
))
.value()}
</div>
</Sidebar>
);
}
export default TableClickBehaviorView;
/* eslint-disable react/prop-types */
import React from "react";
import _ from "underscore";
import Icon from "metabase/components/Icon";
import { color } from "metabase/lib/colors";
import { clickBehaviorOptions, getClickBehaviorOptionName } from "./utils";
import { SidebarItemWrapper, SidebarItemStyle } from "./SidebarItem";
import { SidebarIconWrapper } from "./ClickBehaviorSidebar.styled";
const BehaviorOption = ({
option,
icon,
onClick,
hasNextStep,
selected,
disabled,
}) => (
<SidebarItemWrapper
style={{
...SidebarItemStyle,
backgroundColor: selected ? color("brand") : "transparent",
color: selected ? color("white") : "inherit",
}}
onClick={onClick}
disabled={disabled}
>
<SidebarIconWrapper style={{ borderColor: selected && "transparent" }}>
<Icon
name={selected ? "check" : icon}
color={selected ? color("white") : color("brand")}
/>
</SidebarIconWrapper>
<div className="flex align-center full">
<h4>{option}</h4>
{hasNextStep && (
<span className="ml-auto">
<Icon name="chevronright" size={12} />
</span>
)}
</div>
</SidebarItemWrapper>
);
function TypeSelector({
updateSettings,
clickBehavior,
dashcard,
parameters,
moveToNextPage,
}) {
return (
<div>
{clickBehaviorOptions.map(({ value, icon }) => (
<div key={value} className="mb1">
<BehaviorOption
onClick={() => {
if (value !== clickBehavior.type) {
updateSettings(value === "menu" ? undefined : { type: value });
} else if (value !== "menu") {
moveToNextPage(); // if it didn't change, we need to advance here rather than in `componentDidUpdate`
}
}}
icon={icon}
option={getClickBehaviorOptionName(value, dashcard)}
hasNextStep={value !== "menu"}
selected={clickBehavior.type === value}
disabled={value === "crossfilter" && parameters.length === 0}
/>
</div>
))}
</div>
);
}
export default TypeSelector;
/* eslint-disable react/prop-types */
import React from "react";
import { t } from "ttag";
import _ from "underscore";
import AccordionList from "metabase/core/components/AccordionList";
import Icon from "metabase/components/Icon";
import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
import {
withUserAttributes,
isMappableColumn,
} from "metabase/dashboard/components/ClickMappings";
function prefixIfNeeded(values, prefix, otherLists) {
const otherValues = otherLists.flat().map(s => s.toLowerCase());
return values.map(value =>
otherValues.includes(value.toLowerCase()) ? `${prefix}:${value}` : value,
);
}
const ValuesYouCanReference = withUserAttributes(
({ dashcard, parameters, userAttributes }) => {
const columnMetadata = dashcard.card.result_metadata || [];
const columns = columnMetadata?.filter(isMappableColumn).map(c => c.name);
const parameterNames = parameters.map(p => p.name);
const sections = [
{
items: prefixIfNeeded(columns, "column", [
parameterNames,
userAttributes,
]),
name: t`Columns`,
},
{
items: prefixIfNeeded(parameterNames, "filter", [
columns,
userAttributes,
]),
name: t`Dashboard filters`,
},
{
items: prefixIfNeeded(userAttributes, "user", [
parameterNames,
columns,
]),
name: t`User attributes`,
},
].filter(section => section.items.length > 0);
return (
<PopoverWithTrigger
triggerElement={
<div className="flex align-center cursor-pointer my2 text-medium text-brand-hover">
<h4>{t`Values you can reference`}</h4>
<Icon name="chevrondown" className="ml1" size={12} />
</div>
}
>
<AccordionList
alwaysExpanded
sections={sections}
renderItemName={name => name}
itemIsClickable={() => false}
/>
</PopoverWithTrigger>
);
},
);
export default ValuesYouCanReference;
import { t } from "ttag";
import { hasActionsMenu } from "metabase/lib/click-behavior";
export const clickBehaviorOptions = [
{ value: "menu", icon: "popover" },
{ value: "link", icon: "link" },
{ value: "crossfilter", icon: "filter" },
{ value: "action", icon: "play" },
];
export function getClickBehaviorOptionName(value, dashcard) {
if (value === "menu") {
return hasActionsMenu(dashcard)
? t`Open the Metabase actions menu`
: t`Do nothing`;
}
if (value === "link") {
return t`Go to a custom destination`;
}
if (value === "crossfilter") {
return t`Update a dashboard filter`;
}
if (value === "action") {
return t`Perform action`;
}
return t`Unknown`;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment