mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-28 10:53:13 +01:00
feat: Sidebar and StoreProvider
This commit is contained in:
parent
07fc8af7ed
commit
a863f9730d
67
package-lock.json
generated
67
package-lock.json
generated
@ -14,10 +14,13 @@
|
|||||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||||
"@grafnode/www": "^0.0.1",
|
"@grafnode/www": "^0.0.1",
|
||||||
"@tabler/icons": "^1.46.0",
|
"@tabler/icons": "^1.46.0",
|
||||||
|
"@tippyjs/react": "^4.2.6",
|
||||||
"babel-plugin-styled-components": "^2.0.2",
|
"babel-plugin-styled-components": "^2.0.2",
|
||||||
"babel-preset-next": "^1.4.0",
|
"babel-preset-next": "^1.4.0",
|
||||||
"eslint": "7.32.0",
|
"eslint": "7.32.0",
|
||||||
"eslint-config-next": "12.0.4",
|
"eslint-config-next": "12.0.4",
|
||||||
|
"immer": "^9.0.7",
|
||||||
|
"nanoid": "^3.1.30",
|
||||||
"next": "12.0.4",
|
"next": "12.0.4",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
@ -3529,6 +3532,15 @@
|
|||||||
"@octokit/openapi-types": "^11.2.0"
|
"@octokit/openapi-types": "^11.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@popperjs/core": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
|
||||||
|
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/popperjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rushstack/eslint-patch": {
|
"node_modules/@rushstack/eslint-patch": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
||||||
@ -3547,6 +3559,18 @@
|
|||||||
"react-dom": "^16.x || 17.x"
|
"react-dom": "^16.x || 17.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tippyjs/react": {
|
||||||
|
"version": "4.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
|
||||||
|
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tippy.js": "^6.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tootallnate/once": {
|
"node_modules/@tootallnate/once": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
||||||
@ -7905,6 +7929,15 @@
|
|||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immer": {
|
||||||
|
"version": "9.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.7.tgz",
|
||||||
|
"integrity": "sha512-KGllzpbamZDvOIxnmJ0jI840g7Oikx58lBPWV0hUh7dtAyZpFqqrBZdKka5GlTwMTZ1Tjc/bKKW4VSFAt6BqMA==",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/immer"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/import-cwd": {
|
"node_modules/import-cwd": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
||||||
@ -13326,6 +13359,14 @@
|
|||||||
"node": ">=0.6.0"
|
"node": ">=0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tippy.js": {
|
||||||
|
"version": "6.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
|
||||||
|
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@popperjs/core": "^2.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tmp": {
|
"node_modules/tmp": {
|
||||||
"version": "0.0.33",
|
"version": "0.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||||
@ -16858,6 +16899,11 @@
|
|||||||
"@octokit/openapi-types": "^11.2.0"
|
"@octokit/openapi-types": "^11.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@popperjs/core": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
|
||||||
|
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ=="
|
||||||
|
},
|
||||||
"@rushstack/eslint-patch": {
|
"@rushstack/eslint-patch": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
||||||
@ -16869,6 +16915,14 @@
|
|||||||
"integrity": "sha512-GufZYxw32OcqejSUpn5XdZi7zP/d+tUZH3S+mMlv3AnMn6MStOBKXOxqWYrJ529hjj1m5JHeghwHmHpj3SRJYg==",
|
"integrity": "sha512-GufZYxw32OcqejSUpn5XdZi7zP/d+tUZH3S+mMlv3AnMn6MStOBKXOxqWYrJ529hjj1m5JHeghwHmHpj3SRJYg==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
|
"@tippyjs/react": {
|
||||||
|
"version": "4.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
|
||||||
|
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
|
||||||
|
"requires": {
|
||||||
|
"tippy.js": "^6.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@tootallnate/once": {
|
"@tootallnate/once": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
|
||||||
@ -20274,6 +20328,11 @@
|
|||||||
"queue": "6.0.2"
|
"queue": "6.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"immer": {
|
||||||
|
"version": "9.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.7.tgz",
|
||||||
|
"integrity": "sha512-KGllzpbamZDvOIxnmJ0jI840g7Oikx58lBPWV0hUh7dtAyZpFqqrBZdKka5GlTwMTZ1Tjc/bKKW4VSFAt6BqMA=="
|
||||||
|
},
|
||||||
"import-cwd": {
|
"import-cwd": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
||||||
@ -24425,6 +24484,14 @@
|
|||||||
"setimmediate": "^1.0.4"
|
"setimmediate": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tippy.js": {
|
||||||
|
"version": "6.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
|
||||||
|
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
|
||||||
|
"requires": {
|
||||||
|
"@popperjs/core": "^2.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tmp": {
|
"tmp": {
|
||||||
"version": "0.0.33",
|
"version": "0.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||||
|
@ -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 Navbar from './components/Navbar';
|
||||||
|
import Sidebar from './components/Sidebar';
|
||||||
|
|
||||||
export default Navbar;
|
export {
|
||||||
|
Navbar,
|
||||||
|
Sidebar
|
||||||
|
};
|
||||||
|
13
packages/grafnode-run/jsconfig.json
Normal file
13
packages/grafnode-run/jsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2017",
|
||||||
|
"allowSyntheticDefaultImports": false,
|
||||||
|
"baseUrl": "./",
|
||||||
|
"paths": {
|
||||||
|
"components/*": ["src/components/*"],
|
||||||
|
"pageComponents/*": ["src/pageComponents/*"],
|
||||||
|
"providers/*": ["src/providers/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
67
packages/grafnode-run/package-lock.json
generated
67
packages/grafnode-run/package-lock.json
generated
@ -13,6 +13,9 @@
|
|||||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||||
"@grafnode/www": "^0.0.1",
|
"@grafnode/www": "^0.0.1",
|
||||||
"@tabler/icons": "^1.46.0",
|
"@tabler/icons": "^1.46.0",
|
||||||
|
"@tippyjs/react": "^4.2.6",
|
||||||
|
"immer": "^9.0.7",
|
||||||
|
"nanoid": "^3.1.30",
|
||||||
"next": "12.0.4",
|
"next": "12.0.4",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
@ -2623,6 +2626,15 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@popperjs/core": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
|
||||||
|
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/popperjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rushstack/eslint-patch": {
|
"node_modules/@rushstack/eslint-patch": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
||||||
@ -2642,6 +2654,18 @@
|
|||||||
"react-dom": "^16.x || 17.x"
|
"react-dom": "^16.x || 17.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tippyjs/react": {
|
||||||
|
"version": "4.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
|
||||||
|
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tippy.js": "^6.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/json5": {
|
"node_modules/@types/json5": {
|
||||||
"version": "0.0.29",
|
"version": "0.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
@ -5059,6 +5083,15 @@
|
|||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immer": {
|
||||||
|
"version": "9.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.7.tgz",
|
||||||
|
"integrity": "sha512-KGllzpbamZDvOIxnmJ0jI840g7Oikx58lBPWV0hUh7dtAyZpFqqrBZdKka5GlTwMTZ1Tjc/bKKW4VSFAt6BqMA==",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/immer"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/import-cwd": {
|
"node_modules/import-cwd": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
||||||
@ -7565,6 +7598,14 @@
|
|||||||
"node": ">=0.6.0"
|
"node": ">=0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tippy.js": {
|
||||||
|
"version": "6.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
|
||||||
|
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@popperjs/core": "^2.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tmp": {
|
"node_modules/tmp": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||||
@ -9782,6 +9823,11 @@
|
|||||||
"fastq": "^1.6.0"
|
"fastq": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@popperjs/core": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
|
||||||
|
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ=="
|
||||||
|
},
|
||||||
"@rushstack/eslint-patch": {
|
"@rushstack/eslint-patch": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz",
|
||||||
@ -9794,6 +9840,14 @@
|
|||||||
"integrity": "sha512-GufZYxw32OcqejSUpn5XdZi7zP/d+tUZH3S+mMlv3AnMn6MStOBKXOxqWYrJ529hjj1m5JHeghwHmHpj3SRJYg==",
|
"integrity": "sha512-GufZYxw32OcqejSUpn5XdZi7zP/d+tUZH3S+mMlv3AnMn6MStOBKXOxqWYrJ529hjj1m5JHeghwHmHpj3SRJYg==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
|
"@tippyjs/react": {
|
||||||
|
"version": "4.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz",
|
||||||
|
"integrity": "sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==",
|
||||||
|
"requires": {
|
||||||
|
"tippy.js": "^6.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/json5": {
|
"@types/json5": {
|
||||||
"version": "0.0.29",
|
"version": "0.0.29",
|
||||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
@ -11646,6 +11700,11 @@
|
|||||||
"queue": "6.0.2"
|
"queue": "6.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"immer": {
|
||||||
|
"version": "9.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.7.tgz",
|
||||||
|
"integrity": "sha512-KGllzpbamZDvOIxnmJ0jI840g7Oikx58lBPWV0hUh7dtAyZpFqqrBZdKka5GlTwMTZ1Tjc/bKKW4VSFAt6BqMA=="
|
||||||
|
},
|
||||||
"import-cwd": {
|
"import-cwd": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
|
||||||
@ -13517,6 +13576,14 @@
|
|||||||
"setimmediate": "^1.0.4"
|
"setimmediate": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tippy.js": {
|
||||||
|
"version": "6.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
|
||||||
|
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
|
||||||
|
"requires": {
|
||||||
|
"@popperjs/core": "^2.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tmp": {
|
"tmp": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||||
"@grafnode/www": "^0.0.1",
|
"@grafnode/www": "^0.0.1",
|
||||||
"@tabler/icons": "^1.46.0",
|
"@tabler/icons": "^1.46.0",
|
||||||
|
"@tippyjs/react": "^4.2.6",
|
||||||
|
"immer": "^9.0.7",
|
||||||
|
"nanoid": "^3.1.30",
|
||||||
"next": "12.0.4",
|
"next": "12.0.4",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: calc(100vh - 38px);
|
||||||
|
|
||||||
|
aside {
|
||||||
|
min-width: 230px;
|
||||||
|
border-right: solid 1px #e1e1e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.main {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
section.request-pane, section.response-pane {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div.drag-request {
|
||||||
|
display: flex;
|
||||||
|
width: 1px;
|
||||||
|
padding: 0;
|
||||||
|
cursor: col-resize;
|
||||||
|
background: #e1e1e1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: silver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fw-600 {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs {
|
||||||
|
.react-tabs__tab-list {
|
||||||
|
padding-left: 1rem;
|
||||||
|
border-bottom: 1px solid #cfcfcf;
|
||||||
|
|
||||||
|
.react-tabs__tab--selected {
|
||||||
|
border-color: #cfcfcf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.collection-filter {
|
||||||
|
input {
|
||||||
|
border: 1px solid rgb(211 211 211);
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Wrapper;
|
33
packages/grafnode-run/src/pageComponents/Main/index.js
Normal file
33
packages/grafnode-run/src/pageComponents/Main/index.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {Navbar, Sidebar} from '@grafnode/components';
|
||||||
|
import actions from 'providers/Store/actions';
|
||||||
|
import { useStore } from 'providers/Store';
|
||||||
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
|
export default function Main() {
|
||||||
|
const [state, dispatch] = useStore();
|
||||||
|
|
||||||
|
const {
|
||||||
|
collections,
|
||||||
|
activeRequestTabId
|
||||||
|
} = state;
|
||||||
|
|
||||||
|
console.log(actions);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Navbar />
|
||||||
|
<StyledWrapper>
|
||||||
|
<Sidebar
|
||||||
|
collections={collections}
|
||||||
|
actions={actions}
|
||||||
|
dispatch={dispatch}
|
||||||
|
activeRequestTabId={activeRequestTabId}
|
||||||
|
/>
|
||||||
|
<section className='mt-4 flex flex-grow flex-col'>
|
||||||
|
Request & Response Tabs
|
||||||
|
</section>
|
||||||
|
</StyledWrapper>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -1,8 +1,14 @@
|
|||||||
|
import { StoreProvider } from 'providers/Store';
|
||||||
|
|
||||||
import '../styles/globals.css'
|
import '../styles/globals.css'
|
||||||
import 'tailwindcss/dist/tailwind.min.css';
|
import 'tailwindcss/dist/tailwind.min.css';
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }) {
|
function MyApp({ Component, pageProps }) {
|
||||||
return <Component {...pageProps} />
|
return (
|
||||||
|
<StoreProvider>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</StoreProvider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MyApp
|
export default MyApp
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import Navbar from '@grafnode/components';
|
import Main from 'pageComponents/Main';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
@ -10,7 +10,7 @@ export default function Home() {
|
|||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<Navbar />
|
<Main />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
11
packages/grafnode-run/src/providers/Store/actions.js
Normal file
11
packages/grafnode-run/src/providers/Store/actions.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const SIDEBAR_COLLECTION_CLICK = "SIDEBAR_COLLECTION_CLICK";
|
||||||
|
const SIDEBAR_COLLECTION_ITEM_CLICK = "SIDEBAR_COLLECTION_ITEM_CLICK";
|
||||||
|
const REQUEST_TAB_CLICK = "REQUEST_TAB_CLICK";
|
||||||
|
const REQUEST_TAB_CLOSE = "REQUEST_TAB_CLOSE";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
SIDEBAR_COLLECTION_CLICK,
|
||||||
|
SIDEBAR_COLLECTION_ITEM_CLICK,
|
||||||
|
REQUEST_TAB_CLICK,
|
||||||
|
REQUEST_TAB_CLOSE
|
||||||
|
};
|
79
packages/grafnode-run/src/providers/Store/index.js
Normal file
79
packages/grafnode-run/src/providers/Store/index.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import React, { useContext, useReducer, createContext } from 'react';
|
||||||
|
import reducer from './reducer';
|
||||||
|
import { nanoid } from 'nanoid';
|
||||||
|
|
||||||
|
export const StoreContext = createContext();
|
||||||
|
|
||||||
|
const tabId1 = nanoid();
|
||||||
|
|
||||||
|
const collection = {
|
||||||
|
"id": nanoid(),
|
||||||
|
"name": "SpaceX",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": nanoid(),
|
||||||
|
"name": "Launches",
|
||||||
|
"depth": 1,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": nanoid(),
|
||||||
|
"depth": 2,
|
||||||
|
"name": "Capsules",
|
||||||
|
"request": {
|
||||||
|
"url": "https://api.spacex.land/graphql/",
|
||||||
|
"method": "POST",
|
||||||
|
"headers": [],
|
||||||
|
"body": {
|
||||||
|
"mimeType": "application/graphql",
|
||||||
|
"graphql": {
|
||||||
|
"query": "{\n launchesPast(limit: 10) {\n mission_name\n launch_date_local\n launch_site {\n site_name_long\n }\n links {\n article_link\n video_link\n }\n rocket {\n rocket_name\n first_stage {\n cores {\n flight\n core {\n reuse_count\n status\n }\n }\n }\n second_stage {\n payloads {\n payload_type\n payload_mass_kg\n payload_mass_lbs\n }\n }\n }\n ships {\n name\n home_port\n image\n }\n }\n}",
|
||||||
|
"variables": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": nanoid(),
|
||||||
|
"depth": 2,
|
||||||
|
"name": "Missions",
|
||||||
|
"request": {
|
||||||
|
"url": "https://api.spacex.land/graphql/",
|
||||||
|
"method": "POST",
|
||||||
|
"headers": [],
|
||||||
|
"body": {
|
||||||
|
"mimeType": "application/graphql",
|
||||||
|
"graphql": {
|
||||||
|
"query": "{\n launches {\n launch_site {\n site_id\n site_name\n site_name_long\n }\n launch_success\n }\n}",
|
||||||
|
"variables": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
collections: [collection],
|
||||||
|
activeRequestTabId: null,
|
||||||
|
requestTabs: []
|
||||||
|
};
|
||||||
|
|
||||||
|
export const StoreProvider = props => {
|
||||||
|
const [state, dispatch] = useReducer(reducer, initialState);
|
||||||
|
|
||||||
|
return <StoreContext.Provider value={[state, dispatch]} {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useStore = () => {
|
||||||
|
const context = useContext(StoreContext);
|
||||||
|
|
||||||
|
if (context === undefined) {
|
||||||
|
throw new Error(`useStore must be used within a StoreProvider`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StoreProvider;
|
79
packages/grafnode-run/src/providers/Store/reducer.js
Normal file
79
packages/grafnode-run/src/providers/Store/reducer.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import produce from 'immer';
|
||||||
|
import find from 'lodash/find';
|
||||||
|
import filter from 'lodash/filter';
|
||||||
|
import actions from './actions';
|
||||||
|
import {
|
||||||
|
flattenItems,
|
||||||
|
findItem,
|
||||||
|
isItemARequest,
|
||||||
|
itemIsOpenedInTabs
|
||||||
|
} from './utils';
|
||||||
|
|
||||||
|
const reducer = (state, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case actions.SIDEBAR_COLLECTION_CLICK: {
|
||||||
|
return produce(state, (draft) => {
|
||||||
|
const collecton = find(draft.collections, (c) => c.id === action.id);
|
||||||
|
|
||||||
|
if(collecton) {
|
||||||
|
collecton.collapsed = !collecton.collapsed;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
case actions.SIDEBAR_COLLECTION_ITEM_CLICK: {
|
||||||
|
return produce(state, (draft) => {
|
||||||
|
const collecton = find(draft.collections, (c) => c.id === action.collectionId);
|
||||||
|
|
||||||
|
if(collecton) {
|
||||||
|
let flattenedItems = flattenItems(collecton.items);
|
||||||
|
let item = findItem(flattenedItems, action.itemId);
|
||||||
|
|
||||||
|
if(item) {
|
||||||
|
item.collapsed = !item.collapsed;
|
||||||
|
|
||||||
|
if(isItemARequest(item)) {
|
||||||
|
if(itemIsOpenedInTabs(item, draft.requestTabs)) {
|
||||||
|
draft.activeRequestTabId = item.id;
|
||||||
|
} else {
|
||||||
|
draft.requestTabs.push({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
method: item.request.method,
|
||||||
|
collectionId: collecton.id
|
||||||
|
});
|
||||||
|
draft.activeRequestTabId = item.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
case actions.REQUEST_TAB_CLICK: {
|
||||||
|
return produce(state, (draft) => {
|
||||||
|
draft.activeRequestTabId = action.requestTab.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case actions.REQUEST_TAB_CLOSE: {
|
||||||
|
return produce(state, (draft) => {
|
||||||
|
draft.requestTabs = filter(draft.requestTabs, (rt) => rt.id !== action.requestTab.id);
|
||||||
|
|
||||||
|
if(draft.requestTabs && draft.requestTabs.length) {
|
||||||
|
draft.activeRequestTabId = draft.requestTabs[0].id;
|
||||||
|
console.log(draft.activeRequestTabId);
|
||||||
|
} else {
|
||||||
|
draft.activeRequestTabId = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default reducer;
|
32
packages/grafnode-run/src/providers/Store/utils.js
Normal file
32
packages/grafnode-run/src/providers/Store/utils.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import each from 'lodash/each';
|
||||||
|
import find from 'lodash/find';
|
||||||
|
|
||||||
|
export const flattenItems = (items = []) => {
|
||||||
|
const flattenedItems = [];
|
||||||
|
|
||||||
|
const flatten = (itms, flattened) => {
|
||||||
|
each(itms, (i) => {
|
||||||
|
flattened.push(i);
|
||||||
|
|
||||||
|
if(i.items && i.items.length) {
|
||||||
|
flatten(i.items, flattened);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
flatten(items, flattenedItems);
|
||||||
|
|
||||||
|
return flattenedItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findItem = (items = [], itemId) => {
|
||||||
|
return find(items, (i) => i.id === itemId);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isItemARequest = (item) => {
|
||||||
|
return item.hasOwnProperty('request');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const itemIsOpenedInTabs = (item, tabs) => {
|
||||||
|
return find(tabs, (t) => t.id === item.id);
|
||||||
|
};
|
@ -1,16 +1,16 @@
|
|||||||
html,
|
html, body {
|
||||||
body {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
padding: 0;
|
||||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
font-size: 1rem;
|
||||||
|
color: rgb(62 62 62);
|
||||||
|
|
||||||
|
font-kerning: none;
|
||||||
|
text-rendering: optimizeSpeed;
|
||||||
|
letter-spacing: normal;
|
||||||
|
/* font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; */
|
||||||
|
font-family: Inter, sans-serif !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
body {
|
||||||
color: inherit;
|
font-size: 0.875rem;
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user