2022-02-07 09:03:14 +00:00
|
|
|
//
|
|
|
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
2022-04-29 05:27:17 +00:00
|
|
|
// Copyright © 2022 Hardcore Engineering Inc.
|
2022-02-07 09:03:14 +00:00
|
|
|
//
|
|
|
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License. You may
|
|
|
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
//
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
//
|
|
|
|
|
2023-03-15 14:06:03 +00:00
|
|
|
import {
|
|
|
|
ChannelProvider,
|
|
|
|
Contact,
|
|
|
|
contactId,
|
|
|
|
Employee,
|
|
|
|
EmployeeAccount,
|
|
|
|
formatName,
|
|
|
|
getName
|
|
|
|
} from '@hcengineering/contact'
|
|
|
|
import {
|
|
|
|
Doc,
|
|
|
|
getCurrentAccount,
|
|
|
|
matchQuery,
|
|
|
|
ObjQueryType,
|
|
|
|
Ref,
|
|
|
|
SortingOrder,
|
|
|
|
Timestamp,
|
|
|
|
toIdMap
|
|
|
|
} from '@hcengineering/core'
|
2023-01-14 10:54:54 +00:00
|
|
|
import { createQuery, getClient } from '@hcengineering/presentation'
|
2023-02-21 06:40:03 +00:00
|
|
|
import { TemplateDataProvider } from '@hcengineering/templates'
|
2023-03-15 14:06:03 +00:00
|
|
|
import { getPanelURI, Location } from '@hcengineering/ui'
|
2023-02-20 10:03:35 +00:00
|
|
|
import view, { Filter } from '@hcengineering/view'
|
|
|
|
import { FilterQuery } from '@hcengineering/view-resources'
|
2023-02-21 06:40:03 +00:00
|
|
|
import contact from './plugin'
|
2022-02-07 09:03:14 +00:00
|
|
|
|
|
|
|
const client = getClient()
|
2022-04-29 05:27:17 +00:00
|
|
|
const channelProviders = client.findAll(contact.class.ChannelProvider, {})
|
2022-02-07 09:03:14 +00:00
|
|
|
|
|
|
|
export async function getChannelProviders (): Promise<Map<Ref<ChannelProvider>, ChannelProvider>> {
|
2022-04-29 05:27:17 +00:00
|
|
|
const cp = await channelProviders
|
2022-02-07 09:03:14 +00:00
|
|
|
const map = new Map<Ref<ChannelProvider>, ChannelProvider>()
|
|
|
|
for (const provider of cp) {
|
|
|
|
map.set(provider._id, provider)
|
|
|
|
}
|
|
|
|
return map
|
|
|
|
}
|
2022-05-12 07:05:26 +00:00
|
|
|
|
|
|
|
export function formatDate (dueDateMs: Timestamp): string {
|
|
|
|
return new Date(dueDateMs).toLocaleString('default', {
|
|
|
|
month: 'short',
|
|
|
|
day: 'numeric',
|
|
|
|
hour: '2-digit',
|
|
|
|
minute: '2-digit'
|
|
|
|
})
|
|
|
|
}
|
2023-01-14 10:54:54 +00:00
|
|
|
|
|
|
|
export async function employeeSort (value: Array<Ref<Employee>>): Promise<Array<Ref<Employee>>> {
|
|
|
|
return await new Promise((resolve) => {
|
|
|
|
const query = createQuery(true)
|
|
|
|
query.query(contact.class.Employee, { _id: { $in: value } }, (res) => {
|
2023-01-18 09:57:13 +00:00
|
|
|
const employees = toIdMap(res)
|
2023-01-14 10:54:54 +00:00
|
|
|
value.sort((a, b) => {
|
|
|
|
const employeeId1 = a as Ref<Employee> | null | undefined
|
|
|
|
const employeeId2 = b as Ref<Employee> | null | undefined
|
|
|
|
|
|
|
|
if (employeeId1 == null && employeeId2 != null) {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if (employeeId1 != null && employeeId2 == null) {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
|
|
|
if (employeeId1 != null && employeeId2 != null) {
|
2023-03-09 09:05:42 +00:00
|
|
|
const employee1 = employees.get(employeeId1)
|
|
|
|
const employee2 = employees.get(employeeId2)
|
|
|
|
const name1 = employee1 != null ? getName(employee1) : ''
|
|
|
|
const name2 = employee2 != null ? getName(employee2) : ''
|
2023-01-14 10:54:54 +00:00
|
|
|
|
|
|
|
return name1.localeCompare(name2)
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
resolve(value)
|
|
|
|
query.unsubscribe()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
2023-02-20 10:03:35 +00:00
|
|
|
|
|
|
|
export async function filterChannelInResult (filter: Filter, onUpdate: () => void): Promise<ObjQueryType<any>> {
|
|
|
|
const result = await getRefs(filter, onUpdate)
|
|
|
|
return { $in: result }
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function filterChannelNinResult (filter: Filter, onUpdate: () => void): Promise<ObjQueryType<any>> {
|
|
|
|
const result = await getRefs(filter, onUpdate)
|
|
|
|
return { $nin: result }
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function getRefs (filter: Filter, onUpdate: () => void): Promise<Array<Ref<Doc>>> {
|
|
|
|
const lq = FilterQuery.getLiveQuery(filter.index)
|
|
|
|
const client = getClient()
|
|
|
|
const mode = await client.findOne(view.class.FilterMode, { _id: filter.mode })
|
|
|
|
if (mode === undefined) return []
|
|
|
|
const promise = new Promise<Array<Ref<Doc>>>((resolve, reject) => {
|
|
|
|
const refresh = lq.query(
|
|
|
|
contact.class.Channel,
|
|
|
|
{
|
|
|
|
provider: { $in: filter.value }
|
|
|
|
},
|
|
|
|
(refs) => {
|
|
|
|
const result = Array.from(new Set(refs.map((p) => p.attachedTo)))
|
|
|
|
FilterQuery.results.set(filter.index, result)
|
|
|
|
resolve(result)
|
|
|
|
onUpdate()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
if (!refresh) {
|
|
|
|
resolve(FilterQuery.results.get(filter.index) ?? [])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
return await promise
|
|
|
|
}
|
2023-02-21 06:40:03 +00:00
|
|
|
|
|
|
|
export async function getCurrentEmployeeName (): Promise<string> {
|
|
|
|
const me = getCurrentAccount() as EmployeeAccount
|
|
|
|
return formatName(me.name)
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function getCurrentEmployeeEmail (): Promise<string> {
|
|
|
|
const me = getCurrentAccount() as EmployeeAccount
|
|
|
|
return me.email
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function getContactName (provider: TemplateDataProvider): Promise<string | undefined> {
|
2023-02-28 18:36:00 +00:00
|
|
|
const value = provider.get(contact.class.Contact) as Contact
|
2023-02-21 06:40:03 +00:00
|
|
|
if (value === undefined) return
|
|
|
|
const client = getClient()
|
|
|
|
const hierarchy = client.getHierarchy()
|
|
|
|
if (hierarchy.isDerived(value._class, contact.class.Person)) {
|
2023-03-09 09:05:42 +00:00
|
|
|
return getName(value)
|
2023-02-21 06:40:03 +00:00
|
|
|
} else {
|
|
|
|
return value.name
|
|
|
|
}
|
|
|
|
}
|
2023-03-15 14:06:03 +00:00
|
|
|
|
|
|
|
export async function getContactLink (doc: Doc): Promise<string> {
|
|
|
|
const client = getClient()
|
|
|
|
const hierarchy = client.getHierarchy()
|
|
|
|
let clazz = hierarchy.getClass(doc._class)
|
|
|
|
let label = clazz.shortLabel
|
|
|
|
while (label === undefined && clazz.extends !== undefined) {
|
|
|
|
clazz = hierarchy.getClass(clazz.extends)
|
|
|
|
label = clazz.shortLabel
|
|
|
|
}
|
|
|
|
label = label ?? 'CONT'
|
|
|
|
let length = 5
|
|
|
|
let id = doc._id.slice(-length)
|
|
|
|
const contacts = await client.findAll(clazz._id, {}, { projection: { _id: 1 } })
|
|
|
|
let res = matchQuery(contacts, { _id: { $like: `@${id}` } }, clazz._id, hierarchy)
|
|
|
|
while (res.length > 1) {
|
|
|
|
length++
|
|
|
|
id = doc._id.slice(-length)
|
|
|
|
res = matchQuery(contacts, { _id: { $like: `@${id}` } }, clazz._id, hierarchy)
|
|
|
|
}
|
|
|
|
|
|
|
|
return `${contactId}|${label}-${id}`
|
|
|
|
}
|
|
|
|
|
|
|
|
function isShortId (shortLink: string): boolean {
|
|
|
|
return /^\w+-\w+$/.test(shortLink)
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function resolveLocation (loc: Location): Promise<Location | undefined> {
|
|
|
|
const split = loc.fragment?.split('|') ?? []
|
|
|
|
if (split[0] !== contactId) {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
const shortLink = split[1]
|
|
|
|
|
|
|
|
// shortlink
|
|
|
|
if (isShortId(shortLink)) {
|
|
|
|
return await generateLocation(loc, shortLink)
|
|
|
|
}
|
|
|
|
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
async function generateLocation (loc: Location, shortLink: string): Promise<Location | undefined> {
|
|
|
|
const tokens = shortLink.split('-')
|
|
|
|
if (tokens.length < 2) {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
const classLabel = tokens[0]
|
|
|
|
const lastId = tokens[1]
|
|
|
|
const client = getClient()
|
|
|
|
const hierarchy = client.getHierarchy()
|
|
|
|
const classes = hierarchy.getDescendants(contact.class.Contact)
|
|
|
|
let _class = contact.class.Contact
|
|
|
|
for (const clazz of classes) {
|
|
|
|
if (hierarchy.getClass(clazz).shortLabel === classLabel) {
|
|
|
|
_class = clazz
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const doc = await client.findOne(_class, { _id: { $like: `%${lastId}` } }, { sort: { _id: SortingOrder.Descending } })
|
|
|
|
if (doc === undefined) {
|
|
|
|
console.error(`Could not find contact ${lastId}.`)
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
const appComponent = loc.path[0] ?? ''
|
|
|
|
const workspace = loc.path[1] ?? ''
|
|
|
|
return {
|
2023-03-16 03:44:21 +00:00
|
|
|
path: [appComponent, workspace],
|
2023-03-15 14:06:03 +00:00
|
|
|
fragment: getPanelURI(view.component.EditDoc, doc._id, doc._class, 'content')
|
|
|
|
}
|
|
|
|
}
|