mirror of
https://github.com/mattermost/focalboard.git
synced 2025-01-23 18:34:02 +02:00
implement personal server/desktop cloud advertising
This commit is contained in:
parent
1ff28087f8
commit
1a3612bd8c
@ -0,0 +1,36 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/messages/CloudMessage not plugin mode, close message 1`] = `<div />`;
|
||||
|
||||
exports[`components/messages/CloudMessage not plugin mode, show message, close message 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="CloudMessage"
|
||||
>
|
||||
<div
|
||||
class="banner"
|
||||
>
|
||||
Get your own free cloud server.
|
||||
<a
|
||||
class="link"
|
||||
href="https://customers.mattermost.com/cloud/signup"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
[Learn more].
|
||||
</a>
|
||||
</div>
|
||||
<button
|
||||
aria-label="Close dialog"
|
||||
title="Close dialog"
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
class="CompassIcon icon-close CloseIcon"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`components/messages/CloudMessage plugin mode, no display 1`] = `<div />`;
|
33
webapp/src/components/messages/cloudMessage.scss
Normal file
33
webapp/src/components/messages/cloudMessage.scss
Normal file
@ -0,0 +1,33 @@
|
||||
.CloudMessage {
|
||||
background-color: rgba(230, 220, 192, 0.9);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> .banner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
color: #222;
|
||||
|
||||
a {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
> .banner.error {
|
||||
background-color: rgba(230, 192, 192, 0.9);
|
||||
}
|
||||
|
||||
.IconButton {
|
||||
float: right;
|
||||
}
|
||||
}
|
137
webapp/src/components/messages/cloudMessage.test.tsx
Normal file
137
webapp/src/components/messages/cloudMessage.test.tsx
Normal file
@ -0,0 +1,137 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
|
||||
|
||||
import {render, screen} from '@testing-library/react'
|
||||
import {mocked} from 'jest-mock'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
|
||||
import configureStore from 'redux-mock-store'
|
||||
|
||||
import {Utils} from '../../utils'
|
||||
|
||||
import {IUser} from '../../user'
|
||||
|
||||
import {wrapIntl} from '../../testUtils'
|
||||
|
||||
import client from '../../octoClient'
|
||||
|
||||
import CloudMessage from './cloudMessage'
|
||||
|
||||
jest.mock('../../utils')
|
||||
jest.mock('../../octoClient')
|
||||
const mockedOctoClient = mocked(client, true)
|
||||
|
||||
describe('components/messages/CloudMessage', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
console.log("Cloud message test")
|
||||
const mockedUtils = mocked(Utils, true)
|
||||
const mockStore = configureStore([])
|
||||
|
||||
test('plugin mode, no display', () => {
|
||||
console.log("Cloud message test - no display")
|
||||
mockedUtils.isFocalboardPlugin.mockReturnValue(true)
|
||||
|
||||
const me: IUser = {
|
||||
id: 'user-id-1',
|
||||
username: 'username_1',
|
||||
email: '',
|
||||
props: {},
|
||||
create_at: 0,
|
||||
update_at: 0,
|
||||
is_bot: false
|
||||
}
|
||||
const state = {
|
||||
users: {
|
||||
me,
|
||||
},
|
||||
}
|
||||
|
||||
const store = mockStore(state)
|
||||
|
||||
const component = wrapIntl(
|
||||
<ReduxProvider store={store}>
|
||||
<CloudMessage/>
|
||||
</ReduxProvider>,
|
||||
)
|
||||
|
||||
const {container} = render(component)
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('not plugin mode, close message', () => {
|
||||
console.log("Cloud message test - property set")
|
||||
|
||||
const me: IUser = {
|
||||
id: 'user-id-1',
|
||||
username: 'username_1',
|
||||
email: '',
|
||||
props: {
|
||||
focalboard_cloudMessageCanceled: 'true'
|
||||
},
|
||||
create_at: 0,
|
||||
update_at: 0,
|
||||
is_bot: false
|
||||
}
|
||||
const state = {
|
||||
users: {
|
||||
me,
|
||||
},
|
||||
}
|
||||
const store = mockStore(state)
|
||||
mockedUtils.isFocalboardPlugin.mockReturnValue(false)
|
||||
|
||||
const component = wrapIntl(
|
||||
<ReduxProvider store={store}>
|
||||
<CloudMessage/>
|
||||
</ReduxProvider>,
|
||||
)
|
||||
|
||||
const {container} = render(component)
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('not plugin mode, show message, close message', () => {
|
||||
console.log("Cloud message test - propertynot set")
|
||||
|
||||
const me: IUser = {
|
||||
id: 'user-id-1',
|
||||
username: 'username_1',
|
||||
email: '',
|
||||
props: {},
|
||||
create_at: 0,
|
||||
update_at: 0,
|
||||
is_bot: false
|
||||
}
|
||||
const state = {
|
||||
users: {
|
||||
me,
|
||||
},
|
||||
}
|
||||
const store = mockStore(state)
|
||||
mockedUtils.isFocalboardPlugin.mockReturnValue(false)
|
||||
|
||||
const component = wrapIntl(
|
||||
<ReduxProvider store={store}>
|
||||
<CloudMessage/>
|
||||
</ReduxProvider>,
|
||||
)
|
||||
|
||||
const {container} = render(component)
|
||||
expect(container).toMatchSnapshot()
|
||||
|
||||
const buttonElement = screen.getByRole('button', {name: 'Close dialog'})
|
||||
userEvent.click(buttonElement)
|
||||
expect(mockedOctoClient.patchUserConfig).toBeCalledWith('user-id-1', {
|
||||
updatedFields: {
|
||||
'focalboard_cloudMessageCanceled': 'true',
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
78
webapp/src/components/messages/cloudMessage.tsx
Normal file
78
webapp/src/components/messages/cloudMessage.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React from 'react'
|
||||
|
||||
import {useIntl, FormattedMessage} from 'react-intl'
|
||||
|
||||
import {getCloudMessageCanceled} from '../../store/users'
|
||||
import {Utils} from '../../utils'
|
||||
import IconButton from '../../widgets/buttons/iconButton'
|
||||
import CloseIcon from '../../widgets/icons/close'
|
||||
import {useAppSelector, useAppDispatch} from '../../store/hooks'
|
||||
import octoClient from '../../octoClient'
|
||||
import {IUser, UserConfigPatch} from '../../user'
|
||||
import {getMe, patchProps} from '../../store/users'
|
||||
|
||||
import './cloudMessage.scss'
|
||||
|
||||
const CloudMessage = React.memo(() => {
|
||||
const intl = useIntl()
|
||||
const dispatch = useAppDispatch()
|
||||
const me = useAppSelector<IUser|null>(getMe)
|
||||
const cloudMessageCanceled = useAppSelector(getCloudMessageCanceled)
|
||||
|
||||
const closeDialogText = intl.formatMessage({
|
||||
id: 'Dialog.closeDialog',
|
||||
defaultMessage: 'Close dialog',
|
||||
})
|
||||
|
||||
const onClose = async() => {
|
||||
if (me) {
|
||||
const patch: UserConfigPatch = {
|
||||
updatedFields: {
|
||||
focalboard_cloudMessageCanceled: 'true',
|
||||
},
|
||||
}
|
||||
|
||||
const patchedProps = await octoClient.patchUserConfig(me.id, patch)
|
||||
if (patchedProps) {
|
||||
dispatch(patchProps(patchedProps))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( Utils.isFocalboardPlugin() || cloudMessageCanceled){
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='CloudMessage'>
|
||||
<div className='banner'>
|
||||
<FormattedMessage
|
||||
id='CloudMessage.cloud-server'
|
||||
defaultMessage="Get your own free cloud server."
|
||||
/>
|
||||
<a
|
||||
className='link'
|
||||
href={'https://customers.mattermost.com/cloud/signup'}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='cloudMessage.learn-more'
|
||||
defaultMessage='[Learn more].'
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<IconButton
|
||||
className='margin-right'
|
||||
onClick={onClose}
|
||||
icon={<CloseIcon/>}
|
||||
title={closeDialogText}
|
||||
size='small'
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
export default CloudMessage
|
@ -5,6 +5,7 @@ import {FormattedMessage, useIntl} from 'react-intl'
|
||||
import {useRouteMatch} from 'react-router-dom'
|
||||
|
||||
import Workspace from '../../components/workspace'
|
||||
import CloudMessage from '../../components/messages/cloudMessage'
|
||||
import octoClient from '../../octoClient'
|
||||
import {Utils} from '../../utils'
|
||||
import wsClient from '../../wsclient'
|
||||
@ -143,6 +144,7 @@ const BoardPage = (props: Props): JSX.Element => {
|
||||
readonly={props.readonly || false}
|
||||
loadAction={loadAction}
|
||||
/>
|
||||
<CloudMessage/>
|
||||
|
||||
{!mobileWarningClosed &&
|
||||
<div className='mobileWarning'>
|
||||
|
@ -141,3 +141,16 @@ export const getOnboardingTourCategory = createSelector(
|
||||
getMe,
|
||||
(me): string => (me ? me.props?.focalboard_tourCategory : ''),
|
||||
)
|
||||
|
||||
export const getCloudMessageCanceled = createSelector(
|
||||
getMe,
|
||||
(me): boolean => {
|
||||
if (!me) {
|
||||
console.log("NO ME")
|
||||
return false
|
||||
}
|
||||
|
||||
console.log(me)
|
||||
return Boolean(me.props?.focalboard_cloudMessageCanceled)
|
||||
},
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user