Space actions (#5574)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-05-10 16:54:34 +05:00 committed by GitHub
parent 515bbf5066
commit 1e0e5de097
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 128 additions and 12 deletions

View File

@ -650,6 +650,36 @@ export function createModel (builder: Builder): void {
view.action.Archive
)
createAction(
builder,
{
action: view.actionImpl.Join,
label: view.string.Join,
icon: view.icon.Join,
category: view.category.General,
input: 'focus',
target: core.class.Space,
visibilityTester: view.function.CanJoinSpace,
context: { mode: ['context', 'browser'], group: 'tools' }
},
view.action.Join
)
createAction(
builder,
{
action: view.actionImpl.Leave,
label: view.string.Leave,
icon: view.icon.Leave,
category: view.category.General,
input: 'focus',
target: core.class.Space,
visibilityTester: view.function.CanLeaveSpace,
context: { mode: ['context', 'browser'], group: 'tools' }
},
view.action.Leave
)
// Keyboard actions.
createAction(
builder,

View File

@ -24,6 +24,8 @@ export default mergeIds(viewId, view, {
actionImpl: {
Delete: '' as ViewAction,
Archive: '' as ViewAction,
Join: '' as ViewAction,
Leave: '' as ViewAction,
Move: '' as ViewAction,
MoveLeft: '' as ViewAction,
MoveRight: '' as ViewAction,
@ -128,7 +130,9 @@ export default mergeIds(viewId, view, {
CanDeleteObject: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanEditSpace: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanArchiveSpace: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanDeleteSpace: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>
CanDeleteSpace: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanJoinSpace: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanLeaveSpace: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>
},
pipeline: {
PresentationMiddleware: '' as Ref<PresentationMiddlewareFactory>,

View File

@ -542,7 +542,7 @@ export default async (): Promise<Resources> => ({
) => await getAllStates(query, onUpdate, queryId, attr, false),
GetVisibleFilters: getVisibleFilters,
IssueChatTitleProvider: getIssueChatTitle,
IsProjectJoined: async (project: Project) => !project.private || project.members.includes(getCurrentAccount()._id),
IsProjectJoined: async (project: Project) => project.members.includes(getCurrentAccount()._id),
GetIssueStatusCategories: getIssueStatusCategories
},
actionImpl: {

View File

@ -147,4 +147,12 @@
<symbol id="circle" viewBox="0 0 32 32">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 28.0002C22.6274 28.0002 28 22.6277 28 16.0002C28 9.37283 22.6274 4.00024 16 4.00024C9.37258 4.00024 4 9.37283 4 16.0002C4 22.6277 9.37258 28.0002 16 28.0002ZM16 30.0002C23.732 30.0002 30 23.7322 30 16.0002C30 8.26826 23.732 2.00024 16 2.00024C8.26801 2.00024 2 8.26826 2 16.0002C2 23.7322 8.26801 30.0002 16 30.0002Z" />
</symbol>
<symbol id="join" viewBox="0 0 16 16">
<path d="M7.92231 14.2015L7.99302 14.6964L7.92231 14.2015ZM6.22318 14.311L6.33389 13.8234L6.22318 14.311ZM4.79789 13.0748L5.26492 12.8963L4.79789 13.0748ZM13.373 12.5661L12.9774 12.2603L13.373 12.5661ZM9.05136 14.0402L8.98065 13.5452L9.05136 14.0402ZM13.1512 12.8218L13.5099 13.1701L13.1512 12.8218ZM13.1512 3.17821L12.7926 3.5266L13.1512 3.17821ZM13.373 3.43391L13.7686 3.12813L13.373 3.43391ZM7.98221 2.31213L8.98065 2.45477L9.12207 1.46482L8.12363 1.32218L7.98221 2.31213ZM13.4993 7.66487V8.33509H14.4993V7.66487H13.4993ZM8.98065 13.5452L7.8516 13.7065L7.99302 14.6964L9.12207 14.5351L8.98065 13.5452ZM7.8516 13.7065C7.39911 13.7711 7.0821 13.8162 6.83278 13.8363C6.58629 13.8562 6.44248 13.8481 6.33389 13.8234L6.11247 14.7986C6.364 14.8557 6.62341 14.8565 6.91329 14.8331C7.20033 14.8099 7.55283 14.7593 7.99302 14.6964L7.8516 13.7065ZM4.16602 11.3773C4.16602 11.822 4.1658 12.1781 4.18344 12.4655C4.20126 12.7558 4.23875 13.0125 4.33085 13.2534L5.26492 12.8963C5.22515 12.7923 5.19671 12.6511 5.18156 12.4042C5.16624 12.1546 5.16602 11.8344 5.16602 11.3773H4.16602ZM6.33389 13.8234C5.84503 13.7124 5.44393 13.3645 5.26492 12.8963L4.33085 13.2534C4.62921 14.0338 5.29771 14.6136 6.11247 14.7986L6.33389 13.8234ZM13.4993 8.33509C13.4993 9.48721 13.4986 10.3082 13.4244 10.9439C13.3517 11.5676 13.2136 11.9547 12.9774 12.2603L13.7686 12.8718C14.1587 12.3671 14.3338 11.7788 14.4177 11.0597C14.5001 10.3527 14.4993 9.46335 14.4993 8.33509H13.4993ZM9.12207 14.5351C10.239 14.3756 11.1195 14.2506 11.8078 14.069C12.5078 13.8843 13.0654 13.6277 13.5099 13.1701L12.7926 12.4734C12.5234 12.7504 12.1598 12.9419 11.5526 13.1021C10.9338 13.2654 10.1212 13.3823 8.98065 13.5452L9.12207 14.5351ZM12.9774 12.2603C12.9198 12.3347 12.8581 12.4059 12.7926 12.4734L13.5099 13.1701C13.6017 13.0756 13.688 12.9761 13.7686 12.8718L12.9774 12.2603ZM8.98065 2.45477C10.1212 2.6177 10.9338 2.73458 11.5526 2.89788C12.1598 3.05809 12.5234 3.24952 12.7926 3.5266L13.5099 2.82982C13.0654 2.37222 12.5078 2.11569 11.8078 1.93098C11.1195 1.74936 10.239 1.62438 9.12207 1.46482L8.98065 2.45477ZM14.4993 7.66487C14.4993 6.53661 14.5001 5.64727 14.4177 4.94022C14.3338 4.22111 14.1587 3.63289 13.7686 3.12813L12.9774 3.73968C13.2136 4.04531 13.3517 4.43238 13.4244 5.05606C13.4986 5.69179 13.4993 6.51275 13.4993 7.66487H14.4993ZM12.7926 3.5266C12.8581 3.59409 12.9198 3.66523 12.9774 3.73968L13.7686 3.12813C13.688 3.02391 13.6017 2.92431 13.5099 2.82982L12.7926 3.5266ZM8.12363 1.32218C7.62395 1.2508 7.22383 1.19335 6.89852 1.16973C6.56979 1.14587 6.27615 1.15257 5.99374 1.23142L6.26265 2.19458C6.38494 2.16044 6.54699 2.14684 6.82611 2.16711C7.10865 2.18762 7.46854 2.23875 7.98221 2.31213L8.12363 1.32218ZM5.16602 4.7546C5.16602 4.23572 5.1663 3.87222 5.18595 3.58961C5.20536 3.31043 5.24174 3.15194 5.29283 3.0357L4.37738 2.63328C4.25938 2.90171 4.21122 3.19145 4.18836 3.52025C4.16573 3.84563 4.16602 4.24985 4.16602 4.7546H5.16602ZM5.99374 1.23142C5.27211 1.43289 4.67888 1.9474 4.37738 2.63328L5.29283 3.0357C5.47374 2.62417 5.82967 2.31547 6.26265 2.19458L5.99374 1.23142Z"/>
<path d="M10.666 8.00002L11.0565 7.68767L11.3063 8.00002L11.0565 8.31237L10.666 8.00002ZM2.66602 8.50002C2.38987 8.50002 2.16602 8.27616 2.16602 8.00002C2.16602 7.72388 2.38987 7.50002 2.66602 7.50002V8.50002ZM8.38978 4.35434L11.0565 7.68767L10.2756 8.31237L7.60891 4.97903L8.38978 4.35434ZM11.0565 8.31237L8.38978 11.6457L7.60891 11.021L10.2756 7.68767L11.0565 8.31237ZM10.666 8.50002H2.66602V7.50002H10.666V8.50002Z"/>
</symbol>
<symbol id="leave" viewBox="0 0 32 32">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 4C19.1046 4 20 4.89543 20 6V7C20 7.55228 20.4477 8 21 8C21.5523 8 22 7.55228 22 7V6C22 3.79086 20.2091 2 18 2H10C7.79086 2 6 3.79086 6 6V26C6 28.2091 7.79086 30 10 30H18C20.2091 30 22 28.2091 22 26V25C22 24.4477 21.5523 24 21 24C20.4477 24 20 24.4477 20 25V26C20 27.1046 19.1046 28 18 28H10C8.89543 28 8 27.1046 8 26V6C8 4.89543 8.89543 4 10 4H18Z" />
<path d="M22.59 20.59L26.17 17H13C12.4477 17 12 16.5523 12 16C12 15.4477 12.4477 15 13 15H26.17L22.59 11.41L24 10L30 16L24 22L22.59 20.59Z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -121,6 +121,8 @@
"Pin": "Pin",
"Unpin": "Unpin",
"Archived": "Archived",
"MoreActions": "More actions"
"MoreActions": "More actions",
"Leave": "Leave",
"Join": "Join"
}
}

View File

@ -114,6 +114,8 @@
"ToViewCommands": "para ver los comandos disponibles",
"UnArchive": "Desarchivar",
"Pin": "Fijar",
"Unpin": "Desfijar"
"Unpin": "Desfijar",
"Leave": "Salir",
"Join": "Unirse"
}
}

View File

@ -114,6 +114,8 @@
"ToViewCommands": "para ver os comandos disponíveis",
"UnArchive": "Desarquivar",
"Pin": "Fixar",
"Unpin": "Desafixar"
"Unpin": "Desafixar",
"Leave": "Sair",
"Join": "Ingressar"
}
}

View File

@ -118,6 +118,8 @@
"Pin": "Закрепить",
"Unpin": "Открепить",
"Archived": "Архивированные",
"MoreActions": "Больше действий"
"MoreActions": "Больше действий",
"Leave": "Покинуть",
"Join": "Присоединиться"
}
}

View File

@ -51,5 +51,7 @@ loadMetadata(view.icon, {
Table2: `${icons}#table2`,
CodeBlock: `${icons}#code-block`,
SeparatorLine: `${icons}#separator-line`,
Circle: `${icons}#circle`
Circle: `${icons}#circle`,
Join: `${icons}#join`,
Leave: `${icons}#leave`
})

View File

@ -5,7 +5,8 @@ import {
Hierarchy,
type Ref,
type Space,
type TxResult
type TxResult,
getCurrentAccount
} from '@hcengineering/core'
import { type Asset, type IntlString, type Resource, getResource } from '@hcengineering/platform'
import { MessageBox, getClient, updateAttribute, type ContextStore, contextStore } from '@hcengineering/presentation'
@ -121,6 +122,32 @@ function Archive (object: Space | Space[]): void {
)
}
async function Leave (object: Space | Space[]): Promise<void> {
const client = getClient()
const promises: Array<Promise<TxResult>> = []
const objs = Array.isArray(object) ? object : [object]
const me = getCurrentAccount()._id
for (const obj of objs) {
if (obj.members.includes(me)) {
promises.push(client.update(obj, { $pull: { members: me } }))
}
}
await Promise.all(promises)
}
async function Join (object: Space | Space[]): Promise<void> {
const client = getClient()
const promises: Array<Promise<TxResult>> = []
const objs = Array.isArray(object) ? object : [object]
const me = getCurrentAccount()._id
for (const obj of objs) {
if (!obj.members.includes(me)) {
promises.push(client.update(obj, { $push: { members: me } }))
}
}
await Promise.all(promises)
}
async function Move (docs: Doc | Doc[]): Promise<void> {
showPopup(MoveView, { selected: docs })
}
@ -507,6 +534,8 @@ export const actionImpl = {
CopyTextToClipboard,
Delete,
Archive,
Join,
Leave,
Move,
MoveUp,
MoveDown,

View File

@ -120,7 +120,14 @@ import {
import { IndexedDocumentPreview } from '@hcengineering/presentation'
import { AggregationMiddleware, AnalyticsMiddleware } from './middleware'
import { showEmptyGroups } from './viewOptions'
import { canArchiveSpace, canDeleteObject, canDeleteSpace, canEditSpace } from './visibilityTester'
import {
canArchiveSpace,
canDeleteObject,
canDeleteSpace,
canEditSpace,
canJoinSpace,
canLeaveSpace
} from './visibilityTester'
export { canArchiveSpace, canDeleteObject, canDeleteSpace, canEditSpace } from './visibilityTester'
export { getActions, getContextActions, invokeAction, showMenu } from './actions'
export { default as ActionButton } from './components/ActionButton.svelte'
@ -307,6 +314,8 @@ export default async (): Promise<Resources> => ({
CanDeleteObject: canDeleteObject,
CanEditSpace: canEditSpace,
CanArchiveSpace: canArchiveSpace,
CanDeleteSpace: canDeleteSpace
CanDeleteSpace: canDeleteSpace,
CanJoinSpace: canJoinSpace,
CanLeaveSpace: canLeaveSpace
}
})

View File

@ -108,3 +108,23 @@ export async function canDeleteSpace (doc?: Doc | Doc[]): Promise<boolean> {
return false
}
export async function canJoinSpace (doc?: Doc | Doc[]): Promise<boolean> {
if (doc === undefined || Array.isArray(doc)) {
return false
}
const space = doc as Space
return !space.members?.includes(getCurrentAccount()._id)
}
export async function canLeaveSpace (doc?: Doc | Doc[]): Promise<boolean> {
if (doc === undefined || Array.isArray(doc)) {
return false
}
const space = doc as Space
return space.members?.includes(getCurrentAccount()._id)
}

View File

@ -121,6 +121,8 @@ const view = plugin(viewId, {
action: {
Delete: '' as Ref<Action>,
Archive: '' as Ref<Action>,
Join: '' as Ref<Action>,
Leave: '' as Ref<Action>,
Move: '' as Ref<Action>,
MoveLeft: '' as Ref<Action>,
MoveRight: '' as Ref<Action>,
@ -199,7 +201,9 @@ const view = plugin(viewId, {
Archived: '' as IntlString,
MoreActions: '' as IntlString,
Pin: '' as IntlString,
Unpin: '' as IntlString
Unpin: '' as IntlString,
Join: '' as IntlString,
Leave: '' as IntlString
},
icon: {
Table: '' as Asset,
@ -235,7 +239,9 @@ const view = plugin(viewId, {
Table2: '' as Asset,
CodeBlock: '' as Asset,
SeparatorLine: '' as Asset,
Circle: '' as Asset
Circle: '' as Asset,
Join: '' as Asset,
Leave: '' as Asset
},
category: {
General: '' as Ref<ActionCategory>,