mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-23 10:05:01 +02:00
TSK-833 Доработка Таблицы Vacations TSK-817 Click on Employee is broken, it should open Edit Contact TSK-805 Открывать задачу в новой вкладке при клике колесиком TSK-794 Прикрепление ссылки на вакансию/аппликейшн в чате (#2734)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
@@ -13,24 +13,42 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { Ref, Class, Doc } from '@hcengineering/core'
|
||||
import type { Asset } from '@hcengineering/platform'
|
||||
import { Icon } from '@hcengineering/ui'
|
||||
import { FilterButton } from '@hcengineering/view-resources'
|
||||
import type { Class, Doc, Ref, Space } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { AnyComponent, Icon } from '@hcengineering/ui'
|
||||
import view from '@hcengineering/view'
|
||||
import { DocNavLink, FilterButton } from '@hcengineering/view-resources'
|
||||
import plugin from '../plugin'
|
||||
import { classIcon } from '../utils'
|
||||
|
||||
export let icon: Asset | undefined
|
||||
export let label: string
|
||||
export let description: string | undefined
|
||||
export let space: Space
|
||||
export let _class: Ref<Class<Doc>> | undefined = undefined
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
$: description = space.description
|
||||
|
||||
function getEditor (_class: Ref<Class<Doc>>): AnyComponent | undefined {
|
||||
const clazz = hierarchy.getClass(_class)
|
||||
const editorMixin = hierarchy.as(clazz, view.mixin.ObjectEditor)
|
||||
if (editorMixin?.editor == null && clazz.extends != null) return getEditor(clazz.extends)
|
||||
return editorMixin.editor
|
||||
}
|
||||
|
||||
const icon = classIcon(client, space._class)
|
||||
const editor = getEditor(space._class) ?? plugin.component.SpacePanel
|
||||
</script>
|
||||
|
||||
<div class="ac-header__wrap-description">
|
||||
<div class="flex-row-center clear-mins">
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="ac-header__wrap-title" on:click>
|
||||
{#if icon}<div class="ac-header__icon"><Icon {icon} size={'small'} /></div>{/if}
|
||||
<span class="ac-header__title">{label}</span>
|
||||
</div>
|
||||
<DocNavLink object={space} component={editor}>
|
||||
<div class="ac-header__wrap-title">
|
||||
{#if icon}<div class="ac-header__icon"><Icon {icon} size={'small'} /></div>{/if}
|
||||
<span class="ac-header__title">{space.name}</span>
|
||||
</div>
|
||||
</DocNavLink>
|
||||
{#if _class}<div class="ml-4"><FilterButton {_class} /></div>{/if}
|
||||
</div>
|
||||
{#if description}
|
||||
@@ -47,7 +65,6 @@
|
||||
|
||||
<style lang="scss">
|
||||
.ac-header__wrap-title:hover {
|
||||
cursor: pointer;
|
||||
span {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@@ -16,22 +16,19 @@
|
||||
import type { Class, Doc, Ref, Space } from '@hcengineering/core'
|
||||
import core, { WithLookup } from '@hcengineering/core'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import presentation, { createQuery } from '@hcengineering/presentation'
|
||||
import {
|
||||
AnyComponent,
|
||||
Button,
|
||||
deviceOptionsStore as deviceInfo,
|
||||
IconAdd,
|
||||
SearchEdit,
|
||||
showPanel,
|
||||
showPopup,
|
||||
TabList
|
||||
} from '@hcengineering/ui'
|
||||
import view, { Viewlet, ViewOptions } from '@hcengineering/view'
|
||||
import { Viewlet, ViewOptions } from '@hcengineering/view'
|
||||
import { getActiveViewletId, setActiveViewletId, ViewletSettingButton } from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import plugin from '../plugin'
|
||||
import { classIcon } from '../utils'
|
||||
import Header from './Header.svelte'
|
||||
|
||||
export let spaceId: Ref<Space> | undefined
|
||||
@@ -43,8 +40,6 @@
|
||||
export let _class: Ref<Class<Doc>> | undefined = undefined
|
||||
export let viewOptions: ViewOptions
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const query = createQuery()
|
||||
let space: Space | undefined
|
||||
const dispatch = createEventDispatcher()
|
||||
@@ -66,19 +61,6 @@
|
||||
dispatch('search', '')
|
||||
}
|
||||
|
||||
async function getEditor (_class: Ref<Class<Doc>>): Promise<AnyComponent | undefined> {
|
||||
const clazz = hierarchy.getClass(_class)
|
||||
const editorMixin = hierarchy.as(clazz, view.mixin.ObjectEditor)
|
||||
if (editorMixin?.editor == null && clazz.extends != null) return getEditor(clazz.extends)
|
||||
return editorMixin.editor
|
||||
}
|
||||
|
||||
async function onSpaceEdit (): Promise<void> {
|
||||
if (space === undefined) return
|
||||
const editor = await getEditor(space._class)
|
||||
showPanel(editor ?? plugin.component.SpacePanel, space._id, space._class, 'content')
|
||||
}
|
||||
|
||||
function updateViewlets (viewlets: WithLookup<Viewlet>[]) {
|
||||
const _id = getActiveViewletId()
|
||||
const index = viewlets.findIndex((p) => p._id === (viewlet?._id ?? _id))
|
||||
@@ -99,13 +81,7 @@
|
||||
<div class="ac-header withSettings" class:full={!twoRows} class:mini={twoRows}>
|
||||
{#if space}
|
||||
<div class:ac-header-full={!twoRows} class:flex-stretch={twoRows}>
|
||||
<Header
|
||||
icon={classIcon(client, space._class)}
|
||||
label={space.name}
|
||||
description={space.description}
|
||||
{_class}
|
||||
on:click={onSpaceEdit}
|
||||
/>
|
||||
<Header {space} {_class} />
|
||||
<SearchEdit
|
||||
bind:value={search}
|
||||
on:change={() => {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
import calendar from '@hcengineering/calendar'
|
||||
import contact, { Employee, EmployeeAccount } from '@hcengineering/contact'
|
||||
import core, { Class, Client, Doc, getCurrentAccount, Ref, setCurrentAccount, Space } from '@hcengineering/core'
|
||||
import { getWorkspaces, Workspace } from '@hcengineering/login-resources'
|
||||
import notification, { NotificationStatus } from '@hcengineering/notification'
|
||||
import { BrowserNotificatator, NotificationClientImpl } from '@hcengineering/notification-resources'
|
||||
import { getMetadata, getResource, IntlString } from '@hcengineering/platform'
|
||||
@@ -25,6 +24,7 @@
|
||||
import {
|
||||
AnyComponent,
|
||||
areLocationsEqual,
|
||||
closePanel,
|
||||
closePopup,
|
||||
closeTooltip,
|
||||
Component,
|
||||
@@ -35,8 +35,10 @@
|
||||
location,
|
||||
Location,
|
||||
navigate,
|
||||
openPanel,
|
||||
PanelInstance,
|
||||
Popup,
|
||||
PopupAlignment,
|
||||
PopupPosAlignment,
|
||||
resizeObserver,
|
||||
showPopup,
|
||||
@@ -48,7 +50,6 @@
|
||||
import { getContext, onDestroy, onMount, tick } from 'svelte'
|
||||
import { subscribeMobile } from '../mobile'
|
||||
import workbench from '../plugin'
|
||||
import { workspacesStore } from '../utils'
|
||||
import AccountPopup from './AccountPopup.svelte'
|
||||
import AppItem from './AppItem.svelte'
|
||||
import Applications from './Applications.svelte'
|
||||
@@ -71,6 +72,7 @@
|
||||
let currentSpecial: string | undefined
|
||||
let specialComponent: SpecialNavModel | undefined
|
||||
let asideId: string | undefined
|
||||
let currentFragment: string | undefined = ''
|
||||
|
||||
let currentApplication: Application | undefined
|
||||
let navigatorModel: NavigatorModel | undefined
|
||||
@@ -78,19 +80,13 @@
|
||||
let createItemDialog: AnyComponent | undefined
|
||||
let createItemLabel: IntlString | undefined
|
||||
|
||||
let apps: Application[] = []
|
||||
migrateViewOpttions()
|
||||
|
||||
const excludedApps = getMetadata(workbench.metadata.ExcludedApplications) ?? []
|
||||
|
||||
const query = createQuery()
|
||||
$: query.query(workbench.class.Application, { hidden: false, _id: { $nin: excludedApps } }, (result) => {
|
||||
apps = result
|
||||
})
|
||||
|
||||
getWorkspaces().then((ws: Workspace[]) => {
|
||||
$workspacesStore = ws
|
||||
})
|
||||
let apps: Application[] | Promise<Application[]> = client
|
||||
.findAll(workbench.class.Application, { hidden: false, _id: { $nin: excludedApps } })
|
||||
.then((res) => (apps = res))
|
||||
|
||||
let panelInstance: PanelInstance
|
||||
|
||||
@@ -197,10 +193,39 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveShortLink (loc: Location): Promise<Location | undefined> {
|
||||
let locationResolver = currentApplication?.locationResolver
|
||||
if (loc.fragment !== undefined && loc.fragment.trim().length > 0) {
|
||||
const split = loc.fragment.split('|')
|
||||
if (apps instanceof Promise) {
|
||||
apps = await apps
|
||||
}
|
||||
const app = apps.find((p) => p.alias === split[0])
|
||||
if (app?.locationResolver) {
|
||||
locationResolver = app?.locationResolver
|
||||
}
|
||||
}
|
||||
if (locationResolver) {
|
||||
const resolver = await getResource(locationResolver)
|
||||
return await resolver?.(loc)
|
||||
}
|
||||
}
|
||||
|
||||
async function syncLoc (loc: Location): Promise<void> {
|
||||
const app = loc.path.length > 2 ? loc.path[2] : undefined
|
||||
const space = loc.path.length > 3 ? (loc.path[3] as Ref<Space>) : undefined
|
||||
const special = loc.path.length > 4 ? loc.path[4] : undefined
|
||||
let app = loc.path[2]
|
||||
let space = loc.path[3] as Ref<Space>
|
||||
let special = loc.path[4]
|
||||
let fragment = loc.fragment
|
||||
|
||||
// resolve short links
|
||||
const resolvedLocation = await resolveShortLink(loc)
|
||||
if (resolvedLocation && !areLocationsEqual(loc, resolvedLocation)) {
|
||||
loc.path[2] = app = resolvedLocation.path[2] ?? app
|
||||
loc.path[3] = space = (resolvedLocation.path[3] as Ref<Space>) ?? space
|
||||
loc.path[4] = special = resolvedLocation.path[4] ?? special
|
||||
loc.fragment = fragment = resolvedLocation.fragment ?? fragment
|
||||
navigate(resolvedLocation, false)
|
||||
}
|
||||
|
||||
if (currentAppAlias !== app) {
|
||||
clear(1)
|
||||
@@ -209,17 +234,6 @@
|
||||
navigatorModel = currentApplication?.navigatorModel
|
||||
}
|
||||
|
||||
// resolve short links
|
||||
if (currentApplication?.locationResolver) {
|
||||
const resolver = await getResource(currentApplication.locationResolver)
|
||||
const resolvedLocation = await resolver?.(loc)
|
||||
if (resolvedLocation && !areLocationsEqual(loc, resolvedLocation)) {
|
||||
// make sure not to go into infinite loop here
|
||||
navigate(resolvedLocation)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (space === undefined) {
|
||||
const last = localStorage.getItem(`platform_last_loc_${app}`)
|
||||
if (last !== null) {
|
||||
@@ -252,6 +266,26 @@
|
||||
if (app !== undefined) {
|
||||
localStorage.setItem(`platform_last_loc_${app}`, JSON.stringify(loc))
|
||||
}
|
||||
if (fragment !== currentFragment) {
|
||||
currentFragment = fragment
|
||||
if (fragment !== undefined && fragment.trim().length > 0) {
|
||||
const props = decodeURIComponent(fragment).split('|')
|
||||
|
||||
if (props.length >= 3) {
|
||||
openPanel(
|
||||
props[0] as AnyComponent,
|
||||
props[1],
|
||||
props[2],
|
||||
(props[3] ?? undefined) as PopupAlignment,
|
||||
(props[4] ?? undefined) as AnyComponent
|
||||
)
|
||||
} else {
|
||||
closePanel(false)
|
||||
}
|
||||
} else {
|
||||
closePanel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clear (level: number): void {
|
||||
@@ -403,6 +437,14 @@
|
||||
)())
|
||||
)
|
||||
}
|
||||
|
||||
function getApps (apps: Application[] | Promise<Application[]>): Application[] {
|
||||
if (apps instanceof Promise) {
|
||||
return []
|
||||
} else {
|
||||
return apps
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if employee?.active === true}
|
||||
@@ -449,7 +491,12 @@
|
||||
<Settings size={'small'} />
|
||||
</div>
|
||||
</div>
|
||||
<Applications {apps} active={currentApplication?._id} direction={appsDirection} bind:shown={shownMenu} />
|
||||
<Applications
|
||||
apps={getApps(apps)}
|
||||
active={currentApplication?._id}
|
||||
direction={appsDirection}
|
||||
bind:shown={shownMenu}
|
||||
/>
|
||||
<div class="info-box {appsDirection}" class:vertical-mobile={appsDirection === 'vertical' && appsMini}>
|
||||
<AppItem
|
||||
icon={request.icon.Requests}
|
||||
|
||||
Reference in New Issue
Block a user