Skip to content

Commit

Permalink
Merge pull request #1517 from benjidotsh/ai/rag-modal-sidebar
Browse files Browse the repository at this point in the history
refactor(ai): add SidebarRagModal and make hotkey customizable
  • Loading branch information
Xantier authored Jul 30, 2024
2 parents c15b5d4 + 60f139d commit 9d2b848
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/lazy-ghosts-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@roadiehq/rag-ai': patch
---

Refactored `RagModal` into `ControlledRagModal` and `UncontrolledRagModal`
5 changes: 5 additions & 0 deletions .changeset/pretty-beds-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@roadiehq/rag-ai': patch
---

Added property `hotkey` to `RagModal` to make hotkey customizable
5 changes: 5 additions & 0 deletions .changeset/thin-lemons-fly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@roadiehq/rag-ai': patch
---

Added `SidebarRagModal`
19 changes: 19 additions & 0 deletions plugins/frontend/rag-ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,22 @@ const App = () => (
</AppProvider>
);
```

You can also choose to use the `SidebarRagModal` component instead. In addition to using a hotkey, this will allow you to open the modal from the sidebar as well.

```tsx
// packages/app/src/components/Root/Root.tsx
import { SidebarRagModal } from '@roadiehq/rag-ai';
...
export const Root = ({ children }: PropsWithChildren<{}>) => (
<SidebarPage>
<Sidebar>
<SidebarLogo />
<SidebarSearch />
<SidebarRagModal />
...
</Sidebar>
{children}
</SidebarPage>
);
```
34 changes: 28 additions & 6 deletions plugins/frontend/rag-ai/src/components/RagModal/RagModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ import { useApi } from '@backstage/core-plugin-api';
import { ResponseEmbedding } from '../../types';
import { Thinking } from './Thinking';

export type RagModalProps = {
title?: string;
hotkey?: string;
};

type ControlledRagModalProps = RagModalProps & {
open: boolean;
setOpen: (value: boolean) => void;
};

type UncontrolledRagModalProps = RagModalProps;

const useStyles = makeStyles(theme => ({
dialogTitle: {
gap: theme.spacing(1),
Expand Down Expand Up @@ -66,9 +78,13 @@ const useStyles = makeStyles(theme => ({
viewResultsLink: { verticalAlign: '0.5em' },
}));

export const RagModal = ({ title = 'AI Assistant' }: { title?: string }) => {
export const ControlledRagModal = ({
title = 'AI Assistant',
hotkey = 'ctrl+comma',
open,
setOpen,
}: ControlledRagModalProps) => {
const classes = useStyles();
const [showAiModal, setShowAiModal] = useState(false);
const [thinking, setThinking] = useState(false);
const [questionResult, setQuestionResult] = useState('');
const [embeddings, setEmbeddings] = useState<ResponseEmbedding[]>([]);
Expand All @@ -83,12 +99,12 @@ export const RagModal = ({ title = 'AI Assistant' }: { title?: string }) => {
},
[ragApi],
);
useHotkeys('ctrl+comma', () => setShowAiModal(true), []);
useHotkeys(hotkey, () => setOpen(true), []);
return (
<Dialog
open={Boolean(showAiModal)}
open={open}
onClose={() => {
setShowAiModal(false);
setOpen(false);
setThinking(false);
setQuestionResult('');
setEmbeddings([]);
Expand All @@ -101,7 +117,7 @@ export const RagModal = ({ title = 'AI Assistant' }: { title?: string }) => {
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={() => setShowAiModal(false)}
onClick={() => setOpen(false)}
>
<CloseIcon />
</IconButton>
Expand Down Expand Up @@ -153,3 +169,9 @@ export const RagModal = ({ title = 'AI Assistant' }: { title?: string }) => {
</Dialog>
);
};

export const UncontrolledRagModal = (props: UncontrolledRagModalProps) => {
const [open, setOpen] = useState(false);

return <ControlledRagModal open={open} setOpen={setOpen} {...props} />;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2024 Larder Software Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useState } from 'react';
import AssistantIcon from '@material-ui/icons/Assistant';
import { SidebarItem } from '@backstage/core-components';
import { IconComponent } from '@backstage/core-plugin-api';
import { ControlledRagModal, RagModalProps } from './RagModal';

export type SidebarRagModalProps = RagModalProps & {
icon?: IconComponent;
};

export const SidebarRagModal = ({
title = 'AI Assistant',
icon = AssistantIcon,
...props
}: SidebarRagModalProps) => {
const [open, setOpen] = useState(false);

return (
<>
<SidebarItem icon={icon} text={title} onClick={() => setOpen(true)} />
<ControlledRagModal
title={title}
open={open}
setOpen={setOpen}
{...props}
/>
</>
);
};
3 changes: 2 additions & 1 deletion plugins/frontend/rag-ai/src/components/RagModal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { RagModal } from './RagModal';
export { UncontrolledRagModal } from './RagModal';
export { SidebarRagModal } from './SidebarRagModal';
2 changes: 1 addition & 1 deletion plugins/frontend/rag-ai/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { ragAiPlugin, RagModal } from './plugin';
export { ragAiPlugin, RagModal, SidebarRagModal } from './plugin';
export { RoadieRagAiClient, ragAiApiRef } from './api';
12 changes: 11 additions & 1 deletion plugins/frontend/rag-ai/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,17 @@ export const RagModal = ragAiPlugin.provide(
createComponentExtension({
name: 'RagModal',
component: {
lazy: () => import('./components/RagModal').then(m => m.RagModal),
lazy: () =>
import('./components/RagModal').then(m => m.UncontrolledRagModal),
},
}),
);

export const SidebarRagModal = ragAiPlugin.provide(
createComponentExtension({
name: 'SidebarRagModal',
component: {
lazy: () => import('./components/RagModal').then(m => m.SidebarRagModal),
},
}),
);

0 comments on commit 9d2b848

Please sign in to comment.