Skip to content

Commit

Permalink
fix(console-code-picker): add accordion based on tags and doc link added
Browse files Browse the repository at this point in the history
  • Loading branch information
kartik-gupta-ij committed Nov 8, 2024
1 parent 1818a2e commit ffb818f
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import _ from 'lodash';
import { InputAdornment, TextField } from '@mui/material';
import { Search } from '@mui/icons-material';

const CommandSearch = ({ commands, setCommands }) => {
const ref = React.useRef(null);

const CommandSearch = ({ commands, setCommands, setSearchTerms }) => {

const ref = React.useRef(null);
const handleSearch = (event) => {
const value = event.target.value;
const { value } = event.target;

if (value === '') {
setCommands(commands);
setSearchTerms([]);
} else {
const searchTerms = value.split(' ');
setSearchTerms(searchTerms);
const nextCommands = commands
.reduce((acc, command) => {
const commandTerms = [command.method, command.command, command.description];
Expand Down Expand Up @@ -63,6 +65,7 @@ const CommandSearch = ({ commands, setCommands }) => {
CommandSearch.propTypes = {
commands: PropTypes.array.isRequired,
setCommands: PropTypes.func.isRequired,
setSearchTerms: PropTypes.func.isRequired,
};

export default CommandSearch;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { resolveRequiredBodyParams, resolveRequiredPathParams } from '../../conf
const CommandsDrawer = ({ open, toggleDrawer, handleInsertCommand }) => {
const [allCommands, setAllCommands] = useState([]);
const [commands, setCommands] = useState([]);
const [searchTerms, setSearchTerms] = useState([]);
const matchesMdMedia = useMediaQuery('(max-width: 992px)');
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
const errorSnackbarOptions = getSnackbarOptions('error', closeSnackbar, 6000);
Expand All @@ -32,6 +33,7 @@ const CommandsDrawer = ({ open, toggleDrawer, handleInsertCommand }) => {
if (hasRequestBody) {
requiredBodyParameters = resolveRequiredBodyParams(data, data.paths[path][method].requestBody.content);
}
const operationId = data.paths[path][method].operationId;

return {
method: method.toUpperCase(),
Expand All @@ -41,6 +43,7 @@ const CommandsDrawer = ({ open, toggleDrawer, handleInsertCommand }) => {
tags,
requiredBodyParameters,
requiredPathParameters,
operationId,
};
});
})
Expand Down Expand Up @@ -84,10 +87,14 @@ const CommandsDrawer = ({ open, toggleDrawer, handleInsertCommand }) => {
<Typography variant={'body1'} mb={4}>
This is a list of commands that can be used in the editor.
</Typography>
<CommandSearch commands={allCommands} setCommands={setCommands} />
<CommandSearch commands={allCommands} setCommands={setCommands}
setSearchTerms={setSearchTerms}
/>
</Box>
<Box sx={{ flexGrow: 1, overflowY: 'auto' }}>
<CommandsTable commands={commands} handleInsertCommand={handleInsertCommand} />
<CommandsTable commands={commands} handleInsertCommand={handleInsertCommand}
searchTerms={searchTerms}
/>
</Box>
</Drawer>
);
Expand Down
115 changes: 107 additions & 8 deletions src/components/CodeEditorWindow/Menu/CommandsDrawer/CommandsTable.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import React, { forwardRef, useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { TableBodyWithGaps, TableWithGaps } from '../../../Common/TableWithGaps';
import { alpha, Box, Chip, TableCell, TableRow, Typography, Modal, TextField, Button } from '@mui/material';
import {
alpha,
Box,
Chip,
TableCell,
TableRow,
Typography,
Modal,
TextField,
Button,
Accordion,
AccordionSummary,
AccordionDetails,
Link,
} from '@mui/material';
import { useTheme } from '@mui/material/styles';
import IconButton from '@mui/material/IconButton';
import { ArrowBack } from '@mui/icons-material';
import Tooltip from '@mui/material/Tooltip';
import { useSnackbar } from 'notistack';
import { getSnackbarOptions } from '../../../Common/utils/snackbarOptions';
import { debounce } from 'lodash';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import _ from 'lodash';

const DOCS_BASE_URL = 'https://api.qdrant.tech/api-reference/';

const CommandsTableRow = forwardRef((props, ref) => {
const { method, command, description, tags, onClick, tabIndex, isActive } = props;
const { method, command, description, tags, onClick, tabIndex, isActive, searchTerms, operationId } = props;
const theme = useTheme();

const getColor = (method) => {
Expand All @@ -38,6 +56,23 @@ const CommandsTableRow = forwardRef((props, ref) => {
borderColor: `${color} !important`,
};

const highlightText = (text, searchTerms) => {
if (searchTerms.length === 0) {
return text;
}
const escapedSearchTerms = searchTerms.map(_.escapeRegExp);
const regex = new RegExp(`(${escapedSearchTerms.join('|')})`, 'gi');
return text.split(regex).map((part, index) =>
regex.test(part) ? (
<span key={index} style={{ color: 'yellow' }}>
{part}
</span>
) : (
part
)
);
};

const tagList = tags.map((tag) => (
<React.Fragment key={tag}>
<Typography
Expand All @@ -60,6 +95,8 @@ const CommandsTableRow = forwardRef((props, ref) => {
</React.Fragment>
));

const docsURL = `${DOCS_BASE_URL}${tags[0].toLowerCase()}/${operationId.replace(/_/g, '-')}`;

return (
<TableRow
sx={{
Expand Down Expand Up @@ -87,21 +124,26 @@ const CommandsTableRow = forwardRef((props, ref) => {
<Chip color={colorName} label={method} size="small" />
<Box>
<Typography component={'code'} ml={2}>
{command}
{highlightText(command, searchTerms)}
</Typography>
<br />
<Typography
variant={'caption'}
ml={2}
color={theme.palette.mode === 'light' ? theme.palette.grey[700] : theme.palette.grey[400]}
>
{description}
{highlightText(description, searchTerms)}
</Typography>
</Box>
</Box>
</TableCell>
<TableCell sx={rowStyle} align="right">
{tagList}
<Typography variant="caption">
<Link href={docsURL} target="_blank" rel="noopener noreferrer">
Documentation
</Link>
</Typography>
</TableCell>
</TableRow>
);
Expand All @@ -117,9 +159,11 @@ CommandsTableRow.propTypes = {
onClick: PropTypes.func.isRequired,
isActive: PropTypes.bool.isRequired,
tabIndex: PropTypes.number.isRequired,
searchTerms: PropTypes.array,
operationId: PropTypes.string.isRequired,
};

const CommandsTable = ({ commands, handleInsertCommand }) => {
const CommandsTable = ({ commands, handleInsertCommand, searchTerms }) => {
const [active, setActive] = React.useState(null);
const listRefs = useRef([]);
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
Expand All @@ -133,6 +177,10 @@ const CommandsTable = ({ commands, handleInsertCommand }) => {
listRefs.current = listRefs.current.slice(0, commands.length);
}, [commands, commands.length]);

useEffect(() => {
console.log('commands', searchTerms);
}, [searchTerms]);

const handleModalOpen = (command) => {
setCurrentCommand(command);
setModalData({
Expand Down Expand Up @@ -215,6 +263,49 @@ const CommandsTable = ({ commands, handleInsertCommand }) => {
};
}, [active]);

const groupedCommands = commands.reduce((acc, command) => {
command.tags.forEach((tag) => {
if (!acc[tag]) {
acc[tag] = [];
}
acc[tag].push(command);
});
return acc;
}, {});

const accordions = Object.keys(groupedCommands).map((tag) => (
<Accordion key={tag}>
<AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls={`${tag}-content`} id={`${tag}-header`}>
<Typography>{tag}</Typography>
</AccordionSummary>
<AccordionDetails>
<TableWithGaps>
<TableBodyWithGaps>
{groupedCommands[tag].map((command, index) => (
<CommandsTableRow
tabIndex={0}
ref={(el) => (listRefs.current[index] = el)}
key={command.method + '_' + command.command}
method={command.method}
command={command.command}
description={command.description}
searchTerms={searchTerms}
tags={command.tags}
isActive={active === index}
onClick={(e) => {
if (e.target.classList.contains('insert-button') || e.target.closest('.insert-button')) {
handleClick(command);
}
}}
operationId={command.operationId}
/>
))}
</TableBodyWithGaps>
</TableWithGaps>
</AccordionDetails>
</Accordion>
));

const rows = commands.map((command, index) => (
<CommandsTableRow
tabIndex={0} // Make the list item focusable
Expand All @@ -225,20 +316,27 @@ const CommandsTable = ({ commands, handleInsertCommand }) => {
description={command.description}
tags={command.tags}
isActive={active === index}
searchTerms={searchTerms}
onClick={(e) => {
// we want insert command only if user clicks on the button with the class 'insert-button'
if (e.target.classList.contains('insert-button') || e.target.closest('.insert-button')) {
handleClick(command);
}
}}
operationId={command.operationId}
/>
));

return (
<>
<TableWithGaps data-testid="commands-table">
<TableBodyWithGaps>{rows}</TableBodyWithGaps>
</TableWithGaps>
{searchTerms.length === 0 ? (
accordions
) : (
<TableWithGaps>
<TableBodyWithGaps>{rows}</TableBodyWithGaps>
</TableWithGaps>
)}

<Modal open={modalOpen} onClose={handleModalClose}>
<Box
sx={{
Expand Down Expand Up @@ -280,6 +378,7 @@ CommandsTable.propTypes = {
})
).isRequired,
handleInsertCommand: PropTypes.func.isRequired,
searchTerms: PropTypes.array.isRequired,
};

export default CommandsTable;

0 comments on commit ffb818f

Please sign in to comment.