diff --git a/frontend/ee b/frontend/ee index 777446d71e..5c2787b498 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 777446d71e78e5941d34353606a12d982820438f +Subproject commit 5c2787b498202f4356b4598fb961ddbab04acbbf diff --git a/frontend/src/AppBuilder/LeftSidebar/PageMenu/PageMenu.jsx b/frontend/src/AppBuilder/LeftSidebar/PageMenu/PageMenu.jsx index d4b8573c7d..d55864e91c 100644 --- a/frontend/src/AppBuilder/LeftSidebar/PageMenu/PageMenu.jsx +++ b/frontend/src/AppBuilder/LeftSidebar/PageMenu/PageMenu.jsx @@ -12,11 +12,12 @@ import './style.scss'; import { SortableTree } from './Tree/SortableTree'; import { PageGroupMenu } from './AddPageButton'; import { PageHandlerMenu } from './PageHandlerMenu.jsx'; +import AppPermissionsModal from '@/modules/Appbuilder/components/AppPermissionsModal'; import { EditModal } from './EditModal'; import { SettingsModal } from './SettingsModal'; import { DeletePageConfirmationModal } from './DeletePageConfirmationModal'; import SolidIcon from '@/_ui/Icon/SolidIcons'; -import PagePermission from './PagePermission'; +import { appPermissionService } from '@/_services'; export const PageMenu = ({ darkMode, switchPage, pinned, setPinned }) => { const showAddNewPageInput = useStore((state) => state.showAddNewPageInput); @@ -27,6 +28,11 @@ export const PageMenu = ({ darkMode, switchPage, pinned, setPinned }) => { const shouldFreeze = useStore((state) => state.getShouldFreeze()); const enableReleasedVersionPopupState = useStore((state) => state.enableReleasedVersionPopupState); const closePageEditPopover = useStore((state) => state.closePageEditPopover); + const editingPageId = useStore((state) => state.editingPage?.id); + const showPagePermissionModal = useStore((state) => state.showPagePermissionModal); + const togglePagePermissionModal = useStore((state) => state.togglePagePermissionModal); + const updatePageWithPermissions = useStore((state) => state.updatePageWithPermissions); + useEffect(() => { return () => { closePageEditPopover(); @@ -95,7 +101,20 @@ export const PageMenu = ({ darkMode, switchPage, pinned, setPinned }) => { >
- {isLicensed ? : <>} + {isLicensed && ( + appPermissionService.getPagePermission(appId, id)} + createPermission={(id, appId, body) => appPermissionService.createPagePermission(appId, id, body)} + updatePermission={(id, appId, body) => appPermissionService.updatePagePermission(appId, id, body)} + deletePermission={(id, appId) => appPermissionService.deletePagePermission(appId, id)} + onSuccess={(data) => updatePageWithPermissions(editingPageId, data)} + /> + )} diff --git a/frontend/src/AppBuilder/LeftSidebar/PageMenu/PagePermission.jsx b/frontend/src/AppBuilder/LeftSidebar/PageMenu/PagePermission.jsx deleted file mode 100644 index bd7a865a54..0000000000 --- a/frontend/src/AppBuilder/LeftSidebar/PageMenu/PagePermission.jsx +++ /dev/null @@ -1,505 +0,0 @@ -import React, { useEffect, useMemo, useState } from 'react'; -import { components } from 'react-select'; -import ModalBase from '@/_ui/Modal'; -import Select from '@/_ui/Select'; -import SolidIcon from '@/_ui/Icon/SolidIcons'; -import useStore from '@/AppBuilder/_stores/store'; -import { appPermissionService } from '@/_services'; -import { ConfirmDialog } from '@/_components'; -import toast from 'react-hot-toast'; -import Spinner from '@/_ui/Spinner'; - -const PERMISSION_TYPES = { - single: 'SINGLE', - group: 'GROUP', - all: 'ALL', -}; - -export default function PagePermission({ darkMode }) { - const showPagePermissionModal = useStore((state) => state.showPagePermissionModal); - const togglePagePermissionModal = useStore((state) => state.togglePagePermissionModal); - const editingPage = useStore((state) => state.editingPage); - const appId = useStore((state) => state.app.appId); - const selectedUserGroups = useStore((state) => state.selectedUserGroups); - const setSelectedUserGroups = useStore((state) => state.setSelectedUserGroups); - const selectedUsers = useStore((state) => state.selectedUsers); - const setSelectedUsers = useStore((state) => state.setSelectedUsers); - const pagePermission = useStore((state) => state.pagePermission); - const setPagePermission = useStore((state) => state.setPagePermission); - const updatePageWithPermissions = useStore((state) => state.updatePageWithPermissions); - - const [pagePermissionType, setPagePermissionType] = useState('all'); - const [showUserGroupSelect, toggleUserGroupSelect] = useState(false); - const [showUsersSelect, toggleUsersSelect] = useState(false); - const [showConfirmDelete, setShowConfirmDelete] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const [isPermissionsLoading, setPermissionsLoading] = useState(true); - const [initialSelectedGroups, setInitialSelectedGroups] = useState([]); - const [initialSelectedUsers, setInitialSelectedUsers] = useState([]); - const [initalPagePermissionType, setInitialPagePermissionType] = useState('all'); - - useEffect(() => { - if (!showPagePermissionModal) return; - const fetchPagePermission = () => { - appPermissionService.getPagePermission(appId, editingPage?.id).then((data) => { - if (data) { - if (data[0] && data[0]?.type === PERMISSION_TYPES.group) { - const groups = - data[0]?.groups?.map((user) => ({ - label: user?.permissionGroup?.name, - value: user?.permissionGroup?.id, - count: user?.permissionGroup?.count, - })) ?? []; - setPagePermissionType(data[0]?.type?.toLowerCase()); - setInitialPagePermissionType(data[0]?.type?.toLowerCase()); - setPagePermission(data); - toggleUserGroupSelect(true); - setInitialSelectedGroups(groups); - data?.length && setSelectedUserGroups(groups); - } else if (data[0] && data[0]?.type === PERMISSION_TYPES.single) { - const users = - data[0]?.users?.map(({ user }) => { - const firstName = user.firstName || ''; - const lastName = user.lastName || ''; - return { - value: user.id, - label: `${firstName} ${lastName}`.trim(), - email: user.email, - initials: `${firstName[0] || ''}${lastName[0] || ''}`.toUpperCase(), - }; - }) ?? []; - setPagePermissionType(data[0]?.type?.toLowerCase()); - setInitialPagePermissionType(data[0]?.type?.toLowerCase()); - setPagePermission(data); - toggleUsersSelect(true); - setInitialSelectedUsers(users); - data?.length && setSelectedUsers(users); - } - } - setPermissionsLoading(false); - }); - }; - fetchPagePermission(); - }, [showPagePermissionModal]); - - const isSelectionUnchanged = useMemo(() => { - if (pagePermissionType === 'group') { - if (!selectedUserGroups.length) return true; - const current = selectedUserGroups - .map((g) => g.value) - .sort() - .join(','); - const initial = initialSelectedGroups - .map((g) => g.value) - .sort() - .join(','); - return current === initial; - } else if (pagePermissionType === 'single') { - if (!selectedUsers.length) return true; - const current = selectedUsers - .map((u) => u.value) - .sort() - .join(','); - const initial = initialSelectedUsers - .map((u) => u.value) - .sort() - .join(','); - return current === initial; - } else { - if (!pagePermission?.length) { - return true; - } else { - return initalPagePermissionType == pagePermissionType; - } - } - }, [ - pagePermissionType, - selectedUserGroups, - initialSelectedGroups, - selectedUsers, - initialSelectedUsers, - initalPagePermissionType, - ]); - - const permissionTypeOptions = useMemo( - () => [ - { - label: 'All users with access to the app', - value: 'all', - icon: 'globe', - }, - { - label: 'Users', - value: 'single', - icon: 'user', - }, - { - label: 'User groups', - value: 'group', - icon: 'usergroup', - }, - ], - [] - ); - const handlePermissionTypeChange = (value) => { - switch (value) { - case 'group': { - toggleUserGroupSelect(true); - toggleUsersSelect(false); - setPagePermissionType('group'); - break; - } - case 'single': { - toggleUsersSelect(true); - toggleUserGroupSelect(false); - setPagePermissionType('single'); - break; - } - case 'all': { - toggleUsersSelect(false); - toggleUserGroupSelect(false); - setPagePermissionType('all'); - } - } - }; - - const handlePagePermissionModalClose = () => { - togglePagePermissionModal(false); - toggleUserGroupSelect(false); - toggleUsersSelect(false); - setPagePermissionType('all'); - setPagePermission(null); - setSelectedUsers([]); - setSelectedUserGroups([]); - setInitialSelectedGroups([]); - setInitialSelectedUsers([]); - }; - - const createPagePermission = () => { - const body = { - id: editingPage?.id, - type: PERMISSION_TYPES[pagePermissionType], - ...(pagePermissionType === 'group' - ? { groups: selectedUserGroups.map((group) => group?.value) } - : { users: selectedUsers.map((user) => user?.value) }), - }; - setIsLoading(true); - appPermissionService - .createPagePermission(appId, editingPage?.id, body) - .then((data) => { - toast.success('Permission successfully created!', { - className: 'text-nowrap w-auto mw-100', - }); - updatePageWithPermissions(editingPage?.id, data); - }) - .catch(() => { - toast.error('Permission could not be created. Please try again!', { - className: 'text-nowrap w-auto mw-100', - }); - }) - .finally(() => { - setIsLoading(false); - handlePagePermissionModalClose(); - }); - }; - - const updatePagePermission = () => { - const body = { - id: editingPage?.id, - type: PERMISSION_TYPES[pagePermissionType], - ...(pagePermissionType === 'group' - ? { groups: selectedUserGroups.map((group) => group?.value) } - : { users: selectedUsers.map((user) => user?.value) }), - }; - setIsLoading(true); - appPermissionService - .updatePagePermission(appId, editingPage?.id, body) - .then((data) => { - toast.success('Permission successfully updated!', { - className: 'text-nowrap w-auto mw-100', - }); - updatePageWithPermissions(editingPage?.id, data); - }) - .catch(() => { - toast.error('Permission could not be updated. Please try again!', { - className: 'text-nowrap w-auto mw-100', - }); - }) - .finally(() => { - setIsLoading(false); - handlePagePermissionModalClose(); - }); - }; - - const deletePagePermission = () => { - setIsLoading(true); - appPermissionService - .deletePagePermission(appId, editingPage?.id) - .then((data) => { - toast.success('Permission successfully deleted!', { - className: 'text-nowrap w-auto mw-100', - }); - updatePageWithPermissions(editingPage?.id, []); - }) - .catch(() => { - toast.error('Permission could not be deleted. Please try again!', { - className: 'text-nowrap w-auto mw-100', - }); - setShowConfirmDelete(false); - togglePagePermissionModal(true); - }) - .finally(() => { - setIsLoading(false); - setShowConfirmDelete(false); - }); - }; - - const renderPermissionTypeOptions = ({ label, icon }) => { - return ( -
-
- -
-
- {label} -
-
- ); - }; - - return ( - <> - - Page permission -
- } - handleConfirm={!pagePermission ? createPagePermission : updatePagePermission} - show={showPagePermissionModal} - isLoading={isLoading} - handleClose={handlePagePermissionModalClose} - confirmBtnProps={{ - title: pagePermission - ? 'Save changes' - : pagePermissionType === 'all' - ? 'Default permission' - : 'Create permission', - disabled: isPermissionsLoading || isSelectionUnchanged, - tooltipMessage: '', - leftIcon: pagePermission && 'save', - className: 'action-btn-page-permission', - }} - darkMode={darkMode} - className="page-permissions-modal" - > -
- {isPermissionsLoading ? ( -
- -
- ) : ( - <> -
-
- -
-
-
-

- Only selected users will be allowed to access this page. Read docs to know more. -

-
-
-
- - -
-
{data.label}
-
{data.count} users
-
-
- - ); - }; - - return ( -
- - -
{data.initials}
-
-
{data.label}
-
{data.email}
-
-
- - ); - }; - - const selectStyles = { - option: (base) => ({ - ...base, - padding: '8px 0px', - }), - }; - return ( -
- -