Files
huly-platform/plugins/controlled-documents-resources/src/components/TeamPopup.svelte
T
2025-10-12 08:55:50 +07:00

164 lines
5.4 KiB
Svelte

<!--
//
// Copyright © 2023 Hardcore Engineering Inc.
//
-->
<script lang="ts">
import { Employee } from '@hcengineering/contact'
import { UserBoxItems, getPermittedPersons, permissionsStore } from '@hcengineering/contact-resources'
import documents, {
ControlledDocument,
ControlledDocumentState,
DocumentRequest
} from '@hcengineering/controlled-documents'
import { Class, Ref, TxOperations } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import { RequestStatus } from '@hcengineering/request'
import { Label, ModernDialog, showPopup } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import documentsRes from '../plugin'
import { sendApprovalRequest, sendReviewRequest } from '../utils'
import SignatureDialog from './SignatureDialog.svelte'
type SendRequestFunc = (
client: TxOperations,
controlledDoc: ControlledDocument,
users: Array<Ref<Employee>>,
externalUsers: Array<Ref<Employee>>,
oldExternalUsers: Array<Ref<Employee>>
) => Promise<void>
export let controlledDoc: ControlledDocument
export let requestClass: Ref<Class<DocumentRequest>>
export let readonly: boolean = false
export let requireSignature: boolean = false
const client = getClient()
const hierarchy = client.getHierarchy()
const dispatch = createEventDispatcher()
const isReviewRequest = hierarchy.isDerived(requestClass, documentsRes.class.DocumentReviewRequest)
const docField: keyof ControlledDocument = isReviewRequest ? 'reviewers' : 'approvers'
const label = isReviewRequest ? documentsRes.string.SelectReviewers : documentsRes.string.SelectApprovers
const sendRequestFunc: SendRequestFunc = isReviewRequest ? sendReviewRequest : sendApprovalRequest
const permissionId = isReviewRequest ? documents.permission.ReviewDocument : documents.permission.ApproveDocument
$: permissionsSpace =
controlledDoc.space === documents.space.UnsortedTemplates ? documents.space.QualityDocuments : controlledDoc.space
$: permittedPeople = new Set(getPermittedPersons(permissionId, permissionsSpace, $permissionsStore))
$: permittedEmployees = Array.from(permittedPeople) as Ref<Employee>[]
let docRequest: DocumentRequest | undefined
let loading = true
void client
.findOne(requestClass, {
attachedTo: controlledDoc._id,
status: RequestStatus.Active
})
.then((res) => {
loading = false
docRequest = res
})
let users: Ref<Employee>[] = controlledDoc[docField] ?? []
let externalUsers: Ref<Employee>[] = isReviewRequest ? [] : (controlledDoc.externalApprovers ?? [])
const existingExternalUsers = externalUsers
async function submit (): Promise<void> {
const complete = async (): Promise<void> => {
loading = true
await sendRequestFunc?.(client, controlledDoc, users, isReviewRequest ? [] : externalUsers, existingExternalUsers)
loading = false
dispatch('close')
}
if (requireSignature) {
showPopup(
SignatureDialog,
{
confirmationTitle: isReviewRequest
? documentsRes.string.ConfirmReviewSubmission
: documentsRes.string.ConfirmApprovalSubmission
},
'center',
async (res) => {
if (!res) return
await complete()
}
)
} else {
await complete()
}
}
$: canSubmit = docRequest === undefined && (users.length > 0 || externalUsers.length > 0)
</script>
<ModernDialog {loading} {label} {canSubmit} on:submit={submit} on:close>
<div class="flex-col pt-2 flex-gap-4">
<div class="flex">
<div class="flex labelContainer">
<div class="label mr-1">
<Label label={isReviewRequest ? documentsRes.string.Reviewers : documentsRes.string.Approvers} />
</div>
{users?.length}
</div>
<div class="flex-col">
<UserBoxItems
items={users}
label={isReviewRequest ? documentsRes.string.Reviewers : documentsRes.string.Approvers}
readonly={controlledDoc.controlledState === ControlledDocumentState.InReview ||
controlledDoc.controlledState === ControlledDocumentState.InApproval ||
readonly}
docQuery={{
active: true,
_id: { $in: permittedEmployees }
}}
on:update={({ detail }) => (users = detail)}
/>
</div>
</div>
{#if !isReviewRequest}
<div class="flex">
<div class="flex labelContainer">
<div class="label mr-1">
<Label label={documentsRes.string.ExternalApprovers} />
</div>
{externalUsers?.length}
</div>
<div class="flex-col">
<UserBoxItems
items={externalUsers}
label={documentsRes.string.ExternalApprovers}
readonly={controlledDoc.controlledState === ControlledDocumentState.InReview ||
controlledDoc.controlledState === ControlledDocumentState.InApproval ||
readonly}
docQuery={{
active: true,
role: 'GUEST',
_id: { $nin: permittedEmployees }
}}
on:update={({ detail }) => (externalUsers = detail)}
/>
</div>
</div>
{/if}
</div>
</ModernDialog>
<style lang="scss">
.labelContainer {
min-width: 11rem;
}
.label {
color: var(--theme-qms-form-row-label-color);
font-weight: 500;
}
</style>