mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-28 23:24:05 +00:00
feat: Sidebar and StoreProvider
This commit is contained in:
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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'
|
||||
}}
|
||||
>
|
||||
{/* 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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
38
packages/grafnode-components/src/components/Sidebar/index.js
Normal file
38
packages/grafnode-components/src/components/Sidebar/index.js
Normal 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;
|
||||
@@ -1,4 +1,7 @@
|
||||
import Navbar from './components/Navbar';
|
||||
import Sidebar from './components/Sidebar';
|
||||
|
||||
export default Navbar;
|
||||
|
||||
export {
|
||||
Navbar,
|
||||
Sidebar
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user