Skip to content

Commit

Permalink
fix: hide manage/add/edit tags buttons when not allowed to tag object
Browse files Browse the repository at this point in the history
  • Loading branch information
pomegranited committed Oct 11, 2024
1 parent c2660b1 commit 43783a0
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 49 deletions.
24 changes: 13 additions & 11 deletions src/content-tags-drawer/ContentTagsCollapsible.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -393,16 +393,18 @@ const ContentTagsCollapsible = ({
&& (
<div className="mb-3" key={taxonomyId}>
<p className="text-gray-500">{intl.formatMessage(messages.collapsibleNoTagsAddedText)}
<Button
tabIndex={0}
size="inline"
ref={selectInlineEditModeRef}
variant="link"
className="text-info-500 add-tags-button"
onClick={toEditMode}
>
{ intl.formatMessage(messages.collapsibleAddStagedTagsButtonText) }
</Button>
{canTagObject && (
<Button
tabIndex={0}
size="inline"
ref={selectInlineEditModeRef}
variant="link"
className="text-info-500 add-tags-button"
onClick={toEditMode}
>
{ intl.formatMessage(messages.collapsibleAddStagedTagsButtonText) }
</Button>
)}
</p>
</div>
)}
Expand All @@ -418,7 +420,7 @@ const ContentTagsCollapsible = ({
)}

<div className="d-flex taxonomy-tags-selector-menu">
{isEditMode && canTagObject && (
{isEditMode && (
<Select
onBlur={handleOnBlur}
styles={{
Expand Down
24 changes: 24 additions & 0 deletions src/content-tags-drawer/ContentTagsCollapsible.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,30 @@ describe('<ContentTagsCollapsible />', () => {
expect(data.toEditMode).toHaveBeenCalledTimes(1);
});

it('should not render "add tags" button when expanded and not allowed to tag objects', async () => {
await getComponent({
...data,
isEditMode: false,
taxonomyAndTagsData: {
id: 123,
name: 'Taxonomy 1',
canTagObject: false,
contentTags: [],
},
});

const expandToggle = screen.getByRole('button', {
name: /taxonomy 1/i,
});
fireEvent.click(expandToggle);
expect(screen.queryByText(/no tags added yet/i)).toBeInTheDocument();

const addTags = screen.queryByRole('button', {
name: /add tags/i,
});
expect(addTags).not.toBeInTheDocument();
});

it('should call `openCollapsible` when click in the collapsible', async () => {
await getComponent({
...data,
Expand Down
25 changes: 24 additions & 1 deletion src/content-tags-drawer/ContentTagsDrawer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jest.mock('react-router-dom', () => ({
const renderDrawer = (contentId, drawerParams = {}) => (
render(
<ContentTagsDrawerSheetContext.Provider value={drawerParams}>
<ContentTagsDrawer {...drawerParams} />
<ContentTagsDrawer canTagObject {...drawerParams} />
</ContentTagsDrawerSheetContext.Provider>,
{ path, params: { contentId } },
)
Expand Down Expand Up @@ -244,6 +244,29 @@ describe('<ContentTagsDrawer />', () => {
expect(screen.queryByRole('button', { name: /save/i })).not.toBeInTheDocument();
});

test.each([
{
variant: 'drawer',
editButton: /edit tags/i,
},
{
variant: 'component',
editButton: /manage tags/i,
},
])(
'should hide "$editButton" button on $variant variant if not allowed to tag object',
async ({ variant, editButton }) => {
renderDrawer(stagedTagsId, { variant, canTagObject: false });
expect(await screen.findByText('Taxonomy 1')).toBeInTheDocument();

expect(screen.queryByRole('button', { name: editButton })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /delete/i })).not.toBeInTheDocument();
expect(screen.queryByText(/add a tag/i)).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /cancel/i })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: /save/i })).not.toBeInTheDocument();
},
);

it('should test adding a content tag to the staged tags for a taxonomy', async () => {
renderDrawer(stagedTagsId);
expect(await screen.findByText('Taxonomy 1')).toBeInTheDocument();
Expand Down
51 changes: 29 additions & 22 deletions src/content-tags-drawer/ContentTagsDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ const ContentTagsDrawerTittle = () => {

interface ContentTagsDrawerVariantFooterProps {
onClose: () => void,
canTagObject: boolean,
}

const ContentTagsDrawerVariantFooter = ({ onClose }: ContentTagsDrawerVariantFooterProps) => {
const ContentTagsDrawerVariantFooter = ({ onClose, canTagObject }: ContentTagsDrawerVariantFooterProps) => {
const intl = useIntl();
const {
commitGlobalStagedTagsStatus,
Expand Down Expand Up @@ -130,16 +131,18 @@ const ContentTagsDrawerVariantFooter = ({ onClose }: ContentTagsDrawerVariantFoo
? messages.tagsDrawerCancelButtonText
: messages.tagsDrawerCloseButtonText)}
</Button>
<Button
className="rounded-0"
onClick={isEditMode
? commitGlobalStagedTags
: toEditMode}
>
{ intl.formatMessage(isEditMode
? messages.tagsDrawerSaveButtonText
: messages.tagsDrawerEditTagsButtonText)}
</Button>
{canTagObject && (
<Button
className="rounded-0"
onClick={isEditMode
? commitGlobalStagedTags
: toEditMode}
>
{ intl.formatMessage(isEditMode
? messages.tagsDrawerSaveButtonText
: messages.tagsDrawerEditTagsButtonText)}
</Button>
)}
</Stack>
)
: (
Expand All @@ -154,7 +157,7 @@ const ContentTagsDrawerVariantFooter = ({ onClose }: ContentTagsDrawerVariantFoo
);
};

const ContentTagsComponentVariantFooter = () => {
const ContentTagsComponentVariantFooter = ({ canTagObject }: { canTagObject: boolean }) => {
const intl = useIntl();
const {
commitGlobalStagedTagsStatus,
Expand Down Expand Up @@ -196,13 +199,15 @@ const ContentTagsComponentVariantFooter = () => {
)}
</div>
) : (
<Button
variant="outline-primary"
onClick={toEditMode}
block
>
{intl.formatMessage(messages.manageTagsButton)}
</Button>
canTagObject && (
<Button
variant="outline-primary"
onClick={toEditMode}
block
>
{intl.formatMessage(messages.manageTagsButton)}
</Button>
)
)}
</div>
);
Expand All @@ -211,6 +216,7 @@ const ContentTagsComponentVariantFooter = () => {
interface ContentTagsDrawerProps {
id?: string;
onClose?: () => void;
canTagObject?: boolean;
variant?: 'drawer' | 'component';
}

Expand All @@ -226,6 +232,7 @@ interface ContentTagsDrawerProps {
const ContentTagsDrawer = ({
id,
onClose,
canTagObject = false,
variant = 'drawer',
}: ContentTagsDrawerProps) => {
const intl = useIntl();
Expand All @@ -237,7 +244,7 @@ const ContentTagsDrawer = ({
throw new Error('Error: contentId cannot be null.');
}

const context = useContentTagsDrawerContext(contentId);
const context = useContentTagsDrawerContext(contentId, canTagObject);
const { blockingSheet } = useContext(ContentTagsDrawerSheetContext);

const {
Expand Down Expand Up @@ -301,9 +308,9 @@ const ContentTagsDrawer = ({
if (isTaxonomyListLoaded && isContentTaxonomyTagsLoaded) {
switch (variant) {
case 'drawer':
return <ContentTagsDrawerVariantFooter onClose={onCloseDrawer} />;
return <ContentTagsDrawerVariantFooter onClose={onCloseDrawer} canTagObject={canTagObject} />;
case 'component':
return <ContentTagsComponentVariantFooter />;
return <ContentTagsComponentVariantFooter canTagObject={canTagObject} />;
default:
return null;
}
Expand Down
4 changes: 3 additions & 1 deletion src/content-tags-drawer/ContentTagsDrawerHelper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ContentTagsDrawerSheetContext } from './common/context';
/**
* Handles the context and all the underlying logic for the ContentTagsDrawer component
* @param {string} contentId
* @param {boolean} canTagObject
* @returns {{
* stagedContentTags: Record<number, StagedTagData[]>,
* addStagedContentTag: (taxonomyId: number, addedTag: StagedTagData) => void,
Expand Down Expand Up @@ -46,7 +47,7 @@ import { ContentTagsDrawerSheetContext } from './common/context';
* otherTaxonomies: TagsInTaxonomy[],
* }}
*/
const useContentTagsDrawerContext = (contentId) => {
const useContentTagsDrawerContext = (contentId, canTagObject) => {
const intl = useIntl();
const org = extractOrgFromContentId(contentId);

Expand Down Expand Up @@ -115,6 +116,7 @@ const useContentTagsDrawerContext = (contentId) => {
// Initialize list of content tags in taxonomies to populate
const taxonomiesList = taxonomyListData.results.map((taxonomy) => ({
...taxonomy,
canTagObject: taxonomy.canTagObject && canTagObject,
contentTags: /** @type {ContentTagData[]} */([]),
}));

Expand Down
5 changes: 5 additions & 0 deletions src/content-tags-drawer/ContentTagsDrawerSheet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const ContentTagsDrawerSheet = ({ id, onClose, showSheet }) => {
blockingSheet, setBlockingSheet,
}), [blockingSheet, setBlockingSheet]);

// ContentTagsDrawerSheet is only used when editing Courses/Course Units,
// so we assume it's ok to edit the object tags too.
const canTagObject = true;

return (
<ContentTagsDrawerSheetContext.Provider value={context}>
<Sheet
Expand All @@ -23,6 +27,7 @@ const ContentTagsDrawerSheet = ({ id, onClose, showSheet }) => {
<ContentTagsDrawer
id={id}
onClose={onClose}
canTagObject={canTagObject}
/>
</Sheet>
</ContentTagsDrawerSheetContext.Provider>
Expand Down
2 changes: 1 addition & 1 deletion src/library-authoring/component-info/ComponentInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const ComponentInfo = ({ usageKey }: ComponentInfoProps) => {
<ComponentPreview usageKey={usageKey} />
</Tab>
<Tab eventKey="manage" title={intl.formatMessage(messages.manageTabTitle)}>
<ComponentManagement usageKey={usageKey} />
<ComponentManagement usageKey={usageKey} canEdit={canEdit} />
</Tab>
<Tab eventKey="details" title={intl.formatMessage(messages.detailsTabTitle)}>
<ComponentDetails usageKey={usageKey} />
Expand Down
38 changes: 26 additions & 12 deletions src/library-authoring/component-info/ComponentManagement.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import ComponentManagement from './ComponentManagement';
import { mockContentTaxonomyTagsData } from '../../content-tags-drawer/data/api.mocks';

jest.mock('../../content-tags-drawer', () => ({
ContentTagsDrawer: () => <div>Mocked ContentTagsDrawer</div>,
ContentTagsDrawer: ({ canTagObject }: { canTagObject: boolean }) => (
<div>Mocked {canTagObject ? 'editable' : 'read-only'} ContentTagsDrawer</div>
),
}));

/*
Expand Down Expand Up @@ -48,17 +50,29 @@ describe('<ComponentManagement />', () => {
).toBeInTheDocument();
});

it('should render the tagging info', async () => {
setConfig({
...getConfig(),
ENABLE_TAGGING_TAXONOMY_PAGES: 'true',
});
initializeMocks();
mockLibraryBlockMetadata.applyMock();
render(<ComponentManagement usageKey={mockLibraryBlockMetadata.usageKeyNeverPublished} />);
expect(await screen.findByText('Tags (0)')).toBeInTheDocument();
expect(screen.queryByText('Mocked ContentTagsDrawer')).toBeInTheDocument();
});
test.each([
{
canEdit: true,
expected: 'editable',
},
{
canEdit: false,
expected: 'read-only',
},
])(
'should render the tagging info as $expected',
async ({ canEdit, expected }) => {
setConfig({
...getConfig(),
ENABLE_TAGGING_TAXONOMY_PAGES: 'true',
});
initializeMocks();
mockLibraryBlockMetadata.applyMock();
render(<ComponentManagement usageKey={mockLibraryBlockMetadata.usageKeyNeverPublished} canEdit={canEdit} />);
expect(await screen.findByText('Tags (0)')).toBeInTheDocument();
expect(screen.queryByText(`Mocked ${expected} ContentTagsDrawer`)).toBeInTheDocument();
},
);

it('should not render draft status', async () => {
setConfig({
Expand Down
4 changes: 3 additions & 1 deletion src/library-authoring/component-info/ComponentManagement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import { useContentTaxonomyTagsData } from '../../content-tags-drawer/data/apiHo

interface ComponentManagementProps {
usageKey: string;
canEdit?: boolean;
}
const ComponentManagement = ({ usageKey }: ComponentManagementProps) => {
const ComponentManagement = ({ usageKey, canEdit = false }: ComponentManagementProps) => {
const intl = useIntl();
const { data: componentMetadata } = useLibraryBlockMetadata(usageKey);
const { data: componentTags } = useContentTaxonomyTagsData(usageKey);
Expand Down Expand Up @@ -62,6 +63,7 @@ const ComponentManagement = ({ usageKey }: ComponentManagementProps) => {
<ContentTagsDrawer
id={usageKey}
variant="component"
canTagObject={canEdit}
/>
</Collapsible>
)}
Expand Down

0 comments on commit 43783a0

Please sign in to comment.