Support for rating system (#10124)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2025-10-24 10:10:01 +07:00
committed by GitHub
parent 768ff39ab1
commit ffd8d90378
137 changed files with 5005 additions and 712 deletions
@@ -13,8 +13,9 @@
// limitations under the License.
-->
<script lang="ts">
import { PluginConfiguration } from '@hcengineering/core'
import { pluginConfigurationStore, getClient } from '@hcengineering/presentation'
import { PluginConfiguration, systemAccountUuid } from '@hcengineering/core'
import { createQuery, getClient, pluginConfigurationStore, hasResource } from '@hcengineering/presentation'
import ratingPlugin, { getRaiting, type PersonRating } from '@hcengineering/rating'
import { Breadcrumb, Button, Header, Icon, IconInfo, Label, Scroller } from '@hcengineering/ui'
import setting from '../plugin'
@@ -25,6 +26,19 @@
enabled: value
})
}
const sysQuery = createQuery()
let sysRating: PersonRating | undefined
sysQuery.query(ratingPlugin.class.PersonRating, { accountId: systemAccountUuid }, (res) => {
sysRating = res[0]
})
$: totalVisible = getRaiting(
100,
sysRating,
$pluginConfigurationStore.list.filter((it) => it.enabled && it.hidden !== true && it.system !== true)
)
</script>
<div class="hulyComponent">
@@ -39,6 +53,7 @@
<div class="flex-row-center flex-wrap gap-around-4">
{#each $pluginConfigurationStore.list as config}
{#if config.hidden !== true && config.system !== true}
{@const pluginRating = getRaiting(totalVisible, sysRating, [config])}
<div class="cardBox flex-col clear-mins" class:enabled={config.enabled ?? true}>
<div class="flex-row-center">
<span class="mr-2">
@@ -46,6 +61,10 @@
</span>
<span class="fs-title">
<Label label={config.label} />
{#if hasResource(ratingPlugin.component.RatingRing)}
- ({pluginRating}%)
{/if}
</span>
</div>
{#if config.description}
@@ -18,20 +18,22 @@
import { getCurrentAccount, SocialIdType } from '@hcengineering/core'
import login, { loginId } from '@hcengineering/login'
import { getResource } from '@hcengineering/platform'
import { AttributeEditor, MessageBox, getClient } from '@hcengineering/presentation'
import { AttributeEditor, createQuery, getClient, hasResource, MessageBox } from '@hcengineering/presentation'
import {
Breadcrumb,
Button,
Component,
createFocusManager,
EditBox,
FocusHandler,
Header,
createFocusManager,
showPopup,
navigate,
Scroller
Scroller,
showPopup
} from '@hcengineering/ui'
import { logIn, logOut } from '@hcengineering/workbench-resources'
import rating, { type PersonRating } from '@hcengineering/rating'
import setting from '../plugin'
import SocialIdsEditor from './socialIds/SocialIdsEditor.svelte'
@@ -39,6 +41,16 @@
const account = getCurrentAccount()
const email = account.fullSocialIds.find((si) => si.type === SocialIdType.EMAIL)?.value ?? ''
const levelQuery = createQuery()
let personRating: PersonRating | undefined
levelQuery.query(rating.class.PersonRating, { accountId: account.uuid }, (res) => {
personRating = res[0]
})
$: console.log('SYS', personRating)
let firstName = ''
let lastName = ''
let initialized = false
@@ -102,7 +114,7 @@
<div class="ac-body p-10 flex-col max-w-240 content">
{#if $myEmployeeStore}
<div class="flex flex-grow w-full">
<div class="mr-8">
<div class="mr-8 flex-col items-center">
<EditableAvatar
person={$myEmployeeStore}
{email}
@@ -111,6 +123,14 @@
bind:this={avatarEditor}
on:done={onAvatarDone}
/>
{#if hasResource(rating.component.RatingRing)}
<div class="flex-row-center">
<Component
is={rating.component.RatingRing}
props={{ rating: personRating?.rating ?? 0, showValues: true }}
/>
</div>
{/if}
</div>
<div class="flex-grow flex-col">
<EditBox
@@ -149,7 +169,15 @@
</div>
{/if}
<div class="separator" />
<SocialIdsEditor />
{#if hasResource(rating.component.RatingRing)}
{#if personRating != null}
<div class="flex-row-center mt-2">
<Component is={rating.component.RatingActivities} props={{ rating: personRating }} />
</div>
{/if}
<div class="separator" />
{/if}
<SocialIdsEditor rating={personRating} />
<div class="footer">
<Button
icon={setting.icon.Signout}
@@ -13,7 +13,8 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import contact, { SocialIdentity, SocialIdentityProvider, SocialIdentityRef } from '@hcengineering/contact'
import { SocialIdentityPresenter } from '@hcengineering/contact-resources'
import {
getCurrentAccount,
loginSocialTypes,
@@ -21,19 +22,20 @@
setCurrentAccount,
SocialId
} from '@hcengineering/core'
import { Button, getPlatformColorDef, Label, PaletteColorIndexes, showPopup, themeStore } from '@hcengineering/ui'
import contact, { SocialIdentity, SocialIdentityProvider, SocialIdentityRef } from '@hcengineering/contact'
import { SocialIdentityPresenter } from '@hcengineering/contact-resources'
import { getClient, MessageBox } from '@hcengineering/presentation'
import { setPlatformStatus, unknownError } from '@hcengineering/platform'
import { getClient, MessageBox } from '@hcengineering/presentation'
import { getPlatformColorDef, Label, PaletteColorIndexes, showPopup, themeStore } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import { Analytics } from '@hcengineering/analytics'
import setting from '../../plugin'
import { getAccountClient } from '../../utils'
import { Analytics } from '@hcengineering/analytics'
export let socialId: SocialId
export let socialIdProvider: SocialIdentityProvider
export let canRelease: boolean = false
export let socialIdRating: number | undefined = undefined
export let socialIdRatingTotal: number | undefined = undefined
const client = getClient()
const accountClient = getAccountClient()
@@ -116,6 +118,12 @@
<div class="flex-row-center flex-gap-2 root">
<SocialIdentityPresenter value={socialIdentity} {socialIdProvider} />
{#if socialIdRating != null && socialIdRatingTotal != null && socialIdRatingTotal > 0}
<div class="on-hover">
{Math.round((socialIdRating / socialIdRatingTotal) * 100)}%
</div>
{/if}
<div class="flex-grow" />
{#if isLogin}
@@ -13,14 +13,18 @@
// limitations under the License.
-->
<script lang="ts">
import { getCurrentAccount, loginSocialTypes, notEmpty, SocialIdType } from '@hcengineering/core'
import { FocusHandler, createFocusManager, showPopup, Label, Button, Menu, Action, Scroller } from '@hcengineering/ui'
import { getClient } from '@hcengineering/presentation'
import contact from '@hcengineering/contact'
import { getCurrentAccount, loginSocialTypes, notEmpty, SocialIdType } from '@hcengineering/core'
import { getClient, hasResource } from '@hcengineering/presentation'
import { Action, Button, createFocusManager, FocusHandler, Label, Menu, Scroller, showPopup } from '@hcengineering/ui'
import view from '@hcengineering/view'
import SocialIdRow from './SocialIdRow.svelte'
import type { PersonRating } from '@hcengineering/rating'
import ratingPlugin from '@hcengineering/rating'
import setting from '../../plugin'
import SocialIdRow from './SocialIdRow.svelte'
export let rating: PersonRating | undefined
let account = getCurrentAccount()
const manager = createFocusManager()
@@ -59,6 +63,9 @@
function handleAccountUpdated (): void {
account = getCurrentAccount()
}
$: socialIdRatingTotal =
rating != null ? Object.values(rating?.socialIds ?? {}).reduce((sum, val) => sum + (val ?? 0), 0) : 0
</script>
<FocusHandler {manager} />
@@ -80,8 +87,19 @@
? !onlyLogin
: true}
{#if socialIdProvider != null && socialId.type !== SocialIdType.HULY}
{@const socialIdRating =
rating != null && hasResource(ratingPlugin.component.RatingRing)
? rating.socialIds?.[socialId?._id]
: undefined}
<div class="item">
<SocialIdRow {socialId} {socialIdProvider} {canRelease} on:released={handleAccountUpdated} />
<SocialIdRow
{socialId}
{socialIdProvider}
{canRelease}
on:released={handleAccountUpdated}
{socialIdRating}
{socialIdRatingTotal}
/>
</div>
{/if}
{/each}