fix: page list item icons aren't permission driven on first load (#18586)
* fix: page list ctas permission driven fix * fix: page list and page context menu , datasource action pane create permission driven * fix: check manage permission on page aswell for cloning * fix: duplicate & fork app permission driven * fix: onclick triggers on disabled icons
This commit is contained in:
parent
058500704e
commit
3e8414b4e0
|
|
@ -310,6 +310,7 @@ type ApplicationCardProps = {
|
||||||
update?: (id: string, data: UpdateApplicationPayload) => void;
|
update?: (id: string, data: UpdateApplicationPayload) => void;
|
||||||
enableImportExport?: boolean;
|
enableImportExport?: boolean;
|
||||||
isMobile?: boolean;
|
isMobile?: boolean;
|
||||||
|
hasCreateNewApplicationPermission?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const EditButton = styled(Button)`
|
const EditButton = styled(Button)`
|
||||||
|
|
@ -469,7 +470,11 @@ export function ApplicationCard(props: ApplicationCardProps) {
|
||||||
cypressSelector: "t--share",
|
cypressSelector: "t--share",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (props.duplicate && hasEditPermission) {
|
if (
|
||||||
|
props.duplicate &&
|
||||||
|
props.hasCreateNewApplicationPermission &&
|
||||||
|
hasEditPermission
|
||||||
|
) {
|
||||||
moreActionItems.push({
|
moreActionItems.push({
|
||||||
onSelect: duplicateApp,
|
onSelect: duplicateApp,
|
||||||
text: "Duplicate",
|
text: "Duplicate",
|
||||||
|
|
@ -516,6 +521,7 @@ export function ApplicationCard(props: ApplicationCardProps) {
|
||||||
const hasDeletePermission = hasDeleteApplicationPermission(
|
const hasDeletePermission = hasDeleteApplicationPermission(
|
||||||
props.application?.userPermissions,
|
props.application?.userPermissions,
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateColor = (color: string) => {
|
const updateColor = (color: string) => {
|
||||||
setSelectedColor(color);
|
setSelectedColor(color);
|
||||||
props.update &&
|
props.update &&
|
||||||
|
|
|
||||||
|
|
@ -922,6 +922,9 @@ function ApplicationsSection(props: any) {
|
||||||
delete={deleteApplication}
|
delete={deleteApplication}
|
||||||
duplicate={duplicateApplicationDispatch}
|
duplicate={duplicateApplicationDispatch}
|
||||||
enableImportExport={enableImportExport}
|
enableImportExport={enableImportExport}
|
||||||
|
hasCreateNewApplicationPermission={
|
||||||
|
hasCreateNewApplicationPermission
|
||||||
|
}
|
||||||
isMobile={isMobile}
|
isMobile={isMobile}
|
||||||
key={application.id}
|
key={application.id}
|
||||||
update={updateApplicationDispatch}
|
update={updateApplicationDispatch}
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,13 @@ import {
|
||||||
createMessage,
|
createMessage,
|
||||||
} from "@appsmith/constants/messages";
|
} from "@appsmith/constants/messages";
|
||||||
import {
|
import {
|
||||||
|
hasCreatePagePermission,
|
||||||
hasDeletePagePermission,
|
hasDeletePagePermission,
|
||||||
hasManagePagePermission,
|
hasManagePagePermission,
|
||||||
} from "@appsmith/utils/permissionHelpers";
|
} from "@appsmith/utils/permissionHelpers";
|
||||||
import { getPageById } from "selectors/editorSelectors";
|
import { getPageById } from "selectors/editorSelectors";
|
||||||
|
import { getCurrentApplication } from "selectors/applicationSelectors";
|
||||||
|
import { AppState } from "@appsmith/reducers";
|
||||||
|
|
||||||
const CustomLabel = styled.div`
|
const CustomLabel = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -101,6 +104,12 @@ export function PageContextMenu(props: {
|
||||||
const pagePermissions =
|
const pagePermissions =
|
||||||
useSelector(getPageById(props.pageId))?.userPermissions || [];
|
useSelector(getPageById(props.pageId))?.userPermissions || [];
|
||||||
|
|
||||||
|
const userAppPermissions = useSelector(
|
||||||
|
(state: AppState) => getCurrentApplication(state)?.userPermissions ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
|
const canCreatePages = hasCreatePagePermission(userAppPermissions);
|
||||||
|
|
||||||
const canManagePages = hasManagePagePermission(pagePermissions);
|
const canManagePages = hasManagePagePermission(pagePermissions);
|
||||||
|
|
||||||
const canDeletePages = hasDeletePagePermission(pagePermissions);
|
const canDeletePages = hasDeletePagePermission(pagePermissions);
|
||||||
|
|
@ -111,11 +120,12 @@ export function PageContextMenu(props: {
|
||||||
onSelect: editPageName,
|
onSelect: editPageName,
|
||||||
label: createMessage(CONTEXT_EDIT_NAME),
|
label: createMessage(CONTEXT_EDIT_NAME),
|
||||||
},
|
},
|
||||||
canManagePages && {
|
canCreatePages &&
|
||||||
value: "clone",
|
canManagePages && {
|
||||||
onSelect: clonePage,
|
value: "clone",
|
||||||
label: createMessage(CONTEXT_CLONE),
|
onSelect: clonePage,
|
||||||
},
|
label: createMessage(CONTEXT_CLONE),
|
||||||
|
},
|
||||||
canManagePages && {
|
canManagePages && {
|
||||||
value: "visibility",
|
value: "visibility",
|
||||||
onSelect: setHiddenField,
|
onSelect: setHiddenField,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import {
|
||||||
getCurrentApplication,
|
getCurrentApplication,
|
||||||
getCurrentApplicationId,
|
getCurrentApplicationId,
|
||||||
getCurrentPageId,
|
getCurrentPageId,
|
||||||
getPagePermissions,
|
|
||||||
} from "selectors/editorSelectors";
|
} from "selectors/editorSelectors";
|
||||||
import Entity, { EntityClassNames } from "../Entity";
|
import Entity, { EntityClassNames } from "../Entity";
|
||||||
import history from "utils/history";
|
import history from "utils/history";
|
||||||
|
|
@ -192,18 +191,16 @@ function Pages() {
|
||||||
(state: AppState) => getCurrentApplication(state)?.userPermissions ?? [],
|
(state: AppState) => getCurrentApplication(state)?.userPermissions ?? [],
|
||||||
);
|
);
|
||||||
|
|
||||||
const pagePermissions = useSelector(getPagePermissions);
|
|
||||||
|
|
||||||
const canCreatePages = hasCreatePagePermission(userAppPermissions);
|
const canCreatePages = hasCreatePagePermission(userAppPermissions);
|
||||||
|
|
||||||
const canManagePages = hasManagePagePermission(pagePermissions);
|
|
||||||
|
|
||||||
const pageElements = useMemo(
|
const pageElements = useMemo(
|
||||||
() =>
|
() =>
|
||||||
pages.map((page) => {
|
pages.map((page) => {
|
||||||
const icon = page.isDefault ? defaultPageIcon : pageIcon;
|
const icon = page.isDefault ? defaultPageIcon : pageIcon;
|
||||||
const rightIcon = !!page.isHidden ? hiddenPageIcon : null;
|
const rightIcon = !!page.isHidden ? hiddenPageIcon : null;
|
||||||
const isCurrentPage = currentPageId === page.pageId;
|
const isCurrentPage = currentPageId === page.pageId;
|
||||||
|
const pagePermissions = page.userPermissions;
|
||||||
|
const canManagePages = hasManagePagePermission(pagePermissions);
|
||||||
const contextMenu = (
|
const contextMenu = (
|
||||||
<PageContextMenu
|
<PageContextMenu
|
||||||
applicationId={applicationId as string}
|
applicationId={applicationId as string}
|
||||||
|
|
@ -247,7 +244,6 @@ function Pages() {
|
||||||
action={onPageListSelection}
|
action={onPageListSelection}
|
||||||
addButtonHelptext={createMessage(ADD_PAGE_TOOLTIP)}
|
addButtonHelptext={createMessage(ADD_PAGE_TOOLTIP)}
|
||||||
alwaysShowRightIcon
|
alwaysShowRightIcon
|
||||||
canEditEntityName={canManagePages}
|
|
||||||
className="group pages"
|
className="group pages"
|
||||||
collapseRef={pageResizeRef}
|
collapseRef={pageResizeRef}
|
||||||
customAddButton={
|
customAddButton={
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,20 @@ import EditName from "./EditName";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
getCurrentApplication,
|
||||||
getCurrentApplicationId,
|
getCurrentApplicationId,
|
||||||
getPagePermissions,
|
getPageById,
|
||||||
} from "selectors/editorSelectors";
|
} from "selectors/editorSelectors";
|
||||||
import { Colors } from "constants/Colors";
|
import { Colors } from "constants/Colors";
|
||||||
import { TooltipComponent } from "design-system";
|
import { TooltipComponent } from "design-system";
|
||||||
import { createMessage, SETTINGS_TOOLTIP } from "@appsmith/constants/messages";
|
import { createMessage, SETTINGS_TOOLTIP } from "@appsmith/constants/messages";
|
||||||
import { TOOLTIP_HOVER_ON_DELAY } from "constants/AppConstants";
|
import { TOOLTIP_HOVER_ON_DELAY } from "constants/AppConstants";
|
||||||
import {
|
import {
|
||||||
|
hasCreatePagePermission,
|
||||||
hasDeletePagePermission,
|
hasDeletePagePermission,
|
||||||
hasManagePagePermission,
|
hasManagePagePermission,
|
||||||
} from "@appsmith/utils/permissionHelpers";
|
} from "@appsmith/utils/permissionHelpers";
|
||||||
|
import { AppState } from "@appsmith/reducers";
|
||||||
|
|
||||||
// render over popover portals
|
// render over popover portals
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
|
|
@ -141,15 +144,24 @@ function ContextMenu(props: Props) {
|
||||||
* opens the context menu on interaction ( on click )
|
* opens the context menu on interaction ( on click )
|
||||||
*/
|
*/
|
||||||
const handleInteraction = useCallback((isOpen) => {
|
const handleInteraction = useCallback((isOpen) => {
|
||||||
setIsOpen(isOpen);
|
(canManagePages || canDeletePages) && setIsOpen(isOpen);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const pagePermissions = useSelector(getPagePermissions);
|
const pagePermissions =
|
||||||
|
useSelector(getPageById(page.pageId))?.userPermissions || [];
|
||||||
|
|
||||||
|
const userAppPermissions = useSelector(
|
||||||
|
(state: AppState) => getCurrentApplication(state)?.userPermissions ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
|
const canCreatePages = hasCreatePagePermission(userAppPermissions);
|
||||||
|
|
||||||
const canManagePages = hasManagePagePermission(pagePermissions);
|
const canManagePages = hasManagePagePermission(pagePermissions);
|
||||||
|
|
||||||
const canDeletePages = hasDeletePagePermission(pagePermissions);
|
const canDeletePages = hasDeletePagePermission(pagePermissions);
|
||||||
|
|
||||||
|
const canClonePages = canCreatePages && canManagePages;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover2
|
<Popover2
|
||||||
content={
|
content={
|
||||||
|
|
@ -164,9 +176,9 @@ function ContextMenu(props: Props) {
|
||||||
<Action>
|
<Action>
|
||||||
<CopyIcon
|
<CopyIcon
|
||||||
color={Colors.GREY_9}
|
color={Colors.GREY_9}
|
||||||
disabled={!canManagePages}
|
disabled={!canClonePages}
|
||||||
height={16}
|
height={16}
|
||||||
onClick={!canManagePages ? noop : () => onCopy(page.pageId)}
|
onClick={!canClonePages ? noop : () => onCopy(page.pageId)}
|
||||||
width={16}
|
width={16}
|
||||||
/>
|
/>
|
||||||
</Action>
|
</Action>
|
||||||
|
|
@ -239,6 +251,7 @@ function ContextMenu(props: Props) {
|
||||||
<Action className={isOpen ? "active" : ""} type="button">
|
<Action className={isOpen ? "active" : ""} type="button">
|
||||||
<SettingsIcon
|
<SettingsIcon
|
||||||
color={Colors.GREY_9}
|
color={Colors.GREY_9}
|
||||||
|
disabled={!canManagePages && !canDeletePages}
|
||||||
height={16}
|
height={16}
|
||||||
onClick={noop}
|
onClick={noop}
|
||||||
width={16}
|
width={16}
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,18 @@ import { TOOLTIP_HOVER_ON_DELAY } from "constants/AppConstants";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getCurrentApplicationId,
|
getCurrentApplicationId,
|
||||||
getPagePermissions,
|
getPageById,
|
||||||
selectApplicationVersion,
|
selectApplicationVersion,
|
||||||
} from "selectors/editorSelectors";
|
} from "selectors/editorSelectors";
|
||||||
import { ApplicationVersion } from "actions/applicationActions";
|
import { ApplicationVersion } from "actions/applicationActions";
|
||||||
import { AppState } from "@appsmith/reducers";
|
import { AppState } from "@appsmith/reducers";
|
||||||
import {
|
import {
|
||||||
|
hasCreatePagePermission,
|
||||||
hasDeletePagePermission,
|
hasDeletePagePermission,
|
||||||
hasManagePagePermission,
|
hasManagePagePermission,
|
||||||
} from "@appsmith/utils/permissionHelpers";
|
} from "@appsmith/utils/permissionHelpers";
|
||||||
import { noop } from "utils/AppsmithUtils";
|
import { noop } from "utils/AppsmithUtils";
|
||||||
|
import { getCurrentApplication } from "selectors/applicationSelectors";
|
||||||
|
|
||||||
export const Container = styled.div`
|
export const Container = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -152,12 +154,21 @@ function PageListItem(props: PageListItemProps) {
|
||||||
return dispatch(updatePage(item.pageId, item.pageName, !item.isHidden));
|
return dispatch(updatePage(item.pageId, item.pageName, !item.isHidden));
|
||||||
}, [dispatch, item]);
|
}, [dispatch, item]);
|
||||||
|
|
||||||
const pagePermissions = useSelector(getPagePermissions);
|
const pagePermissions =
|
||||||
|
useSelector(getPageById(item.pageId))?.userPermissions || [];
|
||||||
|
|
||||||
|
const userAppPermissions = useSelector(
|
||||||
|
(state: AppState) => getCurrentApplication(state)?.userPermissions ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
|
const canCreatePages = hasCreatePagePermission(userAppPermissions);
|
||||||
|
|
||||||
const canManagePages = hasManagePagePermission(pagePermissions);
|
const canManagePages = hasManagePagePermission(pagePermissions);
|
||||||
|
|
||||||
const canDeletePages = hasDeletePagePermission(pagePermissions);
|
const canDeletePages = hasDeletePagePermission(pagePermissions);
|
||||||
|
|
||||||
|
const canClonePages = canCreatePages && canManagePages;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
|
|
@ -212,9 +223,9 @@ function PageListItem(props: PageListItemProps) {
|
||||||
<Action type="button">
|
<Action type="button">
|
||||||
<CopyIcon
|
<CopyIcon
|
||||||
color={Colors.GREY_9}
|
color={Colors.GREY_9}
|
||||||
disabled={!canManagePages}
|
disabled={!canClonePages}
|
||||||
height={16}
|
height={16}
|
||||||
onClick={!canManagePages ? noop : clonePageCallback}
|
onClick={!canClonePages ? noop : clonePageCallback}
|
||||||
width={16}
|
width={16}
|
||||||
/>
|
/>
|
||||||
</Action>
|
</Action>
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ import {
|
||||||
import LoadingOverlayScreen from "components/editorComponents/LoadingOverlayScreen";
|
import LoadingOverlayScreen from "components/editorComponents/LoadingOverlayScreen";
|
||||||
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
|
import { EditorTheme } from "components/editorComponents/CodeEditor/EditorConfig";
|
||||||
import {
|
import {
|
||||||
|
hasCreateDatasourcePermission,
|
||||||
hasDeleteActionPermission,
|
hasDeleteActionPermission,
|
||||||
hasExecuteActionPermission,
|
hasExecuteActionPermission,
|
||||||
hasManageActionPermission,
|
hasManageActionPermission,
|
||||||
|
|
@ -125,6 +126,7 @@ import {
|
||||||
setQueryPaneResponseSelectedTab,
|
setQueryPaneResponseSelectedTab,
|
||||||
} from "actions/queryPaneActions";
|
} from "actions/queryPaneActions";
|
||||||
import { ActionExecutionResizerHeight } from "pages/Editor/APIEditor/constants";
|
import { ActionExecutionResizerHeight } from "pages/Editor/APIEditor/constants";
|
||||||
|
import { getCurrentAppWorkspace } from "@appsmith/selectors/workspaceSelectors";
|
||||||
|
|
||||||
const QueryFormContainer = styled.form`
|
const QueryFormContainer = styled.form`
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
@ -522,6 +524,14 @@ export function EditorJSONtoForm(props: Props) {
|
||||||
currentActionConfig?.userPermissions,
|
currentActionConfig?.userPermissions,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const userWorkspacePermissions = useSelector(
|
||||||
|
(state: AppState) => getCurrentAppWorkspace(state).userPermissions ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
|
const canCreateDatasource = hasCreateDatasourcePermission(
|
||||||
|
userWorkspacePermissions,
|
||||||
|
);
|
||||||
|
|
||||||
// Query is executed even once during the session, show the response data.
|
// Query is executed even once during the session, show the response data.
|
||||||
if (executedQueryData) {
|
if (executedQueryData) {
|
||||||
if (!executedQueryData.isExecutionSuccess) {
|
if (!executedQueryData.isExecutionSuccess) {
|
||||||
|
|
@ -555,10 +565,12 @@ export function EditorJSONtoForm(props: Props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<components.MenuList {...props}>{props.children}</components.MenuList>
|
<components.MenuList {...props}>{props.children}</components.MenuList>
|
||||||
<CreateDatasource onClick={() => onCreateDatasourceClick()}>
|
{canCreateDatasource ? (
|
||||||
<Icon className="createIcon" icon="plus" iconSize={11} />
|
<CreateDatasource onClick={() => onCreateDatasourceClick()}>
|
||||||
{createMessage(CREATE_NEW_DATASOURCE)}
|
<Icon className="createIcon" icon="plus" iconSize={11} />
|
||||||
</CreateDatasource>
|
{createMessage(CREATE_NEW_DATASOURCE)}
|
||||||
|
</CreateDatasource>
|
||||||
|
) : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user