Move services to public (#6156)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2024-07-28 14:55:43 +07:00
committed by Andrey Sobolev
parent 9aad4a4561
commit ddecae80dd
578 changed files with 109084 additions and 390 deletions
@@ -0,0 +1,27 @@
<script lang="ts">
import { Issue } from '@hcengineering/tracker'
import { getClient } from '@hcengineering/presentation'
import { HyperlinkEditor } from '@hcengineering/view-resources'
import github from '../../plugin'
import { integrationRepositories } from '../utils'
export let value: Issue
$: ghIssue = getClient().getHierarchy().asIf(value, github.mixin.GithubIssue)
$: repository = ghIssue?.repository !== undefined ? $integrationRepositories.get(ghIssue?.repository) : undefined
</script>
{#if ghIssue !== undefined && ghIssue.url !== '' && repository !== undefined}
<div class="flex flex-row-center">
<HyperlinkEditor
readonly
icon={github.icon.Github}
kind={'ghost'}
value={ghIssue.url}
placeholder={github.string.Issue}
title={`${repository.name}`}
/>
</div>
{/if}
@@ -0,0 +1,112 @@
<!--
// Copyright © 2023 Hardcore Engineering Inc.
//
-->
<script lang="ts">
import { Ref, WithLookup, groupByArray } from '@hcengineering/core'
import {
GithubPullRequestReviewState,
GithubReview,
GithubReviewComment,
GithubReviewThread
} from '@hcengineering/github'
import { ActivityMessageHeader, ActivityMessageTemplate } from '@hcengineering/activity-resources'
import { Person, PersonAccount } from '@hcengineering/contact'
import { personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
import { IntlString } from '@hcengineering/platform'
import { MessageViewer, createQuery } from '@hcengineering/presentation'
import { Component, PaletteColorIndexes, getPlatformColor, themeStore } from '@hcengineering/ui'
import diffview from '@hcengineering/diffview'
import github from '../../plugin'
import ReviewCommentPresenter from './ReviewCommentPresenter.svelte'
import { isEmptyMarkup } from '@hcengineering/text'
export let value: WithLookup<GithubReview>
export let showNotify: boolean = false
export let isHighlighted: boolean = false
export let isSelected: boolean = false
export let shouldScroll: boolean = false
export let embedded: boolean = false
export let onClick: (() => void) | undefined = undefined
$: personAccount = $personAccountByIdStore.get((value?.createdBy ?? value?.modifiedBy) as Ref<PersonAccount>)
$: person = $personByIdStore.get(personAccount?.person as Ref<Person>)
function getCommentFromState (value?: GithubPullRequestReviewState): {
label: IntlString
color?: number
} {
switch (value) {
case GithubPullRequestReviewState.Approved:
return { label: github.string.ReviewApproved, color: PaletteColorIndexes.Grass }
case GithubPullRequestReviewState.ChangesRequested:
return { label: github.string.ReviewChangesRequested, color: PaletteColorIndexes.Sunshine }
case GithubPullRequestReviewState.Commented:
return { label: github.string.ReviewCommented }
case GithubPullRequestReviewState.Dismissed:
return { label: github.string.ReviewDismissed, color: PaletteColorIndexes.Coin }
case GithubPullRequestReviewState.Pending:
default:
return { label: github.string.ReviewPending }
}
}
$: presentationState = getCommentFromState(value?.state)
</script>
{#if value?.state !== GithubPullRequestReviewState.Commented || (value?.state === GithubPullRequestReviewState.Commented && (value?.body?.length ?? 0) > 0 && !isEmptyMarkup(value?.body ?? ''))}
<div
class:review={presentationState.color !== undefined}
style:border-color={presentationState.color !== undefined
? getPlatformColor(presentationState.color, $themeStore.dark)
: undefined}
>
<ActivityMessageTemplate
message={value}
parentMessage={undefined}
{person}
{showNotify}
{isHighlighted}
{isSelected}
{shouldScroll}
{embedded}
viewlet={undefined}
{onClick}
>
<svelte:fragment slot="header">
<ActivityMessageHeader
message={value}
{person}
object={undefined}
parentObject={undefined}
isEdited={false}
label={presentationState.label}
/>
</svelte:fragment>
<svelte:fragment slot="content">
<div class="flex-row-center">
<div class="customContent">
<MessageViewer message={value.body} />
</div>
</div>
</svelte:fragment>
</ActivityMessageTemplate>
</div>
{/if}
<style lang="scss">
.review {
border: 1px solid;
border-radius: 0.5rem;
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.customContent {
display: flex;
flex-wrap: wrap;
column-gap: 0.625rem;
row-gap: 0.625rem;
}
</style>
@@ -0,0 +1,190 @@
<!--
// Copyright © 2023 Hardcore Engineering Inc.
//
-->
<script lang="ts">
import core, { Account, Ref, WithLookup, getCurrentAccount } from '@hcengineering/core'
import { GithubPullRequest, GithubReviewComment, GithubReviewThread } from '@hcengineering/github'
import { ActivityMessageHeader, ActivityMessageTemplate } from '@hcengineering/activity-resources'
import { Person, PersonAccount } from '@hcengineering/contact'
import { EmployeePresenter, personAccountByIdStore, personByIdStore } from '@hcengineering/contact-resources'
import { getEmbeddedLabel } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { ReferenceInput } from '@hcengineering/text-editor-resources'
import { Button, Component, Label, PaletteColorIndexes, getPlatformColor, themeStore } from '@hcengineering/ui'
import diffview from '@hcengineering/diffview'
import github from '../../plugin'
import ReviewCommentPresenter from './ReviewCommentPresenter.svelte'
import { githubConfiguration } from '../../configuration'
export let value: WithLookup<GithubReviewThread>
export let showNotify: boolean = false
export let isHighlighted: boolean = false
export let isSelected: boolean = false
export let shouldScroll: boolean = false
export let embedded: boolean = false
export let onClick: (() => void) | undefined = undefined
$: personAccount = $personAccountByIdStore.get((value?.createdBy ?? value?.modifiedBy) as Ref<PersonAccount>)
$: person = $personByIdStore.get(personAccount?.person as Ref<Person>)
const commentsQuery = createQuery()
let comments: GithubReviewComment[] = []
$: commentsQuery.query(
github.class.GithubReviewComment,
{ attachedTo: value.attachedTo as Ref<GithubPullRequest>, reviewThreadId: value.threadId },
(res) => {
comments = res
}
)
let expanded = !value.isResolved
async function onMessage (event: CustomEvent<string>): Promise<void> {
await getClient().addCollection(
github.class.GithubReviewComment,
value.space,
value.attachedTo,
value.attachedToClass,
'reviewComments',
{
body: event.detail,
diffHunk: '',
includesCreatedEdit: false,
isMinimized: false,
line: 0,
minimizedReason: null,
originalLine: 0,
originalStartLine: 0,
outdated: false,
path: value.path,
reviewThreadId: value.threadId,
reviewUrl: '',
startLine: 0,
url: ''
}
)
}
async function changeResolution (): Promise<void> {
await getClient().update(value, { isResolved: !value.isResolved, resolvedBy: null })
}
const toRefPersonAccount = (account: Ref<Account>): Ref<PersonAccount> => account as Ref<PersonAccount>
const toRefPerson = (account?: Ref<Person>): Ref<Person> => account as Ref<Person>
</script>
<div
class:reviewUnresolved={!value.isResolved}
style:border-color={!value.isResolved ? getPlatformColor(PaletteColorIndexes.Orange, $themeStore.dark) : undefined}
>
<ActivityMessageTemplate
message={value}
parentMessage={undefined}
{person}
{showNotify}
{isHighlighted}
{isSelected}
{shouldScroll}
{embedded}
viewlet={undefined}
{onClick}
>
<svelte:fragment slot="header">
<ActivityMessageHeader
message={value}
{person}
object={undefined}
parentObject={undefined}
isEdited={false}
label={getEmbeddedLabel('reviewed')}
/>
</svelte:fragment>
<svelte:fragment slot="content">
<div class="file-content">
{#if comments.length > 0}
<Component
is={diffview.component.InlineDiffView}
props={{
patch: comments?.[0]?.diffHunk ?? '',
fileName: value.path,
expandable: value.isResolved,
expanded,
onExpand: (value) => {
expanded = value
}
}}
/>
{/if}
{#if expanded}
<div class="ml-4">
{#each comments as comment}
<ReviewCommentPresenter {comment} />
{/each}
</div>
<ReferenceInput showSend={true} showHeader showActions on:message={onMessage} />
<div class="p-2 flex-row-center flex-grow">
{#if githubConfiguration.ResolveThreadSupported}
<Button
label={value.isResolved
? getEmbeddedLabel('Unresolve conversation')
: getEmbeddedLabel('Resolve conversation')}
on:click={changeResolution}
/>
{/if}
{#if value.isResolved && value.resolvedBy != null}
{@const resolveAccount = $personAccountByIdStore.get(toRefPersonAccount(value.resolvedBy))}
{@const resolvePerson = $personByIdStore.get(toRefPerson(resolveAccount?.person))}
{#if resolvePerson !== undefined}
<div class="flex-row-center ml-4">
<Label label={getEmbeddedLabel('resolved by')} />
<div class="content ml-2 clear-mins">
<div class="header clear-mins">
{#if resolvePerson}
<EmployeePresenter value={resolvePerson} shouldShowAvatar={true} />
{:else}
<div class="strong">
<Label label={core.string.System} />
</div>
{/if}
</div>
</div>
</div>
{/if}
{/if}
</div>
{/if}
</div>
</svelte:fragment>
</ActivityMessageTemplate>
</div>
<style lang="scss">
.reviewUnresolved {
border: 1px solid;
border-radius: 0.5rem;
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.customContent {
display: flex;
flex-wrap: wrap;
column-gap: 0.625rem;
row-gap: 0.625rem;
}
.file-content {
border: 1px solid var(--theme-divider-color);
border-top: 0;
border-bottom-left-radius: 0.25rem;
border-bottom-right-radius: 0.25rem;
overflow-y: hidden;
}
.file-info {
border-top: 1px solid var(--theme-divider-color);
font-weight: 600;
direction: rtl;
text-align: left;
}
</style>
@@ -0,0 +1,16 @@
<script lang="ts">
import { Label } from '@hcengineering/ui'
import { PullRequestMergeable } from '@hcengineering/github'
import github from '../../plugin'
export let value: PullRequestMergeable
export let accent = false
</script>
<div class="p-1" class:fs-bold={accent}>
{#if value === PullRequestMergeable.CONFLICTING}
<Label label={github.string.Conflict} />
{:else if value === PullRequestMergeable.MERGEABLE}
<Label label={github.string.ReadyForMerge} />
{/if}
</div>
@@ -0,0 +1,42 @@
<!--
// Copyright © 2023 Hardcore Engineering Inc.
//
-->
<script lang="ts">
import { createQuery, getClient } from '@hcengineering/presentation'
import { Issue } from '@hcengineering/tracker'
import { GithubIssue, GithubProject, GithubPullRequest } from '@hcengineering/github'
import github from '../../plugin'
export let value: GithubPullRequest
const client = getClient()
const spaceQuery = createQuery()
let currentProject: GithubProject | undefined = undefined
$: spaceQuery.query(github.mixin.GithubProject, { _id: value.space }, (res) => {
;[currentProject] = res
})
$: ghIssue = client.getHierarchy().hasMixin(value, github.mixin.GithubIssue)
? client.getHierarchy().as<Issue, GithubIssue>(value, github.mixin.GithubIssue)
: undefined
</script>
{#if value}
<div class="flex-col">
<div class="flex-row-center crop-presenter">
<span class="font-medium mr-2 whitespace-nowrap clear-mins">{value.identifier}</span>
<span class="overflow-label">
{currentProject?.name}
</span>
</div>
<span class="overflow-label mt-10px">
{value.title}
{#if ghIssue}
# {ghIssue.githubNumber}
{/if}
</span>
</div>
{/if}
@@ -0,0 +1,29 @@
<!--
//
// Copyright © 2023 Hardcore Engineering Inc.
//
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { IssuePresenter } from '@hcengineering/tracker-resources'
import github, { GithubPullRequest } from '@hcengineering/github'
export let value: WithLookup<GithubPullRequest>
export let disabled = false
export let onClick: (() => void) | undefined = undefined
export let shouldShowAvatar: boolean = false
export let noUnderline = false
export let inline = false
export let kind: 'list' | undefined = undefined
</script>
<IssuePresenter
{value}
{disabled}
{onClick}
{shouldShowAvatar}
{noUnderline}
{inline}
{kind}
icon={github.icon.PullRequest}
/>
@@ -0,0 +1,52 @@
<script lang="ts">
import { Asset, IntlString } from '@hcengineering/platform'
import { AnySvelteComponent, Icon, Label, PaletteColorIndexes, getPlatformColor, themeStore } from '@hcengineering/ui'
import { GithubReviewDecisionState } from '@hcengineering/github'
import { ComponentType } from 'svelte'
import github from '../../plugin'
export let value: GithubReviewDecisionState
export let small = false
const labels: Record<
GithubReviewDecisionState,
{ label: IntlString, color: number, icon: Asset | AnySvelteComponent | ComponentType }
> = {
[GithubReviewDecisionState.Approved]: {
icon: github.icon.PullRequest,
label: github.string.ReviewApproved,
color: PaletteColorIndexes.Grass
},
[GithubReviewDecisionState.ChangesRequested]: {
icon: github.icon.PullRequest,
label: github.string.ReviewChangesRequested,
color: PaletteColorIndexes.Firework
},
[GithubReviewDecisionState.ReviewRequired]: {
icon: github.icon.PullRequest,
label: github.string.ReviewPending,
color: PaletteColorIndexes.Blueberry
}
}
$: label = labels[value]
</script>
<div
class={!small ? 'p-1 border-radius-1' : ''}
style:background-color={!small ? getPlatformColor(label.color, $themeStore.dark) : undefined}
style:color={'white'}
>
<div class="flex-row-center no-word-wrap">
<Icon
icon={label.icon}
size={'small'}
fill={small ? getPlatformColor(label.color, $themeStore.dark) : 'currentColor'}
/>
{#if !small}
<div class="ml-1">
<Label label={label.label} />
</div>
{/if}
</div>
</div>
@@ -0,0 +1,18 @@
<script lang="ts">
import { Label } from '@hcengineering/ui'
import { GithubPullRequestState } from '@hcengineering/github'
import github from '../../plugin'
export let value: GithubPullRequestState
export let accent = false
</script>
<div class="p-1" class:fs-bold={accent}>
{#if value === GithubPullRequestState.open}
<Label label={github.string.PROpen} />
{:else if value === GithubPullRequestState.merged}
<Label label={github.string.PRMerged} />
{:else if value === GithubPullRequestState.closed}
<Label label={github.string.PRClosed} />
{/if}
</div>
@@ -0,0 +1,17 @@
<!--
//
// Copyright © 2023 Hardcore Engineering Inc.
//
-->
<script lang="ts">
import { Icon } from '@hcengineering/ui'
import { GithubIntegrationRepository } from '@hcengineering/github'
import github from '../../plugin'
export let value: GithubIntegrationRepository
</script>
<div class="flex-row-center">
<Icon icon={github.icon.GithubRepository} size={'small'} />
<span class="ml-1">{value.name}</span>
</div>
@@ -0,0 +1,58 @@
<script lang="ts">
import { Person, PersonAccount } from '@hcengineering/contact'
import {
EmployeePresenter,
SystemAvatar,
personAccountByIdStore,
personByIdStore
} from '@hcengineering/contact-resources'
import Avatar from '@hcengineering/contact-resources/src/components/Avatar.svelte'
import core, { Ref, getDisplayTime } from '@hcengineering/core'
import { MessageViewer } from '@hcengineering/presentation'
import { Label } from '@hcengineering/ui'
import { GithubReviewComment } from '@hcengineering/github'
export let comment: GithubReviewComment
$: personAccount = $personAccountByIdStore.get((comment?.createdBy ?? comment?.modifiedBy) as Ref<PersonAccount>)
$: person = $personByIdStore.get(personAccount?.person as Ref<Person>)
</script>
{#if comment}
<div>
<div class="flex-row-center">
<div class="min-w-6 mt-1">
{#if $$slots.icon}
<slot name="icon" />
{:else if person}
<Avatar size="tiny" {person} name={person.name} />
{:else}
<SystemAvatar size="tiny" />
{/if}
</div>
<div class="header clear-mins flex-row-center">
{#if person}
<EmployeePresenter value={person} shouldShowAvatar={false} />
{:else}
<div class="strong">
<Label label={core.string.System} />
</div>
{/if}
<span class="text-sm ml-2">{getDisplayTime(comment.createdOn ?? 0)}</span>
</div>
</div>
<div class="customContent p-2">
<MessageViewer message={comment.body} />
</div>
</div>
{/if}
<style lang="scss">
.customContent {
display: flex;
flex-wrap: wrap;
column-gap: 0.625rem;
row-gap: 0.625rem;
}
</style>
@@ -0,0 +1,21 @@
<!--
//
// Copyright © 2023 Hardcore Engineering Inc.
//
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { TitlePresenter } from '@hcengineering/tracker-resources'
import { GithubPullRequest } from '@hcengineering/github'
export let value: WithLookup<GithubPullRequest>
export let shouldUseMargin: boolean = false
export let showParent = true
export let kind: 'list' | undefined = undefined
export let onClick: (() => void) | undefined = undefined
export let disabled = false
</script>
{#if value}
<TitlePresenter {value} {shouldUseMargin} {showParent} {kind} {onClick} {disabled} />
{/if}