Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
addSuccessMessage,
} from 'sentry/actionCreators/indicator';
import type {Client} from 'sentry/api';
import Access from 'sentry/components/acl/access';
import Confirm from 'sentry/components/confirm';
import {Alert} from 'sentry/components/core/alert';
import {Button, LinkButton} from 'sentry/components/core/button';
Expand All @@ -31,6 +30,7 @@ type Props = {
projectItem: PluginProjectItem;
trackIntegrationAnalytics: (eventKey: IntegrationAnalyticsKey) => void; // analytics callback
className?: string;
hasAccess?: boolean;
};

class InstalledPlugin extends Component<Props> {
Expand Down Expand Up @@ -120,55 +120,50 @@ class InstalledPlugin extends Component<Props> {
}

render() {
const {className, plugin, organization, projectItem} = this.props;
const {className, plugin, organization, hasAccess, projectItem} = this.props;
return (
<Container data-test-id="installed-plugin">
<Access access={['org:integrations']}>
{({hasAccess}) => (
<IntegrationFlex className={className}>
<IntegrationItemBox>
<ProjectBadge project={this.projectForBadge} />
</IntegrationItemBox>
<div>
<StyledLinkButton
borderless
icon={<IconSettings />}
disabled={!hasAccess}
to={`/settings/${organization.slug}/projects/${projectItem.projectSlug}/plugins/${plugin.id}/`}
data-test-id="integration-configure-button"
>
{t('Configure')}
</StyledLinkButton>
</div>
<div>
<Confirm
priority="danger"
onConfirming={this.handleUninstallClick}
disabled={!hasAccess}
confirmText="Delete Installation"
onConfirm={() => this.handleReset()}
message={this.getConfirmMessage()}
>
<StyledButton
disabled={!hasAccess}
borderless
icon={<IconDelete />}
data-test-id="integration-remove-button"
>
{t('Uninstall')}
</StyledButton>
</Confirm>
</div>
<Switch
checked={projectItem.enabled}
onChange={() =>
this.toggleEnablePlugin(projectItem.projectId, !projectItem.enabled)
}
<IntegrationFlex className={className}>
<IntegrationItemBox>
<ProjectBadge project={this.projectForBadge} />
</IntegrationItemBox>
<div>
<StyledLinkButton
borderless
icon={<IconSettings />}
to={`/settings/${organization.slug}/projects/${projectItem.projectSlug}/plugins/${plugin.id}/`}
data-test-id="integration-configure-button"
>
{hasAccess ? t('Configure') : t('View')}
</StyledLinkButton>
</div>
<div>
<Confirm
priority="danger"
onConfirming={this.handleUninstallClick}
disabled={!hasAccess}
confirmText="Delete Installation"
onConfirm={() => this.handleReset()}
message={this.getConfirmMessage()}
>
<StyledButton
disabled={!hasAccess}
/>
</IntegrationFlex>
)}
</Access>
borderless
icon={<IconDelete />}
data-test-id="integration-remove-button"
>
{t('Uninstall')}
</StyledButton>
</Confirm>
</div>
<Switch
checked={projectItem.enabled}
onChange={() =>
this.toggleEnablePlugin(projectItem.projectId, !projectItem.enabled)
}
disabled={!hasAccess}
/>
</IntegrationFlex>
</Container>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Fragment, useCallback, useEffect, useMemo} from 'react';
import styled from '@emotion/styled';

import {openModal} from 'sentry/actionCreators/modal';
import {hasEveryAccess} from 'sentry/components/acl/access';
import ContextPickerModal from 'sentry/components/contextPickerModal';
import {Button} from 'sentry/components/core/button';
import LoadingError from 'sentry/components/loadingError';
Expand All @@ -25,6 +26,7 @@ import normalizeUrl from 'sentry/utils/url/normalizeUrl';
import {useNavigate} from 'sentry/utils/useNavigate';
import useOrganization from 'sentry/utils/useOrganization';
import {useParams} from 'sentry/utils/useParams';
import useProjects from 'sentry/utils/useProjects';
import withOrganization from 'sentry/utils/withOrganization';
import {
INSTALLED,
Expand Down Expand Up @@ -58,6 +60,8 @@ function PluginDetailedView() {
const navigate = useNavigate();
const {integrationSlug} = useParams<{integrationSlug: string}>();

const {projects} = useProjects();

const {data: plugins, isPending} = useApiQuery<PluginWithProjectList[]>(
makePluginQueryKey({orgSlug: organization.slug, pluginSlug: integrationSlug}),
{staleTime: Infinity, retry: false}
Expand Down Expand Up @@ -248,6 +252,10 @@ function PluginDetailedView() {
key={projectItem.projectId}
organization={organization}
plugin={plugin}
hasAccess={hasEveryAccess(['project:write'], {
organization,
project: projects.find(p => p.id === projectItem.projectId.toString()),
})}
projectItem={projectItem}
onResetConfiguration={handleResetConfiguration}
onPluginEnableStatusChange={handlePluginEnableStatus}
Expand Down Expand Up @@ -288,6 +296,7 @@ function PluginDetailedView() {
organization,
plugin,
renderTopButton,
projects,
]);

if (isPending) {
Expand Down
8 changes: 3 additions & 5 deletions static/app/views/settings/projectPlugins/projectPluginRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ class ProjectPluginRow extends PureComponent<Props> {
return (
<Access access={['project:write']} project={project}>
{({hasAccess}) => {
const LinkOrSpan = hasAccess ? Link : 'span';

return (
<PluginItem key={id} className={slug}>
<PluginInfo>
Expand All @@ -84,9 +82,9 @@ class ProjectPluginRow extends PureComponent<Props> {
<span>
{' '}
&middot;{' '}
<LinkOrSpan css={grayText} to={configureUrl}>
{t('Configure plugin')}
</LinkOrSpan>
<Link css={grayText} to={configureUrl}>
{hasAccess ? t('Configure plugin') : t('View plugin')}
</Link>
</span>
)}
</div>
Expand Down
Loading