1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-12-09 08:56:07 +02:00

Merge branch 'main' into gh-1059-fix-empty-placeholder-in-card-dialog

This commit is contained in:
Harshil Sharma 2021-09-06 17:18:15 +05:30 committed by GitHub
commit e5c6619555
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 352 additions and 24 deletions

View File

@ -12,12 +12,18 @@ jobs:
- name: Checkout
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
- 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
- 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
run: cd webapp; npm install --no-optional

View File

@ -11,12 +11,18 @@ jobs:
- name: Checkout
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
- 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
- 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
run: cd webapp; npm install --no-optional

View File

@ -11,12 +11,18 @@ jobs:
- name: Checkout
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
- 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
- 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
uses: microsoft/setup-msbuild@v1.0.2

View File

@ -16,12 +16,18 @@ jobs:
- name: Checkout
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
- 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
- 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
run: cd webapp; npm install --no-optional
@ -69,12 +75,18 @@ jobs:
- name: Checkout
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
- 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
- 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
run: cd webapp; npm install --no-optional
@ -105,12 +117,18 @@ jobs:
- name: Checkout
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
- 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
- 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
uses: microsoft/setup-msbuild@v1.0.2
@ -154,12 +172,18 @@ jobs:
- name: Checkout
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
- 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
- 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
run: cd webapp; npm install --no-optional

View File

@ -11,12 +11,18 @@ jobs:
- name: Checkout
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
- 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
- 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
run: cd webapp; npm install --no-optional

View File

@ -11,12 +11,18 @@ jobs:
- name: Checkout
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
- 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
- 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
run: cd webapp; npm install --no-optional

View File

@ -88,6 +88,13 @@ func (p *Plugin) OnActivate() error {
baseURL = *mmconfig.ServiceSettings.SiteURL
}
serverID := client.System.GetDiagnosticID()
enableTelemetry := false
if mmconfig.LogSettings.EnableDiagnostics != nil {
enableTelemetry = *mmconfig.LogSettings.EnableDiagnostics
}
cfg := &config.Configuration{
ServerRoot: baseURL + "/plugins/focalboard",
Port: -1,
@ -100,7 +107,8 @@ func (p *Plugin) OnActivate() error {
FilesDriver: *mmconfig.FileSettings.DriverName,
FilesPath: *mmconfig.FileSettings.Directory,
FilesS3Config: filesS3Config,
Telemetry: true,
Telemetry: enableTelemetry,
TelemetryID: serverID,
WebhookUpdate: []string{},
SessionExpireTime: 2592000,
SessionRefreshTime: 18000,
@ -122,7 +130,6 @@ func (p *Plugin) OnActivate() error {
db = layeredStore
}
serverID := client.System.GetDiagnosticID()
p.wsPluginAdapter = ws.NewPluginAdapter(p.API, auth.New(cfg, db))
server, err := server.New(cfg, "", db, logger, serverID, p.wsPluginAdapter)

View File

@ -5,6 +5,8 @@ import {Store, Action} from 'redux'
import {Provider as ReduxProvider} from 'react-redux'
import {useHistory} from 'mm-react-router-dom'
import {rudderAnalytics, RudderTelemetryHandler} from 'mattermost-redux/client/rudder'
import {GlobalState} from 'mattermost-redux/types/store'
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 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/main.scss'
import '../../../webapp/src/styles/labels.scss'
import octoClient from '../../../webapp/src/octoClient'
import manifest from './manifest'
import ErrorBoundary from './error_boundary'
@ -32,6 +37,22 @@ import {PluginRegistry} from './types/mattermost-webapp'
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 = {
webSocketClient: MMWebSocketClient
}
@ -150,6 +171,32 @@ export default class Plugin {
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
this.registry?.registerWebSocketEventHandler(`custom_${manifest.id}_${ACTION_UPDATE_BLOCK}`, (e: any) => wsClient.updateBlockHandler(e.data))
}

View File

@ -16,7 +16,7 @@
color: rgba(var(--center-channel-text-rgb), 1);
i {
color: inherit;
color: var(--link-color-rgb);
}
&:hover {

View File

@ -143,3 +143,11 @@ module.exports = {
mode,
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,
}));

View File

@ -90,6 +90,7 @@ func (a *API) RegisterRoutes(r *mux.Router) {
apiv1.HandleFunc("/login", a.handleLogin).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")
@ -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 {
token := r.Header.Get(HeaderRequestedWith)
return token == HeaderRequestedWithXML

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

View File

@ -0,0 +1,6 @@
package model
type ClientConfig struct {
Telemetry bool `json:"telemetry"`
TelemetryID string `json:"telemetryid"`
}

View File

@ -38,6 +38,7 @@ type Configuration struct {
FilesS3Config AmazonS3Config `json:"filess3config" mapstructure:"filess3config"`
FilesPath string `json:"filespath" mapstructure:"filespath"`
Telemetry bool `json:"telemetry" mapstructure:"telemetry"`
TelemetryID string `json:"telemetryid" mapstructure:"telemetryid"`
PrometheusAddress string `json:"prometheus_address" mapstructure:"prometheus_address"`
WebhookUpdate []string `json:"webhook_update" mapstructure:"webhook_update"`
Secret string `json:"secret" mapstructure:"secret"`
@ -73,6 +74,7 @@ func ReadConfigFile() (*Configuration, error) {
viper.SetDefault("FilesPath", "./files")
viper.SetDefault("FilesDriver", "local")
viper.SetDefault("Telemetry", true)
viper.SetDefault("TelemetryID", "")
viper.SetDefault("WebhookUpdate", nil)
viper.SetDefault("SessionExpireTime", 60*60*24*30) // 30 days session lifetime
viper.SetDefault("SessionRefreshTime", 60*60*5) // 5 minutes session refresh

62
webapp/i18n/ar.json Normal file
View 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": "لِج"
}

View File

@ -15,6 +15,7 @@
"CardDetail.new-comment-placeholder": "Lägg till kommentar...",
"CardDialog.editing-template": "Du redigerar en mall",
"CardDialog.nocard": "Detta kort existerar inte eller är oåtkomligt",
"ColorOption.selectColor": "Välj {color} färg",
"Comment.delete": "Radera",
"CommentsList.send": "Skicka",
"ContentBlock.Delete": "Radera",
@ -120,6 +121,8 @@
"TableHeaderMenu.sort-ascending": "Sortera stigande",
"TableHeaderMenu.sort-descending": "Sortera fallande",
"TableRow.open": "Öppna",
"ValueSelector.valueSelector": "Värdeväljare",
"ValueSelectorLabel.openMenu": "Öppna meny",
"View.AddView": "Lägg till vy",
"View.Board": "Tavla",
"View.DeleteView": "Radera vy",

View File

@ -12,6 +12,8 @@ import {DndProvider} from 'react-dnd'
import {HTML5Backend} from 'react-dnd-html5-backend'
import {TouchBackend} from 'react-dnd-touch-backend'
import TelemetryClient from './telemetry/telemetryClient'
import {getMessages} from './i18n'
import {FlashMessages} from './components/flashMessages'
import BoardPage from './pages/boardPage'
@ -22,15 +24,18 @@ import LoginPage from './pages/loginPage'
import RegisterPage from './pages/registerPage'
import {Utils} from './utils'
import wsClient from './wsclient'
import {fetchMe, getLoggedIn} from './store/users'
import {fetchMe, getLoggedIn, getMe} from './store/users'
import {getLanguage, fetchLanguage} from './store/language'
import {setGlobalError, getGlobalError} from './store/globalError'
import {useAppSelector, useAppDispatch} from './store/hooks'
import {IUser} from './user'
const App = React.memo((): JSX.Element => {
const language = useAppSelector<string>(getLanguage)
const loggedIn = useAppSelector<boolean|null>(getLoggedIn)
const globalError = useAppSelector<string>(getGlobalError)
const me = useAppSelector<IUser|null>(getMe)
const dispatch = useAppDispatch()
useEffect(() => {
@ -45,6 +50,12 @@ const App = React.memo((): JSX.Element => {
}
}, [])
useEffect(() => {
if (me) {
TelemetryClient.setUser(me)
}
}, [me])
let globalErrorRedirect = null
if (globalError) {
globalErrorRedirect = <Route path='/*'><Redirect to={`/error?id=${globalError}`}/></Route>

View File

@ -19,6 +19,8 @@ import {updateView} from '../store/views'
import './centerPanel.scss'
import TelemetryClient from '../../../webapp/src/telemetry/telemetryClient'
import CardDialog from './cardDialog'
import RootPortal from './rootPortal'
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) {
super(props)
this.state = {
@ -92,6 +98,10 @@ class CenterPanel extends React.Component<Props, State> {
return true
}
componentDidUpdate(): void {
TelemetryClient.trackEvent('boards', 'view', {viewType: this.props.activeView.fields.viewType})
}
render(): JSX.Element {
const {groupByProperty, activeView, board, views, cards} = this.props
const {visible: visibleGroups, hidden: hiddenGroups} = this.getVisibleAndHiddenGroups(cards, activeView.fields.visibleOptionIds, activeView.fields.hiddenOptionIds, groupByProperty)

View File

@ -10,7 +10,7 @@
align-items: center;
> div {
margin-right: 16px;
margin-right: 12px;
white-space: nowrap;
&:last-child {

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

View File

@ -6,6 +6,7 @@ import {IWorkspace} from './blocks/workspace'
import {OctoUtils} from './octoUtils'
import {IUser} from './user'
import {Utils} from './utils'
import {ClientConfig} from './config/clientConfig'
//
// OctoClient is the client interface to the server APIs
@ -64,6 +65,20 @@ class OctoClient {
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}> {
const path = '/api/v1/register'
const body = JSON.stringify({email, username, password, token})

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

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

View 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

View File

@ -1,4 +1,5 @@
.Button {
font-family: 'Open Sans', sans-serif;
display: flex;
flex: 0 0 auto;
align-items: center;
@ -12,6 +13,8 @@
border: 0;
transition: background 100ms ease-out 0s;
color: inherit;
height: 32px;
padding: 0 10px;
&:hover {
background-color: rgba(var(--center-channel-color-rgb), 0.1);
@ -41,7 +44,8 @@
}
&.active {
color: rgb(var(--link-color));
background: rgba(var(--button-bg-rgb), 0.08);
color: rgb(var(--button-bg-rgb));
font-weight: 600;
}