feat: Sidebar and StoreProvider

This commit is contained in:
Anoop M D
2021-12-04 01:07:38 +05:30
parent 07fc8af7ed
commit a863f9730d
22 changed files with 759 additions and 18 deletions

View File

@@ -0,0 +1,34 @@
import styled from 'styled-components';
const Wrapper = styled.div`
.dropdown-toggle {
&:hover {
color: black;
}
}
.tippy-box {
min-width: 135px;
background-color: white;
color: rgb(82 82 82);
box-shadow: rgb(50 50 93 / 25%) 0px 6px 12px -2px, rgb(0 0 0 / 30%) 0px 3px 7px -3px;
.tippy-content {
padding-left: 0;
padding-right: 0;
.dropdown-item {
display: flex;
align-items: center;
padding: .3rem .5rem;
cursor: pointer;
&:hover {
background-color: #eee;
}
}
}
}
`;
export default Wrapper;

View File

@@ -0,0 +1,24 @@
import React from 'react';
import Tippy from '@tippyjs/react';
import StyledWrapper from './StyledWrapper';
const Dropdown = ({icon, children, onCreate, placement}) => {
return (
<StyledWrapper className="dropdown">
<Tippy
content={children}
placement={placement || "bottom-end"}
animation={false}
arrow={false}
onCreate={onCreate}
interactive={true}
trigger="click"
appendTo="parent"
>
{icon}
</Tippy>
</StyledWrapper>
);
};
export default Dropdown;

View File

@@ -0,0 +1,19 @@
import styled from 'styled-components';
const Wrapper = styled.div`
.collection-item-name {
height: 1.875rem;
cursor: pointer;
user-select: none;
.rotate-90 {
transform: rotateZ(90deg);
}
&.item-focused-in-tab, &:hover {
background:#ededed;
}
}
`;
export default Wrapper;

View File

@@ -0,0 +1,84 @@
import React from 'react';
import range from 'lodash/range';
import { IconChevronRight } from '@tabler/icons';
import classnames from 'classnames';
import StyledWrapper from './StyledWrapper';
const CollectionItem = ({item, collectionId, actions, dispatch, activeRequestTabId}) => {
const iconClassName = classnames({
'rotate-90': item.collapsed
});
const itemRowClassName = classnames('flex collection-item-name items-center', {
'item-focused-in-tab': item.id == activeRequestTabId
});
const handleClick = () => {
dispatch({
type: actions.SIDEBAR_COLLECTION_ITEM_CLICK,
itemId: item.id,
collectionId: collectionId
});
};
let indents = range(item.depth);
return (
<StyledWrapper className="flex flex-col">
<div
className={itemRowClassName}
onClick={handleClick}
>
<div className="flex items-center h-full w-full">
{indents && indents.length ? indents.map((i) => {
return (
<div
key={i}
style = {{
width: 16,
height: '100%',
borderRight: 'solid 1px #e1e1e1'
}}
>
&nbsp;{/* Indent */}
</div>
);
}) : null}
<div
className="flex items-center"
style = {{
paddingLeft: 8
}}
>
<div style={{width:16}}>
{item.items && item.items.length ? (
<IconChevronRight size={16} strokeWidth={2} className={iconClassName} style={{color: 'rgb(160 160 160)'}}/>
) : null}
</div>
<span className="ml-1">{item.name}</span>
</div>
</div>
</div>
{item.collapsed ? (
<div>
{item.items && item.items.length ? item.items.map((i) => {
return <CollectionItem
key={i.name}
item={i}
collectionId={collectionId}
actions={actions}
dispatch={dispatch}
activeRequestTabId={activeRequestTabId}
/>
}) : null}
</div>
) : null}
</StyledWrapper>
);
};
export default CollectionItem;

View File

@@ -0,0 +1,21 @@
import styled from 'styled-components';
const Wrapper = styled.div`
.collection-name {
height: 1.875rem;
cursor: pointer;
user-select: none;
padding-left: 8px;
padding-right: 8px;
.rotate-90 {
transform: rotateZ(90deg);
}
&:hover {
background:#ededed;
}
}
`;
export default Wrapper;

View File

@@ -0,0 +1,48 @@
import React from 'react';
import { IconChevronRight } from '@tabler/icons';
import CollectionItem from './CollectionItem';
import classnames from 'classnames';
import StyledWrapper from './StyledWrapper';
const Collection = ({collection, actions, dispatch, activeRequestTabId}) => {
const iconClassName = classnames({
'rotate-90': collection.collapsed
});
const handleClick = () => {
dispatch({
type: actions.SIDEBAR_COLLECTION_CLICK,
id: collection.id
});
};
return (
<StyledWrapper className="flex flex-col">
<div className="flex py-1 collection-name items-center" onClick={handleClick}>
<IconChevronRight size={16} strokeWidth={2} className={iconClassName} style={{width:16, color: 'rgb(160 160 160)'}}/>
<span className="ml-1">{collection.name}</span>
</div>
<div>
{collection.collapsed ? (
<div>
{collection.items && collection.items.length ? collection.items.map((i) => {
return <CollectionItem
key={i.name}
item={i}
collectionId={collection.id}
actions={actions}
dispatch={dispatch}
activeRequestTabId={activeRequestTabId}
/>
}) : null}
</div>
) : null}
</div>
</StyledWrapper>
);
};
export default Collection;

View File

@@ -0,0 +1,20 @@
import React from 'react';
import Collection from './Collection';
const Collections = ({collections, actions, dispatch, activeRequestTabId}) => {
return (
<div className="mt-4 flex flex-col">
{collections && collections.length ? collections.map((c) => {
return <Collection
collection={c}
key={c.id}
actions={actions}
dispatch={dispatch}
activeRequestTabId={activeRequestTabId}
/>
}) : null}
</div>
);
};
export default Collections;

View File

@@ -0,0 +1,38 @@
import React from 'react';
import Collections from './Collections';
import { IconDatabase, IconSearch } from '@tabler/icons';
const Sidebar = ({collections, actions, dispatch, activeRequestTabId}) => {
return (
<aside>
<div className="mt-4 px-2 flex">
<IconDatabase size={20} strokeWidth={1.5}/>
<span className="ml-1">No Environment</span>
</div>
<div className="mt-4 relative collection-filter px-2">
<div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<span className="text-gray-500 sm:text-sm">
<IconSearch size={16} strokeWidth={1.5}/>
</span>
</div>
<input
type="text"
name="price"
id="price"
className="block w-full pl-7 py-1 sm:text-sm"
placeholder="search"
/>
</div>
<Collections
collections={collections}
actions={actions}
dispatch={dispatch}
activeRequestTabId={activeRequestTabId}
/>
</aside>
);
};
export default Sidebar;

View File

@@ -1,4 +1,7 @@
import Navbar from './components/Navbar';
import Sidebar from './components/Sidebar';
export default Navbar;
export {
Navbar,
Sidebar
};