From 8ebcf8ca8f9487d64d271d0199524daed2debfb0 Mon Sep 17 00:00:00 2001 From: Max Techera Date: Sat, 13 Jul 2024 15:13:20 -0300 Subject: [PATCH] Add roles and permissons --- packages/ui/package.json | 1 + packages/ui/src/App.jsx | 17 +++++++- packages/ui/src/index.jsx | 41 +++++++++++-------- .../Sidebar/MenuList/NavGroup/index.jsx | 7 +++- .../ui-component/extended/AnswersSettings.jsx | 34 ++++++++++----- packages/ui/src/views/canvas/CanvasHeader.jsx | 4 +- pnpm-lock.yaml | 8 ++++ 7 files changed, 83 insertions(+), 29 deletions(-) diff --git a/packages/ui/package.json b/packages/ui/package.json index 107324d3..23d0c2cb 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -26,6 +26,7 @@ "axios": "1.6.2", "clsx": "^1.1.1", "dotenv": "^16.0.0", + "flagsmith": "^4.0.3", "aai-embed": "workspace:*", "aai-embed-react": "workspace:*", "flowise-react-json-view": "*", diff --git a/packages/ui/src/App.jsx b/packages/ui/src/App.jsx index eb2939da..5ef83cf0 100644 --- a/packages/ui/src/App.jsx +++ b/packages/ui/src/App.jsx @@ -14,13 +14,28 @@ import themes from '@/themes' import NavigationScroll from '@/layout/NavigationScroll' import { useAuth0 } from '@auth0/auth0-react' import useNotifyParentOfNavigation from './utils/useNotifyParentOfNavigation' +import { useFlagsmith } from 'flagsmith/react' // ==============================|| APP ||============================== // const App = () => { const customization = useSelector((state) => state.customization) - const { getAccessTokenSilently, error } = useAuth0() + const { user, getAccessTokenSilently, error } = useAuth0() + const flagsmith = useFlagsmith() useNotifyParentOfNavigation() + React.useEffect(() => { + if (user) + flagsmith.identify( + `user_${ + user.email + ? user.email.split('').reduce((a, b) => { + a = (a << 5) - a + b.charCodeAt(0) + return a & a + }, 0) + : '' + }` + ) + }, [user, flagsmith]) React.useEffect(() => { ;(async () => { try { diff --git a/packages/ui/src/index.jsx b/packages/ui/src/index.jsx index 729b002f..8a39f78a 100644 --- a/packages/ui/src/index.jsx +++ b/packages/ui/src/index.jsx @@ -13,6 +13,8 @@ import { Provider } from 'react-redux' import { SnackbarProvider } from 'notistack' import ConfirmContextProvider from '@/store/context/ConfirmContextProvider' import { ReactFlowContext } from '@/store/context/ReactFlowContext' +import flagsmith from 'flagsmith' +import { FlagsmithProvider } from 'flagsmith/react' const container = document.getElementById('root') const root = createRoot(container) @@ -26,22 +28,29 @@ const authorizationParams = { root.render( - - - - - - - - - - - - - + + + + + + + + + + + + + + ) diff --git a/packages/ui/src/layout/MainLayout/Sidebar/MenuList/NavGroup/index.jsx b/packages/ui/src/layout/MainLayout/Sidebar/MenuList/NavGroup/index.jsx index 0625d54e..cbc9dda1 100644 --- a/packages/ui/src/layout/MainLayout/Sidebar/MenuList/NavGroup/index.jsx +++ b/packages/ui/src/layout/MainLayout/Sidebar/MenuList/NavGroup/index.jsx @@ -7,14 +7,19 @@ import { Divider, List, Typography } from '@mui/material' // project imports import NavItem from '../NavItem' import NavCollapse from '../NavCollapse' +import { useFlags } from 'flagsmith/react' // ==============================|| SIDEBAR MENU LIST GROUP ||============================== // const NavGroup = ({ item }) => { const theme = useTheme() - + const flags = useFlags(['org:admin']) + const ADMIN_ACTIONS = ['agentflows', 'tools', 'assistants', 'credentials', 'variables', 'apikey'] // menu list collapse & items const items = item.children?.map((menu) => { + if (ADMIN_ACTIONS?.includes(menu.id) && !flags?.org_admin?.enabled) { + return null + } switch (menu.type) { case 'collapse': return diff --git a/packages/ui/src/ui-component/extended/AnswersSettings.jsx b/packages/ui/src/ui-component/extended/AnswersSettings.jsx index ea02e1f8..a0b49196 100644 --- a/packages/ui/src/ui-component/extended/AnswersSettings.jsx +++ b/packages/ui/src/ui-component/extended/AnswersSettings.jsx @@ -4,20 +4,23 @@ import PropTypes from 'prop-types' import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from '@/store/actions' // material-ui -import { Button, Box, Typography, FormGroup, FormLabel, FormControl, FormControlLabel, Checkbox } from '@mui/material' +import { Button, Box, Typography, FormGroup, FormLabel, FormControl, FormControlLabel, Checkbox, Tooltip } from '@mui/material' import { IconX } from '@tabler/icons-react' // Project import import { StyledButton } from '@/ui-component/button/StyledButton' -// store +// Hooks import useNotifier from '@/utils/useNotifier' +import { useFlags } from 'flagsmith/react' // API import chatflowsApi from '@/api/chatflows' import { TooltipWithParser } from '../tooltip/TooltipWithParser' const AnswersSettings = ({ dialogProps }) => { + const flags = useFlags(['chatflow:share:internal', 'org:admin']) + const dispatch = useDispatch() const chatflow = useSelector((state) => state.canvas.chatflow) @@ -89,14 +92,25 @@ const AnswersSettings = ({ dialogProps }) => { - {['Private', 'Organization', 'AnswerAI', 'Marketplace', 'Browser Extension'].map((type) => ( - handleChange(event, type)} />} - label={type} - /> - ))} + {['Private', 'Organization', 'AnswerAI', 'Marketplace', 'Browser Extension'].map((type) => { + const isDisabled = + type === 'Private' || + (!flags['org:admin']?.enabled && type === 'Browser Extension') || + (!flags['org:admin']?.enabled && type === 'Organization') || + (!flags['chatflow:share:internal']?.enabled && type === 'Marketplace') + return ( + + handleChange(event, type)} /> + + } + label={type} + disabled={isDisabled} + /> + ) + })} diff --git a/packages/ui/src/views/canvas/CanvasHeader.jsx b/packages/ui/src/views/canvas/CanvasHeader.jsx index c4d842cf..39e24a98 100644 --- a/packages/ui/src/views/canvas/CanvasHeader.jsx +++ b/packages/ui/src/views/canvas/CanvasHeader.jsx @@ -23,6 +23,7 @@ import chatflowsApi from '@/api/chatflows' // Hooks import useApi from '@/hooks/useApi' +import { useFlags } from 'flagsmith/react' // utils import { generateExportFlowData } from '@/utils/genericHelper' @@ -34,6 +35,7 @@ import ViewLeadsDialog from '@/ui-component/dialog/ViewLeadsDialog' const CanvasHeader = ({ chatflow, isAgentCanvas, handleSaveFlow, handleDeleteFlow, handleLoadFlow }) => { const theme = useTheme() + const flags = useFlags(['chatflow:share:external']) const dispatch = useDispatch() const navigate = useNavigate() const flowNameRef = useRef() @@ -329,7 +331,7 @@ const CanvasHeader = ({ chatflow, isAgentCanvas, handleSaveFlow, handleDeleteFlo - {chatflow?.id && ( + {chatflow?.id && flags?.['chatflow:share:external']?.enabled && ( = 0.10'} + flagsmith@4.0.3: + resolution: {integrity: sha512-F2lI84yCwxP9RZMcqDgpj9cjWfgQ6YQLS1/bXNp4iltZz6K8lr4zECjBbqqZSUBpxpKBOxfPFX6XGdDurAKOuA==} + flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -27546,6 +27552,8 @@ snapshots: flagged-respawn@1.0.1: {} + flagsmith@4.0.3: {} + flat-cache@3.2.0: dependencies: flatted: 3.3.1