Skip to content

Commit

Permalink
Recipes drag and drop feature (#314)
Browse files Browse the repository at this point in the history
This PR closes #230. 

## Test plan

Tested it manually.
Run the extension, head over to the recipes section and try to drag and
reorder the recipes.



https://github.com/sourcegraph/cody/assets/44617923/b1e491f8-40eb-4ba2-b1c3-09a7d80e0282
  • Loading branch information
deepak2431 committed Jul 31, 2023
1 parent d2c7005 commit 101f2e2
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 2 deletions.
2 changes: 2 additions & 0 deletions vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Starting from `0.2.0`, Cody is using `major.EVEN_NUMBER.patch` for release versi

### Added

- Added the functionality to drag and reorder the recipes. [pull/314](https://github.com/sourcegraph/cody/pull/314)

### Fixed

### Changed
Expand Down
2 changes: 2 additions & 0 deletions vscode/webviews/App.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ const dummyVSCodeAPI: VSCodeWrapper = {
return () => {}
},
postMessage: () => {},
getState: () => ({}),
setState: () => {},
}
2 changes: 2 additions & 0 deletions vscode/webviews/Login.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const meta: ComponentMeta<typeof Login> = {
const vscodeAPI: VSCodeWrapper = {
postMessage: () => {},
onMessage: () => () => {},
getState: () => ({}),
setState: () => {},
}

const validAuthStatus: AuthStatus = {
Expand Down
4 changes: 4 additions & 0 deletions vscode/webviews/Recipes.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
padding-bottom: 0.5rem;
}

.recipe-button-drag {
border-top: 2px solid var(--vscode-activityBar-activeBorder);
}

.recipes-header {
display: flex;
justify-content: space-between;
Expand Down
52 changes: 50 additions & 2 deletions vscode/webviews/Recipes.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { useState } from 'react'

import { VSCodeButton } from '@vscode/webview-ui-toolkit/react'
import classNames from 'classnames'

import { RecipeID } from '@sourcegraph/cody-shared/src/chat/recipes/recipe'

import { VSCodeWrapper } from './utils/VSCodeApi'

import styles from './Recipes.module.css'

type RecipeListType = Record<string, string>

interface State {
reorderedRecipes: RecipeListType
}

export const recipesList = {
'explain-code-detailed': 'Explain selected code (detailed)',
'explain-code-high-level': 'Explain selected code (high level)',
Expand All @@ -25,6 +34,10 @@ export const Recipes: React.FunctionComponent<{
vscodeAPI: VSCodeWrapper
myPrompts: string[] | null
}> = ({ vscodeAPI, myPrompts }) => {
const initialState = vscodeAPI.getState() as State | undefined
const reorderedRecipeList: RecipeListType = initialState?.reorderedRecipes ?? recipesList
const [recipes, setRecipes] = useState<RecipeListType>(reorderedRecipeList)
const [draggedIndex, setDraggedIndex] = useState<number | null>(null)
const onRecipeClick = (recipeID: RecipeID): void => {
vscodeAPI.postMessage({ command: 'executeRecipe', recipe: recipeID })
}
Expand All @@ -33,6 +46,34 @@ export const Recipes: React.FunctionComponent<{
}
const myPromptsEnabled = myPrompts !== null

const handleDragStart = (event: React.DragEvent<HTMLElement>, index: number): void => {
setDraggedIndex(index)
}

const handleDragOver = (event: React.DragEvent<HTMLElement>, index: number): void => {
event.preventDefault()

if (draggedIndex !== null && draggedIndex !== index) {
const newRecipes = Object.entries(recipes)
const [removedRecipe] = newRecipes.splice(draggedIndex, 1)
newRecipes.splice(index, 0, removedRecipe)

const reorderedRecipes: RecipeListType = {} as RecipeListType

for (const recipe of newRecipes) {
reorderedRecipes[recipe[0]] = recipe[1]
}

setRecipes(reorderedRecipes)
vscodeAPI.setState({ reorderedRecipes })
setDraggedIndex(index)
}
}

const handleDragEnd = (): void => {
setDraggedIndex(null)
}

return (
<div className="inner-container">
<div className="non-transcript-container">
Expand Down Expand Up @@ -100,12 +141,19 @@ export const Recipes: React.FunctionComponent<{
</div>
</>
)}
{Object.entries(recipesList).map(([key, value]) => (
{Object.entries(recipes).map(([key, value], index) => (
<VSCodeButton
key={key}
className={styles.recipeButton}
className={classNames(
styles.recipeButton,
index === draggedIndex && styles.recipeButtonDrag
)}
type="button"
onClick={() => onRecipeClick(key as RecipeID)}
draggable={true}
onDragStart={e => handleDragStart(e, index)}
onDragOver={e => handleDragOver(e, index)}
onDragEnd={handleDragEnd}
>
{value}
</VSCodeButton>
Expand Down
4 changes: 4 additions & 0 deletions vscode/webviews/utils/VSCodeApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ interface VSCodeApi {
export interface VSCodeWrapper {
postMessage(message: WebviewMessage): void
onMessage(callback: (message: ExtensionMessage) => void): () => void
getState(): unknown
setState(newState: unknown): void
}

let api: VSCodeWrapper
Expand All @@ -27,6 +29,8 @@ export function getVSCodeAPI(): VSCodeWrapper {
window.addEventListener('message', listener)
return () => window.removeEventListener('message', listener)
},
setState: newState => vsCodeApi.setState(newState),
getState: () => vsCodeApi.getState(),
}
}
return api
Expand Down

0 comments on commit 101f2e2

Please sign in to comment.