mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-25 09:23:17 +01:00
Feature | workspace selector (#14)
feat: workspace selector (resolves #13)
This commit is contained in:
parent
3bf18a1127
commit
a17b6bef7a
@ -6,6 +6,7 @@ import MenuBar from './MenuBar';
|
|||||||
import { IconSearch, IconChevronsRight, IconSettings, IconShieldCheck, IconShieldX, IconLayoutGrid} from '@tabler/icons';
|
import { IconSearch, IconChevronsRight, IconSettings, IconShieldCheck, IconShieldX, IconLayoutGrid} from '@tabler/icons';
|
||||||
import { updateLeftSidebarWidth, updateIsDragging, toggleLeftMenuBar } from 'providers/ReduxStore/slices/app';
|
import { updateLeftSidebarWidth, updateIsDragging, toggleLeftMenuBar } from 'providers/ReduxStore/slices/app';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
import WorkspaceSelector from 'components/Workspaces/WorkspaceSelector';
|
||||||
|
|
||||||
const MIN_LEFT_SIDEBAR_WIDTH = 222;
|
const MIN_LEFT_SIDEBAR_WIDTH = 222;
|
||||||
const MAX_LEFT_SIDEBAR_WIDTH = 600;
|
const MAX_LEFT_SIDEBAR_WIDTH = 600;
|
||||||
@ -73,6 +74,7 @@ const Sidebar = () => {
|
|||||||
<div className="flex flex-col w-full">
|
<div className="flex flex-col w-full">
|
||||||
<div className="flex flex-col flex-grow">
|
<div className="flex flex-col flex-grow">
|
||||||
<TitleBar />
|
<TitleBar />
|
||||||
|
<WorkspaceSelector />
|
||||||
|
|
||||||
<div className="mt-4 relative collection-filter px-2">
|
<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">
|
<div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
|
||||||
|
39
renderer/components/Workspaces/WorkspaceConfigurer/index.js
Normal file
39
renderer/components/Workspaces/WorkspaceConfigurer/index.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import Modal from "components/Modal/index";
|
||||||
|
import React from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
const WorkspaceConfigurer = ({onClose}) => {
|
||||||
|
const { workspaces } = useSelector((state) => state.workspaces);
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
size="md"
|
||||||
|
title="Workspaces"
|
||||||
|
confirmText="Create"
|
||||||
|
handleConfirm={onSubmit}
|
||||||
|
handleCancel={onClose}
|
||||||
|
>
|
||||||
|
<ul className="mb-2">
|
||||||
|
{workspaces && workspaces.length && workspaces.map((workspace) => (
|
||||||
|
<div className="flex justify-between items-baseline w-4/5 mb-2">
|
||||||
|
<li key={workspace.uid}>{workspace.name}</li>
|
||||||
|
<button
|
||||||
|
style={{backgroundColor: "var(--color-brand)"}}
|
||||||
|
className="flex items-center h-full text-white active:bg-blue-600 font-bold text-xs px-4 py-2 ml-2 uppercase rounded shadow hover:shadow-md outline-none focus:outline-none ease-linear transition-all duration-150"
|
||||||
|
onClick={() => console.log("delete")}
|
||||||
|
>
|
||||||
|
<span style={{marginLeft: 5}}>Delete</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WorkspaceConfigurer;
|
@ -0,0 +1,17 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
.current-workspace {
|
||||||
|
margin-inline: .5rem;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.caret {
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
color: rgb(140, 140, 140);
|
||||||
|
fill: rgb(140, 140, 140);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Wrapper;
|
68
renderer/components/Workspaces/WorkspaceSelector/index.js
Normal file
68
renderer/components/Workspaces/WorkspaceSelector/index.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import React, { useRef, forwardRef, useState, useEffect } from 'react';
|
||||||
|
import Dropdown from 'components/Dropdown';
|
||||||
|
import { IconAdjustmentsHorizontal, IconCaretDown, IconBox } from '@tabler/icons';
|
||||||
|
import WorkspaceConfigurer from "../WorkspaceConfigurer";
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { selectWorkspace } from 'providers/ReduxStore/slices/workspaces';
|
||||||
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
|
const WorkspaceSelector = () => {
|
||||||
|
const dropdownTippyRef = useRef();
|
||||||
|
const [openWorkspacesModal, setOpenWorkspacesModal] = useState(false);
|
||||||
|
const [activeWorkspace, setActiveWorkspace] = useState({});
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const { workspaces, activeWorkspaceUid } = useSelector((state) => state.workspaces);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setActiveWorkspace(workspaces.find((workspace) => workspace.uid === activeWorkspaceUid));
|
||||||
|
}, [activeWorkspaceUid]);
|
||||||
|
|
||||||
|
const Icon = forwardRef((props, ref) => {
|
||||||
|
return (
|
||||||
|
<div ref={ref} className="current-workspace flex justify-between items-center pl-2 pr-2 py-1 select-none">
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<span className='mr-2'>
|
||||||
|
<IconBox size={18} strokeWidth={1.5}/>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{activeWorkspace.name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<IconCaretDown className="caret" size={14} strokeWidth={2}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const onDropdownCreate = (ref) => dropdownTippyRef.current = ref;
|
||||||
|
|
||||||
|
const handleSelectWorkspace = (workspace) => {
|
||||||
|
dispatch(selectWorkspace(workspace));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledWrapper>
|
||||||
|
<div className="items-center cursor-pointer">
|
||||||
|
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement='bottom-end'>
|
||||||
|
{workspaces && workspaces.length && workspaces.map((workspace) => (
|
||||||
|
<div className="dropdown-item" onClick={() => handleSelectWorkspace(workspace)}>
|
||||||
|
<span>{workspace.name}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<div className="dropdown-item" style={{borderTop: 'solid 1px #e7e7e7'}} onClick={() => {
|
||||||
|
setOpenWorkspacesModal(true);
|
||||||
|
}}>
|
||||||
|
<div className="pr-2 text-gray-600">
|
||||||
|
<IconAdjustmentsHorizontal size={18} strokeWidth={1.5}/>
|
||||||
|
</div>
|
||||||
|
<span>Configure</span>
|
||||||
|
</div>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
{openWorkspacesModal && <WorkspaceConfigurer onClose={() => setOpenWorkspacesModal(false)}/>}
|
||||||
|
</StyledWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default WorkspaceSelector;
|
@ -2,12 +2,14 @@ import { configureStore } from '@reduxjs/toolkit';
|
|||||||
import appReducer from './slices/app';
|
import appReducer from './slices/app';
|
||||||
import collectionsReducer from './slices/collections';
|
import collectionsReducer from './slices/collections';
|
||||||
import tabsReducer from './slices/tabs';
|
import tabsReducer from './slices/tabs';
|
||||||
|
import workspacesReducer from './slices/workspaces';
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
app: appReducer,
|
app: appReducer,
|
||||||
collections: collectionsReducer,
|
collections: collectionsReducer,
|
||||||
tabs: tabsReducer
|
tabs: tabsReducer,
|
||||||
|
workspaces: workspacesReducer
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
31
renderer/providers/ReduxStore/slices/workspaces.js
Normal file
31
renderer/providers/ReduxStore/slices/workspaces.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
workspaces: [{
|
||||||
|
uid: 123,
|
||||||
|
name: 'My Workspace'
|
||||||
|
},{
|
||||||
|
uid: 234,
|
||||||
|
name: 'workspace B'
|
||||||
|
},{
|
||||||
|
uid: 345,
|
||||||
|
name: 'workspace C'
|
||||||
|
}],
|
||||||
|
activeWorkspaceUid: 123
|
||||||
|
};
|
||||||
|
|
||||||
|
export const workspacesSlice = createSlice({
|
||||||
|
name: 'workspaces',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
selectWorkspace: (state, action) => {
|
||||||
|
state.activeWorkspaceUid = action.payload.uid;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {
|
||||||
|
selectWorkspace
|
||||||
|
} = workspacesSlice.actions;
|
||||||
|
|
||||||
|
export default workspacesSlice.reducer;
|
Loading…
Reference in New Issue
Block a user