Added option for query permission in the popup and integration app permissions modal

This commit is contained in:
devanshu052000 2025-05-28 02:59:09 +05:30
parent cbf908362c
commit c2fc4fe60f
4 changed files with 78 additions and 13 deletions

View file

@ -1,5 +1,6 @@
import React, { useState, useCallback } from 'react';
import { Tooltip } from 'react-tooltip';
import { ToolTip } from '@/_components/ToolTip';
import { updateQuerySuggestions } from '@/_helpers/appUtils';
// import { Confirm } from '../Viewer/Confirm';
import { toast } from 'react-hot-toast';
@ -18,6 +19,7 @@ import Edit from '@/_ui/Icon/bulkIcons/Edit';
import Trash from '@/_ui/Icon/solidIcons/Trash';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import classNames from 'classnames';
import SolidIcon from '@/_ui/Icon/SolidIcons';
export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => {
const appId = useStore((state) => state.app.appId);
@ -31,6 +33,7 @@ export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => {
const deleteDataQueries = useStore((state) => state.dataQuery.deleteDataQueries);
const duplicateQuery = useStore((state) => state.dataQuery.duplicateQuery);
const setPreviewData = useStore((state) => state.queryPanel.setPreviewData);
const toggleQueryPermissionModal = useStore((state) => state.queryPanel.toggleQueryPermissionModal);
const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);
const [showQueryMenu, setShowQueryMenu] = useState(false);
const hasPermissions =
@ -40,6 +43,9 @@ export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => {
canDeleteDataSource()
: true;
const featureAccess = useStore((state) => state?.license?.featureAccess, shallow);
const licenseValid = !featureAccess?.licenseStatus?.isExpired && featureAccess?.licenseStatus?.isLicenseValid;
const shouldFreeze = useStore((state) => state.getShouldFreeze());
const QUERY_MENU_OPTIONS = [
@ -47,16 +53,34 @@ export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => {
label: 'Rename',
value: 'rename',
icon: <Edit width={16} />,
showTooltip: false,
},
{
label: 'Duplicate',
value: 'duplicate',
icon: <Copy width={16} />,
showTooltip: false,
},
{
label: 'Query permission',
value: 'permission',
icon: (
<img
alt="permission-icon"
src="assets/images/icons/editor/left-sidebar/authorization.svg"
width="16"
height="16"
/>
),
trailingIcon: !licenseValid ? <SolidIcon width={16} name="enterprisecrown" className="mx-1" /> : undefined,
tooltipText: 'Query permissions are available only in paid plans',
showTooltip: !licenseValid,
},
{
label: 'Delete',
value: 'delete',
icon: <Trash width={16} fill={'#E54D2E'} />,
showTooltip: false,
},
];
@ -67,6 +91,10 @@ export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => {
if (value === 'duplicate') {
debouncedDuplicateQuery(dataQuery?.id, appId);
}
if (value === 'permission') {
if (!licenseValid) return;
toggleQueryPermissionModal(true);
}
if (value === 'delete') {
deleteDataQuery();
}
@ -198,24 +226,32 @@ export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => {
<Popover id="list-menu" className={darkMode && 'dark-theme'}>
<Popover.Body bsPrefix="list-item-popover-body">
{QUERY_MENU_OPTIONS.map((option) => (
<div
data-cy={`query-menu-${String(option?.value).toLowerCase()}-button`}
className="list-item-popover-option"
<ToolTip
key={option?.value}
onClick={(e) => {
e.stopPropagation();
handleQueryMenuActions(option.value);
}}
message={option?.tooltipText}
placement="right"
show={option?.showTooltip}
>
<div className="list-item-popover-menu-option-icon">{option.icon}</div>
<div
className={classNames('list-item-option-menu-label', {
'color-tomato9': option.value === 'delete',
})}
data-cy={`query-menu-${String(option?.value).toLowerCase()}-button`}
className="list-item-popover-option"
key={option?.value}
onClick={(e) => {
e.stopPropagation();
handleQueryMenuActions(option.value);
}}
>
{option?.label}
<div className="list-item-popover-menu-option-icon">{option.icon}</div>
<div
className={classNames('list-item-option-menu-label', {
'color-tomato9': option.value === 'delete',
})}
>
{option?.label}
</div>
{option.trailingIcon && option.trailingIcon}
</div>
</div>
</ToolTip>
))}
</Popover.Body>
</Popover>

View file

@ -16,6 +16,9 @@ import DataSourceSelect from '../QueryManager/Components/DataSourceSelect';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import FolderEmpty from '@/_ui/Icon/solidIcons/FolderEmpty';
import useStore from '@/AppBuilder/_stores/store';
import AppPermissionsModal from '@/modules/Appbuilder/components/AppPermissionsModal';
import { shallow } from 'zustand/shallow';
import { appPermissionService } from '@/_services';
export const QueryDataPane = ({ darkMode }) => {
const { t } = useTranslation();
@ -34,6 +37,11 @@ export const QueryDataPane = ({ darkMode }) => {
function isDataSourceLocal(dataQuery) {
return dataSources.some((dataSource) => dataSource.id === dataQuery.data_source_id);
}
const featureAccess = useStore((state) => state?.license?.featureAccess, shallow);
const licenseValid = !featureAccess?.licenseStatus?.isExpired && featureAccess?.licenseStatus?.isLicenseValid;
const selectedQuery = useStore((state) => state.queryPanel.selectedQuery);
const showQueryPermissionModal = useStore((state) => state.queryPanel.showQueryPermissionModal);
const toggleQueryPermissionModal = useStore((state) => state.queryPanel.toggleQueryPermissionModal);
useEffect(() => {
setQueryPanelSearchTerm(searchTermForFilters);
@ -171,6 +179,20 @@ export const QueryDataPane = ({ darkMode }) => {
{filteredQueries.map((query) => (
<QueryCard key={query.id} dataQuery={query} darkMode={darkMode} localDs={!!isDataSourceLocal(query)} />
))}
{licenseValid && (
<AppPermissionsModal
modalType="query"
resourceId={selectedQuery?.id}
showModal={showQueryPermissionModal}
toggleModal={toggleQueryPermissionModal}
darkMode={darkMode}
fetchPermission={(id, appId) => appPermissionService.getQueryPermission(appId, id)}
createPermission={(id, appId, body) => appPermissionService.createQueryPermission(appId, id, body)}
updatePermission={(id, appId, body) => appPermissionService.updateQueryPermission(appId, id, body)}
deletePermission={(id, appId) => appPermissionService.deleteQueryPermission(appId, id)}
// onSuccess={(data) => updateQueryWithPermissions(selectedQuery?.id, data)}
/>
)}
</div>
<Tooltip
id="query-card-name-tooltip"

View file

@ -26,6 +26,7 @@ const initialState = {
loadingDataQueries: false,
isPreviewQueryLoading: false,
queryPanelSearchTem: '',
showQueryPermissionModal: false,
};
export const createQueryPanelSlice = (set, get) => ({
@ -1113,5 +1114,10 @@ export const createQueryPanelSlice = (set, get) => ({
};
previewQuery(query, false, undefined, moduleId);
},
toggleQueryPermissionModal: (show) => {
set((state) => {
state.queryPanel.showQueryPermissionModal = show;
});
},
},
});

View file

@ -64,6 +64,7 @@ button:focus:not(:focus-visible) {
padding: 10px 14px;
cursor: pointer;
display: flex;
align-items: center;
&:hover {
background-color: var(--slate3);