Allow non-owners to see pinned tags

This commit is contained in:
Chewbacca 2023-05-12 11:51:00 -04:00
parent d2eca144fa
commit f27933965f
4 changed files with 51 additions and 31 deletions

View file

@ -17,11 +17,16 @@ interface IIcon extends Pick<React.SVGAttributes<SVGAElement>, 'strokeWidth'> {
src: string src: string
/** Width and height of the icon in pixels. */ /** Width and height of the icon in pixels. */
size?: number size?: number
/** Override the data-testid */
'data-testid'?: string
} }
/** Renders and SVG icon with optional counter. */ /** Renders and SVG icon with optional counter. */
const Icon: React.FC<IIcon> = ({ src, alt, count, size, countMax, ...filteredProps }): JSX.Element => ( const Icon: React.FC<IIcon> = ({ src, alt, count, size, countMax, ...filteredProps }): JSX.Element => (
<div className='relative flex shrink-0 flex-col' data-testid='icon'> <div
className='relative flex shrink-0 flex-col'
data-testid={filteredProps['data-testid'] || 'icon'}
>
{count ? ( {count ? (
<span className='absolute -right-3 -top-2 flex h-5 min-w-[20px] shrink-0 items-center justify-center whitespace-nowrap break-words'> <span className='absolute -right-3 -top-2 flex h-5 min-w-[20px] shrink-0 items-center justify-center whitespace-nowrap break-words'>
<Counter count={count} countMax={countMax} /> <Counter count={count} countMax={countMax} />

View file

@ -91,31 +91,32 @@ describe('<GroupTagListItem />', () => {
expect(screen.queryAllByTestId('pin-icon')).toHaveLength(0); expect(screen.queryAllByTestId('pin-icon')).toHaveLength(0);
}); });
}); });
});
describe('as a non-owner', () => { describe('as a non-owner', () => {
const group = buildGroup({ const group = buildGroup({
relationship: buildGroupRelationship({ relationship: buildGroupRelationship({
role: GroupRoles.ADMIN, role: GroupRoles.ADMIN,
member: true, member: true,
}), }),
});
describe('when the tag is pinned', () => {
const tag = buildGroupTag({ pinned: true, visible: true });
it('does render the pin icon', () => {
render(<GroupTagListItem group={group} tag={tag} isPinnable />);
screen.debug();
expect(screen.queryAllByTestId('pin-icon')).toHaveLength(1);
}); });
});
describe('when the tag is visible', () => { describe('when the tag is not pinned', () => {
const tag = buildGroupTag({ visible: true }); const tag = buildGroupTag({ pinned: false, visible: true });
it('does not render the pin icon', () => { it('does not render the pin icon', () => {
render(<GroupTagListItem group={group} tag={tag} isPinnable />); render(<GroupTagListItem group={group} tag={tag} isPinnable />);
expect(screen.queryAllByTestId('pin-icon')).toHaveLength(0); expect(screen.queryAllByTestId('pin-icon')).toHaveLength(0);
});
});
describe('when the tag is not visible', () => {
const tag = buildGroupTag({ visible: false });
it('does not render the pin icon', () => {
render(<GroupTagListItem group={group} tag={tag} isPinnable />);
expect(screen.queryAllByTestId('pin-icon')).toHaveLength(0);
});
}); });
}); });
}); });

View file

@ -3,7 +3,7 @@ import { defineMessages, useIntl } from 'react-intl';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useUpdateGroupTag } from 'soapbox/api/hooks'; import { useUpdateGroupTag } from 'soapbox/api/hooks';
import { HStack, IconButton, Stack, Text, Tooltip } from 'soapbox/components/ui'; import { HStack, Icon, IconButton, Stack, Text, Tooltip } from 'soapbox/components/ui';
import { importEntities } from 'soapbox/entity-store/actions'; import { importEntities } from 'soapbox/entity-store/actions';
import { Entities } from 'soapbox/entity-store/entities'; import { Entities } from 'soapbox/entity-store/entities';
import { useAppDispatch } from 'soapbox/hooks'; import { useAppDispatch } from 'soapbox/hooks';
@ -84,6 +84,20 @@ const GroupTagListItem = (props: IGroupMemberListItem) => {
}; };
const renderPinIcon = () => { const renderPinIcon = () => {
if (!isOwner && tag.pinned) {
return (
<Icon
src={require('@tabler/icons/pin-filled.svg')}
className='h-5 w-5 text-gray-600'
data-testid='pin-icon'
/>
);
}
if (!isOwner) {
return null;
}
if (isPinnable) { if (isPinnable) {
return ( return (
<Tooltip <Tooltip
@ -149,12 +163,12 @@ const GroupTagListItem = (props: IGroupMemberListItem) => {
</Stack> </Stack>
</Link> </Link>
{isOwner ? ( <HStack alignItems='center' space={2}>
<HStack alignItems='center' space={2}> {tag.visible ? (
{tag.visible ? ( renderPinIcon()
renderPinIcon() ) : null}
) : null}
{isOwner ? (
<Tooltip <Tooltip
text={ text={
tag.visible ? tag.visible ?
@ -173,8 +187,8 @@ const GroupTagListItem = (props: IGroupMemberListItem) => {
iconClassName='h-5 w-5 text-primary-500 dark:text-accent-blue' iconClassName='h-5 w-5 text-primary-500 dark:text-accent-blue'
/> />
</Tooltip> </Tooltip>
</HStack> ) : null}
) : null} </HStack>
</HStack> </HStack>
); );
}; };

View file

@ -36,7 +36,7 @@ const GroupTopics: React.FC<IGroupTopics> = (props) => {
showLoading={!group || isLoading && tags.length === 0} showLoading={!group || isLoading && tags.length === 0}
placeholderComponent={PlaceholderAccount} placeholderComponent={PlaceholderAccount}
placeholderCount={3} placeholderCount={3}
className='divide-y divide-solid divide-gray-300' className='divide-y divide-solid divide-gray-300 dark:divide-gray-800'
itemClassName='py-3 last:pb-0' itemClassName='py-3 last:pb-0'
emptyMessage={ emptyMessage={
<Stack space={4} className='pt-6' justifyContent='center' alignItems='center'> <Stack space={4} className='pt-6' justifyContent='center' alignItems='center'>