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 { updateLeftSidebarWidth, updateIsDragging, toggleLeftMenuBar } from 'providers/ReduxStore/slices/app';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import WorkspaceSelector from 'components/Workspaces/WorkspaceSelector';
|
||||
|
||||
const MIN_LEFT_SIDEBAR_WIDTH = 222;
|
||||
const MAX_LEFT_SIDEBAR_WIDTH = 600;
|
||||
@ -73,6 +74,7 @@ const Sidebar = () => {
|
||||
<div className="flex flex-col w-full">
|
||||
<div className="flex flex-col flex-grow">
|
||||
<TitleBar />
|
||||
<WorkspaceSelector />
|
||||
|
||||
<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">
|
||||
|
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 collectionsReducer from './slices/collections';
|
||||
import tabsReducer from './slices/tabs';
|
||||
import workspacesReducer from './slices/workspaces';
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
app: appReducer,
|
||||
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