Skip to content

Commit

Permalink
Merge pull request #10 from Gimnath-Perera/feat/inter-mock-connection
Browse files Browse the repository at this point in the history
feat: interface-select-content UI & landing UI changes added
  • Loading branch information
gimnathperera committed Sep 12, 2023
2 parents aacf014 + 00192db commit d9ea3d0
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 192 deletions.
47 changes: 31 additions & 16 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,63 @@ import { useDisclosure } from '@nextui-org/react';
import CodeEditor from '@/components/code-editor';
import Header from '@/components/header';
import Result from '@/components/result';
import { extractInterfaceNames } from '@/utils';
import { extractInterfaceNames, generateMocks } from '@/utils';
import { Initials } from '@/config/constants';
import InterfaceSelectModal from '@/components/interface-select-modal';
import { RowNumber } from '@/types';

const Home: FC = () => {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const detectedInterfaces = useRef<string[] | null>(null);
const mockResult = useRef<string | null>(JSON.stringify(Initials.DefaultMockResult));
const [code, setCode] = useState<string>(Initials.DefaultInterface);
const [numberOfRows, setNumberOfRows] = useState(new Set(['1']));
const [numberOfRows, setNumberOfRows] = useState<RowNumber>('1');
const [interfaces, setInterfaces] = useState<Set<string> | any>(
new Set(detectedInterfaces?.current),
);

const selectedInterfaces = useRef<string[] | null>(null);
const handleChipClose = (closedInterface: string): void => {
if (interfaces.size === 1) return;
const newSelectedKeys = new Set(Array.from(interfaces)?.filter(key => key !== closedInterface));
setInterfaces(newSelectedKeys);
};

const handleOnGenerate = (): void => {
const interfaceNamesToMock = extractInterfaceNames(code);
selectedInterfaces.current = interfaceNamesToMock;
detectedInterfaces.current = interfaceNamesToMock;
setInterfaces(new Set(interfaceNamesToMock));
onOpen();
};

// TODO: fix any type here
const handleOnRowCountChange = (newRowCount: any): void => {
setNumberOfRows(newRowCount);
};

const handleOnCodeChange = (newCode: string): void => {
setCode(newCode);
};

const handleOnMockGenerate = (): void => {
const generatedMocks = generateMocks(code, Array.from(interfaces));
mockResult.current = JSON.stringify(generatedMocks, null, 2);

onOpenChange();
};

return (
<section className='h-full'>
<Header
onGenerate={handleOnGenerate}
numberOfRows={numberOfRows}
onRowCountChange={handleOnRowCountChange}
/>
<Header onGenerate={handleOnGenerate} />
<div className='flex justify-center gap-6 h-[calc(100vh-12rem)]'>
<CodeEditor onCodeChange={handleOnCodeChange} initialCode={code} />
<Result />
<Result mockResult={mockResult?.current ?? ''} />
</div>

<InterfaceSelectModal
isOpen={isOpen}
detectedInterfaces={detectedInterfaces.current}
numberOfRows={numberOfRows}
onOpenChange={onOpenChange}
selectedInterfaces={selectedInterfaces.current}
onMockGenerate={handleOnMockGenerate}
setNumberOfRows={setNumberOfRows}
interfaces={interfaces}
setInterfaces={setInterfaces}
handleChipClose={handleChipClose}
/>
</section>
);
Expand Down
38 changes: 2 additions & 36 deletions components/header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,17 @@
import React, { FC } from 'react';
import {
Dropdown,
DropdownTrigger,
DropdownMenu,
DropdownItem,
Button,
Selection,
} from '@nextui-org/react';
import { Button } from '@nextui-org/react';

type Props = {
onGenerate: () => void;
onRowCountChange: (rowCount: Selection) => void;
numberOfRows: any;
};

const Header: FC<Props> = ({ onGenerate, onRowCountChange, numberOfRows }) => {
const selectedValue = React.useMemo(
() => Array.from(numberOfRows).join(', ').replaceAll('_', ' '),
[numberOfRows],
);

const Header: FC<Props> = ({ onGenerate }) => {
return (
<div className='pb-6 text-center flex items-center justify-between'>
<h1 className='tracking-tight inline font-semibold text-[2.3rem] lg:text-3xl'>
Generate 𝔽𝕒𝕜𝕖 Data
</h1>
<div className='flex items-center gap-4'>
<Dropdown>
<DropdownTrigger>
<Button variant='bordered' className='capitalize'>
{`#️⃣ Scale [${selectedValue} of row${Number(selectedValue) > 1 ? 's' : ''}]`}
</Button>
</DropdownTrigger>
<DropdownMenu
aria-label='row-count-select'
variant='flat'
disallowEmptySelection
selectionMode='single'
selectedKeys={numberOfRows}
onSelectionChange={onRowCountChange}
>
<DropdownItem key='1'>1</DropdownItem>
<DropdownItem key='10'>10</DropdownItem>
<DropdownItem key='50'>50</DropdownItem>
</DropdownMenu>
</Dropdown>

<Button color='primary' variant='shadow' onClick={onGenerate}>
🪄 Generate
</Button>
Expand Down
105 changes: 64 additions & 41 deletions components/interface-select-content/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
import React, { FC, useState } from 'react';
import { Listbox, ListboxItem } from '@nextui-org/react';
import React, { FC, Key } from 'react';
import { Chip } from '@nextui-org/react';
import { Colors } from '@/config/constants';
import { Listbox, ListboxItem, Radio, RadioGroup } from '@nextui-org/react';
import { RowNumber } from '@/types';

const InterfaceSelectContent: FC = () => {
const [selectedKeys, setSelectedKeys] = useState<Set<string> | any>(new Set(['text']));
interface Props {
detectedInterfaces: string[];
interfaces: Set<string>;
numberOfRows: RowNumber;
setInterfaces: (keys: Set<Key>) => void;
handleChipClose: (closedInterface: string) => void;
setNumberOfRows: (numberOfRows: RowNumber) => void;
}

const backgroundColors: string[] = [
'bg-primary',
'bg-secondary',
'bg-warning',
'bg-danger',
'bg-default',
];
const handleChipClose = (closedInterface: string): void => {
if (selectedKeys.size === 1) return;
const newSelectedKeys = new Set(
Array.from(selectedKeys).filter(key => key !== closedInterface),
);
setSelectedKeys(newSelectedKeys);
const InterfaceSelectContent: FC<Props> = ({
detectedInterfaces,
numberOfRows,
setNumberOfRows,
interfaces,
setInterfaces,
handleChipClose,
}) => {
const handleNumberOfRowsChange = (value: string): void => {
setNumberOfRows(value as RowNumber);
};

const handleInterfaceChange = (selectedInterfaces: Set<Key>): void => {
if (selectedInterfaces?.size > 1) setNumberOfRows('1');
setInterfaces(selectedInterfaces);
};

return (
Expand All @@ -27,33 +37,46 @@ const InterfaceSelectContent: FC = () => {
variant='flat'
disallowEmptySelection
selectionMode='multiple'
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
selectedKeys={interfaces}
onSelectionChange={(keys): void => handleInterfaceChange(new Set(keys))}
>
<ListboxItem key='text'>⚡ Text</ListboxItem>
<ListboxItem key='number'>⚡ Number</ListboxItem>
<ListboxItem key='date'>⚡ Date</ListboxItem>
<ListboxItem key='single_date'>⚡ Single Date</ListboxItem>
<ListboxItem key='iteration'>⚡ Iteration</ListboxItem>
{detectedInterfaces?.map((interfaceName: any) => (
<ListboxItem key={interfaceName}>{`⚡ ${interfaceName}`}</ListboxItem>
)) || null}
</Listbox>
<div className='flex flex-wrap gap-2 items-center'>
<p className='text-small text-default-500'>Selected interfaces: </p>
{Array.from(selectedKeys).map((selectedInterface: any, index: number) => (
<Chip
size='sm'
radius='full'
variant='flat'
key={selectedInterface}
onClose={(): void => handleChipClose(selectedInterface)}
classNames={{
base: backgroundColors[index % backgroundColors.length],
content: 'text-white',
}}
>
{selectedInterface}
</Chip>
))}

<div className='mb-4'>
<p className='mb-3'>Selected interfaces </p>
<div className='flex flex-wrap gap-2 items-center'>
{Array.from(interfaces).map((interfaceName: any, index: number) => (
<Chip
size='sm'
radius='full'
variant='flat'
key={interfaceName}
onClose={(): void => handleChipClose(interfaceName)}
classNames={{
base: Colors.ChipClors[index % Colors.ChipClors.length],
content: 'text-white',
}}
>
{interfaceName}
</Chip>
))}
</div>
</div>
{interfaces.size === 1 ? (
<RadioGroup
label={<p className='text-white'>Scale number of rows</p>}
orientation='horizontal'
value={numberOfRows}
onValueChange={handleNumberOfRowsChange}
>
<Radio value='1'>1 Row</Radio>
<Radio value='10'>10 Rows</Radio>
<Radio value='50'>50 Rows</Radio>
</RadioGroup>
) : null}
</div>
);
};
Expand Down
36 changes: 29 additions & 7 deletions components/interface-select-modal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC } from 'react';
import React, { FC, Key } from 'react';
import {
Modal,
ModalContent,
Expand All @@ -8,16 +8,31 @@ import {
Button,
} from '@nextui-org/react';
import InterfaceSelectContent from '@/components/interface-select-content';
import { RowNumber } from '@/types';

interface Props {
isOpen: boolean;
selectedInterfaces: string[] | null;
detectedInterfaces: string[] | null;
numberOfRows: RowNumber;
interfaces: Set<string>;
onOpenChange: () => void;
setNumberOfRows: (numberOfRows: RowNumber) => void;
setInterfaces: (keys: Set<Key>) => void;
handleChipClose: (closedInterface: string) => void;
onMockGenerate: () => void;
}

const InterfaceSelectModal: FC<Props> = ({ isOpen, onOpenChange, selectedInterfaces }) => {
console.log('🚀 ~ file: index.tsx:18 ~ selectedInterfaces:', selectedInterfaces);

const InterfaceSelectModal: FC<Props> = ({
isOpen,
detectedInterfaces,
numberOfRows,
interfaces,
setNumberOfRows,
onOpenChange,
setInterfaces,
handleChipClose,
onMockGenerate,
}) => {
return (
<>
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
Expand All @@ -29,13 +44,20 @@ const InterfaceSelectModal: FC<Props> = ({ isOpen, onOpenChange, selectedInterfa
</ModalHeader>
<ModalBody>
<p>Please select the interfaces you want to generate mock data for.</p>
<InterfaceSelectContent />
<InterfaceSelectContent
detectedInterfaces={detectedInterfaces ?? []}
numberOfRows={numberOfRows}
setNumberOfRows={setNumberOfRows}
interfaces={interfaces}
setInterfaces={setInterfaces}
handleChipClose={handleChipClose}
/>
</ModalBody>
<ModalFooter>
<Button color='danger' variant='bordered' onPress={onClose}>
Close
</Button>
<Button color='primary' onPress={onClose}>
<Button color='primary' onPress={onMockGenerate}>
🪄 Generate
</Button>
</ModalFooter>
Expand Down
Loading

0 comments on commit d9ea3d0

Please sign in to comment.