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

Add multiple files to code studio in one go #1254

Merged
merged 1 commit into from
Apr 8, 2024
Merged
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
37 changes: 20 additions & 17 deletions client/src/CommandBar/Body/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,26 @@ const CommandBarItem = ({
[index, setFocusedIndex],
);

const handleClick = useCallback(() => {
if (onClick) {
onClick();
if (closeOnClick) {
setIsVisible(false);
setChosenStep({ id: CommandBarStepEnum.INITIAL });
const handleClick = useCallback(
(e: React.MouseEvent | KeyboardEvent) => {
if (onClick) {
onClick(e);
if (closeOnClick) {
setIsVisible(false);
setChosenStep({ id: CommandBarStepEnum.INITIAL });
}
} else {
setChosenStep({
id: id as Exclude<
CommandBarStepEnum,
CommandBarStepEnum.ADD_TO_STUDIO | CommandBarStepEnum.SEARCH_DOCS
>,
});
}
} else {
setChosenStep({
id: id as Exclude<
CommandBarStepEnum,
CommandBarStepEnum.ADD_TO_STUDIO | CommandBarStepEnum.SEARCH_DOCS
>,
});
}
updateArrayInStorage(RECENT_COMMANDS_KEY, itemKey);
}, [id, onClick, closeOnClick, itemKey]);
updateArrayInStorage(RECENT_COMMANDS_KEY, itemKey);
},
[id, onClick, closeOnClick, itemKey],
);

const handleKeyEvent = useCallback(
(e: KeyboardEvent) => {
Expand All @@ -103,7 +106,7 @@ const CommandBarItem = ({
) {
e.preventDefault();
e.stopPropagation();
handleClick();
handleClick(e);
return;
}
if (focusedIndex === index && shortAction?.action) {
Expand Down
124 changes: 89 additions & 35 deletions client/src/CommandBar/steps/SeachFiles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {
import React, {
ChangeEvent,
memo,
useCallback,
Expand All @@ -12,7 +12,11 @@ import { Trans, useTranslation } from 'react-i18next';
import Header from '../Header';
import { CommandBarStepEnum, TabTypesEnum } from '../../types/general';
import { CommandBarContext } from '../../context/commandBarContext';
import { getAutocomplete } from '../../services/api';
import {
getAutocomplete,
getCodeStudio,
patchCodeStudio,
} from '../../services/api';
import { FileResItem } from '../../types/api';
import Body from '../Body';
import FileIcon from '../../components/FileIcon';
Expand All @@ -34,7 +38,9 @@ const SearchFiles = ({ studioId }: Props) => {
const { setChosenStep, setIsVisible } = useContext(
CommandBarContext.Handlers,
);
const { project } = useContext(ProjectContext.Current);
const { project, refreshCurrentProjectRepos } = useContext(
ProjectContext.Current,
);
const { openNewTab } = useContext(TabsContext.Handlers);
const { setIsLeftSidebarFocused } = useContext(UIContext.Focus);
const [files, setFiles] = useState<
Expand Down Expand Up @@ -65,7 +71,7 @@ const SearchFiles = ({ studioId }: Props) => {
if (project?.id) {
getAutocomplete(
project.id,
`path:${searchValue}&content=false&page_size=20`,
`path:${searchValue}&content=false&file=true&page_size=20`,
).then((respPath) => {
const fileResults = respPath.data
.filter(
Expand Down Expand Up @@ -96,41 +102,89 @@ const SearchFiles = ({ studioId }: Props) => {
items: filterOutDuplicates(
files.map((f) => ({ ...f, key: `${f.path}-${f.repo}-${f.branch}` })),
'key',
).map(({ path, repo, branch, key }) => ({
key,
id: key,
onClick: () => {
openNewTab({
type: TabTypesEnum.FILE,
path,
repoRef: repo,
branch,
studioId,
});
setIsLeftSidebarFocused(false);
setIsVisible(false);
setChosenStep({ id: CommandBarStepEnum.INITIAL });
},
label: path,
footerHint: `${splitPath(repo)
.slice(repo.startsWith('local//') ? -1 : -2)
.join('/')} ${
branch ? `/ ${splitPath(branch).pop()} ` : ''
}/ ${path}`,
footerBtns: [
{
label: studioId ? t('Add file') : t('Open'),
shortcut: ['entr'],
).map(({ path, repo, branch, key }) => {
const addMultipleFilesToStudio = async () => {
if (project?.id && studioId) {
const studio = await getCodeStudio(project.id, studioId);
const patchedFile = studio?.context.find(
(f) =>
f.path === path && f.repo === repo && f.branch === branch,
);
if (!patchedFile) {
await patchCodeStudio(project.id, studioId, {
context: [
...(studio?.context || []),
{
path,
branch: branch,
repo,
hidden: false,
ranges: [],
},
],
});
refreshCurrentProjectRepos();
openNewTab({
type: TabTypesEnum.FILE,
path,
repoRef: repo,
branch,
studioId,
isFileInContext: true,
initialRanges: [],
});
}
}
};
return {
key,
id: key,
onClick: async (e: React.MouseEvent | KeyboardEvent) => {
if (studioId && e.shiftKey && project?.id) {
await addMultipleFilesToStudio();
} else {
openNewTab({
type: TabTypesEnum.FILE,
path,
repoRef: repo,
branch,
studioId,
});
setIsLeftSidebarFocused(false);
setIsVisible(false);
setChosenStep({ id: CommandBarStepEnum.INITIAL });
}
},
],
Icon: (props: { sizeClassName?: string }) => (
<FileIcon filename={path} noMargin />
),
})),
label: path,
footerHint: `${splitPath(repo)
.slice(repo.startsWith('local//') ? -1 : -2)
.join('/')} ${
branch ? `/ ${splitPath(branch).pop()} ` : ''
}/ ${path}`,
footerBtns: [
...(studioId
? [
{
label: t('Add multiple files'),
shortcut: ['shift', 'entr'],
action: addMultipleFilesToStudio,
},
]
: []),
{
label: studioId ? t('Add file') : t('Open'),
shortcut: ['entr'],
},
],
Icon: (props: { sizeClassName?: string }) => (
<FileIcon filename={path} noMargin />
),
};
}),
itemsOffset: 0,
},
];
}, [files, studioId]);
}, [files, studioId, project?.id]);

return (
<div className="flex flex-col h-[28.875rem] w-[40rem] overflow-auto">
Expand Down
36 changes: 26 additions & 10 deletions client/src/Project/LeftSidebar/NavPanel/Studios/AddContextFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import Button from '../../../../components/Button';
import { CommandBarContext } from '../../../../context/commandBarContext';
import { CommandBarStepEnum } from '../../../../types/general';
import { useArrowNavigationItemProps } from '../../../../hooks/useArrowNavigationItemProps';
import PlusSign from '../../../../icons/PlusSign';

type Props = {
studioId: string;
index: string;
isFull?: boolean;
};

const AddContextFile = ({ studioId, index }: Props) => {
const AddContextFile = ({ studioId, index, isFull }: Props) => {
useTranslation();
const { setChosenStep, setIsVisible } = useContext(
CommandBarContext.Handlers,
Expand All @@ -28,17 +30,31 @@ const AddContextFile = ({ studioId, index }: Props) => {

return (
<div
className={`pb-2 pr-4 pl-10.5 ${isFocused ? 'bg-bg-sub-hover' : ''}`}
className={`${
isFull ? 'pb-2' : isFocused ? 'text-label-title' : 'text-label-base '
} pr-4 pl-10.5 ${isFocused ? 'bg-bg-sub-hover' : ''}`}
{...props}
>
<div className="flex flex-col items-center p-4 gap-4 rounded-md border border-dashed border-bg-border">
<p className="select-none body-mini text-label-base">
<Trans>Studio conversation require at least one context file.</Trans>
</p>
<Button variant="secondary" size="mini" onClick={onClick}>
<Trans>Add file</Trans>
</Button>
</div>
{isFull ? (
<div className="flex flex-col items-center p-4 gap-4 rounded-md border border-dashed border-bg-border">
<p className="select-none body-mini text-label-base">
<Trans>
Studio conversation require at least one context file.
</Trans>
</p>
<Button variant="secondary" size="mini" onClick={onClick}>
<Trans>Add files</Trans>
</Button>
</div>
) : (
<div
className="flex items-center gap-3 cursor-pointer h-7 w-full"
onClick={onClick}
>
<PlusSign sizeClassName="w-3.5 h-3.5" />
<Trans>Add files</Trans>
</div>
)}
</div>
);
};
Expand Down
10 changes: 8 additions & 2 deletions client/src/Project/LeftSidebar/NavPanel/Studios/StudioEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import Tooltip from '../../../../components/Tooltip';
import Badge from '../../../../components/Badge';
import { IndexingStatusType } from '../../../../types/general';
import { useArrowNavigationItemProps } from '../../../../hooks/useArrowNavigationItemProps';
import PlusSign from '../../../../icons/PlusSign';
import Button from '../../../../components/Button';
import StudioSubItem from './StudioSubItem';
import AddContextFile from './AddContextFile';
import StudioFile from './StudioFile';
Expand Down Expand Up @@ -121,8 +123,12 @@ const StudioEntry = ({
<div className="body-tiny text-label-base pl-10.5 pr-4 h-7 flex items-center">
<Trans>Context files</Trans>
</div>
{!context.length && !previewingSnapshot && (
<AddContextFile studioId={id} index={`${index}-add-file`} />
{!previewingSnapshot && (
<AddContextFile
studioId={id}
index={`${index}-add-file`}
isFull={!context.length}
/>
)}
{(previewingSnapshot?.context || context).map((f, i) => (
<StudioFile
Expand Down
3 changes: 2 additions & 1 deletion client/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -536,5 +536,6 @@
"Default": "Default",
"Simplified": "Simplified",
"Recommended: The classic input": "Recommended: The classic input",
"Fallback: Use if experiencing problems with the default one": "Fallback: Use if experiencing problems with the default one"
"Fallback: Use if experiencing problems with the default one": "Fallback: Use if experiencing problems with the default one",
"Add multiple files": "Add multiple files"
}
3 changes: 2 additions & 1 deletion client/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -535,5 +535,6 @@
"Fallback: Use if experiencing problems with the default one": "Fallback: use si experimenta problemas con el predeterminado",
"Select the input type to use in conversations": "Seleccione el tipo de entrada a usar en conversaciones",
"Default": "Por defecto",
"Recommended: The classic input": "Recomendado: la entrada clásica"
"Recommended: The classic input": "Recomendado: la entrada clásica",
"Add multiple files": "Agregar varios archivos"
}
3 changes: 2 additions & 1 deletion client/src/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -517,5 +517,6 @@
"Simplified": "Semplificata",
"Select the input type to use in conversations": "Seleziona il tipo di input da utilizzare nelle conversazioni",
"Recommended: The classic input": "Consigliato: l'ingresso classico",
"Conversation input": "Input di conversazione"
"Conversation input": "Input di conversazione",
"Add multiple files": "Aggiungi più file"
}
3 changes: 2 additions & 1 deletion client/src/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -522,5 +522,6 @@
"Simplified": "簡素化",
"Default": "デフォルト",
"Recommended: The classic input": "推奨:クラシック入力",
"Conversation input": "会話の入力"
"Conversation input": "会話の入力",
"Add multiple files": "複数のファイルを追加します"
}
3 changes: 2 additions & 1 deletion client/src/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,5 +532,6 @@
"Simplified": "简化",
"Select the input type to use in conversations": "选择要在对话中使用的输入类型",
"Default": "默认",
"Recommended: The classic input": "推荐:经典输入"
"Recommended: The classic input": "推荐:经典输入",
"Add multiple files": "添加多个文件"
}
2 changes: 1 addition & 1 deletion client/src/types/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ export type CommandBarItemGeneralType = {
action?: () => void | Promise<void>;
}[];
iconContainerClassName?: string;
onClick?: () => void;
onClick?: (e: React.MouseEvent | KeyboardEvent) => void | Promise<void>;
};

export type CommandBarItemInvisibleType = {
Expand Down