Skip to content
Snippets Groups Projects
Unverified Commit fea1b191 authored by Gustavo Saiani's avatar Gustavo Saiani Committed by GitHub
Browse files

Extract FieldPicker from DataSelector (#25162)

parent 920d1c02
Branches
Tags
No related merge requests found
......@@ -39,6 +39,7 @@ import {
import SavedQuestionPicker from "./saved-question-picker/SavedQuestionPicker";
import DataSelectorLoading from "./DataSelectorLoading";
import DataSelectorSectionHeader from "./DataSelectorSectionHeader";
import FieldPicker from "./DataSelectorFieldPicker";
import {
DataSelectorSection,
DataBucketList,
......@@ -1516,73 +1517,3 @@ const TablePicker = ({
);
}
};
class FieldPicker extends Component {
render() {
const {
isLoading,
fields,
selectedTable,
selectedField,
onChangeField,
onBack,
hasFiltering,
hasInitialFocus,
} = this.props;
const header = (
<span className="flex align-center">
<span
className="flex align-center text-slate cursor-pointer"
onClick={onBack}
>
<Icon name="chevronleft" size={18} />
<span className="ml1 text-wrap">
{selectedTable?.display_name || t`Fields`}
</span>
</span>
</span>
);
if (isLoading) {
return <DataSelectorLoading header={header} />;
}
const sections = [
{
name: header,
items: fields.map(field => ({
name: field.display_name,
field: field,
})),
},
];
return (
<div style={{ width: 300, overflowY: "auto" }}>
<AccordionList
id="FieldPicker"
key="fieldPicker"
className="text-brand"
hasInitialFocus={hasInitialFocus}
sections={sections}
maxHeight={Infinity}
width="100%"
searchable={hasFiltering}
onChange={item => onChangeField(item.field)}
itemIsSelected={item =>
item.field && selectedField
? item.field.id === selectedField.id
: false
}
itemIsClickable={item => item.field}
renderItemIcon={item =>
item.field ? (
<Icon name={item.field.dimension().icon()} size={18} />
) : null
}
/>
</div>
);
}
}
import styled from "@emotion/styled";
import { color } from "metabase/lib/colors";
import { space } from "metabase/styled-components/theme";
export const Container = styled.div`
overflow-y: auto;
width: 300px;
`;
export const HeaderContainer = styled.div`
align-items: center;
color: ${color("text-medium")};
cursor: pointer;
display: flex;
`;
export const HeaderName = styled.span`
margin-left: ${space(1)};
overflow-wrap: anywhere;
word-break: break-word;
word-wrap: anywhere;
`;
import React from "react";
import { t } from "ttag";
import AccordionList from "metabase/core/components/AccordionList";
import Icon from "metabase/components/Icon";
import DataSelectorLoading from "../DataSelectorLoading";
import {
Container,
HeaderContainer,
HeaderName,
} from "./DataSelectorFieldPicker.styled";
import type { Field } from "metabase-types/api/field";
import type { Table } from "metabase-types/api/table";
type DataSelectorFieldPickerProps = {
fields: Field[];
hasFiltering: boolean;
hasInitialFocus: boolean;
isLoading: boolean;
selectedField: Field;
selectedTable: Table;
onBack: () => void;
onChangeField: (field: Field) => void;
};
type HeaderProps = {
onBack: DataSelectorFieldPickerProps["onBack"];
selectedTable: DataSelectorFieldPickerProps["selectedTable"];
};
type FieldWithName = {
name: string;
field: {
id: number;
dimension: () => any;
};
};
const DataSelectorFieldPicker = ({
isLoading,
fields,
selectedTable,
selectedField,
onChangeField,
onBack,
hasFiltering,
hasInitialFocus,
}: DataSelectorFieldPickerProps) => {
const header = <Header onBack={onBack} selectedTable={selectedTable} />;
if (isLoading) {
return <DataSelectorLoading header={header} />;
}
const sections = [
{
name: header,
items: fields.map(field => ({
name: field.display_name,
field: field,
})),
},
];
const checkIfItemIsSelected = (item: FieldWithName) =>
item.field && selectedField && item.field.id === selectedField.id;
const renderItemIcon = (item: FieldWithName) =>
item.field && <Icon name={item.field.dimension().icon()} size={18} />;
return (
<Container>
<AccordionList
id="FieldPicker"
key="fieldPicker"
className="text-brand"
hasInitialFocus={hasInitialFocus}
sections={sections}
maxHeight={Infinity}
width="100%"
searchable={hasFiltering}
onChange={(item: { field: Field }) => onChangeField(item.field)}
itemIsSelected={checkIfItemIsSelected}
itemIsClickable={(item: FieldWithName) => item.field}
renderItemIcon={renderItemIcon}
/>
</Container>
);
};
const Header = ({ onBack, selectedTable }: HeaderProps) => (
<HeaderContainer onClick={onBack}>
<Icon name="chevronleft" size={18} />
<HeaderName>{selectedTable?.display_name || t`Fields`}</HeaderName>
</HeaderContainer>
);
export default DataSelectorFieldPicker;
export { default } from "./DataSelectorFieldPicker";
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment