mirror of
https://github.com/hcengineering/platform.git
synced 2025-01-08 21:27:45 +03:00
Update window title (#2138)
Signed-off-by: Dvinyanin Alexandr <dvinyanin.alexandr@gmail.com>
This commit is contained in:
parent
32d2b6ed69
commit
6c3070c85d
@ -409,6 +409,10 @@ export function createModel (builder: Builder): void {
|
||||
presenter: tracker.component.IssuePreview
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.Issue, core.class.Class, view.mixin.ObjectTitle, {
|
||||
titleProvider: tracker.function.getIssueTitle
|
||||
})
|
||||
|
||||
builder.mixin(tracker.class.TypeIssuePriority, core.class.Class, view.mixin.AttributePresenter, {
|
||||
presenter: tracker.component.PriorityPresenter
|
||||
})
|
||||
|
@ -40,6 +40,7 @@ import type {
|
||||
ObjectEditor,
|
||||
ObjectEditorHeader,
|
||||
ObjectFactory,
|
||||
ObjectTitle,
|
||||
ObjectValidator,
|
||||
PreviewPresenter,
|
||||
SpaceHeader,
|
||||
@ -158,6 +159,11 @@ export class TObjectFactory extends TClass implements ObjectFactory {
|
||||
component!: AnyComponent
|
||||
}
|
||||
|
||||
@Mixin(view.mixin.ObjectTitle, core.class.Class)
|
||||
export class TObjectTitle extends TClass implements ObjectTitle {
|
||||
titleProvider!: Resource<<T extends Doc>(client: Client, ref: Ref<T>) => Promise<string>>
|
||||
}
|
||||
|
||||
@Model(view.class.ViewletPreference, preference.class.Preference)
|
||||
export class TViewletPreference extends TPreference implements ViewletPreference {
|
||||
attachedTo!: Ref<Viewlet>
|
||||
@ -276,6 +282,7 @@ export function createModel (builder: Builder): void {
|
||||
TActionCategory,
|
||||
TObjectValidator,
|
||||
TObjectFactory,
|
||||
TObjectTitle,
|
||||
TObjectEditorHeader,
|
||||
THTMLPresenter,
|
||||
TSpaceHeader,
|
||||
|
@ -56,7 +56,7 @@ import SetParentIssueActionPopup from './components/SetParentIssueActionPopup.sv
|
||||
import Views from './components/views/Views.svelte'
|
||||
import KanbanView from './components/issues/KanbanView.svelte'
|
||||
import tracker from './plugin'
|
||||
import { getIssueId } from './utils'
|
||||
import { getIssueId, getIssueTitle } from './utils'
|
||||
|
||||
export async function queryIssue<D extends Issue> (
|
||||
_class: Ref<Class<D>>,
|
||||
@ -148,5 +148,8 @@ export default async (): Promise<Resources> => ({
|
||||
},
|
||||
completion: {
|
||||
IssueQuery: async (client: Client, query: string) => await queryIssue(tracker.class.Issue, client, query)
|
||||
},
|
||||
function: {
|
||||
getIssueTitle
|
||||
}
|
||||
})
|
||||
|
@ -12,10 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import type { IntlString, Resource } from '@anticrm/platform'
|
||||
import { mergeIds } from '@anticrm/platform'
|
||||
import tracker, { trackerId } from '../../tracker/lib'
|
||||
import { AnyComponent } from '@anticrm/ui'
|
||||
import { Client, Doc, Ref } from '@anticrm/core'
|
||||
|
||||
export default mergeIds(trackerId, tracker, {
|
||||
string: {
|
||||
@ -209,5 +210,8 @@ export default mergeIds(trackerId, tracker, {
|
||||
Roadmap: '' as AnyComponent,
|
||||
TeamProjects: '' as AnyComponent,
|
||||
IssuePreview: '' as AnyComponent
|
||||
},
|
||||
function: {
|
||||
getIssueTitle: '' as Resource<(client: Client, ref: Ref<Doc>) => Promise<string>>
|
||||
}
|
||||
})
|
||||
|
@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import contact, { Employee, formatName } from '@anticrm/contact'
|
||||
import { DocumentQuery, Ref, SortingOrder, TxOperations } from '@anticrm/core'
|
||||
import { Doc, DocumentQuery, Ref, SortingOrder, TxOperations } from '@anticrm/core'
|
||||
import { Asset, IntlString, translate } from '@anticrm/platform'
|
||||
import {
|
||||
IssuePriority,
|
||||
@ -504,3 +504,13 @@ export async function getKanbanStatuses (
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
export async function getIssueTitle (client: TxOperations, ref: Ref<Doc>): Promise<string> {
|
||||
const issue = await client.findOne(
|
||||
tracker.class.Issue,
|
||||
{ _id: ref as Ref<Issue> },
|
||||
{ lookup: { space: tracker.class.Team } }
|
||||
)
|
||||
if (issue?.$lookup?.space === undefined) throw new Error(`Issue Team not found, _id: ${ref}`)
|
||||
return getIssueId(issue.$lookup.space, issue)
|
||||
}
|
||||
|
@ -154,6 +154,13 @@ export interface ObjectValidator extends Class<Doc> {
|
||||
validator: Resource<<T extends Doc>(doc: T, client: Client) => Promise<Status>>
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ObjectTitle extends Class<Doc> {
|
||||
titleProvider: Resource<<T extends Doc>(client: Client, ref: Ref<T>) => Promise<string>>
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -384,6 +391,7 @@ const view = plugin(viewId, {
|
||||
ObjectEditorHeader: '' as Ref<Mixin<ObjectEditorHeader>>,
|
||||
ObjectValidator: '' as Ref<Mixin<ObjectValidator>>,
|
||||
ObjectFactory: '' as Ref<Mixin<ObjectFactory>>,
|
||||
ObjectTitle: '' as Ref<Mixin<ObjectTitle>>,
|
||||
SpaceHeader: '' as Ref<Mixin<SpaceHeader>>,
|
||||
SpaceName: '' as Ref<Mixin<SpaceName>>,
|
||||
IgnoreActions: '' as Ref<Mixin<IgnoreActions>>,
|
||||
|
@ -15,10 +15,10 @@
|
||||
<script lang="ts">
|
||||
import calendar from '@anticrm/calendar'
|
||||
import contact, { Employee, EmployeeAccount } from '@anticrm/contact'
|
||||
import core, { Client, getCurrentAccount, Ref, Space } from '@anticrm/core'
|
||||
import core, { Class, Client, Doc, getCurrentAccount, Ref, Space } from '@anticrm/core'
|
||||
import notification, { NotificationStatus } from '@anticrm/notification'
|
||||
import { NotificationClientImpl } from '@anticrm/notification-resources'
|
||||
import { getMetadata, IntlString } from '@anticrm/platform'
|
||||
import { getMetadata, getResource, IntlString } from '@anticrm/platform'
|
||||
import { Avatar, createQuery, setClient } from '@anticrm/presentation'
|
||||
import {
|
||||
AnyComponent,
|
||||
@ -26,6 +26,7 @@
|
||||
closeTooltip,
|
||||
Component,
|
||||
DatePickerPopup,
|
||||
fetchMetadataLocalStorage,
|
||||
getCurrentLocation,
|
||||
location,
|
||||
Location,
|
||||
@ -35,6 +36,8 @@
|
||||
showPopup,
|
||||
TooltipInstance
|
||||
} from '@anticrm/ui'
|
||||
import login from '@anticrm/login'
|
||||
import view from '@anticrm/view'
|
||||
import { ActionContext, ActionHandler } from '@anticrm/view-resources'
|
||||
import type { Application, NavigatorModel, SpecialNavModel, ViewConfiguration } from '@anticrm/workbench'
|
||||
import { onDestroy, tick } from 'svelte'
|
||||
@ -125,9 +128,33 @@
|
||||
closePopup()
|
||||
|
||||
await syncLoc(loc)
|
||||
await updateWindowTitle(loc)
|
||||
})
|
||||
)
|
||||
|
||||
async function updateWindowTitle (loc: Location) {
|
||||
const title = (await getWindowTitle(loc)) ?? getMetadata(workbench.metadata.PlatformTitle) ?? 'Platform'
|
||||
const ws = fetchMetadataLocalStorage(login.metadata.CurrentWorkspace)
|
||||
document.title = ws == null ? title : `${ws} - ${title}`
|
||||
}
|
||||
async function getWindowTitle (loc: Location) {
|
||||
if (loc.fragment == null) return
|
||||
const hierarchy = client.getHierarchy()
|
||||
const [, _id, _class] = decodeURIComponent(loc.fragment).split('|')
|
||||
if (_class == null) return
|
||||
|
||||
const clazz = hierarchy.getClass(_class as Ref<Class<Doc>>)
|
||||
if (!hierarchy.hasMixin(clazz, view.mixin.ObjectTitle)) return
|
||||
|
||||
const mixin = hierarchy.as(clazz, view.mixin.ObjectTitle)
|
||||
const titleProvider = await getResource(mixin.titleProvider)
|
||||
try {
|
||||
return await titleProvider(client, _id as Ref<Doc>)
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
async function syncLoc (loc: Location): Promise<void> {
|
||||
const app = loc.path.length > 1 ? (loc.path[1] as Ref<Application>) : undefined
|
||||
const space = loc.path.length > 2 ? (loc.path[2] as Ref<Space>) : undefined
|
||||
|
Loading…
Reference in New Issue
Block a user