UBERF-4472-sharing-views (#4272)

* query param sharing implementation

Signed-off-by: Sergey Voytsehovich <syargreg@gmail.com>

* formatting fixes

Signed-off-by: Sergey Voytsehovich <syargreg@gmail.com>

* fixes

Signed-off-by: Sergey Voytsehovich <syargreg@gmail.com>

* formatting fix

Signed-off-by: Sergey Voytsehovich <syargreg@gmail.com>

* formatting fix

Signed-off-by: Sergey Voytsehovich <syargreg@gmail.com>

---------

Signed-off-by: Sergey Voytsehovich <syargreg@gmail.com>
This commit is contained in:
Sergey Voytsehovich 2023-12-27 12:20:15 +03:00 committed by GitHub
parent 689e2d4caa
commit 76d051bf76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 7 deletions

View File

@ -107,6 +107,7 @@
"Or": "Or",
"HyperlinkPlaceholder": "https://jappleseed.com",
"CopyToClipboard": "Copy to clipboard",
"PublicView": "Public",
"ChooseIcon": "Choose icon",
"IconColor": "Choose icon color",

View File

@ -103,6 +103,7 @@
"Or": "Или",
"HyperlinkPlaceholder": "https://jappleseed.com",
"CopyToClipboard": "Скопировать в буфер обмена",
"PublicView": "Публичный",
"ChooseIcon": "Выбрать иконку",
"IconColor": "Выберите цвет",

View File

@ -26,7 +26,8 @@
Menu,
showPopup,
getTreeCollapsed,
setTreeCollapsed
setTreeCollapsed,
IconActivity
} from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
@ -47,13 +48,25 @@
export let actions: (originalEvent?: MouseEvent) => Promise<Action[]> = async () => []
let hovered = false
let inlineActions: Action[] = []
let popupMenuActions: Action[] = []
$: actions().then((result) => {
inlineActions = result.filter((action) => action.inline === true)
popupMenuActions = result.filter((action) => action.inline !== true)
})
async function onMenuClick (ev: MouseEvent) {
showPopup(Menu, { actions: await actions(ev), ctx: _id }, ev.target as HTMLElement, () => {
showPopup(Menu, { actions: popupMenuActions, ctx: _id }, ev.target as HTMLElement, () => {
hovered = false
})
hovered = true
}
async function onInlineClick (ev: MouseEvent, action: Action) {
action.action([], ev)
}
const dispatch = createEventDispatcher()
$: if (_id) collapsed = getTreeCollapsed(_id)
$: setTreeCollapsed(_id, collapsed)
@ -91,6 +104,15 @@
<div class="an-element__grow" />
{#if !parent}
{#each inlineActions as action}
<div
class="an-element__tool"
class:pressed={hovered}
on:click|preventDefault|stopPropagation={(ev) => onInlineClick(ev, action)}
>
<Icon icon={action.icon ?? ActionIcon} size={'small'} />
</div>
{/each}
<div class="an-element__tool" class:pressed={hovered} on:click|preventDefault|stopPropagation={onMenuClick}>
<IconMoreH size={'small'} />
</div>

View File

@ -883,7 +883,8 @@ const view = plugin(viewId, {
Subscribed: '' as IntlString,
HyperlinkPlaceholder: '' as IntlString,
CopyToClipboard: '' as IntlString,
NoGrouping: '' as IntlString
NoGrouping: '' as IntlString,
PublicView: '' as IntlString
},
icon: {
Table: '' as Asset,

View File

@ -1,6 +1,6 @@
<script lang="ts">
import { Ref, getCurrentAccount, toIdMap } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { copyTextToClipboard, createQuery, getClient } from '@hcengineering/presentation'
import setting from '@hcengineering/setting'
import {
Action,
@ -12,7 +12,9 @@
showPopup,
SelectPopup,
getEventPopupPositionElement,
getPopupPositionElement
getPopupPositionElement,
locationToUrl,
getLocation
} from '@hcengineering/ui'
import view, { Filter, FilteredView, ViewOptions, Viewlet } from '@hcengineering/view'
import {
@ -33,6 +35,7 @@
import copy from 'fast-copy'
import { createEventDispatcher } from 'svelte'
import contact from '@hcengineering/contact'
import task from '../../../task/lib'
export let currentApplication: Application | undefined
@ -49,6 +52,14 @@
(result) => {
myFilteredViews = result.filter((p) => p.users.includes(me))
availableFilteredViews = result.filter((p) => p.sharable && !p.users.includes(me))
const location = getLocation()
if (location.query?.filterViewId) {
const targetView = result.find((view) => view._id === location.query?.filterViewId)
if (targetView) {
load(targetView)
}
}
}
)
@ -85,13 +96,52 @@
]
}
async function switchPublicAction (object: FilteredView, originalEvent: MouseEvent | undefined): Promise<Action[]> {
return [
{
icon: object.sharable ? task.icon.TodoCheck : task.icon.TodoUnCheck,
label: view.string.PublicView,
action: async (ctx: any, evt: Event) => {
await client.update(object, { sharable: !object.sharable })
}
}
]
}
async function copyUrlAction (filteredView: FilteredView): Promise<Action[]> {
return [
{
icon: view.icon.CopyLink,
label: view.string.CopyToClipboard,
inline: true,
action: async (ctx: any, evt: Event) => {
const { protocol, hostname, port } = window.location
const baseUrl = `${protocol}//${hostname}${port ? `:${port}` : ''}`
const query = filteredView.location.query || {}
query.filterViewId = filteredView._id
const targetUrl = locationToUrl({
path: filteredView.location.path,
query,
fragment: filteredView.location.fragment ?? undefined
})
copyTextToClipboard(baseUrl + targetUrl)
}
}
]
}
async function viewAction (filteredView: FilteredView, originalEvent: MouseEvent | undefined): Promise<Action[]> {
const copyUrl = await copyUrlAction(filteredView)
const rename = await renameAction(filteredView, originalEvent)
const setPublic = await switchPublicAction(filteredView, originalEvent)
const hide = await hideAction(filteredView)
if (filteredView.createdBy === me) {
const remove = await removeAction(filteredView)
return [...remove, ...rename]
return [...setPublic, ...rename, ...remove, ...copyUrl]
}
return await hideAction(filteredView)
return [...hide, ...copyUrl]
}
async function hideAction (object: FilteredView): Promise<Action[]> {