Skip to content

Commit

Permalink
Merge pull request #426 from TransformerOptimus/frontend_cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
nborthy authored Jun 20, 2023
2 parents e6d0840 + 4f10be5 commit 18ddf11
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 153 deletions.
174 changes: 86 additions & 88 deletions gui/pages/Content/Agents/ActionConsole.js
Original file line number Diff line number Diff line change
@@ -1,116 +1,114 @@
import React, { useState, useEffect } from 'react';
import styles from './Agents.module.css';
import Image from "next/image";
import Image from 'next/image';
import { updatePermissions } from '@/pages/api/DashboardService';
import { formatTime } from '@/utils/utils';

function ActionBox({ action, index, denied, reasons, handleDeny, handleSelection, setReasons }) {
const isDenied = denied[index];

return (
<div key={action.id} className={styles.history_box} style={{ background: '#272335', padding: '16px', cursor: 'default' }}>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div>Tool <b>{action.tool_name}</b> is seeking for Permissions</div>
{isDenied && (
<div style={{ marginTop: '26px' }}>
<div>Provide Feedback <span style={{ color: '#888888' }}>(Optional)</span></div>
<input style={{ marginTop: '6px' }} type="text" value={reasons[index]} placeholder="Enter your input here" className="input_medium"
onChange={(e) => {
const newReasons = [...reasons];
newReasons[index] = e.target.value;
setReasons(newReasons);
}}/>
</div>
)}
{isDenied ? (
<div style={{ display: 'inline-flex', marginTop: '16px', gap: '8px' }}>
<button onClick={() => handleDeny(index)} className="secondary_button" style={{ paddingLeft: '10px', paddingTop: '2px' }}>
<Image style={{ marginTop: '2px' }} width={12} height={12} src="/images/undo.svg" alt="check-icon" />
<span className={styles.text_12_n}>Go Back</span>
</button>
<button onClick={() => handleSelection(index, false, action.id)} className="secondary_button" style={{ paddingLeft: '10px', paddingTop: '2px', background: 'transparent', border: 'none' }}>
<span className={styles.text_12_n}>Proceed to Deny</span>
</button>
</div>
) : (
<div style={{ display: 'inline-flex', marginTop: '16px', gap: '8px' }}>
<button onClick={() => handleSelection(index, true, action.id)} className="secondary_button" style={{ paddingLeft: '10px', paddingTop: '2px' }}>
<Image style={{ marginTop: '4px' }} width={12} height={12} src="/images/check.svg" alt="check-icon" />
<span className={styles.text_12_n}>Approve</span>
</button>
<button onClick={() => handleDeny(index)} className="secondary_button" style={{ paddingLeft: '10px', paddingTop: '2px', background: 'transparent', border: 'none' }}>
<Image style={{ marginTop: '4px' }} width={16} height={16} src="/images/close.svg" alt="close-icon" />
<span className={styles.text_12_n}>Deny</span>
</button>
</div>
)}
</div>
<div style={{ display: 'flex', alignItems: 'center', paddingLeft: '0', paddingBottom: '0' }} className={styles.tab_text}>
<div>
<Image width={12} height={12} src="/images/schedule.svg" alt="schedule-icon" />
</div>
<div className={styles.history_info}>{formatTime(action.created_at)}</div>
</div>
</div>
);
}

export default function ActionConsole({ actions }) {
const [hiddenActions, setHiddenActions] = useState([]);
const [reasons, setReasons] = useState(actions.map(() => ''));
const [localActions, setLocalActions] = useState(actions);
const [denied, setDenied] = useState([]);
const [reasons, setReasons] = useState([]);
const [localActionIds, setLocalActionIds] = useState([]);

useEffect(() => {
const updatedActions = actions.filter(
(action) => !localActionIds.includes(action.id)
);

if (updatedActions.length > 0) {
setLocalActions(
localActions.map((localAction) =>
updatedActions.find(({ id }) => id === localAction.id) || localAction
)
);

const updatedDenied = updatedActions.map(() => false);
const updatedReasons = updatedActions.map(() => '');
const updatedActions = actions?.filter((action) => !localActionIds.includes(action.id));

setDenied((prev) => prev.map((value, index) => updatedDenied[index] || value));
setReasons((prev) => prev.map((value, index) => updatedReasons[index] || value));
if (updatedActions && updatedActions.length > 0) {
setLocalActionIds((prevIds) => [...prevIds, ...updatedActions.map(({ id }) => id)]);

setLocalActionIds([...localActionIds, ...updatedActions.map(({ id }) => id)]);
setDenied((prevDenied) => prevDenied.map((value, index) => updatedActions[index] ? false : value));
setReasons((prevReasons) => prevReasons.map((value, index) => updatedActions[index] ? '' : value));
}
}, [actions]);

const handleDeny = index => {
const newDeniedState = [...denied];
newDeniedState[index] = !newDeniedState[index];
setDenied(newDeniedState);
};

const formatDate = (dateString) => {
const now = new Date();
const date = new Date(dateString);
const seconds = Math.floor((now - date) / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const weeks = Math.floor(days / 7);
const months = Math.floor(days / 30);
const years = Math.floor(days / 365);

if (years > 0) return `${years} yr${years === 1 ? '' : 's'}`;
if (months > 0) return `${months} mon${months === 1 ? '' : 's'}`;
if (weeks > 0) return `${weeks} wk${weeks === 1 ? '' : 's'}`;
if (days > 0) return `${days} day${days === 1 ? '' : 's'}`;
if (hours > 0) return `${hours} hr${hours === 1 ? '' : 's'}`;
if (minutes > 0) return `${minutes} min${minutes === 1 ? '' : 's'}`;

return `${seconds} sec${seconds === 1 ? '' : 's'}`;
const handleDeny = (index) => {
setDenied((prevDenied) => {
const newDeniedState = [...prevDenied];
newDeniedState[index] = !newDeniedState[index];
return newDeniedState;
});
};

const handleSelection = (index, status, permissionId) => {
setHiddenActions([...hiddenActions, index]);
setHiddenActions((prevHiddenActions) => [...prevHiddenActions, index]);

const data = {
status: status,
user_feedback: reasons[index],
};

updatePermissions(permissionId, data).then((response) => {
console.log("voila")
});
updatePermissions(permissionId, data).then((response) => {});
};

return (
<>
{actions.some(action => action.status === "PENDING") ? (<div className={styles.detail_body} style={{ height: "auto" }}>
{actions.map((action, index) => action.status === "PENDING" && !hiddenActions.includes(index) && (
<div key={index} className={styles.history_box} style={{ background: "#272335", padding: "16px", cursor: "default" }}>
<div style={{ display: "flex", flexDirection: 'column' }}>
<div>Tool <b>{action.tool_name}</b> is seeking for Permissions</div>
{denied[index] && (
<div style={{marginTop: '26px' }}>
<div>Provide Feedback <span style={{color: '#888888'}}>(Optional)</span></div>
<input style={{marginTop: '6px'}} type="text" value={reasons[index]} onChange={(e) => {const newReasons = [...reasons];newReasons[index] = e.target.value;setReasons(newReasons);}} placeholder="Enter your input here" className="input_medium" />
</div>
)}
{denied[index] ? (
<div style={{ display: "inline-flex", marginTop: '16px',gap: '8px' }}>
<button onClick={() => handleDeny(index)} className="secondary_button"><Image width={12} height={12} src="/images/undo.svg" alt="check-icon" /><span className={styles.text_12_n}>Go Back</span></button>
<button onClick={() => handleSelection(index, false, action.id)} className="secondary_button" style={{ marginLeft: "4px", padding: "5px", background: "transparent", border: "none" }}><span className={styles.text_12_n}>Proceed to Deny</span></button>
</div>
) : (
<div style={{ display: "inline-flex", marginTop: '16px',gap: '8px' }}>
<button onClick={() => handleSelection(index, true, action.id)} className="secondary_button"><Image width={12} height={12} src="/images/check.svg" alt="check-icon" /><span className={styles.text_12_n}>Approve</span></button>
<button onClick={() => handleDeny(index)} className="secondary_button" style={{ marginLeft: "4px", padding: "5px", background: "transparent", border: "none" }}><Image width={16} height={16} src="/images/close.svg" alt="close-icon" /><div className={styles.text_12_n}>Deny</div></button>
</div>
)}
</div>
<div style={{ display: "flex", alignItems: "center", paddingLeft: "0", paddingBottom: "0" }} className={styles.tab_text}>
<div>
<Image width={12} height={12} src="/images/schedule.svg" alt="schedule-icon" />
</div>
<div className={styles.history_info}>{formatDate(action.created_at)}</div>
</div>
</div>
))}
</div>):
(
<div style={{display:'flex',flexDirection:'column',alignItems:'center',marginTop:'40px'}}>
<Image width={150} height={60} src="/images/no_permissions.svg" alt="no permissions" />
<span className={styles.feed_title} style={{marginTop: '8px'}}>No Actions to Display!</span>
</div>)}
</>
<>
{actions?.some((action) => action.status === 'PENDING') ? (
<div className={styles.detail_body} style={{ height: 'auto' }}>
{actions.map((action, index) => {
if (action.status === 'PENDING' && !hiddenActions.includes(index)) {
return (<ActionBox key={action.id} action={action} index={index} denied={denied} setReasons={setReasons}
reasons={reasons} handleDeny={handleDeny} handleSelection={handleSelection}/>);
}
return null;
})}
</div>
) : (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', marginTop: '40px' }}>
<Image width={150} height={60} src="/images/no_permissions.svg" alt="no-permissions" />
<span className={styles.feed_title} style={{ marginTop: '8px' }}>No Actions to Display!</span>
</div>
)}
</>
);
}
}
12 changes: 2 additions & 10 deletions gui/pages/Content/Agents/ActivityFeed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, {useEffect, useRef, useState} from 'react';
import styles from './Agents.module.css';
import {getExecutionFeeds} from "@/pages/api/DashboardService";
import Image from "next/image";
import {formatTime} from "@/utils/utils";
import {formatTime, loadingTextEffect} from "@/utils/utils";
import {EventBus} from "@/utils/eventBus";

export default function ActivityFeed({selectedRunId, selectedView, setFetchedData }) {
Expand All @@ -13,15 +13,7 @@ export default function ActivityFeed({selectedRunId, selectedView, setFetchedDat
const [prevFeedsLength, setPrevFeedsLength] = useState(0);

useEffect(() => {
const text = 'Thinking';
let dots = '';

const interval = setInterval(() => {
dots = dots.length < 3 ? dots + '.' : '';
setLoadingText(`${text}${dots}`);
}, 250);

return () => clearInterval(interval);
loadingTextEffect('Thinking', setLoadingText, 250);
}, []);

useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion gui/pages/Content/Agents/AgentTemplatesList.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function AgentTemplatesList({sendAgentData, selectedProjectId, fe
</div>
<div className={styles.rowContainer} style={{maxHeight: '78vh',overflowY: 'auto',marginTop:'10px',marginLeft:'3px'}}>
{agentTemplates.length > 0 ? <div className={styles.resources} style={agentTemplates.length === 1 ? {justifyContent:'flex-start',gap:'7px'} : {}}>
{agentTemplates.map((item, index) => (
{agentTemplates.map((item) => (
<div className={styles.market_tool} key={item.id} style={{cursor: 'pointer',height:'90px'}}
onClick={() => handleTemplateClick(item)}>
<div style={{display: 'inline',overflow:'auto'}}>
Expand Down
18 changes: 11 additions & 7 deletions gui/pages/Content/Agents/AgentWorkspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {EventBus} from "@/utils/eventBus";

export default function AgentWorkspace({agentId, selectedView}) {
const [leftPanel, setLeftPanel] = useState('activity_feed')
const [rightPanel, setRightPanel] = useState('details')
const [rightPanel, setRightPanel] = useState('')
const [history, setHistory] = useState(true)
const [selectedRun, setSelectedRun] = useState(null)
const [runModal, setRunModal] = useState(false)
Expand All @@ -30,16 +30,19 @@ export default function AgentWorkspace({agentId, selectedView}) {
const addInstruction = () => {
setInstructions((prevArray) => [...prevArray, 'new instructions']);
};

const handleInstructionDelete = (index) => {
const updatedInstructions = [...instructions];
updatedInstructions.splice(index, 1);
setInstructions(updatedInstructions);
};

const handleInstructionChange = (index, newValue) => {
const updatedInstructions = [...instructions];
updatedInstructions[index] = newValue;
setInstructions(updatedInstructions);
};

const addGoal = () => {
setGoals((prevArray) => [...prevArray, 'new goal']);
};
Expand Down Expand Up @@ -138,14 +141,19 @@ export default function AgentWorkspace({agentId, selectedView}) {
fetchExecutions(agentId);
}, [agentId])

useEffect(() => {
if(agentDetails) {
setRightPanel(agentDetails.permission_type.includes('RESTRICTED') ? 'action_console' : 'details');
}
}, [agentDetails])

function fetchAgentDetails(agentId) {
getAgentDetails(agentId)
.then((response) => {
setAgentDetails(response.data);
setTools(response.data.tools);
setGoals(response.data.goal);
setInstructions(response.data.instruction);
console.log(response.data)
})
.catch((error) => {
console.error('Error fetching agent details:', error);
Expand Down Expand Up @@ -217,11 +225,7 @@ export default function AgentWorkspace({agentId, selectedView}) {
</div>
<div className={styles.detail_body}>
{leftPanel === 'activity_feed' && <div className={styles.detail_content}>
<ActivityFeed
selectedView={selectedView}
selectedRunId={selectedRun?.id || 0}
setFetchedData={setFetchedData} // Pass the setFetchedData function as a prop
/>
<ActivityFeed selectedView={selectedView} selectedRunId={selectedRun?.id || 0} setFetchedData={setFetchedData}/>
</div>}
{leftPanel === 'agent_type' && <div className={styles.detail_content}><TaskQueue selectedRunId={selectedRun?.id || 0}/></div>}
</div>
Expand Down
14 changes: 10 additions & 4 deletions gui/pages/Content/Agents/ResourceManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,16 @@ export default function ResourceManager({agentId}) {
};

const ResourceList = ({ files }) => (
<div className={styles.resources}>
{files.map((file, index) => (
<ResourceItem key={index} file={file} />
))}
<div>
{files.length <= 0 && channel === 'output' ? <div style={{display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',marginTop:'40px',width:'100%'}}>
<Image width={150} height={60} src="/images/no_permissions.svg" alt="no-permissions" />
<span className={styles.feed_title} style={{marginTop: '8px'}}>No Output files!</span>
</div> : <div className={styles.resources}>
{files.map((file, index) => (
<ResourceItem key={index} file={file} />
))}
</div>
}
</div>
);

Expand Down
9 changes: 6 additions & 3 deletions gui/pages/Content/Marketplace/Market.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ export default function Market() {

useEffect(() => {
const handleOpenTemplateDetails = (item) => {
setAgentTemplateData(item)
setItemClicked(true)
setAgentTemplateData(item);
setItemClicked(true);
};

const handleBackClick = ()=>{
setItemClicked(false)
setItemClicked(false);
}

EventBus.on('openTemplateDetails', handleOpenTemplateDetails);
EventBus.on('goToMarketplace', handleBackClick);

return () => {
EventBus.off('openTemplateDetails', handleOpenTemplateDetails);
EventBus.off('goToMarketplace', handleBackClick);
Expand Down
38 changes: 15 additions & 23 deletions gui/pages/Content/Marketplace/MarketAgent.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,30 @@ import Image from "next/image";
import styles from './Market.module.css';
import {fetchAgentTemplateList} from "@/pages/api/DashboardService";
import {EventBus} from "@/utils/eventBus";
import {loadingTextEffect} from "@/utils/utils";

export default function MarketAgent(){
const [agentTemplates, setAgentTemplates] = useState([])
const [showMarketplace, setShowMarketplace] = useState(false);
const [isLoading, setIsLoading] = useState(true)
const [loadingText, setLoadingText] = useState("Loading Templates");

useEffect(() => {
const text = 'Loading Templates';
let dots = '';

const interval = setInterval(() => {
dots = dots.length < 3 ? dots + '.' : '';
setLoadingText(`${text}${dots}`);
}, 500);
useEffect(() => {
loadingTextEffect('Loading Templates', setLoadingText, 500);

return () => clearInterval(interval);
}, []);
if(window.location.href.toLowerCase().includes('marketplace')) {
setShowMarketplace(true)
}

useEffect(() => {
if(window.location.href.toLowerCase().includes('marketplace')) {
setShowMarketplace(true)
}
fetchAgentTemplateList()
.then((response) => {
const data = response.data || [];
setAgentTemplates(data);
setIsLoading(false);
})
.catch((error) => {
console.error('Error fetching agent templates:', error);
});
fetchAgentTemplateList()
.then((response) => {
const data = response.data || [];
setAgentTemplates(data);
setIsLoading(false);
})
.catch((error) => {
console.error('Error fetching agent templates:', error);
});
}, []);

function handleTemplateClick(item) {
Expand Down
Loading

0 comments on commit 18ddf11

Please sign in to comment.