fix: document visibility logic (#1521)
Update the logic of document visibility logic and added some tests & updated some existing ones.
This commit is contained in:
@@ -17,23 +17,25 @@ The default document visibility option allows you to control who can view and ac
|
|||||||
|
|
||||||
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [team's general preferences page](/users/teams/preferences) and selecting a different visibility option.
|
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [team's general preferences page](/users/teams/preferences) and selecting a different visibility option.
|
||||||
|
|
||||||
<Callout type="warning">
|
|
||||||
If the team member uploading the document has a role lower than the default document visibility,
|
|
||||||
the document visibility will be set to a lower visibility level matching the team member's role.
|
|
||||||
</Callout>
|
|
||||||
|
|
||||||
Here's how it works:
|
Here's how it works:
|
||||||
|
|
||||||
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Admin_" or "_Managers and above_", the document's visibility is set to "_Everyone_".
|
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Everyone_", the document's visibility is set to "_EVERYONE_".
|
||||||
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Admin_", the document's visibility is set to "_Managers and above_".
|
- The user can't change the visibility of the document in the document editor.
|
||||||
- Otherwise, the document's visibility is set to the default document visibility.
|
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Admin_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Admin_" or "_Managers and above_" in this case).
|
||||||
|
- The user can't change the visibility of the document in the document editor.
|
||||||
|
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Everyone_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Everyone_" or "_Managers and above_" in this case).
|
||||||
|
- The user can change the visibility of the document to any of these options, except "_Admin_", in the document editor.
|
||||||
|
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Admin_", the document's visibility is set to "_Admin_".
|
||||||
|
- The user can't change the visibility of the document in the document editor.
|
||||||
|
- If a user with the "_Admin_" role creates a document, and the default document visibility is set to "_Everyone_", "_Managers and above_", or "_Admin_", the document's visibility is set to the default document visibility.
|
||||||
|
- The user can change the visibility of the document to any of these options in the document editor.
|
||||||
|
|
||||||
You can change the visibility of a document at any time by editing the document and selecting a different visibility option.
|
You can change the visibility of a document at any time by editing the document and selecting a different visibility option.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<Callout type="warning">
|
<Callout type="warning">
|
||||||
Updating the default document visibility in the team's general settings will not affect the
|
Updating the default document visibility in the team's general preferences will not affect the
|
||||||
visibility of existing documents. You will need to update the visibility of each document
|
visibility of existing documents. You will need to update the visibility of each document
|
||||||
individually.
|
individually.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client';
|
import { DocumentStatus, DocumentVisibility, TeamMemberRole } from '@documenso/prisma/client';
|
||||||
|
import { seedBlankDocument } from '@documenso/prisma/seed/documents';
|
||||||
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
import { seedDocuments, seedTeamDocuments } from '@documenso/prisma/seed/documents';
|
||||||
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
|
import { seedTeam, seedTeamEmail, seedTeamMember } from '@documenso/prisma/seed/teams';
|
||||||
import { seedUser } from '@documenso/prisma/seed/users';
|
import { seedUser } from '@documenso/prisma/seed/users';
|
||||||
@@ -538,7 +539,7 @@ test('[TEAMS]: ensure recipient can see document regardless of visibility', asyn
|
|||||||
await apiSignout({ page });
|
await apiSignout({ page });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[TEAMS]: check that members cannot see ADMIN-only documents', async ({ page }) => {
|
test('[TEAMS]: check that MEMBER role cannot see ADMIN-only documents', async ({ page }) => {
|
||||||
const team = await seedTeam();
|
const team = await seedTeam();
|
||||||
|
|
||||||
// Seed a member user
|
// Seed a member user
|
||||||
@@ -575,7 +576,46 @@ test('[TEAMS]: check that members cannot see ADMIN-only documents', async ({ pag
|
|||||||
await apiSignout({ page });
|
await apiSignout({ page });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[TEAMS]: check that managers cannot see ADMIN-only documents', async ({ page }) => {
|
test('[TEAMS]: check that MEMBER role cannot see MANAGER_AND_ABOVE-only documents', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const team = await seedTeam();
|
||||||
|
|
||||||
|
// Seed a member user
|
||||||
|
const memberUser = await seedTeamMember({
|
||||||
|
teamId: team.id,
|
||||||
|
role: TeamMemberRole.MEMBER,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Seed an ADMIN-only document
|
||||||
|
await seedDocuments([
|
||||||
|
{
|
||||||
|
sender: team.owner,
|
||||||
|
recipients: [],
|
||||||
|
type: DocumentStatus.COMPLETED,
|
||||||
|
documentOptions: {
|
||||||
|
teamId: team.id,
|
||||||
|
visibility: 'MANAGER_AND_ABOVE',
|
||||||
|
title: 'Manager and Above Only Document',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: memberUser.email,
|
||||||
|
redirectPath: `/t/${team.url}/documents?status=COMPLETED`,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check that the member user cannot see the ADMIN-only document
|
||||||
|
await expect(
|
||||||
|
page.getByRole('link', { name: 'Admin Only Document', exact: true }),
|
||||||
|
).not.toBeVisible();
|
||||||
|
|
||||||
|
await apiSignout({ page });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[TEAMS]: check that MANAGER role cannot see ADMIN-only documents', async ({ page }) => {
|
||||||
const team = await seedTeam();
|
const team = await seedTeam();
|
||||||
|
|
||||||
// Seed a manager user
|
// Seed a manager user
|
||||||
@@ -612,7 +652,7 @@ test('[TEAMS]: check that managers cannot see ADMIN-only documents', async ({ pa
|
|||||||
await apiSignout({ page });
|
await apiSignout({ page });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[TEAMS]: check that admin can see MANAGER_AND_ABOVE documents', async ({ page }) => {
|
test('[TEAMS]: check that ADMIN role can see MANAGER_AND_ABOVE documents', async ({ page }) => {
|
||||||
const team = await seedTeam();
|
const team = await seedTeam();
|
||||||
|
|
||||||
// Seed an admin user
|
// Seed an admin user
|
||||||
@@ -649,6 +689,187 @@ test('[TEAMS]: check that admin can see MANAGER_AND_ABOVE documents', async ({ p
|
|||||||
await apiSignout({ page });
|
await apiSignout({ page });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('[TEAMS]: check that ADMIN role can change document visibility', async ({ page }) => {
|
||||||
|
const team = await seedTeam({
|
||||||
|
createTeamOptions: {
|
||||||
|
teamGlobalSettings: {
|
||||||
|
create: {
|
||||||
|
documentVisibility: DocumentVisibility.MANAGER_AND_ABOVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const adminUser = await seedTeamMember({
|
||||||
|
teamId: team.id,
|
||||||
|
role: TeamMemberRole.ADMIN,
|
||||||
|
});
|
||||||
|
|
||||||
|
const document = await seedBlankDocument(adminUser, {
|
||||||
|
createDocumentOptions: {
|
||||||
|
teamId: team.id,
|
||||||
|
visibility: team.teamGlobalSettings?.documentVisibility,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: adminUser.email,
|
||||||
|
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.getByTestId('documentVisibilitySelectValue').click();
|
||||||
|
await page.getByLabel('Admins only').click();
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Continue' }).click();
|
||||||
|
await expect(page.getByRole('heading', { name: 'Add Signers' })).toBeVisible();
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Go Back' }).click();
|
||||||
|
await expect(page.getByRole('heading', { name: 'General' })).toBeVisible();
|
||||||
|
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toContainText('Admins only');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[TEAMS]: check that MEMBER role cannot change visibility of EVERYONE documents', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const team = await seedTeam({
|
||||||
|
createTeamOptions: {
|
||||||
|
teamGlobalSettings: {
|
||||||
|
create: {
|
||||||
|
documentVisibility: DocumentVisibility.EVERYONE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const teamMember = await seedTeamMember({
|
||||||
|
teamId: team.id,
|
||||||
|
role: TeamMemberRole.MEMBER,
|
||||||
|
});
|
||||||
|
|
||||||
|
const document = await seedBlankDocument(teamMember, {
|
||||||
|
createDocumentOptions: {
|
||||||
|
teamId: team.id,
|
||||||
|
visibility: team.teamGlobalSettings?.documentVisibility,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: teamMember.email,
|
||||||
|
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Everyone');
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[TEAMS]: check that MEMBER role cannot change visibility of MANAGER_AND_ABOVE documents', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const team = await seedTeam({
|
||||||
|
createTeamOptions: {
|
||||||
|
teamGlobalSettings: {
|
||||||
|
create: {
|
||||||
|
documentVisibility: DocumentVisibility.MANAGER_AND_ABOVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const teamMember = await seedTeamMember({
|
||||||
|
teamId: team.id,
|
||||||
|
role: TeamMemberRole.MEMBER,
|
||||||
|
});
|
||||||
|
|
||||||
|
const document = await seedBlankDocument(teamMember, {
|
||||||
|
createDocumentOptions: {
|
||||||
|
teamId: team.id,
|
||||||
|
visibility: team.teamGlobalSettings?.documentVisibility,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: teamMember.email,
|
||||||
|
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Managers and above');
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[TEAMS]: check that MEMBER role cannot change visibility of ADMIN documents', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const team = await seedTeam({
|
||||||
|
createTeamOptions: {
|
||||||
|
teamGlobalSettings: {
|
||||||
|
create: {
|
||||||
|
documentVisibility: DocumentVisibility.ADMIN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const teamMember = await seedTeamMember({
|
||||||
|
teamId: team.id,
|
||||||
|
role: TeamMemberRole.MEMBER,
|
||||||
|
});
|
||||||
|
|
||||||
|
const document = await seedBlankDocument(teamMember, {
|
||||||
|
createDocumentOptions: {
|
||||||
|
teamId: team.id,
|
||||||
|
visibility: team.teamGlobalSettings?.documentVisibility,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: teamMember.email,
|
||||||
|
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Admins only');
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[TEAMS]: check that MANAGER role cannot change visibility of ADMIN documents', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const team = await seedTeam({
|
||||||
|
createTeamOptions: {
|
||||||
|
teamGlobalSettings: {
|
||||||
|
create: {
|
||||||
|
documentVisibility: DocumentVisibility.ADMIN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const teamManager = await seedTeamMember({
|
||||||
|
teamId: team.id,
|
||||||
|
role: TeamMemberRole.MANAGER,
|
||||||
|
});
|
||||||
|
|
||||||
|
const document = await seedBlankDocument(teamManager, {
|
||||||
|
createDocumentOptions: {
|
||||||
|
teamId: team.id,
|
||||||
|
visibility: team.teamGlobalSettings?.documentVisibility,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await apiSignin({
|
||||||
|
page,
|
||||||
|
email: teamManager.email,
|
||||||
|
redirectPath: `/t/${team.url}/documents/${document.id}/edit`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toHaveText('Admins only');
|
||||||
|
await expect(page.getByTestId('documentVisibilitySelectValue')).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
test('[TEAMS]: users cannot see documents from other teams', async ({ page }) => {
|
test('[TEAMS]: users cannot see documents from other teams', async ({ page }) => {
|
||||||
// Seed two teams with documents
|
// Seed two teams with documents
|
||||||
const { team: teamA, teamMember2: teamAMember } = await seedTeamDocuments();
|
const { team: teamA, teamMember2: teamAMember } = await seedTeamDocuments();
|
||||||
|
|||||||
@@ -89,18 +89,17 @@ export const createDocument = async ({
|
|||||||
globalVisibility: DocumentVisibility | null | undefined,
|
globalVisibility: DocumentVisibility | null | undefined,
|
||||||
userRole: TeamMemberRole,
|
userRole: TeamMemberRole,
|
||||||
): DocumentVisibility => {
|
): DocumentVisibility => {
|
||||||
const defaultVisibility = globalVisibility ?? DocumentVisibility.EVERYONE;
|
if (globalVisibility) {
|
||||||
|
return globalVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
if (userRole === TeamMemberRole.ADMIN) {
|
if (userRole === TeamMemberRole.ADMIN) {
|
||||||
return defaultVisibility;
|
return DocumentVisibility.ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userRole === TeamMemberRole.MANAGER) {
|
if (userRole === TeamMemberRole.MANAGER) {
|
||||||
if (defaultVisibility === DocumentVisibility.ADMIN) {
|
|
||||||
return DocumentVisibility.MANAGER_AND_ABOVE;
|
return DocumentVisibility.MANAGER_AND_ABOVE;
|
||||||
}
|
}
|
||||||
return defaultVisibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DocumentVisibility.EVERYONE;
|
return DocumentVisibility.EVERYONE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -91,7 +91,10 @@ export const updateDocumentSettings = async ({
|
|||||||
|
|
||||||
if (teamId) {
|
if (teamId) {
|
||||||
const currentUserRole = document.team?.members[0]?.role;
|
const currentUserRole = document.team?.members[0]?.role;
|
||||||
|
const isDocumentOwner = document.userId === userId;
|
||||||
|
const requestedVisibility = data.visibility;
|
||||||
|
|
||||||
|
if (!isDocumentOwner) {
|
||||||
match(currentUserRole)
|
match(currentUserRole)
|
||||||
.with(TeamMemberRole.ADMIN, () => true)
|
.with(TeamMemberRole.ADMIN, () => true)
|
||||||
.with(TeamMemberRole.MANAGER, () => {
|
.with(TeamMemberRole.MANAGER, () => {
|
||||||
@@ -102,7 +105,7 @@ export const updateDocumentSettings = async ({
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!allowedVisibilities.includes(document.visibility) ||
|
!allowedVisibilities.includes(document.visibility) ||
|
||||||
(data.visibility && !allowedVisibilities.includes(data.visibility))
|
(requestedVisibility && !allowedVisibilities.includes(requestedVisibility))
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||||
message: 'You do not have permission to update the document visibility',
|
message: 'You do not have permission to update the document visibility',
|
||||||
@@ -112,7 +115,7 @@ export const updateDocumentSettings = async ({
|
|||||||
.with(TeamMemberRole.MEMBER, () => {
|
.with(TeamMemberRole.MEMBER, () => {
|
||||||
if (
|
if (
|
||||||
document.visibility !== DocumentVisibility.EVERYONE ||
|
document.visibility !== DocumentVisibility.EVERYONE ||
|
||||||
(data.visibility && data.visibility !== DocumentVisibility.EVERYONE)
|
(requestedVisibility && requestedVisibility !== DocumentVisibility.EVERYONE)
|
||||||
) {
|
) {
|
||||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||||
message: 'You do not have permission to update the document visibility',
|
message: 'You do not have permission to update the document visibility',
|
||||||
@@ -125,6 +128,7 @@ export const updateDocumentSettings = async ({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const { documentAuthOption } = extractDocumentAuthMethods({
|
const { documentAuthOption } = extractDocumentAuthMethods({
|
||||||
documentAuth: document.authOptions,
|
documentAuth: document.authOptions,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
|
|
||||||
import { prisma } from '..';
|
import { prisma } from '..';
|
||||||
|
import type { Prisma } from '../client';
|
||||||
import { TeamMemberInviteStatus, TeamMemberRole } from '../client';
|
import { TeamMemberInviteStatus, TeamMemberRole } from '../client';
|
||||||
import { seedUser } from './users';
|
import { seedUser } from './users';
|
||||||
|
|
||||||
@@ -10,11 +11,13 @@ const nanoid = customAlphabet('1234567890abcdef', 10);
|
|||||||
type SeedTeamOptions = {
|
type SeedTeamOptions = {
|
||||||
createTeamMembers?: number;
|
createTeamMembers?: number;
|
||||||
createTeamEmail?: true | string;
|
createTeamEmail?: true | string;
|
||||||
|
createTeamOptions?: Partial<Prisma.TeamUncheckedCreateInput>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const seedTeam = async ({
|
export const seedTeam = async ({
|
||||||
createTeamMembers = 0,
|
createTeamMembers = 0,
|
||||||
createTeamEmail,
|
createTeamEmail,
|
||||||
|
createTeamOptions = {},
|
||||||
}: SeedTeamOptions = {}) => {
|
}: SeedTeamOptions = {}) => {
|
||||||
const teamUrl = `team-${nanoid()}`;
|
const teamUrl = `team-${nanoid()}`;
|
||||||
const teamEmail = createTeamEmail === true ? `${teamUrl}@${EMAIL_DOMAIN}` : createTeamEmail;
|
const teamEmail = createTeamEmail === true ? `${teamUrl}@${EMAIL_DOMAIN}` : createTeamEmail;
|
||||||
@@ -54,6 +57,7 @@ export const seedTeam = async ({
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
...createTeamOptions,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -69,6 +73,7 @@ export const seedTeam = async ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
teamEmail: true,
|
teamEmail: true,
|
||||||
|
teamGlobalSettings: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import React, { forwardRef } from 'react';
|
import React, { forwardRef } from 'react';
|
||||||
|
|
||||||
|
import { TeamMemberRole } from '@prisma/client';
|
||||||
import type { SelectProps } from '@radix-ui/react-select';
|
import type { SelectProps } from '@radix-ui/react-select';
|
||||||
import { InfoIcon } from 'lucide-react';
|
import { InfoIcon } from 'lucide-react';
|
||||||
|
import { match } from 'ts-pattern';
|
||||||
|
|
||||||
import { DOCUMENT_VISIBILITY } from '@documenso/lib/constants/document-visibility';
|
import { DOCUMENT_VISIBILITY } from '@documenso/lib/constants/document-visibility';
|
||||||
import { DocumentVisibility } from '@documenso/lib/types/document-visibility';
|
import { DocumentVisibility } from '@documenso/lib/types/document-visibility';
|
||||||
@@ -18,15 +20,27 @@ export type DocumentVisibilitySelectType = SelectProps & {
|
|||||||
currentMemberRole?: string;
|
currentMemberRole?: string;
|
||||||
isTeamSettings?: boolean;
|
isTeamSettings?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
visibility?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DocumentVisibilitySelect = forwardRef<HTMLButtonElement, DocumentVisibilitySelectType>(
|
export const DocumentVisibilitySelect = forwardRef<HTMLButtonElement, DocumentVisibilitySelectType>(
|
||||||
({ currentMemberRole, isTeamSettings = false, disabled, ...props }, ref) => {
|
({ currentMemberRole, isTeamSettings = false, disabled, visibility, ...props }, ref) => {
|
||||||
const canUpdateVisibility =
|
const canUpdateVisibility = match(currentMemberRole)
|
||||||
currentMemberRole === 'ADMIN' || currentMemberRole === 'MANAGER' || isTeamSettings;
|
.with(TeamMemberRole.ADMIN, () => true)
|
||||||
|
.with(
|
||||||
|
TeamMemberRole.MANAGER,
|
||||||
|
() =>
|
||||||
|
visibility === DocumentVisibility.EVERYONE ||
|
||||||
|
visibility === DocumentVisibility.MANAGER_AND_ABOVE,
|
||||||
|
)
|
||||||
|
.otherwise(() => false);
|
||||||
|
|
||||||
|
const isAdmin = currentMemberRole === TeamMemberRole.ADMIN;
|
||||||
|
const isManager = currentMemberRole === TeamMemberRole.MANAGER;
|
||||||
|
const canEdit = isTeamSettings || canUpdateVisibility;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select {...props} disabled={(!canUpdateVisibility && !isTeamSettings) || disabled}>
|
<Select {...props} disabled={!canEdit || disabled}>
|
||||||
<SelectTrigger ref={ref} className="bg-background text-muted-foreground">
|
<SelectTrigger ref={ref} className="bg-background text-muted-foreground">
|
||||||
<SelectValue data-testid="documentVisibilitySelectValue" placeholder="Everyone" />
|
<SelectValue data-testid="documentVisibilitySelectValue" placeholder="Everyone" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -35,13 +49,13 @@ export const DocumentVisibilitySelect = forwardRef<HTMLButtonElement, DocumentVi
|
|||||||
<SelectItem value={DocumentVisibility.EVERYONE}>
|
<SelectItem value={DocumentVisibility.EVERYONE}>
|
||||||
{DOCUMENT_VISIBILITY.EVERYONE.value}
|
{DOCUMENT_VISIBILITY.EVERYONE.value}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value={DocumentVisibility.MANAGER_AND_ABOVE} disabled={!canUpdateVisibility}>
|
<SelectItem
|
||||||
|
value={DocumentVisibility.MANAGER_AND_ABOVE}
|
||||||
|
disabled={!isAdmin && (!isManager || visibility === DocumentVisibility.ADMIN)}
|
||||||
|
>
|
||||||
{DOCUMENT_VISIBILITY.MANAGER_AND_ABOVE.value}
|
{DOCUMENT_VISIBILITY.MANAGER_AND_ABOVE.value}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem
|
<SelectItem value={DocumentVisibility.ADMIN} disabled={!isAdmin}>
|
||||||
value={DocumentVisibility.ADMIN}
|
|
||||||
disabled={currentMemberRole !== 'ADMIN' && !isTeamSettings}
|
|
||||||
>
|
|
||||||
{DOCUMENT_VISIBILITY.ADMIN.value}
|
{DOCUMENT_VISIBILITY.ADMIN.value}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ export const AddSettingsFormPartial = ({
|
|||||||
<FormControl>
|
<FormControl>
|
||||||
<DocumentVisibilitySelect
|
<DocumentVisibilitySelect
|
||||||
currentMemberRole={currentTeamMemberRole}
|
currentMemberRole={currentTeamMemberRole}
|
||||||
|
visibility={document.visibility}
|
||||||
{...field}
|
{...field}
|
||||||
onValueChange={field.onChange}
|
onValueChange={field.onChange}
|
||||||
/>
|
/>
|
||||||
@@ -273,7 +274,7 @@ export const AddSettingsFormPartial = ({
|
|||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
|
|
||||||
<AccordionContent className="text-muted-foreground -mx-1 px-1 pt-2 text-sm leading-relaxed">
|
<AccordionContent className="text-muted-foreground -mx-1 px-1 pt-2 text-sm leading-relaxed">
|
||||||
<div className="flex flex-col space-y-6 ">
|
<div className="flex flex-col space-y-6">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="externalId"
|
name="externalId"
|
||||||
|
|||||||
Reference in New Issue
Block a user