Skip to content

Commit

Permalink
Merge pull request #3479 from ingef/master
Browse files Browse the repository at this point in the history
Reintegrate Master
  • Loading branch information
awildturtok authored Jul 8, 2024
2 parents 25851aa + 6e0c8c5 commit 68fce29
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand All @@ -14,8 +15,6 @@
import com.bakdata.conquery.models.datasets.concepts.filters.specific.SelectFilter;
import com.bakdata.conquery.util.search.TrieSearch;
import com.fasterxml.jackson.annotation.JsonIgnore;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -35,7 +34,7 @@ public class FilterSearch {
*/
@JsonIgnore
private Map<Searchable, TrieSearch<FrontendValue>> searchCache = new HashMap<>();
private Object2LongMap<SelectFilter<?>> totals = new Object2LongOpenHashMap<>();
private Map<SelectFilter<?>, Integer> totals = new HashMap<>();

/**
* From a given {@link FrontendValue} extract all relevant keywords.
Expand Down Expand Up @@ -69,12 +68,16 @@ public final List<TrieSearch<FrontendValue>> getSearchesFor(SelectFilter<?> sear
.collect(Collectors.toList());
}

public long getTotal(SelectFilter<?> filter) {
return totals.computeIfAbsent(filter, (f) -> filter.getSearchReferences().stream()
.map(searchCache::get)
.flatMap(TrieSearch::stream)
.distinct()
.count());
public int getTotal(SelectFilter<?> filter) {
return totals.computeIfAbsent(filter, (f) -> {
HashSet<FrontendValue> count = new HashSet<>();

for (TrieSearch<FrontendValue> search : getSearchesFor(filter)) {
search.iterator().forEachRemaining(count::add);
}

return count.size();
});
}


Expand Down Expand Up @@ -116,7 +119,7 @@ public void shrinkSearch(Searchable searchable) {
}

public synchronized void clearSearch() {
totals = new Object2LongOpenHashMap<>();
totals = new HashMap<>();
searchCache = new HashMap<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ private Cursor<FrontendValue> listAllValues(SelectFilter<?> searchable) {
return new Cursor<>(Iterators.filter(iterators, seen::add));
}

private long countAllValues(SelectFilter<?> searchable) {
private int countAllValues(SelectFilter<?> searchable) {
final Namespace namespace = namespaces.get(searchable.getDataset().getId());

return namespace.getFilterSearch().getTotal(searchable);
Expand Down Expand Up @@ -313,10 +313,10 @@ public ResolvedConceptsResult resolveConceptElements(TreeConcept concept, List<S
/**
* Container class to pair number of available values and Cursor for those values.
*/
private record CursorAndLength(Cursor<FrontendValue> values, long size) {
private record CursorAndLength(Cursor<FrontendValue> values, int size) {
}

public record AutoCompleteResult(List<FrontendValue> values, long total) {
public record AutoCompleteResult(List<FrontendValue> values, int total) {
}

public record ResolvedFilterResult(ConnectorId tableId, String filterId, Collection<FrontendValue> value) {
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/js/concept-trees/ConceptTreeSearchBox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styled from "@emotion/styled";
import { useCallback, useRef } from "react";
import { FC, useCallback, useRef } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";

Expand Down Expand Up @@ -48,8 +48,11 @@ const TopRow = styled("div")`
align-items: center;
gap: 5px;
`;
interface PropsT {
className?: string;
}

const ConceptTreeSearchBox = ({ className }: { className?: string }) => {
const ConceptTreeSearchBox: FC<PropsT> = ({ className }) => {
const showMismatches = useSelector<StateT, boolean>(
(state) => state.conceptTrees.search.showMismatches,
);
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/js/previous-queries/list/ProjectItemsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import { canUploadResult } from "../../user/selectors";
import ProjectItemsFilter from "../filter/ProjectItemsFilter";
import type { ProjectItemsFilterStateT } from "../filter/reducer";
import { toggleFoldersOpen } from "../folder-filter/actions";
import ProjectItemsSearchBox from "../search/ProjectItemsSearchBox";
import ProjectItemsTypeFilter from "../type-filter/ProjectItemsTypeFilter";
import { ProjectItemsTypeFilterStateT } from "../type-filter/reducer";
import UploadQueryResults from "../upload/UploadQueryResults";

import { Panel, PanelGroup } from "react-resizable-panels";
import { ResizeHandle } from "../../common/ResizeHandle";
import ProjectItemsSearchBox from "../search/ProjectItemsSearchBox";
import Folders from "./Folders";
import FoldersToggleButton from "./FoldersToggleButton";
import { ProjectItemT } from "./ProjectItem";
Expand All @@ -46,6 +46,9 @@ const FoldersAndQueries = styled(Row)`
overflow: hidden;
position: relative;
`;
const SxProjectItemsSearchBox = styled(ProjectItemsSearchBox)`
flex-grow: 1;
`;

const Filters = styled("div")`
display: flex;
Expand Down Expand Up @@ -116,7 +119,7 @@ const ProjectItemsTab = ({ datasetId }: PropsT) => {
active={areFoldersOpen}
onClick={onToggleFoldersOpen}
/>
<ProjectItemsSearchBox />
<SxProjectItemsSearchBox />
{hasPermissionToUpload && (
<SxUploadQueryResults datasetId={datasetId} />
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback } from "react";
import { FC, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";

Expand All @@ -8,7 +8,11 @@ import SearchBar from "../../search-bar/SearchBar";
import { clearSearch, useSearchItems } from "./actions";
import type { ProjectItemsSearchStateT } from "./reducer";

const ProjectItemsSearchBox = () => {
interface Props {
className?: string;
}

const ProjectItemsSearchBox: FC<Props> = ({ className }) => {
const { t } = useTranslation();
const search = useSelector<StateT, ProjectItemsSearchStateT>(
(state) => state.projectItemsSearch,
Expand All @@ -21,6 +25,7 @@ const ProjectItemsSearchBox = () => {

return (
<SearchBar
className={className}
searchTerm={search.searchTerm}
placeholder={t("previousQueries.searchPlaceholder")}
onClear={onClear}
Expand Down
68 changes: 51 additions & 17 deletions frontend/src/js/search-bar/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import styled from "@emotion/styled";
import { faSearch } from "@fortawesome/free-solid-svg-icons";
import { memo, useEffect, useState } from "react";

import IconButton from "../button/IconButton";
import { exists } from "../common/helpers/exists";
import { useDebounce } from "../common/helpers/useDebounce";
import BaseInput from "../ui-components/BaseInput";

const InputContainer = styled("div")`
flex-grow: 1;
position: relative;
`;

const SxBaseInput = styled(BaseInput)`
width: 100%;
input {
padding-right: 60px;
height: 34px;
width: 100%;
&::placeholder {
Expand All @@ -17,33 +24,44 @@ const SxBaseInput = styled(BaseInput)`
}
`;

const Right = styled("div")`
position: absolute;
top: 0px;
right: 30px;
display: flex;
flex-direction: row;
align-items: center;
height: 34px;
`;

const StyledIconButton = styled(IconButton)`
padding: 8px 10px;
color: ${({ theme }) => theme.col.gray};
`;

interface Props {
className?: string;
searchTerm: string | null;
placeholder: string;
onSearch: (value: string) => void;
onClear: () => void;
}

const SearchBar = ({
className,
searchTerm,
placeholder,
onSearch,
onClear,
}: {
searchTerm: string | null;
placeholder: string;
onSearch: (value: string) => void;
onClear: () => void;
}) => {
}: Props) => {
const [localSearchTerm, setLocalSearchTerm] = useState<string | null>(null);

useDebounce(
() => {
if (exists(localSearchTerm)) onSearch(localSearchTerm);
},
500,
[localSearchTerm],
);

useEffect(() => {
setLocalSearchTerm(searchTerm);
}, [searchTerm]);

return (
<div className="flex-grow">
<InputContainer className={className}>
<SxBaseInput
inputType="text"
placeholder={placeholder}
Expand All @@ -53,8 +71,24 @@ const SearchBar = ({

setLocalSearchTerm(value as string | null);
}}
inputProps={{
onKeyPress: (e) => {
return e.key === "Enter" && exists(localSearchTerm)
? onSearch(localSearchTerm)
: null;
},
}}
/>
</div>
{exists(localSearchTerm) && (
<Right>
<StyledIconButton
icon={faSearch}
aria-hidden="true"
onClick={() => onSearch(localSearchTerm)}
/>
</Right>
)}
</InputContainer>
);
};

Expand Down

0 comments on commit 68fce29

Please sign in to comment.