Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 3 additions & 25 deletions src/components/shared/FavoriteComponentToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { Spinner } from "@/components/ui/spinner";
import { useGuaranteedHydrateComponentReference } from "@/hooks/useHydrateComponentReference";
import { cn } from "@/lib/utils";
import { useComponentLibrary } from "@/providers/ComponentLibraryProvider";
import { flattenFolders } from "@/providers/ComponentLibraryProvider/componentLibrary";
import { hydrateComponentReference } from "@/services/componentService";
import { type ComponentReference } from "@/utils/componentSpec";
import { MINUTES } from "@/utils/constants";
Expand Down Expand Up @@ -143,43 +142,22 @@ const FavoriteToggleButton = withSuspenseWrapper(
);

const useComponentFlags = (component: ComponentReference) => {
const { checkIfUserComponent, componentLibrary } = useComponentLibrary();
const { checkIfUserComponent, getComponentLibrary } = useComponentLibrary();
const componentLibrary = getComponentLibrary("standard_components");

const isUserComponent = useMemo(
() => checkIfUserComponent(component),
[component, checkIfUserComponent],
);

const flatComponentList = useMemo(
() => (componentLibrary ? flattenFolders(componentLibrary) : []),
[componentLibrary],
);

const { data: isInLibrary } = useSuspenseQuery({
queryKey: ["component", "flags", component.digest],
queryFn: async () => {
if (!componentLibrary) return false;

if (isUserComponent) return true;

for (const c of flatComponentList) {
if (component.name === "Chicago Taxi Trips dataset") {
console.log(c.name, c.digest, component.digest);
}

if (c.name && c.name !== component.name) {
// micro optimization to skip components with different names
continue;
}

const digest = c.digest ?? (await hydrateComponentReference(c))?.digest;

if (digest === component.digest) {
return true;
}
}

return false;
return componentLibrary.hasComponent(component);
},
staleTime: 10 * MINUTES,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,3 @@ export const LoadingState = () => (
export const ErrorState = ({ message }: { message: string }) => (
<SidebarMenuItem className="text-red-500">Error: {message}</SidebarMenuItem>
);

export const EmptyState = () => (
<SidebarMenuItem>No components found</SidebarMenuItem>
);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { default as FolderItem } from "./FolderItem";
export { default as ImportComponent } from "./ImportComponent";
export { EmptyState, ErrorState, LoadingState } from "./LibraryStates";
export { ErrorState, LoadingState } from "./LibraryStates";
export { default as SearchInput } from "./SearchInput";
export { default as SearchResults } from "./SearchResults";
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { useForcedSearchContext } from "@/providers/ComponentLibraryProvider/For
import type { UIComponentFolder } from "@/types/componentLibrary";

import {
EmptyState,
ErrorState,
FolderItem,
ImportComponent,
Expand Down Expand Up @@ -131,14 +130,15 @@ function ComponentLibrarySection() {

const { updateSearchFilter } = useForcedSearchContext();
const {
componentLibrary,
usedComponentsFolder,
userComponentsFolder,
isLoading,
error,
searchResult,
} = useComponentLibrary();

const standardComponentsLibrary = getComponentLibrary("standard_components");

const handleFiltersChange = (filters: string[]) => {
updateSearchFilter({
filters,
Expand All @@ -147,7 +147,6 @@ function ComponentLibrarySection() {

if (isLoading) return <LoadingState />;
if (error) return <ErrorState message={(error as Error).message} />;
if (!componentLibrary) return <EmptyState />;

if (!remoteComponentLibrarySearchEnabled && searchResult) {
// If there's a search result, use the SearchResults component
Expand Down Expand Up @@ -210,15 +209,9 @@ function ComponentLibrarySection() {
icon="Cable"
/>
<Separator />
<FolderItem
key="standard-library-folder"
folder={
{
name: "Standard library",
components: [],
folders: componentLibrary.folders,
} as UIComponentFolder
}
<LibraryFolderItem
key="standard-library-folder-v2"
library={standardComponentsLibrary}
icon="Folder"
/>
{githubComponentLibraryEnabled && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,12 @@ vi.mock("./componentLibrary");

// Import mocked modules
import * as componentLibraryUtils from "@/providers/ComponentLibraryProvider/componentLibrary";
import * as componentService from "@/services/componentService";
import * as componentStore from "@/utils/componentStore";
import * as getComponentName from "@/utils/getComponentName";
import * as localforage from "@/utils/localforage";

// Mock implementations
const mockFetchAndStoreComponentLibrary = vi.mocked(
componentService.fetchAndStoreComponentLibrary,
);

const mockFetchUserComponents = vi.mocked(
componentLibraryUtils.fetchUserComponents,
);
Expand Down Expand Up @@ -134,7 +131,6 @@ describe("ComponentLibraryProvider - Component Management", () => {
componentDuplicateDialogProps.handleImportComponent = undefined;

// Setup default mock implementations
mockFetchAndStoreComponentLibrary.mockResolvedValue(mockComponentLibrary);
mockFetchUserComponents.mockResolvedValue(mockUserComponentsFolder);
mockFetchUsedComponents.mockReturnValue({
name: "Used Components",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@ import {
isYamlLibraryConfiguration,
} from "@/components/shared/GitHubLibrary/types";
import {
fetchAndStoreComponentLibrary,
COMPONENT_LIBRARY_URL,
hydrateComponentReference,
} from "@/services/componentService";
import type {
ComponentFolder,
ComponentLibrary,
SearchResult,
} from "@/types/componentLibrary";
import type { ComponentFolder, SearchResult } from "@/types/componentLibrary";
import type {
ComponentReference,
HydratedComponentReference,
Expand Down Expand Up @@ -69,7 +65,6 @@ type AvailableComponentLibraries =
| string;

type ComponentLibraryContextType = {
componentLibrary: ComponentLibrary | undefined;
userComponentsFolder: ComponentFolder | undefined;
usedComponentsFolder: ComponentFolder;
isLoading: boolean;
Expand Down Expand Up @@ -136,6 +131,10 @@ function useComponentLibraryRegistry() {
/**
* In future we will have other library types, including "standard_library", "favorite_components", "used_components", etc.
*/
[
"standard_components",
new YamlFileLibrary("Standard library", COMPONENT_LIBRARY_URL),
],
]),
[queryClient],
);
Expand Down Expand Up @@ -187,7 +186,6 @@ export const ComponentLibraryProvider = ({
const { getComponentLibraryObject, existingComponentLibraries } =
useComponentLibraryRegistry();

const [componentLibrary, setComponentLibrary] = useState<ComponentLibrary>();
const [userComponentsFolder, setUserComponentsFolder] =
useState<ComponentFolder>();

Expand All @@ -196,17 +194,6 @@ export const ComponentLibraryProvider = ({
const [newComponent, setNewComponent] =
useState<HydratedComponentReference | null>(null);

// Fetch main component library
const {
data: rawComponentLibrary,
isLoading: isLibraryLoading,
error: libraryError,
refetch: refetchLibrary,
} = useQuery({
queryKey: ["componentLibrary"],
queryFn: fetchAndStoreComponentLibrary,
});

// Fetch user components
const {
data: rawUserComponentsFolder,
Expand All @@ -227,14 +214,6 @@ export const ComponentLibraryProvider = ({
);

// Methods
const refreshComponentLibrary = useCallback(async () => {
const { data: updatedLibrary } = await refetchLibrary();

if (updatedLibrary) {
setComponentLibrary(updatedLibrary);
}
}, [refetchLibrary]);

const refreshUserComponents = useCallback(async () => {
const { data: updatedUserComponents } = await refetchUserComponents();

Expand Down Expand Up @@ -273,15 +252,7 @@ export const ComponentLibraryProvider = ({
},
};

if (componentLibrary) {
const uniqueComponents = filterToUniqueByDigest(
flattenFolders(componentLibrary),
);

result.components.standard = uniqueComponents.filter(
(c) => c.spec && componentMatchesSearch(c.spec, search, filters),
);
}
// classic search is not supported for now

if (userComponentsFolder) {
const uniqueComponents = filterToUniqueByDigest(
Expand All @@ -303,13 +274,13 @@ export const ComponentLibraryProvider = ({

return result;
},
[componentLibrary, userComponentsFolder, usedComponentsFolder],
[userComponentsFolder, usedComponentsFolder],
);

const internalAddComponentToLibrary = useCallback(
async (hydratedComponent: HydratedComponentReference) => {
await importComponent(hydratedComponent);
await refreshComponentLibrary();

await refreshUserComponents();
setNewComponent(null);
setExistingComponent(null);
Expand All @@ -322,7 +293,7 @@ export const ComponentLibraryProvider = ({
}),
);
},
[refreshComponentLibrary, refreshUserComponents, importComponent],
[refreshUserComponents, importComponent],
);

const handleImportComponent = useCallback(
Expand All @@ -341,12 +312,7 @@ export const ComponentLibraryProvider = ({
console.error("Error importing component:", error);
}
},
[
newComponent,
refreshComponentLibrary,
refreshUserComponents,
importComponent,
],
[newComponent, refreshUserComponents, importComponent],
);

const addToComponentLibraryWithDuplicateCheck = useCallback(
Expand Down Expand Up @@ -376,12 +342,7 @@ export const ComponentLibraryProvider = ({
console.error("Error adding component to library:", error);
}
},
[
userComponentsFolder,
refreshComponentLibrary,
refreshUserComponents,
importComponent,
],
[userComponentsFolder, refreshUserComponents, importComponent],
);

const addToComponentLibrary = useCallback(
Expand Down Expand Up @@ -420,7 +381,6 @@ export const ComponentLibraryProvider = ({
USER_COMPONENTS_LIST_NAME,
component.name,
).then(async () => {
await refreshComponentLibrary();
await refreshUserComponents();
});
} else {
Expand All @@ -432,7 +392,7 @@ export const ComponentLibraryProvider = ({
console.error("Error deleting component:", error);
}
},
[refreshComponentLibrary, refreshUserComponents],
[refreshUserComponents],
);

const handleCloseDuplicationDialog = useCallback(() => {
Expand All @@ -451,14 +411,6 @@ export const ComponentLibraryProvider = ({
[currentSearchFilter, searchComponentLibrary],
);

useEffect(() => {
if (!rawComponentLibrary) {
setComponentLibrary(undefined);
return;
}
setComponentLibrary(rawComponentLibrary);
}, [rawComponentLibrary]);

useEffect(() => {
if (!rawUserComponentsFolder) {
setUserComponentsFolder(undefined);
Expand All @@ -476,12 +428,11 @@ export const ComponentLibraryProvider = ({
[],
);

const isLoading = isLibraryLoading || isUserComponentsLoading;
const error = libraryError || userComponentsError;
const isLoading = isUserComponentsLoading;
const error = userComponentsError;

const value = useMemo(
() => ({
componentLibrary,
userComponentsFolder,
usedComponentsFolder,
isLoading,
Expand All @@ -495,7 +446,6 @@ export const ComponentLibraryProvider = ({
checkIfUserComponent,
}),
[
componentLibrary,
userComponentsFolder,
usedComponentsFolder,
isLoading,
Expand Down
Loading