1
0
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:
Scott Bishel 2022-05-09 09:49:10 -06:00
parent 1ff28087f8
commit 1a3612bd8c
6 changed files with 299 additions and 0 deletions

View File

@ -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 />`;

View 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;
}
}

View 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',
},
})
})
})

View 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

View File

@ -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'>

View File

@ -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)
},
)