Skip to content

Commit

Permalink
Show a refresh banner on plugin update (#1720)
Browse files Browse the repository at this point in the history
* Reload plugin on plugin update

* Add a banner that shows when updating the plugin and asks the user to reload

* Fix linter
  • Loading branch information
mgdelacroix committed Nov 10, 2021
1 parent cf67da1 commit 67c7cb8
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 1 deletion.
17 changes: 17 additions & 0 deletions mattermost-plugin/webapp/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,23 @@ export default class Plugin {
// register websocket handlers
this.registry?.registerWebSocketEventHandler(`custom_${manifest.id}_${ACTION_UPDATE_BLOCK}`, (e: any) => wsClient.updateBlockHandler(e.data))
this.registry?.registerWebSocketEventHandler(`custom_${manifest.id}_${ACTION_UPDATE_CLIENT_CONFIG}`, (e: any) => wsClient.updateClientConfigHandler(e.data))
this.registry?.registerWebSocketEventHandler(`plugin_statuses_changed`, (e: any) => wsClient.pluginStatusesChangedHandler(e.data))
this.registry?.registerWebSocketEventHandler('preferences_changed', (e: any) => {
let preferences
try {
preferences = JSON.parse(e.data.preferences)
} catch {
preferences = []
}
if (preferences) {
for (const preference of preferences) {
if (preference.category === 'theme' && theme !== preference.value) {
setMattermostTheme(JSON.parse(preference.value))
theme = preference.value
}
}
}
})
}

uninitialize(): void {
Expand Down
37 changes: 36 additions & 1 deletion webapp/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,41 @@
"BoardComponent.no-property-title": "Items with an empty {property} property will go here. This column cannot be removed.",
"BoardComponent.show": "Show",
"BoardPage.syncFailed": "Board may be deleted or access revoked.",
"BoardPage.newVersion": "A new version of Boards is available, click here to reload.",
"Calculations.Options.average.displayName": "Average",
"Calculations.Options.average.label": "Average",
"Calculations.Options.count.displayName": "Count",
"Calculations.Options.count.label": "Count",
"Calculations.Options.countChecked.displayName": "Checked",
"Calculations.Options.countChecked.label": "Count Checked",
"Calculations.Options.countUnchecked.displayName": "Unchecked",
"Calculations.Options.countUnchecked.label": "Count Unchecked",
"Calculations.Options.countUniqueValue.displayName": "Unique",
"Calculations.Options.countUniqueValue.label": "Count Unique Values",
"Calculations.Options.countValue.displayName": "Values",
"Calculations.Options.countValue.label": "Count Value",
"Calculations.Options.dateRange.displayName": "Range",
"Calculations.Options.dateRange.label": "Range",
"Calculations.Options.earliest.displayName": "Earliest",
"Calculations.Options.earliest.label": "Earliest",
"Calculations.Options.latest.displayName": "Latest",
"Calculations.Options.latest.label": "Latest",
"Calculations.Options.max.displayName": "Max",
"Calculations.Options.max.label": "Max",
"Calculations.Options.median.displayName": "Median",
"Calculations.Options.median.label": "Median",
"Calculations.Options.min.displayName": "Min",
"Calculations.Options.min.label": "Min",
"Calculations.Options.none.displayName": "Calculate",
"Calculations.Options.none.label": "None",
"Calculations.Options.percentChecked.displayName": "Checked",
"Calculations.Options.percentChecked.label": "Percent Checked",
"Calculations.Options.percentUnchecked.displayName": "Unchecked",
"Calculations.Options.percentUnchecked.label": "Percent Unchecked",
"Calculations.Options.range.displayName": "Range",
"Calculations.Options.range.label": "Range",
"Calculations.Options.sum.displayName": "Sum",
"Calculations.Options.sum.label": "Sum",
"BoardsUnfurl.Remainder": "+{remainder} more",
"BoardsUnfurl.Updated": "Updated {time}",
"CardDetail.add-content": "Add content",
Expand Down Expand Up @@ -197,4 +232,4 @@
"login.register-button": "or create an account if you don't have one",
"register.login-button": "or log in if you already have an account",
"register.signup-title": "Sign up for your account"
}
}
2 changes: 2 additions & 0 deletions webapp/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import TelemetryClient from './telemetry/telemetryClient'
import {IAppWindow} from './types'
import {getMessages} from './i18n'
import {FlashMessages} from './components/flashMessages'
import NewVersionBanner from './components/newVersionBanner'
import BoardPage from './pages/boardPage'
import ChangePasswordPage from './pages/changePasswordPage'
import DashboardPage from './pages/dashboard/dashboardPage'
Expand Down Expand Up @@ -141,6 +142,7 @@ const App = React.memo((): JSX.Element => {
>
<div id='frame'>
<div id='main'>
<NewVersionBanner/>
<Switch>
{globalErrorRedirect}
<Route path='/error'>
Expand Down
5 changes: 5 additions & 0 deletions webapp/src/components/newVersionBanner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.NewVersionBanner {
background-color: var(--prop-blue);
text-align: center;
padding: 10px;
}
41 changes: 41 additions & 0 deletions webapp/src/components/newVersionBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useState, useEffect} from 'react'
import {FormattedMessage} from 'react-intl'

import wsClient from '../wsclient'

import './newVersionBanner.scss'

const NewVersionBanner = () => {
const [appVersionChanged, setAppVersionChanged] = useState(false)
useEffect(() => {
wsClient.onAppVersionChangeHandler = setAppVersionChanged
}, [])

if (!appVersionChanged) {
return null
}

const newVersionReload = (e: any) => {
e.preventDefault()
location.reload()
}

return (
<div className='NewVersionBanner'>
<a
target='_blank'
rel='noreferrer'
onClick={newVersionReload}
>
<FormattedMessage
id='BoardPage.newVersion'
defaultMessage='A new version of Boards is available, click here to reload.'
/>
</a>
</div>
)
}

export default NewVersionBanner
18 changes: 18 additions & 0 deletions webapp/src/wsclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type OnConfigChangeHandler = (client: WSClient, clientConfig: ClientConfig) => v
class WSClient {
ws: WebSocket|null = null
client: MMWebSocketClient|null = null
pluginId = ''
onAppVersionChangeHandler: ((versionHasChanged: boolean) => void) | null = null
clientPrefix = ''
serverUrl: string | undefined
state: 'init'|'open'|'close' = 'init'
Expand Down Expand Up @@ -88,6 +90,7 @@ class WSClient {
}

initPlugin(pluginId: string, client: MMWebSocketClient): void {
this.pluginId = pluginId
this.clientPrefix = `custom_${pluginId}_`
this.client = client
Utils.log(`WSClient initialised for plugin id "${pluginId}"`)
Expand Down Expand Up @@ -299,6 +302,21 @@ class WSClient {
}
}

setOnAppVersionChangeHandler(fn: (versionHasChanged: boolean) => void): void {
this.onAppVersionChangeHandler = fn
}

pluginStatusesChangedHandler(data: any): void {
if (this.pluginId === '' || !this.onAppVersionChangeHandler) {
return
}

if (data.plugin_statuses.some((s: any) => s.plugin_id === this.pluginId)) {
Utils.log('Boards plugin has been updated')
this.onAppVersionChangeHandler(true)
}
}

authenticate(workspaceId: string, token: string): void {
if (!this.hasConn()) {
Utils.assertFailure('WSClient.addBlocks: ws is not open')
Expand Down

0 comments on commit 67c7cb8

Please sign in to comment.