Skip to content

Commit

Permalink
Merge pull request #3274 from dlabrecq/read-only
Browse files Browse the repository at this point in the history
Add read only access for new settings tabs
  • Loading branch information
dlabrecq authored Jul 4, 2023
2 parents a1415a3 + e46ebfd commit 4145883
Show file tree
Hide file tree
Showing 28 changed files with 212 additions and 73 deletions.
12 changes: 6 additions & 6 deletions locales/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -1410,12 +1410,6 @@
"value": "Should not exceed 10 decimals"
}
],
"costModelsReadOnly": [
{
"type": 0,
"value": "You have read only permissions"
}
],
"costModelsRefreshDialog": [
{
"type": 0,
Expand Down Expand Up @@ -11236,6 +11230,12 @@
"value": "Failed to get RBAC information"
}
],
"readOnlyPermissions": [
{
"type": 0,
"value": "You have read only permissions"
}
],
"recommended": [
{
"type": 0,
Expand Down
2 changes: 1 addition & 1 deletion locales/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@
"costModelsPopoverAriaLabel": "Cost model info popover",
"costModelsPopoverButtonAriaLabel": "Opens a dialog with cost model info",
"costModelsRateTooLong": "Should not exceed 10 decimals",
"costModelsReadOnly": "You have read only permissions",
"costModelsRefreshDialog": "Refresh this dialog",
"costModelsRemoveTagLabel": "Remove tag value",
"costModelsRequiredField": "This field is required",
Expand Down Expand Up @@ -485,6 +484,7 @@
"rawCostTitle": "Raw cost",
"rbacErrorDesc": "There was a problem receiving user permissions. Refreshing this page may fix it. If it does not, please contact your admin.",
"rbacErrorTitle": "Failed to get RBAC information",
"readOnlyPermissions": "You have read only permissions",
"recommended": "Recommended",
"redHatStatusUrl": "https://status.redhat.com",
"remove": "Remove",
Expand Down
1 change: 1 addition & 0 deletions src/api/userAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const enum UserAccessType {
ocp = 'ocp',
rhel = 'ocp', // Todo: update to use RHEL when APIs are available
ros = 'ocp',
settings = 'settings',
}

// If the user-access API is called without a query parameter, all types are returned in the response
Expand Down
4 changes: 2 additions & 2 deletions src/components/permissions/permissions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type PermissionsProps = PermissionsOwnProps & PermissionsStateProps;

const PermissionsBase: React.FC<PermissionsProps> = ({
children = null,
chrome,
// chrome,
isFinsightsFeatureEnabled,
isIbmFeatureEnabled,
isRosFeatureEnabled,
Expand All @@ -68,7 +68,7 @@ const PermissionsBase: React.FC<PermissionsProps> = ({
const ocp = hasOcpAccess(userAccess);
const rhel = isFinsightsFeatureEnabled && hasRhelAccess(userAccess);
const ros = isRosFeatureEnabled && hasRosAccess(userAccess);
const settings = isSettingsFeatureEnabled && (chrome.isOrgAdmin || costModel);
const settings = isSettingsFeatureEnabled;

switch (pathname) {
case formatPath(routes.explorer.path):
Expand Down
10 changes: 5 additions & 5 deletions src/locales/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,11 +637,6 @@ export default defineMessages({
description: 'Should not exceed 10 decimals',
id: 'costModelsRateTooLong',
},
costModelsReadOnly: {
defaultMessage: 'You have read only permissions',
description: 'You have read only permissions',
id: 'costModelsReadOnly',
},
costModelsRefreshDialog: {
defaultMessage: 'Refresh this dialog',
description: 'Refresh this dialog',
Expand Down Expand Up @@ -3018,6 +3013,11 @@ export default defineMessages({
description: 'RBAC error title',
id: 'rbacErrorTitle',
},
readOnlyPermissions: {
defaultMessage: 'You have read only permissions',
description: 'You have read only permissions',
id: 'readOnlyPermissions',
},
recommended: {
defaultMessage: 'Recommended',
description: 'Recommended',
Expand Down
5 changes: 4 additions & 1 deletion src/routes/components/dataToolbar/basicToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ interface BasicToolbarOwnProps {
isAllSelected?: boolean;
isBulkSelectDisabled?: boolean;
isDisabled?: boolean;
isReadOnly?: boolean;
itemsPerPage?: number;
itemsTotal?: number;
onBulkSelected?: (action: string) => void;
Expand Down Expand Up @@ -124,7 +125,8 @@ export class BasicToolbarBase extends React.Component<BasicToolbarProps, BasicTo
// Bulk select

public getBulkSelectComponent = () => {
const { isAllSelected, isBulkSelectDisabled, isDisabled, itemsPerPage, itemsTotal, selectedItems } = this.props;
const { isAllSelected, isBulkSelectDisabled, isDisabled, isReadOnly, itemsPerPage, itemsTotal, selectedItems } =
this.props;
const { isBulkSelectOpen } = this.state;

return getBulkSelect({
Expand All @@ -135,6 +137,7 @@ export class BasicToolbarBase extends React.Component<BasicToolbarProps, BasicTo
isBulkSelectDisabled,
isBulkSelectOpen,
isDisabled,
isReadOnly,
itemsPerPage,
itemsTotal,
selectedItems,
Expand Down
12 changes: 10 additions & 2 deletions src/routes/components/dataToolbar/utils/bulkSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
DropdownPosition,
DropdownToggle,
DropdownToggleCheckbox,
Tooltip,
} from '@patternfly/react-core';
import { intl } from 'components/i18n';
import messages from 'locales/messages';
Expand All @@ -19,6 +20,7 @@ export const getBulkSelect = ({
isBulkSelectDisabled,
isBulkSelectOpen,
isDisabled,
isReadOnly,
itemsPerPage,
itemsTotal,
selectedItems,
Expand All @@ -30,6 +32,7 @@ export const getBulkSelect = ({
isBulkSelectDisabled?: boolean;
isBulkSelectOpen?: boolean;
isDisabled?: boolean;
isReadOnly?: boolean;
itemsPerPage?: number;
itemsTotal?: number;
selectedItems?: ComputedReportItem[];
Expand All @@ -52,13 +55,13 @@ export const getBulkSelect = ({
</DropdownItem>,
];

return (
const bulkSelect = (
<Dropdown
onSelect={handleOnBulkSelect}
position={DropdownPosition.left}
toggle={
<DropdownToggle
isDisabled={isDisabled || isBulkSelectDisabled}
isDisabled={isDisabled || isReadOnly || isBulkSelectDisabled}
splitButtonItems={[
<DropdownToggleCheckbox
id="bulk-select"
Expand All @@ -83,4 +86,9 @@ export const getBulkSelect = ({
dropdownItems={dropdownItems}
/>
);
return isReadOnly ? (
<Tooltip content={intl.formatMessage(messages.readOnlyPermissions)}>{bulkSelect}</Tooltip>
) : (
bulkSelect
);
};
4 changes: 2 additions & 2 deletions src/routes/costModels/costModel/priceListTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ class PriceListTable extends React.Component<PriceListTableProps, PriceListTable
// HACK: to display tooltip on disable
style: !isWritePermission ? { pointerEvents: 'auto' } : undefined,
tooltip: !isWritePermission ? (
<div>{intl.formatMessage(messages.costModelsReadOnly)}</div>
<div>{intl.formatMessage(messages.readOnlyPermissions)}</div>
) : undefined,
onClick: (_evt, _rowIndex, rowData) => {
this.setState({
Expand All @@ -330,7 +330,7 @@ class PriceListTable extends React.Component<PriceListTableProps, PriceListTable
// HACK: to display tooltip on disable
style: !isWritePermission ? { pointerEvents: 'auto' } : {},
tooltip: !isWritePermission ? (
<div>{intl.formatMessage(messages.costModelsReadOnly)}</div>
<div>{intl.formatMessage(messages.readOnlyPermissions)}</div>
) : undefined,
onClick: (_evt, _rowIndex, rowData) => {
const rowIndex = rowData.data.stateIndex;
Expand Down
2 changes: 1 addition & 1 deletion src/routes/costModels/costModel/sourcesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const SourcesTable: React.FC<SourcesTableProps> = ({ canWrite, costModels, intl,
return [
{
style: { pointerEvents: 'auto' },
tooltip: intl.formatMessage(messages.costModelsReadOnly),
tooltip: intl.formatMessage(messages.readOnlyPermissions),
isDisabled: true,
title: intl.formatMessage(messages.costModelsSourceDelete),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const buttonMergeProps = (

return {
isDisabled: !canWrite,
tooltip: intl.formatMessage(messages.costModelsReadOnly),
tooltip: intl.formatMessage(messages.readOnlyPermissions),
children: (
<Button isDisabled={!canWrite} onClick={openWizard}>
{intl.formatMessage(messages.costModelsWizardCreateCostModel)}
Expand Down
2 changes: 1 addition & 1 deletion src/routes/costModels/costModelsDetails/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class CostModelsTableBase extends React.Component<CostModelsTableProps, CostMode
const actions = createActions(stateName, canWrite, [
{
title: intl.formatMessage(messages.delete),
tooltip: intl.formatMessage(messages.costModelsReadOnly),
tooltip: intl.formatMessage(messages.readOnlyPermissions),
onClick: (_evt: React.MouseEvent, _rowIx: number, rowData: IRowData) => {
openDeleteDialog(rowData.data);
},
Expand Down
56 changes: 41 additions & 15 deletions src/routes/settings/calculations/calculations.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PageSection, Title, TitleSizes } from '@patternfly/react-core';
import { PageSection, Title, TitleSizes, Tooltip } from '@patternfly/react-core';
import messages from 'locales/messages';
import React from 'react';
import type { WrappedComponentProps } from 'react-intl';
Expand All @@ -8,6 +8,7 @@ import { CostType } from 'routes/components/costType';
import { Currency } from 'routes/components/currency';
import type { FetchStatus } from 'store/common';
import { createMapStateToProps } from 'store/common';
import { rbacActions, rbacSelectors } from 'store/rbac';
import { settingsActions, settingsSelectors } from 'store/settings';
import { getCostType, getCurrency, setAccountCurrency, setCostType, setCurrency } from 'utils/localStorage';
import type { RouterComponentProps } from 'utils/router';
Expand All @@ -20,10 +21,12 @@ interface SettingsOwnProps {
}

interface SettingsDispatchProps {
fetchRbac: typeof rbacActions.fetchRbac;
updateSettings: typeof settingsActions.updateSettings;
}

interface SettingsStateProps {
canWrite?: boolean;
updateSettingsStatus: FetchStatus;
}

Expand All @@ -45,8 +48,12 @@ class SettingsBase extends React.Component<SettingsProps, SettingsState> {
};
public state: SettingsState = { ...this.defaultState };

public componentDidMount() {
this.updateReport();
}

private getCostType = () => {
const { intl } = this.props;
const { canWrite, intl } = this.props;
const { currentCostType } = this.state;

return (
Expand All @@ -56,19 +63,22 @@ class SettingsBase extends React.Component<SettingsProps, SettingsState> {
</Title>
{intl.formatMessage(messages.costTypeSettingsDesc)}
<div style={styles.costType}>
<CostType
costType={currentCostType}
isLocalStorage={false}
onSelect={this.handleOnCostTypeSelected}
showLabel={false}
/>
{this.getTooltip(
<CostType
costType={currentCostType}
isDisabled={!canWrite}
isLocalStorage={false}
onSelect={this.handleOnCostTypeSelected}
showLabel={false}
/>
)}
</div>
</div>
);
};

private getCurrency = () => {
const { intl } = this.props;
const { canWrite, intl } = this.props;
const { currentCurrency } = this.state;

return (
Expand All @@ -78,17 +88,26 @@ class SettingsBase extends React.Component<SettingsProps, SettingsState> {
</Title>
{intl.formatMessage(messages.currencyDesc)}
<div style={styles.currency}>
<Currency
currency={currentCurrency}
isLocalStorage={false}
onSelect={this.handleOnCurrencySelected}
showLabel={false}
/>
{this.getTooltip(
<Currency
currency={currentCurrency}
isDisabled={!canWrite}
isLocalStorage={false}
onSelect={this.handleOnCurrencySelected}
showLabel={false}
/>
)}
</div>
</div>
);
};

private getTooltip = comp => {
const { canWrite, intl } = this.props;

return !canWrite ? <Tooltip content={intl.formatMessage(messages.readOnlyPermissions)}>{comp}</Tooltip> : comp;
};

private handleOnCostTypeSelected = value => {
const { updateSettings } = this.props;

Expand Down Expand Up @@ -120,6 +139,11 @@ class SettingsBase extends React.Component<SettingsProps, SettingsState> {
});
};

private updateReport = () => {
const { fetchRbac } = this.props;
fetchRbac();
};

public render() {
return (
<PageSection isFilled>
Expand All @@ -135,11 +159,13 @@ const mapStateToProps = createMapStateToProps<SettingsOwnProps, SettingsStatePro
const updateSettingsStatus = settingsSelectors.selectSettingsUpdateStatus(state);

return {
canWrite: rbacSelectors.isSettingsWritePermission(state),
updateSettingsStatus,
};
});

const mapDispatchToProps: SettingsDispatchProps = {
fetchRbac: rbacActions.fetchRbac,
updateSettings: settingsActions.updateSettings,
};

Expand Down
Loading

0 comments on commit 4145883

Please sign in to comment.