Skip to content

Commit

Permalink
Add members to space type for easy management members, and add autojo… (
Browse files Browse the repository at this point in the history
hcengineering#5612)

Signed-off-by: Denis Bykhov <[email protected]>
  • Loading branch information
BykhovDenis authored May 17, 2024
1 parent fa3df99 commit 8f52663
Show file tree
Hide file tree
Showing 25 changed files with 297 additions and 44 deletions.
9 changes: 7 additions & 2 deletions models/core/src/security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ export class TSpace extends TDoc implements Space {
@Prop(ArrOf(TypeRef(core.class.Account)), core.string.Owners)
owners?: Ref<Account>[]

@Prop(TypeBoolean(), getEmbeddedLabel('Auto-Join members'))
@Hidden() // let's hide it for now
@Prop(TypeBoolean(), core.string.AutoJoin)
autoJoin?: boolean
}

Expand Down Expand Up @@ -119,6 +118,12 @@ export class TSpaceType extends TDoc implements SpaceType {

@Prop(Collection(core.class.Role), core.string.Roles)
roles!: CollectionSize<Role>

@Prop(ArrOf(TypeRef(core.class.Account)), core.string.Members)
members!: Arr<Ref<Account>>

@Prop(TypeBoolean(), core.string.AutoJoin)
autoJoin?: boolean
}

@Model(core.class.Role, core.class.AttachedDoc, DOMAIN_MODEL)
Expand Down
8 changes: 8 additions & 0 deletions models/server-contact/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ export function createModel (builder: Builder): void {
}
})

builder.createDoc(serverCore.class.Trigger, core.space.Model, {
trigger: serverContact.trigger.OnSpaceTypeMembers,
txMatch: {
objectClass: core.class.SpaceType,
_class: core.class.TxUpdateDoc
}
})

builder.mixin(
contact.templateField.CurrentEmployeeName,
templates.class.TemplateField,
Expand Down
4 changes: 3 additions & 1 deletion packages/core/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
"DeleteObjectDescription": "Grants users ability to delete objects in the space",
"ForbidDeleteObjectDescription": "Forbid users deleting objects in the space",
"UpdateSpaceDescription": "Grants users ability to update the space",
"ArchiveSpaceDescription": "Grants users ability to archive the space"
"ArchiveSpaceDescription": "Grants users ability to archive the space",
"AutoJoin": "Auto join",
"AutoJoinDescr": "Automatically join new employees to this space"
}
}
17 changes: 16 additions & 1 deletion packages/core/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@
"StatusCategory": "Categoría de estado",
"Account": "Cuenta",
"Rank": "Rango",
"Owners": "Propietarios"
"Owners": "Propietarios",
"Permission": "Permiso",
"CreateObject": "Crear objeto",
"UpdateObject": "Actualizar objeto",
"DeleteObject": "Eliminar objeto",
"ForbidDeleteObject": "Prohibir eliminar objeto",
"UpdateSpace": "Actualizar espacio",
"ArchiveSpace": "Archivar espacio",
"CreateObjectDescription": "Concede a los usuarios la capacidad de crear objetos en el espacio",
"UpdateObjectDescription": "Concede a los usuarios la capacidad de actualizar objetos en el espacio",
"DeleteObjectDescription": "Concede a los usuarios la capacidad de eliminar objetos en el espacio",
"ForbidDeleteObjectDescription": "Prohíbe a los usuarios eliminar objetos en el espacio",
"UpdateSpaceDescription": "Concede a los usuarios la capacidad de actualizar el espacio",
"ArchiveSpaceDescription": "Concede a los usuarios la capacidad de archivar el espacio",
"AutoJoin": "Auto unirse",
"AutoJoinDescr": "Unirse automáticamente a los nuevos empleados a este espacio"
}
}
17 changes: 16 additions & 1 deletion packages/core/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@
"StatusCategory": "Categoria de estado",
"Account": "Conta",
"Rank": "Ranking",
"Owners": "Proprietários"
"Owners": "Proprietários",
"Permission": "Permissão",
"CreateObject": "Criar objeto",
"UpdateObject": "Atualizar objeto",
"DeleteObject": "Apagar objeto",
"ForbidDeleteObject": "Proibir apagar objeto",
"UpdateSpace": "Atualizar espaço",
"ArchiveSpace": "Arquivar espaço",
"CreateObjectDescription": "Concede aos usuários a capacidade de criar objetos no espaço",
"UpdateObjectDescription": "Concede aos usuários a capacidade de atualizar objetos no espaço",
"DeleteObjectDescription": "Concede aos usuários a capacidade de apagar objetos no espaço",
"ForbidDeleteObjectDescription": "Proíbe aos usuários a capacidade de apagar objetos no espaço",
"UpdateSpaceDescription": "Concede aos usuários a capacidade de atualizar o espaço",
"ArchiveSpaceDescription": "Concede aos usuários a capacidade de arquivar o espaço",
"AutoJoin": "Auto adesão",
"AutoJoinDescr": "Adesão automática de novos funcionários a este espaço"
}
}
4 changes: 3 additions & 1 deletion packages/core/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
"DeleteObjectDescription": "Дает пользователям разрешение удалять объекты в пространстве",
"ForbidDeleteObjectDescription": "Запрещает пользователям удалять объекты в пространстве",
"UpdateSpaceDescription": "Дает пользователям разрешение обновлять пространство",
"ArchiveSpaceDescription": "Дает пользователям разрешение архивировать пространство"
"ArchiveSpaceDescription": "Дает пользователям разрешение архивировать пространство",
"AutoJoin": "Автоприсоединение",
"AutoJoinDescr": "Автоматически присоединять новых сотрудников к этому пространству"
}
}
2 changes: 2 additions & 0 deletions packages/core/src/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ export interface SpaceType extends Doc {
name: string
shortDescription?: string
descriptor: Ref<SpaceTypeDescriptor>
members?: Ref<Account>[] // this members will be added automatically to new space, also change this fiield will affect existing spaces
autoJoin?: boolean // if true, all new users will be added to space automatically
targetClass: Ref<Class<Space>> // A dynamic mixin for Spaces to hold custom attributes and roles assignment of the space type
roles: CollectionSize<Role>
}
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,9 @@ export default plugin(coreId, {
DeleteObjectDescription: '' as IntlString,
ForbidDeleteObjectDescription: '' as IntlString,
UpdateSpaceDescription: '' as IntlString,
ArchiveSpaceDescription: '' as IntlString
ArchiveSpaceDescription: '' as IntlString,
AutoJoin: '' as IntlString,
AutoJoinDescr: '' as IntlString
},
descriptor: {
SpacesType: '' as Ref<SpaceTypeDescriptor>
Expand Down
12 changes: 8 additions & 4 deletions packages/ui/src/components/Toggle.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
import { LabelAndProps } from '../types'
import { tooltip } from '../tooltips'
export let id: string | undefined = undefined
export let on: boolean = false
export let disabled: boolean = false
export let showTooltip: LabelAndProps | undefined = undefined
const dispatch = createEventDispatcher()
</script>

<label class="toggle" use:tooltip={showTooltip}>
<label {id} class="toggle" use:tooltip={showTooltip} class:disabled>
<input
class="chBox"
type="checkbox"
Expand All @@ -47,6 +48,12 @@
vertical-align: middle;
font-size: inherit;
user-select: none;
cursor: pointer;
&.disabled {
cursor: default;
}
.chBox {
position: absolute;
width: 1px;
Expand All @@ -67,9 +74,6 @@
background: var(--theme-toggle-on-sw-color);
}
}
&:not(:disabled) + .toggle-switch {
cursor: pointer;
}
&:disabled + .toggle-switch {
filter: grayscale(70%);
&:before {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
export let label: IntlString
export let value: Ref<Account>[]
export let onChange: ((refs: Ref<Account>[]) => void) | undefined
export let onChange: ((refs: Ref<Account>[]) => void | Promise<void>) | undefined
export let readonly = false
export let kind: ButtonKind = 'link'
export let size: ButtonSize = 'large'
Expand Down
1 change: 0 additions & 1 deletion plugins/contact-resources/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export default mergeIds(contactId, contact, {
CopyToClipboard: '' as IntlString,
ViewFullProfile: '' as IntlString,
Member: '' as IntlString,
Members: '' as IntlString,
NoMembers: '' as IntlString,
AddMember: '' as IntlString,
KickEmployee: '' as IntlString,
Expand Down
3 changes: 2 additions & 1 deletion plugins/contact/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ export const contactPlugin = plugin(contactId, {
Position: '' as IntlString,
For: '' as IntlString,
SelectUsers: '' as IntlString,
AddGuest: '' as IntlString
AddGuest: '' as IntlString,
Members: '' as IntlString
},
viewlet: {
TableMember: '' as Ref<Viewlet>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
private: isPrivate,
members,
owners,
autoJoin,
archived: false,
icon,
color
Expand Down Expand Up @@ -146,6 +147,9 @@
if (teamspaceData.color !== teamspace?.color) {
update.color = teamspaceData.color
}
if (teamspaceData.autoJoin !== teamspace?.autoJoin) {
update.autoJoin = teamspaceData.autoJoin
}
if (teamspaceData.members.length !== teamspace?.members.length) {
update.members = teamspaceData.members
} else {
Expand Down Expand Up @@ -236,6 +240,7 @@
}
function handleMembersChanged (newMembers: Ref<Account>[]): void {
membersChanged = true
// If a member was removed we need to remove it from any roles assignments as well
const newMembersSet = new Set(newMembers)
const removedMembersSet = new Set(members.filter((m) => !newMembersSet.has(m)))
Expand All @@ -257,6 +262,21 @@
rolesAssignment[roleId] = newMembers
}
let autoJoin = teamspace?.autoJoin ?? spaceType?.autoJoin ?? false
$: setDefaultMembers(spaceType)
let membersChanged: boolean = false
function setDefaultMembers (typeType: SpaceType | undefined): void {
if (typeType === undefined) return
if (membersChanged) return
if (teamspace !== undefined) return
autoJoin = typeType.autoJoin ?? false
if (typeType.members === undefined || typeType.members.length === 0) return
members = typeType.members
}
$: canSave =
name.trim().length > 0 &&
!(members.length === 0 && isPrivate) &&
Expand Down Expand Up @@ -366,7 +386,7 @@
<Label label={presentation.string.MakePrivate} />
<span><Label label={presentation.string.MakePrivateDescription} /></span>
</div>
<Toggle bind:on={isPrivate} disabled={!isPrivate && members.length === 0} />
<Toggle id={'teamspace-private'} bind:on={isPrivate} disabled={!isPrivate && members.length === 0} />
</div>

<div class="antiGrid-row">
Expand All @@ -383,6 +403,14 @@
/>
</div>

<div class="antiGrid-row">
<div class="antiGrid-row__header withDesciption">
<Label label={core.string.AutoJoin} />
<span><Label label={core.string.AutoJoinDescr} /></span>
</div>
<Toggle bind:on={autoJoin} />
</div>

{#each roles as role}
<div class="antiGrid-row">
<div class="antiGrid-row__header">
Expand Down
48 changes: 43 additions & 5 deletions plugins/lead-resources/src/components/CreateFunnel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import lead, { Funnel } from '@hcengineering/lead'
import presentation, { getClient, SpaceCreateCard } from '@hcengineering/presentation'
import task, { ProjectType } from '@hcengineering/task'
import ui, { Component, EditBox, Grid, Label, ToggleWithLabel } from '@hcengineering/ui'
import ui, { Component, EditBox, Label, Toggle, ToggleWithLabel } from '@hcengineering/ui'
import { deepEqual } from 'fast-equals'
import { createEventDispatcher } from 'svelte'
Expand Down Expand Up @@ -99,6 +99,7 @@
private: isPrivate,
archived: false,
members,
autoJoin,
owners,
type: typeId
})
Expand All @@ -111,7 +112,11 @@
if (isNew) {
await createFunnel()
} else if (funnel !== undefined && spaceType?.targetClass !== undefined) {
await client.diffUpdate<Funnel>(funnel, { name, description, members, owners, private: isPrivate }, Date.now())
await client.diffUpdate<Funnel>(
funnel,
{ name, description, members, owners, private: isPrivate, autoJoin },
Date.now()
)
if (!deepEqual(rolesAssignment, getRolesAssignment())) {
await client.updateMixin(
Expand All @@ -133,6 +138,7 @@
}
function handleMembersChanged (newMembers: Ref<Account>[]): void {
membersChanged = true
// If a member was removed we need to remove it from any roles assignments as well
const newMembersSet = new Set(newMembers)
const removedMembersSet = new Set(members.filter((m) => !newMembersSet.has(m)))
Expand All @@ -156,6 +162,21 @@
$: canSave =
name.trim().length > 0 && members.length > 0 && owners.length > 0 && owners.some((o) => members.includes(o))
let autoJoin = funnel?.autoJoin ?? spaceType?.autoJoin ?? false
$: setDefaultMembers(spaceType)
let membersChanged: boolean = false
function setDefaultMembers (typeType: SpaceType | undefined): void {
if (typeType === undefined) return
if (membersChanged) return
if (funnel !== undefined) return
autoJoin = typeType.autoJoin ?? false
if (typeType.members === undefined || typeType.members.length === 0) return
members = typeType.members
}
</script>

<SpaceCreateCard
Expand All @@ -167,27 +188,37 @@
dispatch('close')
}}
>
<Grid column={1} rowGap={1.5}>
<div class="antiGrid-row">
<EditBox label={leadRes.string.FunnelName} bind:value={name} placeholder={leadRes.string.FunnelName} autoFocus />
</div>

<div class="antiGrid-row">
<ToggleWithLabel
label={presentation.string.MakePrivate}
description={presentation.string.MakePrivateDescription}
bind:on={isPrivate}
/>
</div>

<div class="antiGrid-row">
<div class="antiGrid-row__header">
<Label label={task.string.ProjectType} />
</div>
<Component
is={task.component.ProjectTypeSelector}
disabled={!isNew}
props={{
descriptors: [leadRes.descriptors.FunnelType],
type: typeId,
kind: 'regular',
size: 'large',
disabled: funnel !== undefined
}}
on:change={(evt) => {
typeId = evt.detail
}}
/>
</Grid>
</div>
<div class="antiGrid-row">
<div class="antiGrid-row__header">
<Label label={core.string.Owners} />
Expand All @@ -201,7 +232,7 @@
/>
</div>

<div class="antiGrid-row mt-4">
<div class="antiGrid-row">
<div class="antiGrid-row__header">
<Label label={leadRes.string.Members} />
</div>
Expand All @@ -214,6 +245,13 @@
size={'large'}
/>
</div>
<div class="antiGrid-row">
<div class="antiGrid-row__header withDesciption">
<Label label={core.string.AutoJoin} />
<span><Label label={core.string.AutoJoinDescr} /></span>
</div>
<Toggle bind:on={autoJoin} />
</div>

{#each roles as role}
<div class="antiGrid-row">
Expand Down
Loading

0 comments on commit 8f52663

Please sign in to comment.