Skip to content

Commit 24e5147

Browse files
authored
fix: show members edit table for department (#9571)
Signed-off-by: Alexander Onnikov <[email protected]>
1 parent 4dcdb47 commit 24e5147

File tree

5 files changed

+130
-1
lines changed

5 files changed

+130
-1
lines changed

plugins/hr-assets/assets/icons.svg

Lines changed: 12 additions & 0 deletions
Loading

plugins/hr-assets/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ loadMetadata(hr.icon, {
2121
HR: `${icons}#hr`,
2222
Department: `${icons}#department`,
2323
Structure: `${icons}#structure`,
24+
Members: `${icons}#members`,
2425
Vacation: `${icons}#vacation`,
2526
Sick: `${icons}#sick`,
2627
PTO: `${icons}#pto`,

plugins/hr-resources/src/components/EditDepartment.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import setting, { IntegrationType } from '@hcengineering/setting'
2323
import { createEventDispatcher, onMount } from 'svelte'
2424
import hr from '../plugin'
25+
import Members from './Members.svelte'
2526
2627
export let object: Department
28+
export let readonly: boolean = false
2729
2830
let avatarEditor: EditableAvatar
2931
@@ -65,12 +67,14 @@
6567
collectionArrays: ['members']
6668
})
6769
})
70+
71+
$: members = object.members ?? []
6872
</script>
6973

7074
<FocusHandler {manager} />
7175

7276
{#if object !== undefined}
73-
<div class="flex-row-stretch flex-grow">
77+
<div class="flex-row-stretch flex-grow step-tb-6">
7478
<div class="mr-8">
7579
{#key object}
7680
<EditableAvatar
@@ -92,6 +96,8 @@
9296
</div>
9397
</div>
9498
</div>
99+
100+
<Members department={object} {members} {readonly} />
95101
{/if}
96102

97103
<style lang="scss">
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<!--
2+
// Copyright © 2025 Hardcore Engineering Inc.
3+
//
4+
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License. You may
6+
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
//
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
-->
15+
<script lang="ts">
16+
import contact, { Employee } from '@hcengineering/contact'
17+
import { UsersPopup } from '@hcengineering/contact-resources'
18+
import type { Ref } from '@hcengineering/core'
19+
import { type Department } from '@hcengineering/hr'
20+
import { getClient } from '@hcengineering/presentation'
21+
import { Button, IconAdd, Label, Section, showPopup, Scroller } from '@hcengineering/ui'
22+
import { Viewlet, ViewletPreference } from '@hcengineering/view'
23+
import { Table, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
24+
import hr from '../plugin'
25+
26+
export let department: Department
27+
export let members: Array<Ref<Employee>>
28+
export let readonly: boolean = false
29+
30+
const client = getClient()
31+
let loading = true
32+
33+
const createApp = async (ev: MouseEvent): Promise<void> => {
34+
if (readonly) {
35+
return
36+
}
37+
38+
showPopup(
39+
UsersPopup,
40+
{
41+
_class: contact.mixin.Employee,
42+
ignoreUsers: members,
43+
icon: contact.icon.Person,
44+
allowDeselect: false,
45+
placeholder: hr.string.Members
46+
},
47+
ev.target as HTMLElement,
48+
async (result) => {
49+
if (result != null) {
50+
const selected: Employee[] = Array.isArray(result) ? result : [result]
51+
for (const member of selected) {
52+
await client.updateMixin(member._id, member._class, member.space, hr.mixin.Staff, {
53+
department: department._id
54+
})
55+
}
56+
}
57+
}
58+
)
59+
}
60+
61+
let viewlet: Viewlet | undefined
62+
let preference: ViewletPreference | undefined
63+
</script>
64+
65+
<Section id="members" label={hr.string.Members} icon={hr.icon.Members}>
66+
<svelte:fragment slot="header">
67+
<div class="buttons-group xsmall-gap">
68+
<ViewletSelector
69+
hidden
70+
bind:viewlet
71+
bind:preference
72+
bind:loading
73+
viewletQuery={{ _id: hr.viewlet.TableMember }}
74+
/>
75+
<ViewletSettingButton kind={'tertiary'} bind:viewlet />
76+
{#if !readonly}
77+
<Button id={hr.string.AddMember} icon={IconAdd} kind={'ghost'} on:click={createApp} />
78+
{/if}
79+
</div>
80+
</svelte:fragment>
81+
82+
<svelte:fragment slot="content">
83+
{#if members.length > 0 && viewlet}
84+
<Scroller horizontal noFade={false}>
85+
<Table
86+
_class={contact.mixin.Employee}
87+
config={preference?.config ?? viewlet.config}
88+
options={viewlet.options}
89+
query={{ _id: { $in: members } }}
90+
loadingProps={{ length: members.length }}
91+
{readonly}
92+
/>
93+
</Scroller>
94+
{:else}
95+
<div class="antiSection-empty solid flex-col mt-3">
96+
<span class="content-dark-color">
97+
<Label label={hr.string.NoMembers} />
98+
</span>
99+
<!-- svelte-ignore a11y-click-events-have-key-events -->
100+
<!-- svelte-ignore a11y-no-static-element-interactions -->
101+
{#if !readonly}
102+
<span class="over-underline content-color" on:click={createApp}>
103+
<Label label={hr.string.AddMember} />
104+
</span>
105+
{/if}
106+
</div>
107+
{/if}
108+
</svelte:fragment>
109+
</Section>

plugins/hr/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ const hr = plugin(hrId, {
121121
HR: '' as Asset,
122122
Department: '' as Asset,
123123
Structure: '' as Asset,
124+
Members: '' as Asset,
124125
Vacation: '' as Asset,
125126
Sick: '' as Asset,
126127
PTO: '' as Asset,

0 commit comments

Comments
 (0)