platform/plugins/telegram-resources/src/components/ConfigureBotPopup.svelte
2024-08-13 10:00:49 +07:00

210 lines
6.3 KiB
Svelte

<!--
// Copyright © 2024 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 { CodeForm, Icon, IconCheckmark, Label, Loading, Modal, ModernButton } from '@hcengineering/ui'
import presentation from '@hcengineering/presentation'
import { getEmbeddedLabel, getMetadata, IntlString } from '@hcengineering/platform'
import { concatLink, getCurrentAccount } from '@hcengineering/core'
import { onMount } from 'svelte'
import telegram from '../plugin'
import TelegramColor from './icons/TelegramColor.svelte'
let isTestingConnection = false
let isConnectionEstablished = false
let connectionError: Error | undefined
let info: { name: string, username: string, photoUrl: string } | undefined = undefined
let isLoading = false
const url = getMetadata(telegram.metadata.BotUrl) ?? ''
onMount(() => {
void loadBotInfo()
})
async function loadBotInfo (): Promise<void> {
if (info !== undefined || isLoading) return
isLoading = true
try {
const link = concatLink(url, '/info')
const res = await fetch(link, {
method: 'GET',
headers: {
Authorization: 'Bearer ' + getMetadata(presentation.metadata.Token),
'Content-Type': 'application/json'
}
})
info = await res.json()
} catch (e) {}
isLoading = false
}
async function handleTestConnection (): Promise<void> {
isTestingConnection = true
isConnectionEstablished = false
connectionError = undefined
try {
const link = concatLink(url, '/test')
const res = await fetch(link, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + getMetadata(presentation.metadata.Token),
'Content-Type': 'application/json'
}
})
isConnectionEstablished = res.ok
if (!res.ok) {
connectionError = new Error('Connection failed')
}
} catch (e) {
connectionError = e as Error
}
isTestingConnection = false
}
const codeFields = [
{ id: 'code-1', name: 'code-1', optional: false },
{ id: 'code-2', name: 'code-2', optional: false },
{ id: 'code-3', name: 'code-3', optional: false },
{ id: 'code-4', name: 'code-4', optional: false },
{ id: 'code-5', name: 'code-5', optional: false },
{ id: 'code-6', name: 'code-6', optional: false }
]
let isCodeValid = false
let codeError: IntlString | undefined
async function handleCode (event: CustomEvent<string>): Promise<void> {
isCodeValid = false
codeError = undefined
try {
const link = concatLink(url, '/auth')
const res = await fetch(link, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + getMetadata(presentation.metadata.Token),
'Content-Type': 'application/json'
},
body: JSON.stringify({ code: event.detail, account: getCurrentAccount()._id })
})
isCodeValid = res.ok
if (!res.ok) {
codeError = res.status === 409 ? telegram.string.AccountAlreadyConnected : telegram.string.InvalidCode
}
} catch (e) {
codeError = telegram.string.SomethingWentWrong
}
}
</script>
<Modal
label={getEmbeddedLabel('Connect Telegram Bot')}
type="type-popup"
okLabel={presentation.string.Ok}
okAction={() => {}}
showCancelButton={false}
canSave
on:close
>
<div class="hulyModal-content__titleGroup" style="padding: 0">
{#if isLoading}
<div class="flex-row-top mt-2 h-32">
<Loading size="medium" />
</div>
{:else if info}
<div class="flex-col mt-2">
<div class="title overflow-label mb-4">
<div class="flex-row-center flex-gap-2">
{#if info.photoUrl !== ''}
<img class="photo" src={info.photoUrl} alt="" />
{:else}
<Icon icon={TelegramColor} size="x-large" />
{/if}
{info.name} (@{info.username})
<ModernButton
label={telegram.string.TestConnection}
size="small"
loading={isTestingConnection}
on:click={handleTestConnection}
/>
{#if isConnectionEstablished}
<span class="flex-row-center flex-gap-1 label-connected">
<Label label={telegram.string.Connected} />
<Icon icon={IconCheckmark} size="medium" />
</span>
{/if}
</div>
{#if connectionError}
<span class="label-error mt-2">
<Label label={telegram.string.ConnectBotError} />
</span>
{/if}
</div>
<div class="flex-row-center flex-gap-1 mt-2">
<Label label={telegram.string.ConnectBotInfoStart} />
<a target="_blank" href={`https://t.me/${info.username}`}>{info.username}</a>
<Label label={telegram.string.ConnectBotInfoEnd} />
</div>
<CodeForm fields={codeFields} size="small" on:submit={handleCode} />
{#if codeError}
<span class="label-error mt-2">
<Label label={codeError} />
</span>
{:else if isCodeValid}
<span class="flex-row-center flex-gap-1 mt-2 label-connected">
<Label label={telegram.string.Connected} />
<Icon icon={IconCheckmark} size="medium" />
</span>
{/if}
</div>
{:else}
<span class="label-error mt-2">
<Label label={getEmbeddedLabel('Unable connect to service. Please try again.')} />
</span>
{/if}
</div>
</Modal>
<style lang="scss">
.label-connected {
color: var(--global-online-color);
}
.label-error {
color: var(--global-error-TextColor);
}
a {
color: var(--theme-link-color);
&:hover,
&:active,
&:visited {
color: var(--theme-link-color);
}
}
.photo {
border-radius: 50%;
width: 2.5rem;
height: 2.5rem;
}
</style>