)}
diff --git a/packages/web/src/components/search/SearchDropdownMenu.tsx b/packages/web/src/components/search/SearchDropdownMenu.tsx
index 9aa1346f..4a17ed02 100644
--- a/packages/web/src/components/search/SearchDropdownMenu.tsx
+++ b/packages/web/src/components/search/SearchDropdownMenu.tsx
@@ -23,6 +23,7 @@ import {
} from "@/components/ui/command";
interface SearchDropdownMenuProps {
+ removedOperators?: SearchOperator[];
commandRef: React.RefObject;
commandInputRef: React.RefObject;
commandInputValue: string;
@@ -41,11 +42,13 @@ const preventDefault = (e: React.MouseEvent | React.TouchEvent) => {
function OperatorItems({
commandInputValue,
onSelect,
+ removedOperators,
}: {
commandInputValue: string;
onSelect: (operator: OperatorWithIcon) => void;
+ removedOperators: SearchOperator[];
}) {
- return getFilteredOperators(commandInputValue).map((o) => (
+ return getFilteredOperators(commandInputValue, removedOperators).map((o) => (
onSelect(o)}
@@ -89,6 +92,7 @@ export function SearchDropdownMenu({
handleValueSelect,
commandValue,
setCommandValue,
+ removedOperators = [],
}: SearchDropdownMenuProps) {
return (
)}
{subMenu === "state" && handleValueSelect && (
@@ -192,11 +197,15 @@ export const OPERATOR_SUBMENU_VALUES = new Map([
],
]);
-export function getFilteredOperators(word: string) {
+export function getFilteredOperators(
+ word: string,
+ removedOperators: SearchOperator[],
+) {
return OPERATORS_WITH_ICONS.filter(
(o) =>
- o.operator.toLowerCase().startsWith(word.toLowerCase()) ||
- o.name.toLowerCase().startsWith(word.toLowerCase()),
+ !removedOperators.includes(o.operator) &&
+ (o.operator.toLowerCase().startsWith(word.toLowerCase()) ||
+ o.name.toLowerCase().startsWith(word.toLowerCase())),
);
}
diff --git a/packages/web/src/hooks/useSearchBar.ts b/packages/web/src/hooks/useSearchBar.ts
index c02c42b4..9459e570 100644
--- a/packages/web/src/hooks/useSearchBar.ts
+++ b/packages/web/src/hooks/useSearchBar.ts
@@ -1,6 +1,9 @@
import { useEffect, useMemo, useRef, useState } from "react";
-import { SEARCH_OPERATORS } from "@/core/constants/search.constant";
+import {
+ SEARCH_OPERATORS,
+ type SearchOperator,
+} from "@/core/constants/search.constant";
import type {
OperatorWithIcon,
SubmenuValue,
@@ -81,7 +84,15 @@ const getValSelectCursorPosition = (
return cursorPosition - commandInputValue.length + value.length;
};
-export function useSearchBar(initialQuery = "") {
+interface UseSearchBarProps {
+ initialQuery?: string;
+ removedOperators?: SearchOperator[];
+}
+
+export function useSearchBar({
+ initialQuery = "",
+ removedOperators = [],
+}: UseSearchBarProps) {
const [query, setQuery] = useState(initialQuery);
const commandInputRef = useRef(null);
const commandRef = useRef(null);
@@ -95,6 +106,12 @@ export function useSearchBar(initialQuery = "") {
const defaultCommandValue = "__no_selection__";
const [commandValue, setCommandValue] = useState(defaultCommandValue);
+ const searchOperators = useMemo(() => {
+ return SEARCH_OPERATORS.filter(
+ (op) => !removedOperators.includes(op.operator),
+ );
+ }, [removedOperators]);
+
const cursorWord = useMemo(() => {
return getCursorWord(query, cursorPosition).cursorWord;
}, [query, cursorPosition]);
@@ -103,7 +120,7 @@ export function useSearchBar(initialQuery = "") {
if (!cursorWord || !cursorWord.includes(":")) return null;
const op = cursorWord.slice(0, cursorWord.indexOf(":")).toLowerCase();
const val = cursorWord.slice(cursorWord.indexOf(":") + 1).toLowerCase();
- const matchedOp = SEARCH_OPERATORS.find(
+ const matchedOp = searchOperators.find(
({ operator }) => operator === op,
)?.operator;
// user has not fully typed an operator, show main menu
@@ -115,7 +132,7 @@ export function useSearchBar(initialQuery = "") {
if (!matchedVal) return matchedOp;
// finally, revert to main menu when operator's submenu value is fully typed
return null;
- }, [cursorWord]);
+ }, [cursorWord, searchOperators]);
const commandInputValue = useMemo(() => {
// default menu to show
@@ -126,7 +143,8 @@ export function useSearchBar(initialQuery = "") {
const shouldShowDropdown = useMemo(() => {
const showOperatorList =
- !subMenu && getFilteredOperators(commandInputValue).length > 0;
+ !subMenu &&
+ getFilteredOperators(commandInputValue, removedOperators).length > 0;
const showSubmenuList =
subMenu &&
getFilteredSubmenuValues(commandInputValue, subMenu).length > 0;
From 8fa6863eda335ea03a645bc51116e75febc7238a Mon Sep 17 00:00:00 2001
From: zx <67887489+tan-zx@users.noreply.github.com>
Date: Sat, 18 Jan 2025 01:17:16 +0800
Subject: [PATCH 15/15] standardise spelling
---
README.md | 4 ++--
packages/core/migrations/0033_vector-plain-storage.sql | 2 +-
packages/core/src/email/index.ts | 2 +-
packages/core/src/github/permission/github-app.ts | 2 +-
packages/web/src/hooks/usePlaceholderAnimation.ts | 4 ++--
packages/web/src/routes/r/$owner/$repo.tsx | 2 +-
packages/web/src/routes/repos/index.tsx | 2 +-
7 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index 868b1543..b5a54888 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Semhub
+# SemHub
## Development
@@ -84,7 +84,7 @@ To set up a GitHub App:
- In terms of permissions:
- Select the following read-only Repository permissions: Metadata (mandatory), Discussions, Issues, Pull Requests, Contents. (These should be tracked in code via `github-app.ts`.)
- Select the following read-only User permissions: Emails (actually would've gotten the user's email from the login process)
- - Select the following read-only Organization permissions: Members (to enable Semhub to work for users in the same organization after it has been installed by an admin)
+ - Select the following read-only Organization permissions: Members (to enable SemHub to work for users in the same organization after it has been installed by an admin)
- Leave unchecked the box that says "Request user authorization (OAuth) during installation". Our app handles user login + creation.
- Select redirect on update and use the frontend `/repos` page as the Setup URL
- Local dev: `https://local.semhub.dev:3001/repos`
diff --git a/packages/core/migrations/0033_vector-plain-storage.sql b/packages/core/migrations/0033_vector-plain-storage.sql
index bddbfb0e..85532f0f 100644
--- a/packages/core/migrations/0033_vector-plain-storage.sql
+++ b/packages/core/migrations/0033_vector-plain-storage.sql
@@ -1,7 +1,7 @@
/*
pg (or pgvector?) uses EXTENDED storage by default for for all columns bigger than 2KB
-Changes vector storage to PLAIN if vector operation is in hot path (which it is for Semhub):
+Changes vector storage to PLAIN if vector operation is in hot path (which it is for SemHub):
- this only works if your row size is within PG page limit of 8KB
- you cannot increase page limit beyond 8KB for index
diff --git a/packages/core/src/email/index.ts b/packages/core/src/email/index.ts
index 6af52153..d4b4baaf 100644
--- a/packages/core/src/email/index.ts
+++ b/packages/core/src/email/index.ts
@@ -18,7 +18,7 @@ export async function sendEmail(
envPrefix: string,
) {
const { data, error } = await client.emails.send({
- from: `${envPrefix ? `${envPrefix} ` : ""}Semhub `,
+ from: `${envPrefix ? `${envPrefix} ` : ""}SemHub `,
to,
subject,
html,
diff --git a/packages/core/src/github/permission/github-app.ts b/packages/core/src/github/permission/github-app.ts
index 228b9d03..54b6824a 100644
--- a/packages/core/src/github/permission/github-app.ts
+++ b/packages/core/src/github/permission/github-app.ts
@@ -1,6 +1,6 @@
import { type Permissions } from "../schema.webhook";
-// this file tracks the current permissions requested by Semhub Github App
+// this file tracks the current permissions requested by SemHub Github App
// however, the actual permissions are configured via UI on GitHub
export const CURRENT_REQUESTED_PERMISSIONS: Permissions = {
diff --git a/packages/web/src/hooks/usePlaceholderAnimation.ts b/packages/web/src/hooks/usePlaceholderAnimation.ts
index c20e6c6f..c7ad0ee9 100644
--- a/packages/web/src/hooks/usePlaceholderAnimation.ts
+++ b/packages/web/src/hooks/usePlaceholderAnimation.ts
@@ -2,10 +2,10 @@ import { useEffect, useState } from "react";
// need to be short for entire text to fit in mobile
const PLACEHOLDER_TEXTS = [
- "Semhub understands what you mean",
+ "SemHub understands what you mean",
"Search issues across multiple repos",
"Login to customize your search",
- "Add Semhub Search to your repo",
+ "Add SemHub search to your repo",
] as const;
const TYPING_DELAY_MS = 20;
diff --git a/packages/web/src/routes/r/$owner/$repo.tsx b/packages/web/src/routes/r/$owner/$repo.tsx
index 7449567d..074f1439 100644
--- a/packages/web/src/routes/r/$owner/$repo.tsx
+++ b/packages/web/src/routes/r/$owner/$repo.tsx
@@ -47,7 +47,7 @@ function RepoSearch() {
could not be found.
- Please ensure this repository has been added to Semhub.
+ Please ensure this repository has been added to SemHub.
);
diff --git a/packages/web/src/routes/repos/index.tsx b/packages/web/src/routes/repos/index.tsx
index c4bb3b0d..cf2308a8 100644
--- a/packages/web/src/routes/repos/index.tsx
+++ b/packages/web/src/routes/repos/index.tsx
@@ -88,7 +88,7 @@ function RepoSection({ title, type, repos }: RepoSectionProps) {
Want to add your private repos?
- Click “Authorize” to grant Semhub access to your private
+ Click “Authorize” to grant SemHub access to your private
repositories.