mirror of
https://github.com/mattermost/focalboard.git
synced 2025-03-23 20:52:42 +02:00
Added confirmation dialog for unlinking a channel (#3432)
* Added confirmation dialog for unlinking a channel * Updated texts
This commit is contained in:
parent
67608a833b
commit
4f7ce070bc
@ -361,6 +361,9 @@
|
||||
"shareBoard.confirm-link-public-channel": "You're adding a public channel",
|
||||
"shareBoard.confirm-link-public-channel-button": "Yes, add public channel",
|
||||
"shareBoard.confirm-link-public-channel-subtext": "Anyone who joins that public channel will now get “Editor” access to the board, are you sure you want to proceed?",
|
||||
"shareBoard.confirm-unlink.title": "Unlink channel from board",
|
||||
"shareBoard.confirm-unlink.body": "When you unlink a channel from a board, all members of the channel (existing and new) will loose access to it unless they are given permission separately. {lineBreak} Are you sure you want to unlink it?",
|
||||
"shareBoard.confirm-unlink.confirmBtnText": "Yes, unlink",
|
||||
"shareBoard.lastAdmin": "Boards must have at least one Administrator",
|
||||
"shareBoard.members-select-group": "Members",
|
||||
"tutorial_tip.finish_tour": "Done",
|
||||
|
@ -1,5 +1,255 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`src/components/shareBoard/shareBoard confirm unlinking linked channel 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="Dialog dialog-back ShareBoardDialog"
|
||||
>
|
||||
<div
|
||||
class="backdrop"
|
||||
/>
|
||||
<div
|
||||
class="wrapper"
|
||||
>
|
||||
<div
|
||||
class="dialog"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="toolbar"
|
||||
>
|
||||
<button
|
||||
aria-label="Close dialog"
|
||||
title="Close dialog"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-close CloseIcon"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="toolbar--right"
|
||||
>
|
||||
<div>
|
||||
<span
|
||||
class="text-heading5"
|
||||
>
|
||||
Share Board
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="share-input__container"
|
||||
>
|
||||
<div
|
||||
class="share-input"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-magnify MagnifyIcon"
|
||||
/>
|
||||
<div
|
||||
class="userSearchInput css-b62m3t-container"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-12-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
/>
|
||||
<div
|
||||
class=" css-1wmrr75-Control"
|
||||
>
|
||||
<div
|
||||
class=" css-30zlo3-ValueContainer"
|
||||
>
|
||||
<div
|
||||
class=" css-14el2xx-placeholder"
|
||||
id="react-select-12-placeholder"
|
||||
>
|
||||
Search for people
|
||||
</div>
|
||||
<div
|
||||
class=" css-ox1y69-Input"
|
||||
data-value=""
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-describedby="react-select-12-placeholder"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
class=""
|
||||
id="react-select-12-input"
|
||||
role="combobox"
|
||||
spellcheck="false"
|
||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class=" css-1hb7zxy-IndicatorsContainer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="user-items"
|
||||
>
|
||||
<div
|
||||
class="user-item"
|
||||
>
|
||||
<div
|
||||
class="user-item__content"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-mattermost user-item__img"
|
||||
/>
|
||||
<div
|
||||
class="ml-3"
|
||||
>
|
||||
<strong>
|
||||
Everyone at Test Team Team
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="menuwrapper"
|
||||
class="MenuWrapper"
|
||||
role="button"
|
||||
>
|
||||
<button
|
||||
class="user-item__button"
|
||||
>
|
||||
None
|
||||
<i
|
||||
class="CompassIcon icon-chevron-down CompassIcon"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="user-item channel-item"
|
||||
>
|
||||
<div
|
||||
class="user-item__content"
|
||||
>
|
||||
<span
|
||||
class="user-item__img"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-lock-outline LockOutlineIcon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ml-3"
|
||||
>
|
||||
<strong>
|
||||
Dunder Mifflin Party Planing Committee
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="menuwrapper"
|
||||
class="MenuWrapper"
|
||||
role="button"
|
||||
>
|
||||
<button
|
||||
class="user-item__button"
|
||||
>
|
||||
Editor
|
||||
<i
|
||||
class="CompassIcon icon-chevron-down CompassIcon"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="tabs-container"
|
||||
>
|
||||
<button
|
||||
class="tab-item tab-item--active"
|
||||
>
|
||||
Share
|
||||
</button>
|
||||
<button
|
||||
class="tab-item false"
|
||||
>
|
||||
Publish
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="tabs-content"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="d-flex justify-content-between"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-column"
|
||||
>
|
||||
<div
|
||||
class="text-heading2"
|
||||
>
|
||||
Share internally
|
||||
</div>
|
||||
<div
|
||||
class="text-light"
|
||||
>
|
||||
Users who have permissions will be able to use this link.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex justify-content-between tabs-inputs"
|
||||
>
|
||||
<div
|
||||
class="d-flex input-container"
|
||||
>
|
||||
<a
|
||||
class="shareUrl"
|
||||
href="http://localhost/1/1"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
http://localhost/1/1
|
||||
</a>
|
||||
</div>
|
||||
<button
|
||||
title="Copy internal link"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-content-copy CompassIcon"
|
||||
/>
|
||||
<span>
|
||||
Copy link
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`src/components/shareBoard/shareBoard return shareBoard and click Copy link 1`] = `
|
||||
<div>
|
||||
<div
|
||||
@ -790,6 +1040,44 @@ exports[`src/components/shareBoard/shareBoard return shareBoard and click Select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="user-item channel-item"
|
||||
>
|
||||
<div
|
||||
class="user-item__content"
|
||||
>
|
||||
<span
|
||||
class="user-item__img"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-lock-outline LockOutlineIcon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ml-3"
|
||||
>
|
||||
<strong>
|
||||
Dunder Mifflin Party Planing Committee
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="menuwrapper"
|
||||
class="MenuWrapper"
|
||||
role="button"
|
||||
>
|
||||
<button
|
||||
class="user-item__button"
|
||||
>
|
||||
Editor
|
||||
<i
|
||||
class="CompassIcon icon-chevron-down CompassIcon"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="tabs-content"
|
||||
@ -1220,6 +1508,44 @@ exports[`src/components/shareBoard/shareBoard return shareBoard and click Select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="user-item channel-item"
|
||||
>
|
||||
<div
|
||||
class="user-item__content"
|
||||
>
|
||||
<span
|
||||
class="user-item__img"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-lock-outline LockOutlineIcon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ml-3"
|
||||
>
|
||||
<strong>
|
||||
Dunder Mifflin Party Planing Committee
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="menuwrapper"
|
||||
class="MenuWrapper"
|
||||
role="button"
|
||||
>
|
||||
<button
|
||||
class="user-item__button"
|
||||
>
|
||||
Editor
|
||||
<i
|
||||
class="CompassIcon icon-chevron-down CompassIcon"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="tabs-content"
|
||||
@ -1418,6 +1744,44 @@ exports[`src/components/shareBoard/shareBoard return shareBoard and click Select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="user-item channel-item"
|
||||
>
|
||||
<div
|
||||
class="user-item__content"
|
||||
>
|
||||
<span
|
||||
class="user-item__img"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-lock-outline LockOutlineIcon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ml-3"
|
||||
>
|
||||
<strong>
|
||||
Dunder Mifflin Party Planing Committee
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="menuwrapper"
|
||||
class="MenuWrapper"
|
||||
role="button"
|
||||
>
|
||||
<button
|
||||
class="user-item__button"
|
||||
>
|
||||
Editor
|
||||
<i
|
||||
class="CompassIcon icon-chevron-down CompassIcon"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="tabs-content"
|
||||
@ -1848,6 +2212,44 @@ exports[`src/components/shareBoard/shareBoard return shareBoard and click Select
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="user-item channel-item"
|
||||
>
|
||||
<div
|
||||
class="user-item__content"
|
||||
>
|
||||
<span
|
||||
class="user-item__img"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-lock-outline LockOutlineIcon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ml-3"
|
||||
>
|
||||
<strong>
|
||||
Dunder Mifflin Party Planing Committee
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="menuwrapper"
|
||||
class="MenuWrapper"
|
||||
role="button"
|
||||
>
|
||||
<button
|
||||
class="user-item__button"
|
||||
>
|
||||
Editor
|
||||
<i
|
||||
class="CompassIcon icon-chevron-down CompassIcon"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="tabs-content"
|
||||
|
@ -19,16 +19,19 @@ import PrivateIcon from '../../widgets/icons/lockOutline'
|
||||
import PublicIcon from '../../widgets/icons/globe'
|
||||
import DeleteIcon from '../../widgets/icons/delete'
|
||||
import CompassIcon from '../../widgets/icons/compassIcon'
|
||||
import ConfirmationDialogBox from "../confirmationDialogBox"
|
||||
|
||||
const ChannelPermissionsRow = (): JSX.Element => {
|
||||
const intl = useIntl()
|
||||
const board = useAppSelector(getCurrentBoard)
|
||||
const [linkedChannel, setLinkedChannel] = useState<Channel|null>(null)
|
||||
const [showUnlinkChannelConfirmation, setShowUnlinkChannelConfirmation] = useState<boolean>(false)
|
||||
|
||||
const onUnlinkBoard = async () => {
|
||||
const newBoard = createBoard(board)
|
||||
newBoard.channelId = ''
|
||||
mutator.updateBoard(newBoard, board, 'unlinked channel')
|
||||
setShowUnlinkChannelConfirmation(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@ -43,8 +46,32 @@ const ChannelPermissionsRow = (): JSX.Element => {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const confirmationDialog = (
|
||||
<ConfirmationDialogBox
|
||||
dialogBox={{
|
||||
heading: intl.formatMessage({
|
||||
id: 'shareBoard.confirm-unlink.title',
|
||||
defaultMessage: 'Unlink channel from board',
|
||||
}),
|
||||
subText: intl.formatMessage({
|
||||
id: 'shareBoard.confirm-unlink.body',
|
||||
defaultMessage: 'When you unlink a channel from a board, all members of the channel (existing and new) will loose access to it unless they are given permission separately. {lineBreak} Are you sure you want to unlink it?',
|
||||
}, {
|
||||
lineBreak: <p/>
|
||||
}),
|
||||
confirmButtonText: intl.formatMessage({
|
||||
id: 'shareBoard.confirm-unlink.confirmBtnText',
|
||||
defaultMessage: 'Yes, unlink',
|
||||
}),
|
||||
onConfirm: onUnlinkBoard,
|
||||
onClose: () => setShowUnlinkChannelConfirmation(false),
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className='user-item'>
|
||||
<div className='user-item channel-item'>
|
||||
{showUnlinkChannelConfirmation && confirmationDialog}
|
||||
<div className='user-item__content'>
|
||||
<span className='user-item__img'>
|
||||
{linkedChannel.type === 'P' && <PrivateIcon/>}
|
||||
@ -69,7 +96,7 @@ const ChannelPermissionsRow = (): JSX.Element => {
|
||||
id='Unlink'
|
||||
icon={<DeleteIcon/>}
|
||||
name={intl.formatMessage({id: 'BoardMember.unlinkChannel', defaultMessage: 'Unlink'})}
|
||||
onClick={onUnlinkBoard}
|
||||
onClick={() => setShowUnlinkChannelConfirmation(true)}
|
||||
/>
|
||||
</Menu>
|
||||
</MenuWrapper>
|
||||
|
@ -77,21 +77,27 @@ board.cardProperties = [
|
||||
],
|
||||
},
|
||||
]
|
||||
board.channelId = 'channel_1'
|
||||
|
||||
const activeView = TestBlockFactory.createBoardView(board)
|
||||
activeView.id = 'view1'
|
||||
activeView.fields.hiddenOptionIds = []
|
||||
activeView.fields.visiblePropertyIds = ['property1']
|
||||
activeView.fields.visibleOptionIds = ['value1']
|
||||
|
||||
const fakeBoard = {id: board.id}
|
||||
activeView.boardId = fakeBoard.id
|
||||
|
||||
const card1 = TestBlockFactory.createCard(board)
|
||||
card1.id = 'card1'
|
||||
card1.title = 'card-1'
|
||||
card1.boardId = fakeBoard.id
|
||||
|
||||
const card2 = TestBlockFactory.createCard(board)
|
||||
card2.id = 'card2'
|
||||
card2.title = 'card-2'
|
||||
card2.boardId = fakeBoard.id
|
||||
|
||||
const card3 = TestBlockFactory.createCard(board)
|
||||
card3.id = 'card3'
|
||||
card3.title = 'card-3'
|
||||
@ -187,6 +193,8 @@ describe('src/components/shareBoard/shareBoard', () => {
|
||||
viewId,
|
||||
workspaceId,
|
||||
}
|
||||
|
||||
mockedOctoClient.getChannel.mockResolvedValue({type: 'P', display_name: 'Dunder Mifflin Party Planing Committee'} as Channel)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
@ -335,6 +343,7 @@ describe('src/components/shareBoard/shareBoard', () => {
|
||||
expect(mockedOctoClient.setSharing).toBeCalledTimes(1)
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('return shareBoard, and click switch', async () => {
|
||||
const sharing:ISharing = {
|
||||
id: boardId,
|
||||
@ -374,6 +383,7 @@ describe('src/components/shareBoard/shareBoard', () => {
|
||||
expect(mockedOctoClient.getSharing).toBeCalledTimes(2)
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('return shareBoardComponent and click Switch without sharing', async () => {
|
||||
const sharing:ISharing = {
|
||||
id: '',
|
||||
@ -425,6 +435,7 @@ describe('src/components/shareBoard/shareBoard', () => {
|
||||
expect(mockedUtils.createGuid).toBeCalledTimes(1)
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('should match snapshot with sharing and without workspaceId and subpath', async () => {
|
||||
w.baseURL = '/test-subpath/plugins/boards'
|
||||
const sharing:ISharing = {
|
||||
@ -575,4 +586,48 @@ describe('src/components/shareBoard/shareBoard', () => {
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('confirm unlinking linked channel', async () => {
|
||||
const sharing:ISharing = {
|
||||
id: '',
|
||||
enabled: false,
|
||||
token: '',
|
||||
}
|
||||
mockedOctoClient.getSharing.mockResolvedValue(sharing)
|
||||
mockedUtils.isFocalboardPlugin.mockReturnValue(true)
|
||||
|
||||
let container: Element | DocumentFragment | null = null
|
||||
await act(async () => {
|
||||
const result = render(
|
||||
wrapDNDIntl(
|
||||
<ReduxProvider store={store}>
|
||||
<ShareBoard
|
||||
onClose={jest.fn()}
|
||||
enableSharedBoards={true}
|
||||
/>
|
||||
</ReduxProvider>),
|
||||
{wrapper: MemoryRouter},
|
||||
)
|
||||
container = result.container
|
||||
})
|
||||
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
const channelMenuBtn = container!.querySelector('.user-item.channel-item .MenuWrapper')
|
||||
expect(channelMenuBtn).not.toBeNull()
|
||||
userEvent.click(channelMenuBtn as Element)
|
||||
|
||||
const unlinkOption = screen.getByText('Unlink')
|
||||
expect(unlinkOption).not.toBeNull()
|
||||
userEvent.click(unlinkOption)
|
||||
|
||||
const unlinkConfirmationBtn = screen.getByText('Yes, unlink')
|
||||
expect(unlinkConfirmationBtn).not.toBeNull()
|
||||
userEvent.click(unlinkConfirmationBtn)
|
||||
|
||||
expect(mockedOctoClient.patchBoard).toBeCalled()
|
||||
|
||||
const closeButton = screen.getByRole('button', {name: 'Close dialog'})
|
||||
expect(closeButton).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user