mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
fix(editor): Keep the used-in rows on the credential sharing tab when personal-space sharing is disabled (#41207)
This commit is contained in:
parent
a94f5dc8b7
commit
ca9661c091
|
|
@ -1058,8 +1058,8 @@ describe('CredentialSharing.ee', () => {
|
|||
expect(queryByTestId('project-sharing-unshared-item')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not show used-in projects when the viewer cannot share', () => {
|
||||
getDependenciesMock.mockReturnValue({
|
||||
describe('when the viewer cannot share', () => {
|
||||
const usedInMarketing = {
|
||||
dependencies: [
|
||||
{
|
||||
id: 'wf-1',
|
||||
|
|
@ -1069,24 +1069,86 @@ describe('CredentialSharing.ee', () => {
|
|||
},
|
||||
],
|
||||
inaccessibleCount: 0,
|
||||
};
|
||||
|
||||
it('keeps the used-in row and disables the Share button when sharing is disabled in personal spaces', async () => {
|
||||
getDependenciesMock.mockReturnValue(usedInMarketing);
|
||||
|
||||
const credential = createCredential({
|
||||
homeProject: ownerPersonalProject,
|
||||
sharedWithProjects: [],
|
||||
});
|
||||
const { getByTestId, findAllByText } = renderComponent({
|
||||
props: {
|
||||
credentialId: credential.id,
|
||||
credentialData: {},
|
||||
credentialPermissions: { share: false },
|
||||
credential,
|
||||
modalBus: createEventBus(),
|
||||
},
|
||||
});
|
||||
|
||||
expect(fetchDependenciesMock).toHaveBeenCalledWith([credential.id], 'credential');
|
||||
|
||||
const row = getByTestId('project-sharing-unshared-item');
|
||||
expect(row).toHaveTextContent('Marketing');
|
||||
expect(row).toHaveTextContent('Used in "Email summary"');
|
||||
|
||||
const share = getByTestId('credential-used-in-project-share');
|
||||
expect(share).toBeDisabled();
|
||||
|
||||
await userEvent.hover(share.parentElement as HTMLElement);
|
||||
expect(
|
||||
await findAllByText("You don't have permission to share personal credentials"),
|
||||
).not.toHaveLength(0);
|
||||
});
|
||||
|
||||
const credential = createCredential({
|
||||
homeProject: ownerPersonalProject,
|
||||
sharedWithProjects: [],
|
||||
});
|
||||
const { queryByTestId } = renderComponent({
|
||||
props: {
|
||||
credentialId: credential.id,
|
||||
credentialData: {},
|
||||
credentialPermissions: { share: false },
|
||||
credential,
|
||||
modalBus: createEventBus(),
|
||||
},
|
||||
it('does not share the project when the disabled Share button is clicked', async () => {
|
||||
getDependenciesMock.mockReturnValue(usedInMarketing);
|
||||
|
||||
const credential = createCredential({
|
||||
homeProject: ownerPersonalProject,
|
||||
sharedWithProjects: [],
|
||||
});
|
||||
const { getByTestId, emitted } = renderComponent({
|
||||
props: {
|
||||
credentialId: credential.id,
|
||||
credentialData: {},
|
||||
credentialPermissions: { share: false },
|
||||
credential,
|
||||
modalBus: createEventBus(),
|
||||
},
|
||||
});
|
||||
|
||||
await userEvent.click(getByTestId('credential-used-in-project-share'));
|
||||
|
||||
expect(emitted()['update:modelValue']).toBeUndefined();
|
||||
expect(getByTestId('project-sharing-unshared-item')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(queryByTestId('project-sharing-unshared-item')).not.toBeInTheDocument();
|
||||
expect(fetchDependenciesMock).not.toHaveBeenCalled();
|
||||
it('shows a disabled Share button without the personal-space tooltip when the credential lives in a team project', async () => {
|
||||
getDependenciesMock.mockReturnValue(usedInMarketing);
|
||||
|
||||
const credential = createCredential({ sharedWithProjects: [] });
|
||||
const { getByTestId, queryByText } = renderComponent({
|
||||
props: {
|
||||
credentialId: credential.id,
|
||||
credentialData: {},
|
||||
credentialPermissions: { share: false },
|
||||
credential,
|
||||
modalBus: createEventBus(),
|
||||
},
|
||||
});
|
||||
|
||||
expect(getByTestId('project-sharing-unshared-item')).toBeInTheDocument();
|
||||
const share = getByTestId('credential-used-in-project-share');
|
||||
expect(share).toBeDisabled();
|
||||
|
||||
await userEvent.hover(share.parentElement as HTMLElement);
|
||||
expect(
|
||||
queryByText("You don't have permission to share personal credentials"),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not fetch or show used-in projects when the flag is disabled', () => {
|
||||
|
|
|
|||
|
|
@ -156,13 +156,18 @@ const confirmRemoval = computed(() => {
|
|||
const { fetchDependencies, getDependencies } = useDependencies();
|
||||
|
||||
onMounted(() => {
|
||||
if (isCredSharingEnabled.value && props.credentialPermissions.share) {
|
||||
if (isCredSharingEnabled.value) {
|
||||
void fetchDependencies([props.credentialId], 'credential');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Projects where the credential is used without a share. The rows stay visible
|
||||
* when the viewer cannot share: where a credential is used is audit information,
|
||||
* so the share permission only gates the Share button.
|
||||
*/
|
||||
const usedInProjects = computed(() => {
|
||||
if (!isCredSharingEnabled.value || !props.credentialPermissions.share) return [];
|
||||
if (!isCredSharingEnabled.value) return [];
|
||||
|
||||
const deps = getDependencies(props.credentialId, 'credential');
|
||||
if (!deps) return [];
|
||||
|
|
@ -215,6 +220,12 @@ function usedInProjectName(project: Pick<ProjectSharingData, 'name'>) {
|
|||
}
|
||||
|
||||
function usedInShareTooltip(project: ProjectSharingData) {
|
||||
if (!props.credentialPermissions.share) {
|
||||
return isPersonalSpaceRestricted.value
|
||||
? i18n.baseText('credentialEdit.credentialSharing.info.personalSpaceRestricted')
|
||||
: '';
|
||||
}
|
||||
|
||||
const name = usedInProjectName(project);
|
||||
|
||||
if (hasInstanceWideUse(project)) {
|
||||
|
|
@ -373,13 +384,17 @@ function goToUpgrade() {
|
|||
:disabled="!usedInShareTooltip(project)"
|
||||
placement="top"
|
||||
>
|
||||
<N8nButton
|
||||
variant="outline"
|
||||
data-test-id="credential-used-in-project-share"
|
||||
@click="shareUsedInProject(project.id)"
|
||||
>
|
||||
{{ i18n.baseText('credentialEdit.credentialSharing.share') }}
|
||||
</N8nButton>
|
||||
<!-- A disabled button gets no hover events, so the span carries the tooltip -->
|
||||
<span>
|
||||
<N8nButton
|
||||
variant="outline"
|
||||
:disabled="!credentialPermissions.share"
|
||||
data-test-id="credential-used-in-project-share"
|
||||
@click="shareUsedInProject(project.id)"
|
||||
>
|
||||
{{ i18n.baseText('credentialEdit.credentialSharing.share') }}
|
||||
</N8nButton>
|
||||
</span>
|
||||
</N8nTooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user