Skip to content

Commit

Permalink
Move BrowseModelsBody into a separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
rafpaf committed May 3, 2024
1 parent 5cf68d9 commit 8330add
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 115 deletions.
121 changes: 6 additions & 115 deletions frontend/src/metabase/browse/components/BrowseModels.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
import { useEffect, useMemo, useState } from "react";
import { useEffect, useState } from "react";
import { t } from "ttag";
import _ from "underscore";

import NoResults from "assets/img/no_results.svg";
import { useSearchQuery } from "metabase/api";
import type { SortingOptions } from "metabase/components/ItemsTable/BaseItemsTable";
import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
import Search from "metabase/entities/search";
import { color } from "metabase/lib/colors";
import { useDispatch } from "metabase/lib/redux";
import { PLUGIN_CONTENT_VERIFICATION } from "metabase/plugins";
import { Box, Flex, Group, Icon, Stack, Title } from "metabase/ui";
import type {
CollectionEssentials,
type SearchRequest,
} from "metabase-types/api";
import { SortDirection } from "metabase-types/api";
import { Flex, Group, Icon, Title } from "metabase/ui";

import { filterModels, type ActualModelFilters } from "../utils";
import type { ActualModelFilters } from "../utils";

import {
BrowseContainer,
BrowseHeader,
BrowseMain,
BrowseSection,
CenteredEmptyState,
BrowseSection
} from "./BrowseApp.styled";
import { ModelExplanationBanner } from "./ModelExplanationBanner";
import { ModelsTable } from "./ModelsTable";
import { getCollectionPathString } from "./utils";
import { BrowseModelsBody } from "./BrowseModelsBody";

const { availableModelFilters, useModelFilterSettings } =
PLUGIN_CONTENT_VERIFICATION;
const { useModelFilterSettings } = PLUGIN_CONTENT_VERIFICATION;

export const BrowseModels = () => {
const initialModelFilters = useModelFilterSettings();
Expand Down Expand Up @@ -69,96 +53,3 @@ export const BrowseModels = () => {
</BrowseContainer>
);
};

export const BrowseModelsBody = ({
actualModelFilters,
}: {
actualModelFilters: ActualModelFilters;
}) => {
const dispatch = useDispatch();
const [sortingOptions, setSortingOptions] = useState<SortingOptions>({
sort_column: "name",
sort_direction: SortDirection.Asc,
});

const query: SearchRequest = {
models: ["dataset"], // 'model' in the sense of 'type of thing'
model_ancestors: true,
filter_items_in_personal_collection: "exclude",
};

const { data, error, isLoading } = useSearchQuery(query);
const unfilteredModels = useMemo(() => data?.data, [data]);

const filteredModels = useMemo(
() =>
filterModels(
unfilteredModels || [],
actualModelFilters,
availableModelFilters,
),
[unfilteredModels, actualModelFilters],
);

const sortedModels = useMemo(() => {
const { sort_column, sort_direction } = sortingOptions;
const sorted = _.sortBy(filteredModels, model => {
if (sort_column === "collection") {
const collection: CollectionEssentials = model.collection;
return getCollectionPathString(collection);
}
if (sort_column in model) {
return model[sort_column as keyof typeof model];
} else {
console.error("Invalid sort column", sort_column);
return null;
}
});
if (sort_direction === SortDirection.Desc) {
sorted.reverse();
}
return sorted;
}, [filteredModels, sortingOptions]);

const wrappedModels = useMemo(
() => sortedModels.map(model => Search.wrapEntity(model, dispatch)),
[sortedModels, dispatch],
);

if (error || isLoading) {
return (
<LoadingAndErrorWrapper
error={error}
loading={isLoading}
style={{ display: "flex", flex: 1 }}
/>
);
}

if (filteredModels.length) {
return (
<Stack spacing="md" mb="lg">
<ModelExplanationBanner />
<ModelsTable
items={wrappedModels}
sortingOptions={sortingOptions}
onSortingOptionsChange={setSortingOptions}
/>
</Stack>
);
}

return (
<CenteredEmptyState
title={<Box mb=".5rem">{t`No models here yet`}</Box>}
message={
<Box maw="24rem">{t`Models help curate data to make it easier to find answers to questions all in one place.`}</Box>
}
illustrationElement={
<Box mb=".5rem">
<img src={NoResults} />
</Box>
}
/>
);
};
116 changes: 116 additions & 0 deletions frontend/src/metabase/browse/components/BrowseModelsBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { useMemo, useState } from "react";
import { t } from "ttag";
import _ from "underscore";

import NoResults from "assets/img/no_results.svg";
import { useSearchQuery } from "metabase/api";
import type { SortingOptions } from "metabase/components/ItemsTable/BaseItemsTable";
import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
import Search from "metabase/entities/search";
import { useDispatch } from "metabase/lib/redux";
import { PLUGIN_CONTENT_VERIFICATION } from "metabase/plugins";
import { Box, Stack } from "metabase/ui";
import type { CollectionEssentials, SearchRequest } from "metabase-types/api";
import { SortDirection } from "metabase-types/api";

import { filterModels, type ActualModelFilters } from "../utils";

import { CenteredEmptyState } from "./BrowseApp.styled";
import { ModelExplanationBanner } from "./ModelExplanationBanner";
import { ModelsTable } from "./ModelsTable";
import { getCollectionPathString } from "./utils";

const { availableModelFilters } = PLUGIN_CONTENT_VERIFICATION;

export const BrowseModelsBody = ({
actualModelFilters,
}: {
actualModelFilters: ActualModelFilters;
}) => {
const dispatch = useDispatch();
const [sortingOptions, setSortingOptions] = useState<SortingOptions>({
sort_column: "name",
sort_direction: SortDirection.Asc,
});

const query: SearchRequest = {
models: ["dataset"], // 'model' in the sense of 'type of thing'
model_ancestors: true,
filter_items_in_personal_collection: "exclude",
};

const { data, error, isLoading } = useSearchQuery(query);
const unfilteredModels = useMemo(() => data?.data, [data]);

const filteredModels = useMemo(
() =>
filterModels(
unfilteredModels || [],
actualModelFilters,
availableModelFilters,
),
[unfilteredModels, actualModelFilters],
);

const sortedModels = useMemo(() => {
const { sort_column, sort_direction } = sortingOptions;
const sorted = _.sortBy(filteredModels, model => {
if (sort_column === "collection") {
const collection: CollectionEssentials = model.collection;
return getCollectionPathString(collection);
}
if (sort_column in model) {
return model[sort_column as keyof typeof model];
} else {
console.error("Invalid sort column", sort_column);
return null;
}
});
if (sort_direction === SortDirection.Desc) {
sorted.reverse();
}
return sorted;
}, [filteredModels, sortingOptions]);

const wrappedModels = useMemo(
() => sortedModels.map(model => Search.wrapEntity(model, dispatch)),
[sortedModels, dispatch],
);

if (error || isLoading) {
return (
<LoadingAndErrorWrapper
error={error}
loading={isLoading}
style={{ display: "flex", flex: 1 }}
/>
);
}

if (filteredModels.length) {
return (
<Stack spacing="md" mb="lg">
<ModelExplanationBanner />
<ModelsTable
items={wrappedModels}
sortingOptions={sortingOptions}
onSortingOptionsChange={setSortingOptions}
/>
</Stack>
);
}

return (
<CenteredEmptyState
title={<Box mb=".5rem">{t`No models here yet`}</Box>}
message={
<Box maw="24rem">{t`Models help curate data to make it easier to find answers to questions all in one place.`}</Box>
}
illustrationElement={
<Box mb=".5rem">
<img src={NoResults} />
</Box>
}
/>
);
};

0 comments on commit 8330add

Please sign in to comment.