Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add docs in search #841

Closed
wants to merge 2 commits into from
Closed
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
159 changes: 143 additions & 16 deletions src/Search/TypeAheadDropdown.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
const SEARCH_API_KEY = props.searchApiKey ?? "fc7644a5da5306311e8e9418c24fddc4";
const APPLICATION_ID = props.appId ?? "B6PI9UKKJT";
const INDEX = props.index ?? "replica_prod_near-social-feed";
const API_URL = props.apiUrl ?? `https://${APPLICATION_ID}-dsn.algolia.net/1/indexes/${INDEX}/query?`;
const SEARCH_API_KEY_APPS = props.searchApiKey ?? "fc7644a5da5306311e8e9418c24fddc4";
const APPLICATION_ID_APPS = props.appId ?? "B6PI9UKKJT";
const INDEX_APPS = props.index ?? "replica_prod_near-social-feed";
const API_URL_APPS = props.apiUrl ?? `https://${APPLICATION_ID_APPS}-dsn.algolia.net/1/indexes/${INDEX_APPS}/query?`;

const SEARCH_API_KEY_DOCS = props.searchApiKey ?? "6b114c851c9921e654b5a1ffa8cffb93";
const APPLICATION_ID_DOCS = props.appId ?? "0LUM67N2P2";
const INDEX_DOCS = props.index ?? "near";
const API_URL_DOCS = props.apiUrl ?? `https://${APPLICATION_ID_DOCS}-dsn.algolia.net/1/indexes/${INDEX_DOCS}/query?`;

const INITIAL_PAGE = props.initialPage ?? 0;
const facets = props.facets ?? ["All", "Apps", "Components"];
const tab = props.tab ?? "All";
const facets = props.facets ?? ["All", "Docs", "Apps", "Components"];
const tab = props.tab ?? "Docs";
const userId = props.accountId ?? context.accountId;
const searchPageUrl = "/${REPL_ACCOUNT}/widget/Search.IndexPage";
const topmostCount = props.topmostCount ?? 3;

const URLS = {
Docs: {
SEARCH_API_KEY: SEARCH_API_KEY_DOCS,
APPLICATION_ID: APPLICATION_ID_DOCS,
INDEX: INDEX_DOCS,
API_URL: API_URL_DOCS,
},
Apps: {
SEARCH_API_KEY: SEARCH_API_KEY_APPS,
APPLICATION_ID: APPLICATION_ID_APPS,
INDEX: INDEX_APPS,
API_URL: API_URL_APPS,
},
Components: {
SEARCH_API_KEY: SEARCH_API_KEY_APPS,
APPLICATION_ID: APPLICATION_ID_APPS,
INDEX: INDEX_APPS,
API_URL: API_URL_APPS,
},
};

State.init({
currentPage: 0,
selectedTab: tab,
Expand Down Expand Up @@ -218,6 +245,48 @@ const ScrollableContent = styled.div`
height: 350px;
`;

const CardDocs = styled.a`
width: 100%;
display: block;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding: 16px;
max-width: 400px;
text-decoration: none;
color: white;
text-align: left;

&:hover {
cursor: pointer;
text-decoration: none;
}
`;

const TitleDocs = styled.h2`
font-size: 18px;
font-weight: 500;
color: white;
margin: 0;
font-weigth: bold;
text-align: left;
`;

const SubtitleDocs = styled.h3`
font-size: 14px;
font-weight: normal;
margin: 4px 0 12px;
text-align: left;
`;

const ContentDocs = styled.p`
font-size: 14px;
color: #333;
margin: 0;
line-height: 1.4;
text-align: left;
color: white;
`;

const Item = styled.div``;

const _parceDataByFacet = (facet, arr) => {
Expand Down Expand Up @@ -323,6 +392,7 @@ const resetSearcheHits = () => {
profiles: undefined,
apps: undefined,
components: undefined,
docs: undefined,
postsAndComments: undefined,
});
};
Expand Down Expand Up @@ -374,6 +444,20 @@ const nearcatalog = (records) => {
return components;
};

const convertUrl = (url) => url.replace(/^https:\/\/docs\.near\.org\/(.+)$/, "https://dev.near.org/documentation/$1");

const docsComponents = (rawResp) => {
return rawResp.hits.map((item) => {
return (
<CardDocs href={convertUrl(item.url)}>
<TitleDocs>{item.hierarchy.lvl0}</TitleDocs>
<SubtitleDocs>{item.hierarchy.lvl1}</SubtitleDocs>
<ContentDocs>{item.content ? item.content.substr(0, 80) : ""}</ContentDocs>
</CardDocs>
);
});
};

const categorizeSearchHits = (rawResp) => {
const results = {};
for (const [i, result] of rawResp.hits?.entries()) {
Expand All @@ -393,6 +477,14 @@ const categorizeSearchHits = (rawResp) => {
};
};

const parseSearchHitsForDocs = (rawResp) => {
return {
results: rawResp.hits,
hitsTotal: rawResp.nbHits,
hitsPerPage: rawResp.hitsPerPage,
};
};

const debounce = (callable, timeout) => {
return (args) => {
clearTimeout(state.timer);
Expand All @@ -402,20 +494,21 @@ const debounce = (callable, timeout) => {
};
};

const fetchSearchHits = (query, { pageNumber, configs, optionalFilters }) => {
const fetchSearchHits = (facet, query, { pageNumber, configs, optionalFilters }) => {
let body = {
query,
page: pageNumber ?? 0,
optionalFilters: optionalFilters ?? ["categories:nearcatalog<score=1>", "categories:widget<score=2>"],
clickAnalytics: true,
...configs,
};
return asyncFetch(API_URL, {

return asyncFetch(URLS[facet].API_URL, {
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json; charset=UTF-8",
"X-Algolia-Api-Key": SEARCH_API_KEY,
"X-Algolia-Application-Id": APPLICATION_ID,
"X-Algolia-Api-Key": URLS[facet].SEARCH_API_KEY,
"X-Algolia-Application-Id": URLS[facet].APPLICATION_ID,
},
method: "POST",
});
Expand All @@ -431,7 +524,8 @@ const updateSearchHits = debounce(({ term, pageNumber }) => {
// state with current near social isn't feasible.
const updateStateAfterFetching = (facet) => {
return (resp) => {
const { results, hitsTotal, hitsPerPage } = categorizeSearchHits(resp.body);
const { results, hitsTotal, hitsPerPage } =
facet != "Docs" ? categorizeSearchHits(resp.body) : parseSearchHitsForDocs(resp.body);

if (facet === "Apps") {
State.update({
Expand All @@ -444,7 +538,20 @@ const updateSearchHits = debounce(({ term, pageNumber }) => {
queryID: resp.body.queryID,
},
});
} else {
}

if (facet === "Docs") {
State.update({
docs: {
hitsTotal,
hitsPerPage,
hits: docsComponents(resp.body),
queryID: resp.body.queryID,
},
});
}

if (facet === "Components") {
State.update({
components: {
hitsTotal,
Expand All @@ -469,7 +576,7 @@ const updateSearchHits = debounce(({ term, pageNumber }) => {
};

for (const facet of facets.filter((i) => i !== "All")) {
fetchSearchHits(term, {
fetchSearchHits(facet, term, {
pageNumber,
configs: configsPerFacet(facet),
}).then(updateStateAfterFetching(facet));
Expand Down Expand Up @@ -562,6 +669,9 @@ const tabCount = (tab) => {
case "Apps":
// Return the count for Apps
return state.apps.hitsTotal ?? 0;
case "Docs":
// Return the count for Apps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Return the count for Apps
// Return the count for Docs

return state.docs.hitsTotal ?? 0;
case "Components":
// Return the count for Components
return state.components.hitsTotal ?? 0;
Expand All @@ -572,6 +682,9 @@ const tabCount = (tab) => {
};

const topmostComponents = (apps) => {
if (state.selectedTab === "Docs") {
return <Items>{state.docs.hits}</Items>;
}
Comment on lines +685 to +687
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (state.selectedTab === "Docs") {
return <Items>{state.docs.hits}</Items>;
}

Let's remove this changes and apply my next suggestion instead

let output = [];
if (state.selectedTab === "Components" || state.selectedTab === "Apps") {
if (state.selectedTab === "Components") {
Expand Down Expand Up @@ -620,6 +733,20 @@ const topmostComponents = (apps) => {

const displayResultsByFacet = (selectedTab) => {
switch (selectedTab) {
case "Docs":
return state.components.hits?.length > 0 ? (
<DisplayResultsByFacet title="Components" count={state.docs.hitsTotal} items={topmostComponents(false)} />
) : (
<>
<TextMessage message={`No Component matches were found for "${state.term}".`} />
<TextMessage
message={`Trying to find a app built by an user? Try search their account id.`}
$fontSize="12px"
$top="45%"
/>{" "}
</>
);
Comment on lines +736 to +748
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
case "Docs":
return state.components.hits?.length > 0 ? (
<DisplayResultsByFacet title="Components" count={state.docs.hitsTotal} items={topmostComponents(false)} />
) : (
<>
<TextMessage message={`No Component matches were found for "${state.term}".`} />
<TextMessage
message={`Trying to find a app built by an user? Try search their account id.`}
$fontSize="12px"
$top="45%"
/>{" "}
</>
);
case "Docs":
return state.docs.hits?.length > 0 ? (
<DisplayResultsByFacet title="Docs" count={state.docs.hitsTotal} items={state.docs.hits} />
) : (
<>
<TextMessage message={`No matches were found for "${state.term}".`} />
</>
);


case "Apps": {
return state.apps.hits?.length > 0 ? (
<DisplayResultsByFacet title="Apps" count={state.apps.hitsTotal} items={topmostComponents(true)} />
Expand Down Expand Up @@ -736,9 +863,9 @@ return (
src="${REPL_ACCOUNT}/widget/Search.Insights"
props={{
event: state.event,
searchApiKey: SEARCH_API_KEY,
appId: APPLICATION_ID,
index: INDEX,
searchApiKey: SEARCH_API_KEY_APPS,
appId: APPLICATION_ID_APPS,
index: INDEX_APPS,
}}
/>
)}
Expand Down