Merge branch 'main' into gh-1059-fix-empty-placeholder-in-card-dialog
This commit is contained in:
commit
e5c6619555
25 changed files with 352 additions and 24 deletions
10
.github/workflows/build-mac.yml
vendored
10
.github/workflows/build-mac.yml
vendored
|
@ -12,12 +12,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: cd webapp; npm install --no-optional
|
run: cd webapp; npm install --no-optional
|
||||||
|
|
||||||
|
|
10
.github/workflows/build-ubuntu.yml
vendored
10
.github/workflows/build-ubuntu.yml
vendored
|
@ -11,12 +11,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: cd webapp; npm install --no-optional
|
run: cd webapp; npm install --no-optional
|
||||||
|
|
||||||
|
|
10
.github/workflows/build-win-wpf.yml
vendored
10
.github/workflows/build-win-wpf.yml
vendored
|
@ -11,12 +11,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v1.0.2
|
||||||
|
|
||||||
|
|
40
.github/workflows/dev-release.yml
vendored
40
.github/workflows/dev-release.yml
vendored
|
@ -16,12 +16,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: cd webapp; npm install --no-optional
|
run: cd webapp; npm install --no-optional
|
||||||
|
|
||||||
|
@ -69,12 +75,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: cd webapp; npm install --no-optional
|
run: cd webapp; npm install --no-optional
|
||||||
|
|
||||||
|
@ -105,12 +117,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v1.0.2
|
||||||
|
|
||||||
|
@ -154,12 +172,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_DEV_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: cd webapp; npm install --no-optional
|
run: cd webapp; npm install --no-optional
|
||||||
|
|
||||||
|
|
10
.github/workflows/plugin-release.yml
vendored
10
.github/workflows/plugin-release.yml
vendored
|
@ -11,12 +11,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_PROD_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_PROD_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_PROD_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: cd webapp; npm install --no-optional
|
run: cd webapp; npm install --no-optional
|
||||||
|
|
||||||
|
|
10
.github/workflows/prod-release.yml
vendored
10
.github/workflows/prod-release.yml
vendored
|
@ -11,12 +11,18 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Replace token 1
|
- name: Replace token 1 server
|
||||||
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
- name: Replace token 2
|
- name: Replace token 1 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_dataplane_url,${{ secrets.RUDDER_DATAPLANE_URL }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
|
- name: Replace token 2 server
|
||||||
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_PROD_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_PROD_KEY }},g" ${{ github.workspace }}/server/services/telemetry/telemetry.go
|
||||||
|
|
||||||
|
- name: Replace token 2 webapp
|
||||||
|
run: sed -i -e "s,placeholder_rudder_key,${{ secrets.RUDDER_PROD_KEY }},g" ${{ github.workspace }}/mattermost-plugin/webapp/src/index.tsx
|
||||||
|
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: cd webapp; npm install --no-optional
|
run: cd webapp; npm install --no-optional
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,13 @@ func (p *Plugin) OnActivate() error {
|
||||||
baseURL = *mmconfig.ServiceSettings.SiteURL
|
baseURL = *mmconfig.ServiceSettings.SiteURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverID := client.System.GetDiagnosticID()
|
||||||
|
|
||||||
|
enableTelemetry := false
|
||||||
|
if mmconfig.LogSettings.EnableDiagnostics != nil {
|
||||||
|
enableTelemetry = *mmconfig.LogSettings.EnableDiagnostics
|
||||||
|
}
|
||||||
|
|
||||||
cfg := &config.Configuration{
|
cfg := &config.Configuration{
|
||||||
ServerRoot: baseURL + "/plugins/focalboard",
|
ServerRoot: baseURL + "/plugins/focalboard",
|
||||||
Port: -1,
|
Port: -1,
|
||||||
|
@ -100,7 +107,8 @@ func (p *Plugin) OnActivate() error {
|
||||||
FilesDriver: *mmconfig.FileSettings.DriverName,
|
FilesDriver: *mmconfig.FileSettings.DriverName,
|
||||||
FilesPath: *mmconfig.FileSettings.Directory,
|
FilesPath: *mmconfig.FileSettings.Directory,
|
||||||
FilesS3Config: filesS3Config,
|
FilesS3Config: filesS3Config,
|
||||||
Telemetry: true,
|
Telemetry: enableTelemetry,
|
||||||
|
TelemetryID: serverID,
|
||||||
WebhookUpdate: []string{},
|
WebhookUpdate: []string{},
|
||||||
SessionExpireTime: 2592000,
|
SessionExpireTime: 2592000,
|
||||||
SessionRefreshTime: 18000,
|
SessionRefreshTime: 18000,
|
||||||
|
@ -122,7 +130,6 @@ func (p *Plugin) OnActivate() error {
|
||||||
db = layeredStore
|
db = layeredStore
|
||||||
}
|
}
|
||||||
|
|
||||||
serverID := client.System.GetDiagnosticID()
|
|
||||||
p.wsPluginAdapter = ws.NewPluginAdapter(p.API, auth.New(cfg, db))
|
p.wsPluginAdapter = ws.NewPluginAdapter(p.API, auth.New(cfg, db))
|
||||||
|
|
||||||
server, err := server.New(cfg, "", db, logger, serverID, p.wsPluginAdapter)
|
server, err := server.New(cfg, "", db, logger, serverID, p.wsPluginAdapter)
|
||||||
|
|
|
@ -5,6 +5,8 @@ import {Store, Action} from 'redux'
|
||||||
import {Provider as ReduxProvider} from 'react-redux'
|
import {Provider as ReduxProvider} from 'react-redux'
|
||||||
import {useHistory} from 'mm-react-router-dom'
|
import {useHistory} from 'mm-react-router-dom'
|
||||||
|
|
||||||
|
import {rudderAnalytics, RudderTelemetryHandler} from 'mattermost-redux/client/rudder'
|
||||||
|
|
||||||
import {GlobalState} from 'mattermost-redux/types/store'
|
import {GlobalState} from 'mattermost-redux/types/store'
|
||||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences'
|
import {getTheme} from 'mattermost-redux/selectors/entities/preferences'
|
||||||
|
|
||||||
|
@ -20,9 +22,12 @@ import FocalboardIcon from '../../../webapp/src/widgets/icons/logo'
|
||||||
import {setMattermostTheme} from '../../../webapp/src/theme'
|
import {setMattermostTheme} from '../../../webapp/src/theme'
|
||||||
import wsClient, {MMWebSocketClient, ACTION_UPDATE_BLOCK} from './../../../webapp/src/wsclient'
|
import wsClient, {MMWebSocketClient, ACTION_UPDATE_BLOCK} from './../../../webapp/src/wsclient'
|
||||||
|
|
||||||
|
import TelemetryClient from '../../../webapp/src/telemetry/telemetryClient'
|
||||||
|
|
||||||
import '../../../webapp/src/styles/focalboard-variables.scss'
|
import '../../../webapp/src/styles/focalboard-variables.scss'
|
||||||
import '../../../webapp/src/styles/main.scss'
|
import '../../../webapp/src/styles/main.scss'
|
||||||
import '../../../webapp/src/styles/labels.scss'
|
import '../../../webapp/src/styles/labels.scss'
|
||||||
|
import octoClient from '../../../webapp/src/octoClient'
|
||||||
|
|
||||||
import manifest from './manifest'
|
import manifest from './manifest'
|
||||||
import ErrorBoundary from './error_boundary'
|
import ErrorBoundary from './error_boundary'
|
||||||
|
@ -32,6 +37,22 @@ import {PluginRegistry} from './types/mattermost-webapp'
|
||||||
|
|
||||||
import './plugin.scss'
|
import './plugin.scss'
|
||||||
|
|
||||||
|
const TELEMETRY_RUDDER_KEY = 'placeholder_rudder_key'
|
||||||
|
const TELEMETRY_RUDDER_DATAPLANE_URL = 'placeholder_rudder_dataplane_url'
|
||||||
|
const TELEMETRY_OPTIONS = {
|
||||||
|
context: {
|
||||||
|
ip: '0.0.0.0',
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
path: '',
|
||||||
|
referrer: '',
|
||||||
|
search: '',
|
||||||
|
title: '',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
|
anonymousId: '00000000000000000000000000',
|
||||||
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
webSocketClient: MMWebSocketClient
|
webSocketClient: MMWebSocketClient
|
||||||
}
|
}
|
||||||
|
@ -150,6 +171,32 @@ export default class Plugin {
|
||||||
this.registry.registerCustomRoute('/', MainApp)
|
this.registry.registerCustomRoute('/', MainApp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const config = await octoClient.getClientConfig()
|
||||||
|
if (config?.telemetry) {
|
||||||
|
let rudderKey = TELEMETRY_RUDDER_KEY
|
||||||
|
let rudderUrl = TELEMETRY_RUDDER_DATAPLANE_URL
|
||||||
|
|
||||||
|
if (rudderKey.startsWith('placeholder') && rudderUrl.startsWith('placeholder')) {
|
||||||
|
rudderKey = process.env.RUDDER_KEY as string //eslint-disable-line no-process-env
|
||||||
|
rudderUrl = process.env.RUDDER_DATAPLANE_URL as string //eslint-disable-line no-process-env
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rudderKey !== '') {
|
||||||
|
rudderAnalytics.load(rudderKey, rudderUrl)
|
||||||
|
|
||||||
|
rudderAnalytics.identify(config?.telemetryid, {}, TELEMETRY_OPTIONS)
|
||||||
|
|
||||||
|
rudderAnalytics.page('BoardsLoaded', '',
|
||||||
|
TELEMETRY_OPTIONS.page,
|
||||||
|
{
|
||||||
|
context: TELEMETRY_OPTIONS.context,
|
||||||
|
anonymousId: TELEMETRY_OPTIONS.anonymousId,
|
||||||
|
})
|
||||||
|
|
||||||
|
TelemetryClient.setTelemetryHandler(new RudderTelemetryHandler())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// register websocket handlers
|
// 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_BLOCK}`, (e: any) => wsClient.updateBlockHandler(e.data))
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
color: rgba(var(--center-channel-text-rgb), 1);
|
color: rgba(var(--center-channel-text-rgb), 1);
|
||||||
|
|
||||||
i {
|
i {
|
||||||
color: inherit;
|
color: var(--link-color-rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
|
@ -143,3 +143,11 @@ module.exports = {
|
||||||
mode,
|
mode,
|
||||||
plugins,
|
plugins,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const env = {};
|
||||||
|
env.RUDDER_KEY = JSON.stringify(process.env.RUDDER_KEY || ''); //eslint-disable-line no-process-env
|
||||||
|
env.RUDDER_DATAPLANE_URL = JSON.stringify(process.env.RUDDER_DATAPLANE_URL || ''); //eslint-disable-line no-process-env
|
||||||
|
|
||||||
|
module.exports.plugins.push(new webpack.DefinePlugin({
|
||||||
|
'process.env': env,
|
||||||
|
}));
|
||||||
|
|
|
@ -90,6 +90,7 @@ func (a *API) RegisterRoutes(r *mux.Router) {
|
||||||
|
|
||||||
apiv1.HandleFunc("/login", a.handleLogin).Methods("POST")
|
apiv1.HandleFunc("/login", a.handleLogin).Methods("POST")
|
||||||
apiv1.HandleFunc("/register", a.handleRegister).Methods("POST")
|
apiv1.HandleFunc("/register", a.handleRegister).Methods("POST")
|
||||||
|
apiv1.HandleFunc("/clientConfig", a.getClientConfig).Methods("GET")
|
||||||
|
|
||||||
apiv1.HandleFunc("/workspaces/{workspaceID}/{rootID}/files", a.sessionRequired(a.handleUploadFile)).Methods("POST")
|
apiv1.HandleFunc("/workspaces/{workspaceID}/{rootID}/files", a.sessionRequired(a.handleUploadFile)).Methods("POST")
|
||||||
|
|
||||||
|
@ -115,6 +116,17 @@ func (a *API) requireCSRFToken(next http.Handler) http.Handler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *API) getClientConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
|
clientConfig := a.app.GetClientConfig()
|
||||||
|
|
||||||
|
configData, err := json.Marshal(clientConfig)
|
||||||
|
if err != nil {
|
||||||
|
a.errorResponse(w, r.URL.Path, http.StatusInternalServerError, "", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jsonBytesResponse(w, http.StatusOK, configData)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *API) checkCSRFToken(r *http.Request) bool {
|
func (a *API) checkCSRFToken(r *http.Request) bool {
|
||||||
token := r.Header.Get(HeaderRequestedWith)
|
token := r.Header.Get(HeaderRequestedWith)
|
||||||
return token == HeaderRequestedWithXML
|
return token == HeaderRequestedWithXML
|
||||||
|
|
12
server/app/clientConfig.go
Normal file
12
server/app/clientConfig.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/focalboard/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *App) GetClientConfig() *model.ClientConfig {
|
||||||
|
return &model.ClientConfig{
|
||||||
|
Telemetry: a.config.Telemetry,
|
||||||
|
TelemetryID: a.config.TelemetryID,
|
||||||
|
}
|
||||||
|
}
|
6
server/model/clientConfig.go
Normal file
6
server/model/clientConfig.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
type ClientConfig struct {
|
||||||
|
Telemetry bool `json:"telemetry"`
|
||||||
|
TelemetryID string `json:"telemetryid"`
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ type Configuration struct {
|
||||||
FilesS3Config AmazonS3Config `json:"filess3config" mapstructure:"filess3config"`
|
FilesS3Config AmazonS3Config `json:"filess3config" mapstructure:"filess3config"`
|
||||||
FilesPath string `json:"filespath" mapstructure:"filespath"`
|
FilesPath string `json:"filespath" mapstructure:"filespath"`
|
||||||
Telemetry bool `json:"telemetry" mapstructure:"telemetry"`
|
Telemetry bool `json:"telemetry" mapstructure:"telemetry"`
|
||||||
|
TelemetryID string `json:"telemetryid" mapstructure:"telemetryid"`
|
||||||
PrometheusAddress string `json:"prometheus_address" mapstructure:"prometheus_address"`
|
PrometheusAddress string `json:"prometheus_address" mapstructure:"prometheus_address"`
|
||||||
WebhookUpdate []string `json:"webhook_update" mapstructure:"webhook_update"`
|
WebhookUpdate []string `json:"webhook_update" mapstructure:"webhook_update"`
|
||||||
Secret string `json:"secret" mapstructure:"secret"`
|
Secret string `json:"secret" mapstructure:"secret"`
|
||||||
|
@ -73,6 +74,7 @@ func ReadConfigFile() (*Configuration, error) {
|
||||||
viper.SetDefault("FilesPath", "./files")
|
viper.SetDefault("FilesPath", "./files")
|
||||||
viper.SetDefault("FilesDriver", "local")
|
viper.SetDefault("FilesDriver", "local")
|
||||||
viper.SetDefault("Telemetry", true)
|
viper.SetDefault("Telemetry", true)
|
||||||
|
viper.SetDefault("TelemetryID", "")
|
||||||
viper.SetDefault("WebhookUpdate", nil)
|
viper.SetDefault("WebhookUpdate", nil)
|
||||||
viper.SetDefault("SessionExpireTime", 60*60*24*30) // 30 days session lifetime
|
viper.SetDefault("SessionExpireTime", 60*60*24*30) // 30 days session lifetime
|
||||||
viper.SetDefault("SessionRefreshTime", 60*60*5) // 5 minutes session refresh
|
viper.SetDefault("SessionRefreshTime", 60*60*5) // 5 minutes session refresh
|
||||||
|
|
62
webapp/i18n/ar.json
Normal file
62
webapp/i18n/ar.json
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{
|
||||||
|
"BoardComponent.add-a-group": "+ إضافة فريق",
|
||||||
|
"BoardComponent.delete": "حذف",
|
||||||
|
"BoardComponent.hidden-columns": "الأعمدية المخفية",
|
||||||
|
"BoardComponent.hide": "إخفاء",
|
||||||
|
"BoardComponent.new": "+ جديد",
|
||||||
|
"BoardComponent.show": "عرض",
|
||||||
|
"CardDetail.add-content": "إضافة محتوى",
|
||||||
|
"CardDetail.add-icon": "إضافة أيقونة",
|
||||||
|
"CardDetail.new-comment-placeholder": "إضافة تعليق…",
|
||||||
|
"Comment.delete": "حذف",
|
||||||
|
"CommentsList.send": "إرسال",
|
||||||
|
"ContentBlock.Delete": "حذف",
|
||||||
|
"ContentBlock.DeleteAction": "حذف",
|
||||||
|
"ContentBlock.addElement": "إضافة {type}",
|
||||||
|
"ContentBlock.text": "نص",
|
||||||
|
"DashboardPage.title": "أهلًا بك إلى Focalboard (تجريبي)!",
|
||||||
|
"EditableDayPicker.today": "اليوم",
|
||||||
|
"Filter.is-empty": "فارغ",
|
||||||
|
"Filter.is-not-empty": "ليس فارغًا",
|
||||||
|
"FilterComponent.add-filter": "+ إضافة عامل تصفية",
|
||||||
|
"FilterComponent.delete": "حذف",
|
||||||
|
"GalleryCard.delete": "حذف",
|
||||||
|
"KanbanCard.delete": "حذف",
|
||||||
|
"PropertyMenu.Delete": "حذف",
|
||||||
|
"PropertyMenu.typeTitle": "النوع",
|
||||||
|
"PropertyType.CreatedBy": "قام بإنشائها",
|
||||||
|
"PropertyType.Date": "التاريخ",
|
||||||
|
"PropertyType.Email": "البريد الإلكتروني",
|
||||||
|
"PropertyType.File": "ملف أو وسائط",
|
||||||
|
"PropertyType.Number": "رقم",
|
||||||
|
"PropertyType.Person": "شخص",
|
||||||
|
"PropertyType.Text": "نص",
|
||||||
|
"PropertyType.URL": "رابط URL",
|
||||||
|
"RegistrationLink.copiedLink": "تم نسخها",
|
||||||
|
"RegistrationLink.copyLink": "انسخ الرابط",
|
||||||
|
"ShareBoard.copiedLink": "تم نسخها!",
|
||||||
|
"ShareBoard.copyLink": "انسخ الرابط",
|
||||||
|
"Sidebar.about": "عن Focalboard",
|
||||||
|
"Sidebar.add-template": "نموذج جديد",
|
||||||
|
"Sidebar.changePassword": "تغيير الكلمة السرية",
|
||||||
|
"Sidebar.delete-template": "حذف",
|
||||||
|
"Sidebar.edit-template": "تعديل",
|
||||||
|
"Sidebar.logout": "الخروج",
|
||||||
|
"Sidebar.set-language": "ضبط اللغة",
|
||||||
|
"Sidebar.settings": "الإعدادت",
|
||||||
|
"TableComponent.add-icon": "إضافة أيقونة",
|
||||||
|
"TableComponent.name": "الإسم",
|
||||||
|
"TableComponent.plus-new": "+ جديد",
|
||||||
|
"TableHeaderMenu.delete": "حذف",
|
||||||
|
"TableHeaderMenu.hide": "إخفاء",
|
||||||
|
"TableRow.open": "افتح",
|
||||||
|
"View.Table": "جدول",
|
||||||
|
"ViewHeader.add-template": "نموذج جديد",
|
||||||
|
"ViewHeader.delete-template": "حذف",
|
||||||
|
"ViewHeader.new": "جديز",
|
||||||
|
"ViewHeader.search": "البحث",
|
||||||
|
"ViewTitle.pick-icon": "اختر أيقونة",
|
||||||
|
"default-properties.title": "العنوان",
|
||||||
|
"login.log-in-button": "لِج",
|
||||||
|
"login.log-in-title": "لِج"
|
||||||
|
}
|
|
@ -15,6 +15,7 @@
|
||||||
"CardDetail.new-comment-placeholder": "Lägg till kommentar...",
|
"CardDetail.new-comment-placeholder": "Lägg till kommentar...",
|
||||||
"CardDialog.editing-template": "Du redigerar en mall",
|
"CardDialog.editing-template": "Du redigerar en mall",
|
||||||
"CardDialog.nocard": "Detta kort existerar inte eller är oåtkomligt",
|
"CardDialog.nocard": "Detta kort existerar inte eller är oåtkomligt",
|
||||||
|
"ColorOption.selectColor": "Välj {color} färg",
|
||||||
"Comment.delete": "Radera",
|
"Comment.delete": "Radera",
|
||||||
"CommentsList.send": "Skicka",
|
"CommentsList.send": "Skicka",
|
||||||
"ContentBlock.Delete": "Radera",
|
"ContentBlock.Delete": "Radera",
|
||||||
|
@ -120,6 +121,8 @@
|
||||||
"TableHeaderMenu.sort-ascending": "Sortera stigande",
|
"TableHeaderMenu.sort-ascending": "Sortera stigande",
|
||||||
"TableHeaderMenu.sort-descending": "Sortera fallande",
|
"TableHeaderMenu.sort-descending": "Sortera fallande",
|
||||||
"TableRow.open": "Öppna",
|
"TableRow.open": "Öppna",
|
||||||
|
"ValueSelector.valueSelector": "Värdeväljare",
|
||||||
|
"ValueSelectorLabel.openMenu": "Öppna meny",
|
||||||
"View.AddView": "Lägg till vy",
|
"View.AddView": "Lägg till vy",
|
||||||
"View.Board": "Tavla",
|
"View.Board": "Tavla",
|
||||||
"View.DeleteView": "Radera vy",
|
"View.DeleteView": "Radera vy",
|
||||||
|
|
|
@ -12,6 +12,8 @@ import {DndProvider} from 'react-dnd'
|
||||||
import {HTML5Backend} from 'react-dnd-html5-backend'
|
import {HTML5Backend} from 'react-dnd-html5-backend'
|
||||||
import {TouchBackend} from 'react-dnd-touch-backend'
|
import {TouchBackend} from 'react-dnd-touch-backend'
|
||||||
|
|
||||||
|
import TelemetryClient from './telemetry/telemetryClient'
|
||||||
|
|
||||||
import {getMessages} from './i18n'
|
import {getMessages} from './i18n'
|
||||||
import {FlashMessages} from './components/flashMessages'
|
import {FlashMessages} from './components/flashMessages'
|
||||||
import BoardPage from './pages/boardPage'
|
import BoardPage from './pages/boardPage'
|
||||||
|
@ -22,15 +24,18 @@ import LoginPage from './pages/loginPage'
|
||||||
import RegisterPage from './pages/registerPage'
|
import RegisterPage from './pages/registerPage'
|
||||||
import {Utils} from './utils'
|
import {Utils} from './utils'
|
||||||
import wsClient from './wsclient'
|
import wsClient from './wsclient'
|
||||||
import {fetchMe, getLoggedIn} from './store/users'
|
import {fetchMe, getLoggedIn, getMe} from './store/users'
|
||||||
import {getLanguage, fetchLanguage} from './store/language'
|
import {getLanguage, fetchLanguage} from './store/language'
|
||||||
import {setGlobalError, getGlobalError} from './store/globalError'
|
import {setGlobalError, getGlobalError} from './store/globalError'
|
||||||
import {useAppSelector, useAppDispatch} from './store/hooks'
|
import {useAppSelector, useAppDispatch} from './store/hooks'
|
||||||
|
|
||||||
|
import {IUser} from './user'
|
||||||
|
|
||||||
const App = React.memo((): JSX.Element => {
|
const App = React.memo((): JSX.Element => {
|
||||||
const language = useAppSelector<string>(getLanguage)
|
const language = useAppSelector<string>(getLanguage)
|
||||||
const loggedIn = useAppSelector<boolean|null>(getLoggedIn)
|
const loggedIn = useAppSelector<boolean|null>(getLoggedIn)
|
||||||
const globalError = useAppSelector<string>(getGlobalError)
|
const globalError = useAppSelector<string>(getGlobalError)
|
||||||
|
const me = useAppSelector<IUser|null>(getMe)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -45,6 +50,12 @@ const App = React.memo((): JSX.Element => {
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (me) {
|
||||||
|
TelemetryClient.setUser(me)
|
||||||
|
}
|
||||||
|
}, [me])
|
||||||
|
|
||||||
let globalErrorRedirect = null
|
let globalErrorRedirect = null
|
||||||
if (globalError) {
|
if (globalError) {
|
||||||
globalErrorRedirect = <Route path='/*'><Redirect to={`/error?id=${globalError}`}/></Route>
|
globalErrorRedirect = <Route path='/*'><Redirect to={`/error?id=${globalError}`}/></Route>
|
||||||
|
|
|
@ -19,6 +19,8 @@ import {updateView} from '../store/views'
|
||||||
|
|
||||||
import './centerPanel.scss'
|
import './centerPanel.scss'
|
||||||
|
|
||||||
|
import TelemetryClient from '../../../webapp/src/telemetry/telemetryClient'
|
||||||
|
|
||||||
import CardDialog from './cardDialog'
|
import CardDialog from './cardDialog'
|
||||||
import RootPortal from './rootPortal'
|
import RootPortal from './rootPortal'
|
||||||
import TopBar from './topBar'
|
import TopBar from './topBar'
|
||||||
|
@ -80,6 +82,10 @@ class CenterPanel extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount(): void {
|
||||||
|
TelemetryClient.trackEvent('boards', 'view', {viewType: this.props.activeView.fields.viewType})
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -92,6 +98,10 @@ class CenterPanel extends React.Component<Props, State> {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(): void {
|
||||||
|
TelemetryClient.trackEvent('boards', 'view', {viewType: this.props.activeView.fields.viewType})
|
||||||
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
const {groupByProperty, activeView, board, views, cards} = this.props
|
const {groupByProperty, activeView, board, views, cards} = this.props
|
||||||
const {visible: visibleGroups, hidden: hiddenGroups} = this.getVisibleAndHiddenGroups(cards, activeView.fields.visibleOptionIds, activeView.fields.hiddenOptionIds, groupByProperty)
|
const {visible: visibleGroups, hidden: hiddenGroups} = this.getVisibleAndHiddenGroups(cards, activeView.fields.visibleOptionIds, activeView.fields.hiddenOptionIds, groupByProperty)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
margin-right: 16px;
|
margin-right: 12px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
|
7
webapp/src/config/clientConfig.ts
Normal file
7
webapp/src/config/clientConfig.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
export type ClientConfig = {
|
||||||
|
telemetry: boolean,
|
||||||
|
telemetryid: string,
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import {IWorkspace} from './blocks/workspace'
|
||||||
import {OctoUtils} from './octoUtils'
|
import {OctoUtils} from './octoUtils'
|
||||||
import {IUser} from './user'
|
import {IUser} from './user'
|
||||||
import {Utils} from './utils'
|
import {Utils} from './utils'
|
||||||
|
import {ClientConfig} from './config/clientConfig'
|
||||||
|
|
||||||
//
|
//
|
||||||
// OctoClient is the client interface to the server APIs
|
// OctoClient is the client interface to the server APIs
|
||||||
|
@ -64,6 +65,20 @@ class OctoClient {
|
||||||
localStorage.removeItem('focalboardSessionId')
|
localStorage.removeItem('focalboardSessionId')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getClientConfig(): Promise<ClientConfig | null> {
|
||||||
|
const path = '/api/v1/clientConfig'
|
||||||
|
const response = await fetch(this.serverUrl + path, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: this.headers(),
|
||||||
|
})
|
||||||
|
if (response.status !== 200) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = (await this.getJson(response, {})) as ClientConfig
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
async register(email: string, username: string, password: string, token?: string): Promise<{code: number, json: any}> {
|
async register(email: string, username: string, password: string, token?: string): Promise<{code: number, json: any}> {
|
||||||
const path = '/api/v1/register'
|
const path = '/api/v1/register'
|
||||||
const body = JSON.stringify({email, username, password, token})
|
const body = JSON.stringify({email, username, password, token})
|
||||||
|
|
7
webapp/src/telemetry/telemetry.ts
Normal file
7
webapp/src/telemetry/telemetry.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
export interface TelemetryHandler {
|
||||||
|
trackEvent: (userId: string, userRoles: string, category: string, event: string, props?: any) => void;
|
||||||
|
pageVisited: (userId: string, userRoles: string, category: string, name: string) => void;
|
||||||
|
}
|
24
webapp/src/telemetry/telemetryClient.test.ts
Normal file
24
webapp/src/telemetry/telemetryClient.test.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
import '@testing-library/jest-dom'
|
||||||
|
|
||||||
|
import TelemetryClient from './telemetryClient'
|
||||||
|
|
||||||
|
describe('trackEvent', () => {
|
||||||
|
const track = jest.fn()
|
||||||
|
const page = jest.fn()
|
||||||
|
test('should call Rudder\'s track when a RudderTelemetryHandler is attached to TelemetryClient', () => {
|
||||||
|
TelemetryClient.setTelemetryHandler()
|
||||||
|
TelemetryClient.trackEvent('test', 'onClick')
|
||||||
|
TelemetryClient.pageVisited('focalboard', 'test')
|
||||||
|
expect(track).not.toHaveBeenCalled()
|
||||||
|
expect(page).not.toHaveBeenCalled()
|
||||||
|
|
||||||
|
TelemetryClient.setTelemetryHandler({trackEvent: track, pageVisited: page})
|
||||||
|
TelemetryClient.trackEvent('test', 'onClick')
|
||||||
|
TelemetryClient.pageVisited('focalboard', 'test')
|
||||||
|
|
||||||
|
expect(track).toHaveBeenCalledTimes(1)
|
||||||
|
expect(page).toHaveBeenCalledTimes(1)
|
||||||
|
})
|
||||||
|
})
|
37
webapp/src/telemetry/telemetryClient.ts
Normal file
37
webapp/src/telemetry/telemetryClient.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
import {IUser} from '../user'
|
||||||
|
|
||||||
|
import {TelemetryHandler} from './telemetry'
|
||||||
|
|
||||||
|
class TelemetryClient {
|
||||||
|
public telemetryHandler?: TelemetryHandler
|
||||||
|
public user?: IUser
|
||||||
|
|
||||||
|
setTelemetryHandler(telemetryHandler?: TelemetryHandler): void {
|
||||||
|
this.telemetryHandler = telemetryHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
setUser(user: IUser): void {
|
||||||
|
this.user = user
|
||||||
|
}
|
||||||
|
|
||||||
|
trackEvent(category: string, event: string, props?: any): void {
|
||||||
|
if (this.telemetryHandler) {
|
||||||
|
const userId = this.user?.id
|
||||||
|
this.telemetryHandler.trackEvent(userId || '', '', category, event, props)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pageVisited(category: string, name: string): void {
|
||||||
|
if (this.telemetryHandler) {
|
||||||
|
const userId = this.user?.id
|
||||||
|
this.telemetryHandler.pageVisited(userId || '', '', category, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const telemetryClient = new TelemetryClient()
|
||||||
|
|
||||||
|
export {TelemetryClient}
|
||||||
|
export default telemetryClient
|
|
@ -1,4 +1,5 @@
|
||||||
.Button {
|
.Button {
|
||||||
|
font-family: 'Open Sans', sans-serif;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -12,6 +13,8 @@
|
||||||
border: 0;
|
border: 0;
|
||||||
transition: background 100ms ease-out 0s;
|
transition: background 100ms ease-out 0s;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(var(--center-channel-color-rgb), 0.1);
|
background-color: rgba(var(--center-channel-color-rgb), 0.1);
|
||||||
|
@ -41,7 +44,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
color: rgb(var(--link-color));
|
background: rgba(var(--button-bg-rgb), 0.08);
|
||||||
|
color: rgb(var(--button-bg-rgb));
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue