mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-28 20:45:00 +02:00
* UBERF-11414: Use common integration kind Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Allow multiple gmail Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Merge with develop Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Refactor integration kinds Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Add integrations package Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Integrations Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Integration state and config Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Add integration events Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Refresh integration states Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Rename to integration-client Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Add filter button Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Add translations for filters Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Synced channels count Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Actions Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Add isLoading for connect Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Create connection and integration Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Use social id from hulygram Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Remove old integrations Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Gmail state Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Gmail state and disconnect all handler Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Add tests Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Formatting Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Gmail sync state Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix rush check Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix gmail tests Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix calendar actions and config Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Calendar state Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Access config Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Github integration state Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix svelte errors Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix formatting Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix typos Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix validate Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Fix translations Signed-off-by: Artem Savchenko <armisav@gmail.com> * UBERF-11414: Retry on network issues Signed-off-by: Artem Savchenko <armisav@gmail.com> --------- Signed-off-by: Artem Savchenko <armisav@gmail.com>
167 lines
4.8 KiB
Svelte
167 lines
4.8 KiB
Svelte
<!--
|
|
// Copyright © 2025 Hardcore Engineering Inc.
|
|
//
|
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License. You may
|
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
//
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
-->
|
|
<script lang="ts">
|
|
import { onMount, onDestroy } from 'svelte'
|
|
import { fade } from 'svelte/transition'
|
|
|
|
import { IconError, Label, Loading } from '@hcengineering/ui'
|
|
import type { Integration } from '@hcengineering/account-client'
|
|
import { IntegrationEventData, onIntegrationEvent } from '@hcengineering/integration-client'
|
|
import { type GmailSyncState } from '@hcengineering/gmail'
|
|
|
|
import gmail from '../plugin'
|
|
import { getState } from '../api'
|
|
import { IntlString } from '@hcengineering/platform'
|
|
|
|
export let integration: Integration
|
|
|
|
let isLoading = true
|
|
let isRefreshing = false
|
|
let error: string | null = null
|
|
let errorLabel: IntlString | undefined
|
|
let state: GmailSyncState | null | undefined
|
|
|
|
const unsubscribers: (() => void)[] = []
|
|
|
|
onMount(async () => {
|
|
try {
|
|
state = await getState(integration.socialId)
|
|
isLoading = false
|
|
subscribe()
|
|
} catch (err) {
|
|
error = err instanceof Error ? err.message : 'Failed to load gmail state'
|
|
if (error.includes('Failed to fetch')) {
|
|
errorLabel = gmail.string.FailedToConnect
|
|
}
|
|
isLoading = false
|
|
console.error('Error loading gmail state:', err)
|
|
}
|
|
})
|
|
|
|
onDestroy(() => {
|
|
unsubscribers.forEach((unsubscribe) => {
|
|
unsubscribe()
|
|
})
|
|
})
|
|
|
|
function subscribe (): void {
|
|
unsubscribers.push(onIntegrationEvent<IntegrationEventData>('integration:updated', onUpdateIntegration))
|
|
}
|
|
|
|
function onUpdateIntegration (data: IntegrationEventData): void {
|
|
if (
|
|
data.integration?.socialId === integration.socialId &&
|
|
data.integration?.workspaceUuid === integration.workspaceUuid
|
|
) {
|
|
void refresh()
|
|
}
|
|
}
|
|
|
|
async function refresh (): Promise<void> {
|
|
try {
|
|
isRefreshing = true
|
|
state = await getState(integration.socialId)
|
|
} catch (err: any) {
|
|
console.error('Error refresh gmail state:', err.message)
|
|
} finally {
|
|
isRefreshing = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="integration-state">
|
|
<div class="state-content">
|
|
{#if isLoading}
|
|
<div class="loading-container">
|
|
<Loading />
|
|
</div>
|
|
{:else if integration.workspaceUuid == null}
|
|
<div class="flex-center" transition:fade={{ duration: 300 }}>
|
|
<span class="text-normal content-color">
|
|
<Label label={gmail.string.NotConnectedIntegration} params={{ email: state?.email ?? '' }} />
|
|
</span>
|
|
</div>
|
|
{:else if errorLabel !== undefined}
|
|
<div class="error-container" transition:fade={{ duration: 300 }}>
|
|
<IconError size={'medium'} />
|
|
<Label label={errorLabel} />
|
|
</div>
|
|
{:else if error != null}
|
|
<div class="error-container" transition:fade={{ duration: 300 }}>
|
|
<IconError size={'medium'} />
|
|
<Label label={gmail.string.FailedToLoadState} />
|
|
</div>
|
|
{:else if state != null}
|
|
<div class="stats-list" transition:fade={{ duration: 300 }}>
|
|
<div class="stat-row">
|
|
<span class="text-normal content-color"><Label label={gmail.string.Email} /></span>
|
|
<span class="text-normal content-color font-medium">{state.email ?? 'N/A'}</span>
|
|
</div>
|
|
<div class="stat-row">
|
|
<span class="text-normal content-color"><Label label={gmail.string.TotalMessages} /></span>
|
|
<div class="flex justify-between flex-gap-2">
|
|
{#if isRefreshing}
|
|
<Loading size="small" />
|
|
{/if}
|
|
<span class="text-normal content-color font-medium">{state.totalMessages}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
.integration-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.state-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.loading-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 2rem;
|
|
}
|
|
|
|
.error-container {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.stats-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.25rem;
|
|
}
|
|
|
|
.stat-row {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
font-size: 0.85rem;
|
|
padding: 0.15rem 0;
|
|
}
|
|
</style>
|