Skip to content

Commit 91b0ee7

Browse files
authored
Merge pull request #1522 from stakwork/feature/create-code-graph-page-1751453105
Create Code Graph workspace page
2 parents 1efca41 + 7c55136 commit 91b0ee7

File tree

4 files changed

+156
-1
lines changed

4 files changed

+156
-1
lines changed

src/components/common/SidebarComponent.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ export default function SidebarComponent({
621621
history.push(`/workspace/${uuid}/planner`);
622622
};
623623

624+
const handleCodeGraphClick = () => {
625+
history.push(`/workspace/${uuid}/codegraph`);
626+
};
627+
624628
const hasNextPage = chatOffset + CHATS_PER_PAGE < totalChats;
625629
const hasPreviousPage = chatOffset > 0;
626630

@@ -813,6 +817,23 @@ export default function SidebarComponent({
813817
)}
814818
</NavItem>
815819

820+
<NavItem
821+
active={window.location.pathname.includes('/codegraph')}
822+
onClick={handleCodeGraphClick}
823+
collapsed={collapsed}
824+
onMouseEnter={(e) => handleMouseEnter(e, 'codegraph')}
825+
onMouseLeave={() => setHoveredItem(null)}
826+
aria-label="Code Graph"
827+
>
828+
<MaterialIcon icon="code" />
829+
<span>Code Graph</span>
830+
{(collapsed || hoveredItem === 'codegraph') && (
831+
<Tooltip visible={hoveredItem === 'codegraph'} top={tooltipTop} collapsed={collapsed}>
832+
Code Graph
833+
</Tooltip>
834+
)}
835+
</NavItem>
836+
816837
<NavItem
817838
active={activeItem === 'settings'}
818839
onClick={() => handleItemClick('settings')}

src/pages/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import PhasePlannerView from '../people/widgetViews/PhasePlannerView';
1313
import Activities from '../people/widgetViews/workspace/Activities/Activities';
1414
import WorkspaceTicketView from '../people/widgetViews/workspace/WorkspaceTicketView';
1515
import WorkspaceTicketCreateView from '../people/widgetViews/workspace/WorkspaceTicketCreateView.tsx';
16+
import CodeGraphView from '../people/widgetViews/workspace/CodeGraphView.tsx';
1617
import { HiveChatView } from '../people/hiveChat/index';
1718
import WorkSpacePlanner from '../people/WorkSpacePlanner/index';
1819
import HiveFeaturesView from '../people/widgetViews/workspace/HiveFeaturesView/HiveFeaturesView.tsx';
@@ -103,6 +104,9 @@ export const Pages = observer(({ mode }: { mode: AppMode }) => {
103104
<Route path="/workspace/:workspaceId/ticket">
104105
<WorkspaceTicketCreateView />
105106
</Route>
107+
<Route path="/workspace/:workspaceId/codegraph">
108+
<CodeGraphView />
109+
</Route>
106110
<Route path="/workspace/:uuid/planner">
107111
<WorkSpacePlanner />
108112
</Route>

src/people/hiveChat/ActionArtifactRenderer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export const ActionArtifactRenderer: React.FC<ActionArtifactRendererProps> = obs
116116
return null;
117117
}
118118

119-
console.log("actionArtifact", actionArtifact)
119+
console.log('actionArtifact', actionArtifact);
120120
const content = actionArtifact.content as ActionContent;
121121

122122
const hasButtonOptions =
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React, { useCallback, useEffect, useState } from 'react';
2+
import { observer } from 'mobx-react-lite';
3+
import { useParams } from 'react-router-dom';
4+
import styled from 'styled-components';
5+
import { useStores } from 'store';
6+
import SidebarComponent from 'components/common/SidebarComponent';
7+
import ActivitiesHeader from './Activities/header';
8+
import { useBrowserTabTitle } from 'hooks';
9+
import { EuiLoadingSpinner } from '@elastic/eui';
10+
import { Body } from 'pages/tickets/style';
11+
import { FullNoBudgetWrap, FullNoBudgetText } from './style';
12+
import MaterialIcon from '@material/react-material-icon';
13+
import { userHasRole } from 'helpers';
14+
15+
const MainContainer = styled.div<{ collapsed: boolean }>`
16+
flex-grow: 1;
17+
transition:
18+
margin-left 0.3s ease-in-out,
19+
width 0.3s ease-in-out;
20+
margin-left: ${({ collapsed }) => (collapsed ? '50px' : '250px')};
21+
overflow: hidden;
22+
`;
23+
24+
const ContentContainer = styled.div`
25+
padding: 2rem;
26+
background-color: #f8f9fa;
27+
height: calc(100vh - 120px);
28+
overflow-y: auto;
29+
`;
30+
31+
const Title = styled.h1`
32+
font-size: 1.5rem;
33+
font-weight: 500;
34+
margin-bottom: 1rem;
35+
`;
36+
37+
interface WorkspaceParams {
38+
workspaceId: string;
39+
}
40+
41+
const CodeGraphView: React.FC = observer(() => {
42+
const { workspaceId } = useParams<WorkspaceParams>();
43+
const { ui, main } = useStores();
44+
const [collapsed, setCollapsed] = useState(false);
45+
const [workspaceData, setWorkspaceData] = useState<any>(null);
46+
const [userRoles, setUserRoles] = useState<any[]>([]);
47+
const [permissionsChecked, setPermissionsChecked] = useState<boolean>(false);
48+
const [loading, setLoading] = useState(true);
49+
useBrowserTabTitle('Code Graph');
50+
51+
useEffect(() => {
52+
const handleCollapseChange = (e: Event) => {
53+
const customEvent = e as CustomEvent<{ collapsed: boolean }>;
54+
setCollapsed(customEvent.detail.collapsed);
55+
};
56+
window.addEventListener('sidebarCollapse', handleCollapseChange as EventListener);
57+
return () => {
58+
window.removeEventListener('sidebarCollapse', handleCollapseChange as EventListener);
59+
};
60+
}, []);
61+
62+
const checkPermissions = useCallback(async () => {
63+
if (!workspaceId) return;
64+
setLoading(true);
65+
try {
66+
const data = await main.getUserWorkspaceByUuid(workspaceId);
67+
setWorkspaceData(data);
68+
if (ui.meInfo?.owner_pubkey) {
69+
const roles = await main.getUserRoles(workspaceId, ui.meInfo.owner_pubkey);
70+
setUserRoles(roles);
71+
}
72+
} catch (error) {
73+
console.error('Error fetching workspace data:', error);
74+
} finally {
75+
setPermissionsChecked(true);
76+
setLoading(false);
77+
}
78+
}, [workspaceId, main, ui.meInfo]);
79+
80+
useEffect(() => {
81+
checkPermissions();
82+
}, [checkPermissions]);
83+
84+
const editWorkspaceDisabled = React.useMemo(() => {
85+
if (!ui.meInfo) return true;
86+
if (!workspaceData?.owner_pubkey) return false;
87+
const isWorkspaceAdmin = workspaceData.owner_pubkey === ui.meInfo.owner_pubkey;
88+
return (
89+
!isWorkspaceAdmin &&
90+
!userHasRole(main.bountyRoles, userRoles, 'EDIT ORGANIZATION') &&
91+
!userHasRole(main.bountyRoles, userRoles, 'ADD USER') &&
92+
!userHasRole(main.bountyRoles, userRoles, 'VIEW REPORT')
93+
);
94+
}, [workspaceData, ui.meInfo, userRoles, main.bountyRoles]);
95+
96+
if (loading || !permissionsChecked) {
97+
return (
98+
<Body style={{ justifyContent: 'center', alignItems: 'center' }}>
99+
<EuiLoadingSpinner size="xl" />
100+
</Body>
101+
);
102+
}
103+
104+
if (editWorkspaceDisabled) {
105+
return (
106+
<FullNoBudgetWrap>
107+
<MaterialIcon icon={'lock'} style={{ fontSize: 30, cursor: 'pointer', color: '#ccc' }} />
108+
<FullNoBudgetText>
109+
You have restricted permissions and you are unable to view this page. Reach out to the
110+
workspace admin to get them updated.
111+
</FullNoBudgetText>
112+
</FullNoBudgetWrap>
113+
);
114+
}
115+
116+
return (
117+
<>
118+
<SidebarComponent uuid={workspaceId} />
119+
<MainContainer collapsed={collapsed}>
120+
<ActivitiesHeader uuid={workspaceId} />
121+
<ContentContainer>
122+
<Title>Code Graph</Title>
123+
<p>This is the Code Graph page. Content will be added here.</p>
124+
</ContentContainer>
125+
</MainContainer>
126+
</>
127+
);
128+
});
129+
130+
export default CodeGraphView;

0 commit comments

Comments
 (0)