mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-12 13:42:38 +00:00
UBERF-5490 (#4650)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
96b81eabef
commit
e8084b3110
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@
|
||||
"preformat-svelte": "prettier -w src/**/*.svelte",
|
||||
"lint": "",
|
||||
"lint:fix": "yarn preformat-svelte && eslint --fix src",
|
||||
"format": "",
|
||||
"format": "format src",
|
||||
"deploy": "cp -p public/* dist && aws s3 sync dist s3://anticrm-platform --delete --acl public-read"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -16,34 +16,33 @@
|
||||
|
||||
import activity from '@hcengineering/activity'
|
||||
import {
|
||||
type AvatarProvider,
|
||||
AvatarType,
|
||||
contactId,
|
||||
type AvatarProvider,
|
||||
type Channel,
|
||||
type ChannelProvider,
|
||||
type Contact,
|
||||
type ContactsTab,
|
||||
type Employee,
|
||||
type PersonAccount,
|
||||
type GetAvatarUrl,
|
||||
type Member,
|
||||
type Organization,
|
||||
type Organizations,
|
||||
type Person,
|
||||
type PersonAccount,
|
||||
type Persons,
|
||||
type Status,
|
||||
contactId
|
||||
type Status
|
||||
} from '@hcengineering/contact'
|
||||
import {
|
||||
type Class,
|
||||
DOMAIN_MODEL,
|
||||
DateRangeMode,
|
||||
type Domain,
|
||||
IndexKind,
|
||||
type Class,
|
||||
type Domain,
|
||||
type Ref,
|
||||
type Timestamp
|
||||
} from '@hcengineering/core'
|
||||
import {
|
||||
type Builder,
|
||||
Collection,
|
||||
Hidden,
|
||||
Index,
|
||||
@ -51,26 +50,28 @@ import {
|
||||
Model,
|
||||
Prop,
|
||||
ReadOnly,
|
||||
TypeAttachment,
|
||||
TypeBoolean,
|
||||
TypeDate,
|
||||
TypeRef,
|
||||
TypeString,
|
||||
TypeTimestamp,
|
||||
TypeAttachment,
|
||||
UX
|
||||
UX,
|
||||
type Builder
|
||||
} from '@hcengineering/model'
|
||||
import attachment from '@hcengineering/model-attachment'
|
||||
import chunter from '@hcengineering/model-chunter'
|
||||
import core, { TAccount, TAttachedDoc, TDoc, TSpace } from '@hcengineering/model-core'
|
||||
import presentation from '@hcengineering/model-presentation'
|
||||
import view, { type ViewAction, type Viewlet, createAction } from '@hcengineering/model-view'
|
||||
import workbench from '@hcengineering/model-workbench'
|
||||
import { generateClassNotificationTypes } from '@hcengineering/model-notification'
|
||||
import presentation from '@hcengineering/model-presentation'
|
||||
import view, { createAction, type Viewlet } from '@hcengineering/model-view'
|
||||
import workbench from '@hcengineering/model-workbench'
|
||||
import notification from '@hcengineering/notification'
|
||||
import type { Asset, IntlString, Resource } from '@hcengineering/platform'
|
||||
import setting from '@hcengineering/setting'
|
||||
import templates from '@hcengineering/templates'
|
||||
import { type AnyComponent } from '@hcengineering/ui/src/types'
|
||||
import { type Action } from '@hcengineering/view'
|
||||
import contact from './plugin'
|
||||
|
||||
export { contactId } from '@hcengineering/contact'
|
||||
@ -90,7 +91,7 @@ export class TAvatarProvider extends TDoc implements AvatarProvider {
|
||||
export class TChannelProvider extends TDoc implements ChannelProvider {
|
||||
label!: IntlString
|
||||
icon?: Asset
|
||||
action?: ViewAction
|
||||
action?: Ref<Action>
|
||||
placeholder!: IntlString
|
||||
}
|
||||
|
||||
@ -574,7 +575,7 @@ export function createModel (builder: Builder): void {
|
||||
label: contact.string.LinkedIn,
|
||||
icon: contact.icon.LinkedIn,
|
||||
placeholder: contact.string.LinkedInPlaceholder,
|
||||
action: contact.actionImpl.OpenChannel
|
||||
action: contact.action.OpenChannel
|
||||
},
|
||||
contact.channelProvider.LinkedIn
|
||||
)
|
||||
@ -586,7 +587,7 @@ export function createModel (builder: Builder): void {
|
||||
label: contact.string.Twitter,
|
||||
icon: contact.icon.Twitter,
|
||||
placeholder: contact.string.AtPlaceHolder,
|
||||
action: contact.actionImpl.OpenChannel
|
||||
action: contact.action.OpenChannel
|
||||
},
|
||||
contact.channelProvider.Twitter
|
||||
)
|
||||
@ -598,7 +599,7 @@ export function createModel (builder: Builder): void {
|
||||
label: contact.string.GitHub,
|
||||
icon: contact.icon.GitHub,
|
||||
placeholder: contact.string.AtPlaceHolder,
|
||||
action: contact.actionImpl.OpenChannel
|
||||
action: contact.action.OpenChannel
|
||||
},
|
||||
contact.channelProvider.GitHub
|
||||
)
|
||||
@ -610,7 +611,7 @@ export function createModel (builder: Builder): void {
|
||||
label: contact.string.Facebook,
|
||||
icon: contact.icon.Facebook,
|
||||
placeholder: contact.string.FacebookPlaceholder,
|
||||
action: contact.actionImpl.OpenChannel
|
||||
action: contact.action.OpenChannel
|
||||
},
|
||||
contact.channelProvider.Facebook
|
||||
)
|
||||
@ -622,7 +623,7 @@ export function createModel (builder: Builder): void {
|
||||
label: contact.string.Homepage,
|
||||
icon: contact.icon.Homepage,
|
||||
placeholder: contact.string.HomepagePlaceholder,
|
||||
action: contact.actionImpl.OpenChannel
|
||||
action: contact.action.OpenChannel
|
||||
},
|
||||
contact.channelProvider.Homepage
|
||||
)
|
||||
@ -656,7 +657,7 @@ export function createModel (builder: Builder): void {
|
||||
label: contact.string.Profile,
|
||||
icon: contact.icon.Profile,
|
||||
placeholder: contact.string.ProfilePlaceholder,
|
||||
action: contact.actionImpl.OpenChannel
|
||||
action: contact.action.OpenChannel
|
||||
},
|
||||
contact.channelProvider.Profile
|
||||
)
|
||||
@ -839,6 +840,21 @@ export function createModel (builder: Builder): void {
|
||||
contact.action.KickEmployee
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: contact.actionImpl.OpenChannel,
|
||||
category: contact.category.Channel,
|
||||
label: contact.string.Channel,
|
||||
input: 'none',
|
||||
context: {
|
||||
mode: ['none']
|
||||
},
|
||||
target: contact.class.Channel
|
||||
},
|
||||
contact.action.OpenChannel
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
|
@ -109,7 +109,8 @@ export default mergeIds(contactId, contact, {
|
||||
OrganizationCategory: '' as Ref<ObjectSearchCategory>
|
||||
},
|
||||
category: {
|
||||
Contact: '' as Ref<ActionCategory>
|
||||
Contact: '' as Ref<ActionCategory>,
|
||||
Channel: '' as Ref<ActionCategory>
|
||||
},
|
||||
ids: {
|
||||
OrganizationNotificationGroup: '' as Ref<NotificationGroup>,
|
||||
@ -121,7 +122,8 @@ export default mergeIds(contactId, contact, {
|
||||
action: {
|
||||
KickEmployee: '' as Ref<Action>,
|
||||
DeleteEmployee: '' as Ref<Action>,
|
||||
MergePersons: '' as Ref<Action<Doc, any>>
|
||||
MergePersons: '' as Ref<Action<Doc, any>>,
|
||||
OpenChannel: '' as Ref<Action>
|
||||
},
|
||||
actionImpl: {
|
||||
KickEmployee: '' as ViewAction,
|
||||
|
@ -589,6 +589,15 @@ export function createModel (builder: Builder): void {
|
||||
view.pipeline.PresentationMiddleware
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
presentation.class.PresentationMiddlewareFactory,
|
||||
core.space.Model,
|
||||
{
|
||||
createPresentationMiddleware: view.function.AnalyticsMiddleware
|
||||
},
|
||||
view.pipeline.AnalyticsMiddleware
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
|
@ -128,6 +128,7 @@ export default mergeIds(viewId, view, {
|
||||
ShowEmptyGroups: '' as ViewCategoryAction
|
||||
},
|
||||
pipeline: {
|
||||
PresentationMiddleware: '' as Ref<PresentationMiddlewareFactory>
|
||||
PresentationMiddleware: '' as Ref<PresentationMiddlewareFactory>,
|
||||
AnalyticsMiddleware: '' as Ref<PresentationMiddlewareFactory>
|
||||
}
|
||||
})
|
||||
|
7
packages/analytics/.eslintrc.js
Normal file
7
packages/analytics/.eslintrc.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
4
packages/analytics/.npmignore
Normal file
4
packages/analytics/.npmignore
Normal file
@ -0,0 +1,4 @@
|
||||
*
|
||||
!/lib/**
|
||||
!CHANGELOG.md
|
||||
/lib/**/__tests__/
|
4
packages/analytics/config/rig.json
Normal file
4
packages/analytics/config/rig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
7
packages/analytics/jest.config.js
Normal file
7
packages/analytics/jest.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
|
||||
roots: ["./src"],
|
||||
coverageReporters: ["text-summary", "html"]
|
||||
}
|
37
packages/analytics/package.json
Normal file
37
packages/analytics/package.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "@hcengineering/analytics",
|
||||
"version": "0.6.0",
|
||||
"main": "lib/index.js",
|
||||
"author": "Anticrm Platform Contributors",
|
||||
"license": "EPL-2.0",
|
||||
"scripts": {
|
||||
"build": "compile",
|
||||
"build:watch": "compile",
|
||||
"test": "jest --passWithNoTests --silent",
|
||||
"format": "format src",
|
||||
"_phase:build": "compile",
|
||||
"_phase:test": "jest --passWithNoTests --silent",
|
||||
"_phase:format": "format src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hcengineering/platform-rig": "^0.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint": "^8.54.0",
|
||||
"simplytyped": "^3.3.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.3.3",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"@types/jest": "^29.5.5",
|
||||
"prettier-plugin-svelte": "^3.1.0"
|
||||
},
|
||||
"repository": "https://github.com/hcengineering/anticrm",
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
}
|
||||
}
|
53
packages/analytics/src/index.ts
Normal file
53
packages/analytics/src/index.ts
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright © 2024 Hardcore Engineering Inc
|
||||
//
|
||||
|
||||
export const providers: AnalyticProvider[] = []
|
||||
|
||||
export interface AnalyticProvider {
|
||||
init: (config: Record<string, any>) => boolean
|
||||
setUser: (email: string) => void
|
||||
setTag: (key: string, value: string) => void
|
||||
setWorkspace: (ws: string) => void
|
||||
handleEvent: (event: string) => void
|
||||
handleError: (error: Error) => void
|
||||
}
|
||||
|
||||
export const Analytics = {
|
||||
init (provider: AnalyticProvider, config: Record<string, any>): void {
|
||||
const res = provider.init(config)
|
||||
if (res) {
|
||||
providers.push(provider)
|
||||
}
|
||||
},
|
||||
|
||||
setUser (email: string): void {
|
||||
providers.forEach((provider) => {
|
||||
provider.setUser(email)
|
||||
})
|
||||
},
|
||||
|
||||
setTag (key: string, value: string): void {
|
||||
providers.forEach((provider) => {
|
||||
provider.setTag(key, value)
|
||||
})
|
||||
},
|
||||
|
||||
setWorkspace (ws: string): void {
|
||||
providers.forEach((provider) => {
|
||||
provider.setWorkspace(ws)
|
||||
})
|
||||
},
|
||||
|
||||
handleEvent (event: string): void {
|
||||
providers.forEach((provider) => {
|
||||
provider.handleEvent(event)
|
||||
})
|
||||
},
|
||||
|
||||
handleError (error: Error): void {
|
||||
providers.forEach((provider) => {
|
||||
provider.handleError(error)
|
||||
})
|
||||
}
|
||||
}
|
9
packages/analytics/tsconfig.json
Normal file
9
packages/analytics/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import {
|
||||
toFindResult,
|
||||
type Class,
|
||||
type Client,
|
||||
type Doc,
|
||||
@ -6,17 +7,16 @@ import {
|
||||
type FindOptions,
|
||||
type FindResult,
|
||||
type Hierarchy,
|
||||
type MeasureClient,
|
||||
type MeasureDoneOperation,
|
||||
type ModelDb,
|
||||
type Ref,
|
||||
type SearchOptions,
|
||||
type SearchQuery,
|
||||
type SearchResult,
|
||||
type Tx,
|
||||
type TxResult,
|
||||
type WithLookup,
|
||||
toFindResult,
|
||||
type SearchQuery,
|
||||
type SearchOptions,
|
||||
type SearchResult,
|
||||
type MeasureClient,
|
||||
type MeasureDoneOperation
|
||||
type WithLookup
|
||||
} from '@hcengineering/core'
|
||||
import { type Resource } from '@hcengineering/platform'
|
||||
|
||||
|
@ -36,7 +36,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"svelte": "^4.2.5",
|
||||
"@hcengineering/platform": "^0.6.9"
|
||||
"@hcengineering/platform": "^0.6.9",
|
||||
"@hcengineering/analytics": "^0.6.0"
|
||||
},
|
||||
"repository": "https://github.com/hcenginneing/anticrm",
|
||||
"publishConfig": {
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import platform, { loadPluginStrings, setMetadata } from '@hcengineering/platform'
|
||||
import { onMount, setContext } from 'svelte'
|
||||
import {
|
||||
@ -52,6 +53,7 @@
|
||||
if (set) {
|
||||
localStorage.setItem('lang', language)
|
||||
}
|
||||
Analytics.setTag('language', language)
|
||||
setMetadata(platform.metadata.locale, currentLanguage)
|
||||
await loadPluginStrings(currentLanguage, set)
|
||||
setOptions(getCurrentFontSize(), getCurrentTheme(), language)
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import '@hcengineering/platform-rig/profiles/ui/svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
@ -53,7 +54,11 @@ export const getCurrentFontSize = (): string =>
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const getCurrentLanguage = (): string => localStorage.getItem('lang') ?? getDefaultProps('lang', 'en')
|
||||
export const getCurrentLanguage = (): string => {
|
||||
const lang = localStorage.getItem('lang') ?? getDefaultProps('lang', 'en')
|
||||
Analytics.setTag('language', lang)
|
||||
return lang
|
||||
}
|
||||
|
||||
export class ThemeOptions {
|
||||
constructor (
|
||||
|
@ -42,7 +42,7 @@
|
||||
on:click={(e) => {
|
||||
const unarchiveAction = actions.find((a) => a._id === board.action.SendToBoard)
|
||||
if (unarchiveAction) {
|
||||
invokeAction(card, e, unarchiveAction.action, unarchiveAction.actionProps)
|
||||
invokeAction(card, e, unarchiveAction)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@ -51,7 +51,7 @@
|
||||
on:click={async (e) => {
|
||||
const deleteAction = actions.find((a) => a._id === board.action.Delete)
|
||||
if (deleteAction) {
|
||||
invokeAction(card, e, deleteAction.action, deleteAction.actionProps)
|
||||
invokeAction(card, e, deleteAction)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
@ -80,7 +80,7 @@
|
||||
if (!object) {
|
||||
return
|
||||
}
|
||||
invokeAction(object, e, result[0].action, result[0].actionProps)
|
||||
invokeAction(object, e, result[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -37,6 +37,7 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/activity": "^0.6.0",
|
||||
"@hcengineering/activity-resources": "^0.6.1",
|
||||
"@hcengineering/attachment": "^0.6.9",
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
|
||||
import { Class, Doc, generateId, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
@ -104,7 +105,8 @@
|
||||
// Remove draft from Local Storage
|
||||
currentMessage = getDefault()
|
||||
_id = currentMessage._id
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
console.error(err)
|
||||
}
|
||||
dispatch('submit', false)
|
||||
|
@ -36,6 +36,7 @@
|
||||
"prettier-plugin-svelte": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/platform": "^0.6.9",
|
||||
"@hcengineering/core": "^0.6.28",
|
||||
"@hcengineering/client": "^0.6.14",
|
||||
|
@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import client, { ClientSocket, ClientSocketReadyState } from '@hcengineering/client'
|
||||
import core, {
|
||||
Account,
|
||||
@ -146,6 +147,7 @@ class Connection implements ClientConnection {
|
||||
this.pending = undefined
|
||||
console.log('failed to connect', err)
|
||||
if (err?.code === UNAUTHORIZED.code) {
|
||||
Analytics.handleError(err)
|
||||
this.onUnauthorized?.()
|
||||
throw err
|
||||
}
|
||||
|
@ -27,9 +27,9 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import contact, { AvatarProvider, AvatarType, getFirstName, getLastName } from '@hcengineering/contact'
|
||||
import contact, { AvatarProvider, AvatarType, getFirstName, getLastName, getName } from '@hcengineering/contact'
|
||||
import { Client, Ref } from '@hcengineering/core'
|
||||
import { Asset, getResource } from '@hcengineering/platform'
|
||||
import { Asset, getMetadata, getResource } from '@hcengineering/platform'
|
||||
import { getBlobURL, getClient } from '@hcengineering/presentation'
|
||||
import {
|
||||
AnySvelteComponent,
|
||||
@ -54,10 +54,17 @@
|
||||
let avatarProvider: AvatarProvider | undefined
|
||||
let color: ColorDefinition | undefined = undefined
|
||||
|
||||
$: fname = getFirstName(name ?? '')
|
||||
$: lname = getLastName(name ?? '')
|
||||
$: displayName =
|
||||
name != null ? (lname.length > 1 ? lname.trim()[0] : lname) + (fname.length > 1 ? fname.trim()[0] : fname) : ''
|
||||
$: displayName = getDisplayName(name)
|
||||
|
||||
function getDisplayName (name: string | null | undefined): string {
|
||||
if (name == null) {
|
||||
return ''
|
||||
}
|
||||
const lastFirst = getMetadata(contact.metadata.LastNameFirst) === true
|
||||
const fname = getFirstName(name ?? '').trim()[0]
|
||||
const lname = getLastName(name ?? '').trim()[0]
|
||||
return lastFirst ? lname + ' ' + fname : fname + ' ' + lname
|
||||
}
|
||||
|
||||
async function update (size: IconSize, avatar?: string | null, direct?: Blob, name?: string | null) {
|
||||
if (direct !== undefined) {
|
||||
|
@ -19,7 +19,7 @@
|
||||
import { AttachedData, Doc, Ref, toIdMap } from '@hcengineering/core'
|
||||
import notification, { DocNotifyContext, InboxNotification } from '@hcengineering/notification'
|
||||
import { Asset, IntlString, getResource } from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import presentation, { getClient } from '@hcengineering/presentation'
|
||||
import {
|
||||
Action,
|
||||
AnyComponent,
|
||||
@ -32,7 +32,7 @@
|
||||
getFocusManager,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import { ViewAction } from '@hcengineering/view'
|
||||
import view, { Action as ViewAction } from '@hcengineering/view'
|
||||
import { invokeAction } from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher, tick } from 'svelte'
|
||||
import { readable, Readable, Writable, writable } from 'svelte/store'
|
||||
@ -66,7 +66,7 @@
|
||||
icon: Asset
|
||||
value: string
|
||||
presenter?: AnyComponent
|
||||
action?: ViewAction
|
||||
action?: Ref<ViewAction>
|
||||
placeholder: IntlString
|
||||
channel: AttachedData<Channel> | Channel
|
||||
provider: Ref<ChannelProvider>
|
||||
@ -211,6 +211,8 @@
|
||||
dispatch('remove', removed.channel)
|
||||
}
|
||||
|
||||
const client = getClient()
|
||||
|
||||
const editChannel = (el: HTMLElement, n: number, item: Item): void => {
|
||||
if (opened !== n) {
|
||||
opened = n
|
||||
@ -230,7 +232,8 @@
|
||||
if (result === 'open') {
|
||||
if (item.action) {
|
||||
const doc = item.channel as Channel
|
||||
invokeAction(doc, result, item.action)
|
||||
const action = client.getModel().findAllSync(view.class.Action, { _id: item.action })[0]
|
||||
invokeAction(doc, result, action)
|
||||
} else {
|
||||
dispatch('open', item)
|
||||
}
|
||||
@ -270,7 +273,8 @@
|
||||
closeTooltip()
|
||||
if (item.action) {
|
||||
const doc = item.channel as Channel
|
||||
invokeAction(doc, result, item.action)
|
||||
const action = client.getModel().findAllSync(view.class.Action, { _id: item.action })[0]
|
||||
invokeAction(doc, result, action)
|
||||
} else {
|
||||
dispatch('open', item)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import type { Asset, Metadata, Plugin, Resource } from '@hcengineering/platform'
|
||||
import { IntlString, plugin } from '@hcengineering/platform'
|
||||
import { TemplateField, TemplateFieldCategory } from '@hcengineering/templates'
|
||||
import type { AnyComponent, IconSize, ResolvedLocation } from '@hcengineering/ui'
|
||||
import { FilterMode, ViewAction, Viewlet } from '@hcengineering/view'
|
||||
import { Action, FilterMode, Viewlet } from '@hcengineering/view'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -42,7 +42,7 @@ export interface ChannelProvider extends Doc, UXObject {
|
||||
presenter?: AnyComponent
|
||||
|
||||
// Action to be performed if there is no presenter defined.
|
||||
action?: ViewAction
|
||||
action?: Ref<Action>
|
||||
|
||||
// Integration type
|
||||
integrationType?: Ref<Doc>
|
||||
|
@ -54,6 +54,7 @@
|
||||
"@hcengineering/login": "^0.6.8",
|
||||
"@hcengineering/core": "^0.6.28",
|
||||
"@hcengineering/panel": "^0.6.15",
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/templates": "^0.6.7"
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import attachmentP, { Attachment } from '@hcengineering/attachment'
|
||||
import { AttachmentPresenter } from '@hcengineering/attachment-resources'
|
||||
import contact, { Channel, Contact, getName } from '@hcengineering/contact'
|
||||
@ -129,6 +130,7 @@
|
||||
}
|
||||
)
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
setPlatformStatus(unknownError(err))
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import attachmentP, { Attachment } from '@hcengineering/attachment'
|
||||
import { AttachmentPresenter } from '@hcengineering/attachment-resources'
|
||||
import contact, { Channel, Contact, getName as getContactName } from '@hcengineering/contact'
|
||||
@ -155,6 +156,7 @@
|
||||
}
|
||||
)
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
setPlatformStatus(unknownError(err))
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
"@hcengineering/core": "^0.6.28",
|
||||
"@hcengineering/presentation": "^0.6.2",
|
||||
"@hcengineering/setting": "^0.6.11",
|
||||
"@hcengineering/theme": "^0.6.3"
|
||||
"@hcengineering/theme": "^0.6.3",
|
||||
"@hcengineering/analytics": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -13,24 +13,26 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import login, { type LoginInfo, type Workspace, type WorkspaceLoginInfo } from '@hcengineering/login'
|
||||
import {
|
||||
OK,
|
||||
PlatformError,
|
||||
type Status,
|
||||
getMetadata,
|
||||
setMetadata,
|
||||
unknownError,
|
||||
unknownStatus
|
||||
unknownStatus,
|
||||
type Status,
|
||||
translate
|
||||
} from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import {
|
||||
type Location,
|
||||
fetchMetadataLocalStorage,
|
||||
getCurrentLocation,
|
||||
locationStorageKeyId,
|
||||
navigate,
|
||||
setMetadataLocalStorage,
|
||||
locationStorageKeyId
|
||||
type Location
|
||||
} from '@hcengineering/ui'
|
||||
import { workbenchId } from '@hcengineering/workbench'
|
||||
|
||||
@ -69,9 +71,16 @@ export async function doLogin (email: string, password: string): Promise<[Status
|
||||
})
|
||||
const result = await response.json()
|
||||
console.log('login result', result)
|
||||
if (result.error == null) {
|
||||
Analytics.handleEvent('login')
|
||||
Analytics.setUser(email)
|
||||
} else {
|
||||
await handleStatusError('Login error', result.error)
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
console.log('login error', err)
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -110,8 +119,15 @@ export async function signUp (
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error == null) {
|
||||
Analytics.handleEvent('signup')
|
||||
Analytics.setUser(email)
|
||||
} else {
|
||||
await handleStatusError('Sign up error', result.error)
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -158,8 +174,15 @@ export async function createWorkspace (
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error == null) {
|
||||
Analytics.handleEvent('create workspace')
|
||||
Analytics.setTag('workspace', workspaceName)
|
||||
} else {
|
||||
await handleStatusError('Create workspace error', result.error)
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -262,7 +285,9 @@ export async function getAccount (doNavigate: boolean = true, token?: string): P
|
||||
throw new PlatformError(result.error)
|
||||
}
|
||||
return result.result
|
||||
} catch (err) {}
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
}
|
||||
}
|
||||
|
||||
export async function selectWorkspace (workspace: string): Promise<[Status, WorkspaceLoginInfo | undefined]> {
|
||||
@ -305,8 +330,15 @@ export async function selectWorkspace (workspace: string): Promise<[Status, Work
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error == null) {
|
||||
Analytics.handleEvent('Select workspace')
|
||||
Analytics.setTag('workspace', workspace)
|
||||
} else {
|
||||
await handleStatusError('Select workspace error', result.error)
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -387,7 +419,8 @@ export async function checkJoined (inviteId: string): Promise<[Status, Workspace
|
||||
})
|
||||
const result = await response.json()
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -460,8 +493,15 @@ export async function join (
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error == null) {
|
||||
Analytics.handleEvent('Join')
|
||||
Analytics.setUser(email)
|
||||
} else {
|
||||
await handleStatusError('Join error', result.error)
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -501,8 +541,15 @@ export async function signUpJoin (
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error == null) {
|
||||
Analytics.handleEvent('Signup Join')
|
||||
Analytics.setUser(email)
|
||||
} else {
|
||||
await handleStatusError('Sign up join error', result.error)
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -538,7 +585,9 @@ export async function changePassword (oldPassword: string, password: string): Pr
|
||||
})
|
||||
const resp = await response.json()
|
||||
if (resp.error !== undefined) {
|
||||
throw new PlatformError(resp.error)
|
||||
const err = new PlatformError(resp.error)
|
||||
Analytics.handleError(err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,8 +681,12 @@ export async function requestPassword (email: string): Promise<Status> {
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error != null) {
|
||||
await handleStatusError('Request password error', result.error)
|
||||
}
|
||||
return result.error ?? OK
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return unknownError(err)
|
||||
}
|
||||
}
|
||||
@ -666,8 +719,14 @@ export async function confirm (email: string): Promise<[Status, LoginInfo | unde
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error != null) {
|
||||
await handleStatusError('Confirm email error', result.error)
|
||||
} else {
|
||||
Analytics.handleEvent('Confirm email')
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
@ -694,8 +753,19 @@ export async function restorePassword (token: string, password: string): Promise
|
||||
body: JSON.stringify(request)
|
||||
})
|
||||
const result = await response.json()
|
||||
if (result.error != null) {
|
||||
await handleStatusError('Restore password error', result.error)
|
||||
} else {
|
||||
Analytics.handleEvent('Restore password')
|
||||
}
|
||||
return [result.error ?? OK, result.result]
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
return [unknownError(err), undefined]
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStatusError (message: string, err: Status): Promise<void> {
|
||||
const label = await translate(err.code, err.params, 'en')
|
||||
Analytics.handleError(new Error(`${message}: ${label}`))
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
"svelte-eslint-parser": "^0.33.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/activity": "^0.6.0",
|
||||
"@hcengineering/attachment": "^0.6.9",
|
||||
"@hcengineering/attachment-resources": "^0.6.0",
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import attachment from '@hcengineering/attachment'
|
||||
import { deleteFile } from '@hcengineering/attachment-resources/src/utils'
|
||||
import contact, { Channel, ChannelProvider, combineName, findContacts, Person } from '@hcengineering/contact'
|
||||
@ -437,6 +438,7 @@
|
||||
}
|
||||
object.skills = [...object.skills, ...newSkills]
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
@ -464,6 +466,7 @@
|
||||
|
||||
await recognize(file)
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
setPlatformStatus(unknownError(err))
|
||||
} finally {
|
||||
loading = false
|
||||
|
@ -38,6 +38,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/platform": "^0.6.9",
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/core": "^0.6.28",
|
||||
"svelte": "^4.2.5",
|
||||
"@hcengineering/setting": "^0.6.11",
|
||||
|
@ -13,14 +13,14 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import setting from '@hcengineering/setting'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import { Button, EditBox, Icon, Label, Header, Breadcrumb } from '@hcengineering/ui'
|
||||
import login from '@hcengineering/login'
|
||||
import Error from './icons/Error.svelte'
|
||||
import plugin from '../plugin'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import presentation from '@hcengineering/presentation'
|
||||
import setting from '@hcengineering/setting'
|
||||
import { Breadcrumb, Button, EditBox, Header, Icon, Label } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import plugin from '../plugin'
|
||||
import Error from './icons/Error.svelte'
|
||||
|
||||
export let visibleNav: boolean = true
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
"dependencies": {
|
||||
"@hcengineering/activity": "^0.6.0",
|
||||
"@hcengineering/activity-resources": "^0.6.1",
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/attachment": "^0.6.9",
|
||||
"@hcengineering/attachment-resources": "^0.6.0",
|
||||
"@hcengineering/calendar": "^0.6.17",
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { Attachment } from '@hcengineering/attachment'
|
||||
import { AttachmentPresenter, AttachmentStyledBox } from '@hcengineering/attachment-resources'
|
||||
import chunter from '@hcengineering/chunter'
|
||||
@ -514,6 +515,7 @@
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
await doneOp() // Complete in case of error
|
||||
Analytics.handleError(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import core, {
|
||||
ClassifierKind,
|
||||
DOMAIN_CONFIGURATION,
|
||||
@ -318,6 +319,7 @@ async function deleteProject (project: Project | undefined): Promise<void> {
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
Analytics.handleError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { type Contact } from '@hcengineering/contact'
|
||||
import core, {
|
||||
SortingOrder,
|
||||
@ -402,13 +403,14 @@ export async function moveIssuesToAnotherMilestone (
|
||||
await Promise.all(awaitedUpdates)
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
console.error(
|
||||
`Error happened while moving issues between milestones from ${oldMilestone.label} to ${
|
||||
newMilestone?.label ?? 'No Milestone'
|
||||
}: `,
|
||||
error
|
||||
)
|
||||
Analytics.handleError(error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
"@hcengineering/presentation": "^0.6.2",
|
||||
"@hcengineering/setting": "^0.6.11",
|
||||
"@hcengineering/text-editor": "^0.6.0",
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/query": "^0.6.8",
|
||||
"fast-equals": "^2.0.3"
|
||||
}
|
||||
|
@ -14,15 +14,16 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import core, {
|
||||
AccountRole,
|
||||
getCurrentAccount,
|
||||
matchQuery,
|
||||
type Class,
|
||||
type Client,
|
||||
type Doc,
|
||||
type Ref,
|
||||
type WithLookup,
|
||||
getCurrentAccount,
|
||||
matchQuery
|
||||
type WithLookup
|
||||
} from '@hcengineering/core'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
@ -30,7 +31,6 @@ import {
|
||||
type Action,
|
||||
type ActionGroup,
|
||||
type ActionIgnore,
|
||||
type ViewAction,
|
||||
type ViewActionInput,
|
||||
type ViewContextType
|
||||
} from '@hcengineering/view'
|
||||
@ -115,11 +115,15 @@ export async function filterAvailableActions (
|
||||
export async function invokeAction (
|
||||
object: Doc | Doc[],
|
||||
evt: Event,
|
||||
action: ViewAction,
|
||||
action: Action,
|
||||
props?: Record<string, any>
|
||||
): Promise<void> {
|
||||
const impl = await getResource(action)
|
||||
await impl(Array.isArray(object) && object.length === 1 ? object[0] : object, evt, props)
|
||||
const impl = await getResource(action.action)
|
||||
Analytics.handleEvent(action._id)
|
||||
await impl(Array.isArray(object) && object.length === 1 ? object[0] : object, evt, {
|
||||
...action.actionProps,
|
||||
...props
|
||||
})
|
||||
}
|
||||
|
||||
export async function getContextActions (
|
||||
|
@ -63,7 +63,7 @@
|
||||
on:click={async (event) => {
|
||||
if (action !== null) {
|
||||
isBeingInvoked = true
|
||||
await invokeAction(object, event, action.action, action.actionProps)
|
||||
await invokeAction(object, event, action)
|
||||
isBeingInvoked = false
|
||||
}
|
||||
}}
|
||||
|
@ -13,9 +13,10 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import core, { Doc, Hierarchy, Ref, TxRemoveDoc } from '@hcengineering/core'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import { addTxListener, getClient, contextStore } from '@hcengineering/presentation'
|
||||
import { addTxListener, contextStore, getClient } from '@hcengineering/presentation'
|
||||
import { AnyComponent, Component } from '@hcengineering/ui'
|
||||
import { Action, ViewContextType } from '@hcengineering/view'
|
||||
import { fly } from 'svelte/transition'
|
||||
@ -183,6 +184,7 @@
|
||||
sequences = []
|
||||
lastKey = undefined
|
||||
delayedAction = undefined
|
||||
Analytics.handleEvent(a._id)
|
||||
await action(selectionDocs, evt, a.actionProps)
|
||||
return
|
||||
}
|
||||
@ -201,10 +203,12 @@
|
||||
lastKey = undefined
|
||||
sequences = []
|
||||
delayedAction = undefined
|
||||
Analytics.handleEvent(a._id)
|
||||
await action(selectionDocs, evt, a.actionProps)
|
||||
return
|
||||
} else {
|
||||
delayedAction = async () => {
|
||||
Analytics.handleEvent(a._id)
|
||||
await action(selectionDocs, evt, a.actionProps)
|
||||
}
|
||||
found = true
|
||||
|
@ -57,7 +57,7 @@
|
||||
inline: a.inline,
|
||||
group: a.context.group ?? 'other',
|
||||
action: async (_: any, evt: Event) => {
|
||||
invokeAction(object, evt, a.action, a.actionProps)
|
||||
invokeAction(object, evt, a)
|
||||
},
|
||||
component: a.actionPopup,
|
||||
props: { ...a.actionProps, value: object }
|
||||
|
@ -113,7 +113,7 @@ import {
|
||||
|
||||
import { IndexedDocumentPreview } from '@hcengineering/presentation'
|
||||
import { showEmptyGroups } from './viewOptions'
|
||||
import { AggregationMiddleware } from './middleware'
|
||||
import { AggregationMiddleware, AnalyticsMiddleware } from './middleware'
|
||||
export { getActions, invokeAction, getContextActions } from './actions'
|
||||
export { default as ActionButton } from './components/ActionButton.svelte'
|
||||
export { default as ActionHandler } from './components/ActionHandler.svelte'
|
||||
@ -284,6 +284,8 @@ export default async (): Promise<Resources> => ({
|
||||
FilterDateNotSpecified: dateNotSpecified,
|
||||
FilterDateCustom: dateCustom,
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
CreateDocMiddleware: AggregationMiddleware.create
|
||||
CreateDocMiddleware: AggregationMiddleware.create,
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
AnalyticsMiddleware: AnalyticsMiddleware.create
|
||||
}
|
||||
})
|
||||
|
@ -1,22 +1,26 @@
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import core, {
|
||||
type Doc,
|
||||
type Ref,
|
||||
Hierarchy,
|
||||
type TxApplyIf,
|
||||
type TxCUD,
|
||||
TxProcessor,
|
||||
generateId,
|
||||
type AnyAttribute,
|
||||
type Attribute,
|
||||
type Class,
|
||||
type Client,
|
||||
type Doc,
|
||||
type DocumentQuery,
|
||||
type FindOptions,
|
||||
type Client,
|
||||
type Tx,
|
||||
type TxResult,
|
||||
type FindResult,
|
||||
type Attribute,
|
||||
Hierarchy,
|
||||
type Ref,
|
||||
type RefTo,
|
||||
generateId
|
||||
type Tx,
|
||||
type TxResult
|
||||
} from '@hcengineering/core'
|
||||
import { getResource, translate } from '@hcengineering/platform'
|
||||
import { BasePresentationMiddleware, type PresentationMiddleware } from '@hcengineering/presentation'
|
||||
import view, { type AggregationManager } from '@hcengineering/view'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -233,8 +237,57 @@ export class AggregationMiddleware extends BasePresentationMiddleware implements
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export class AnalyticsMiddleware extends BasePresentationMiddleware implements PresentationMiddleware {
|
||||
private constructor (client: Client, next?: PresentationMiddleware) {
|
||||
super(client, next)
|
||||
}
|
||||
|
||||
async notifyTx (tx: Tx): Promise<void> {
|
||||
await this.provideNotifyTx(tx)
|
||||
}
|
||||
|
||||
async close (): Promise<void> {
|
||||
await this.provideClose()
|
||||
}
|
||||
|
||||
static create (client: Client, next?: PresentationMiddleware): AnalyticsMiddleware {
|
||||
return new AnalyticsMiddleware(client, next)
|
||||
}
|
||||
|
||||
async tx (tx: Tx): Promise<TxResult> {
|
||||
void this.handleTx(tx)
|
||||
return await this.provideTx(tx)
|
||||
}
|
||||
|
||||
private async handleTx (tx: Tx): Promise<void> {
|
||||
const etx = TxProcessor.extractTx(tx)
|
||||
if (etx._class === core.class.TxApplyIf) {
|
||||
const applyIf = etx as TxApplyIf
|
||||
applyIf.txes.forEach((it) => {
|
||||
void this.handleTx(it)
|
||||
})
|
||||
}
|
||||
if (this.client.getHierarchy().isDerived(etx._class, core.class.TxCUD)) {
|
||||
const cud = etx as TxCUD<Doc>
|
||||
const _class = this.client.getHierarchy().getClass(cud.objectClass)
|
||||
const label = await translate(_class.label, {}, 'en')
|
||||
if (cud._class === core.class.TxCreateDoc) {
|
||||
Analytics.handleEvent(`Create ${label}`)
|
||||
} else if (cud._class === core.class.TxUpdateDoc || cud._class === core.class.TxMixin) {
|
||||
Analytics.handleEvent(`Update ${label}`)
|
||||
} else if (cud._class === core.class.TxRemoveDoc) {
|
||||
Analytics.handleEvent(`Delete ${label}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ export default mergeIds(viewId, view, {
|
||||
ToViewCommands: '' as IntlString
|
||||
},
|
||||
function: {
|
||||
CreateDocMiddleware: '' as Resource<PresentationMiddlewareCreator>
|
||||
CreateDocMiddleware: '' as Resource<PresentationMiddlewareCreator>,
|
||||
AnalyticsMiddleware: '' as Resource<PresentationMiddlewareCreator>
|
||||
}
|
||||
})
|
||||
|
@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import core, {
|
||||
AccountRole,
|
||||
type FindOptions,
|
||||
@ -364,6 +365,7 @@ export async function buildModel (options: BuildModelOptions): Promise<Attribute
|
||||
return undefined
|
||||
}
|
||||
const stringKey = key.label ?? key.key
|
||||
Analytics.handleError(err)
|
||||
console.error('Failed to find presenter for', key, err)
|
||||
const errorPresenter: AttributeModel = {
|
||||
key: '',
|
||||
|
@ -54,6 +54,7 @@
|
||||
"@hcengineering/support": "^0.6.1",
|
||||
"@hcengineering/support-resources": "^0.6.0",
|
||||
"@hcengineering/view-resources": "^0.6.0",
|
||||
"fast-copy": "~3.0.1"
|
||||
"fast-copy": "~3.0.1",
|
||||
"@hcengineering/analytics": "^0.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import contact, { Employee, PersonAccount } from '@hcengineering/contact'
|
||||
import core, { AccountRole, Class, Doc, Ref, Space, getCurrentAccount } from '@hcengineering/core'
|
||||
import login from '@hcengineering/login'
|
||||
@ -220,6 +221,7 @@
|
||||
try {
|
||||
return await titleProvider(client, _id as Ref<Doc>)
|
||||
} catch (err: any) {
|
||||
Analytics.handleError(err)
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import client from '@hcengineering/client'
|
||||
import core, {
|
||||
ClientConnectEvent,
|
||||
@ -138,6 +139,8 @@ export async function connect (title: string): Promise<Client | undefined> {
|
||||
|
||||
const me = await _client?.getAccount()
|
||||
if (me !== undefined) {
|
||||
Analytics.setUser(me.email)
|
||||
Analytics.setTag('workspace', ws)
|
||||
console.log('login: employee account', me)
|
||||
setCurrentAccount(me)
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user