import { Trans, t } from '@i18next-toolkit/react'; import { Alert, Button, Collapse, Form, Input, Modal, Popconfirm, Table, Typography, } from 'antd'; import React, { useMemo, useState } from 'react'; import { AppRouterOutput, defaultErrorHandler, defaultSuccessHandler, trpc, } from '../../api/trpc'; import { useCurrentWorkspaceId } from '../../store/user'; import { type ColumnsType } from 'antd/es/table/interface'; import { BarChartOutlined, CodeOutlined, EditOutlined, PlusOutlined, DeleteOutlined, } from '@ant-design/icons'; import { useNavigate } from 'react-router'; import { PageHeader } from '../PageHeader'; import { useEvent } from '../../hooks/useEvent'; import { TelemetryCounter } from './TelemetryCounter'; import { LuDelete, LuTrash } from 'react-icons/lu'; type TelemetryInfo = AppRouterOutput['telemetry']['all'][number]; export const TelemetryList: React.FC = React.memo(() => { const workspaceId = useCurrentWorkspaceId(); const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [form] = Form.useForm<{ id?: string; name: string }>(); const upsertTelemetryMutation = trpc.telemetry.upsert.useMutation(); const utils = trpc.useUtils(); const [modal, contextHolder] = Modal.useModal(); const handleAddTelemetry = useEvent(async () => { await form.validateFields(); const values = form.getFieldsValue(); await upsertTelemetryMutation.mutateAsync({ telemetryId: values.id, workspaceId, name: values.name, }); utils.telemetry.all.refetch(); setIsEditModalOpen(false); form.resetFields(); }); const handleShowUsage = useEvent((info: TelemetryInfo) => { const blankGif = `${window.location.origin}/telemetry/${workspaceId}/${info.id}.gif`; const countBadgeUrl = `${window.location.origin}/telemetry/${workspaceId}/${info.id}/badge.svg`; modal.info({ maskClosable: true, title: 'How to Use Telemetry', content: (

Here is some way to use telemetry:

Insert to article:

if your article support raw html, you can direct insert it{' '} {blankGif}

Some website will not allow send `referer` field. so its maybe can not track source. so you can mark it by yourself. for example:

{blankGif}?url=https://xxxxxxxx

), }, ]} />

Count your website visitor:

if your article support raw html, you can direct insert it{' '} {countBadgeUrl}

Like this:

), }); }); const handleEditTelemetry = useEvent(async (info: TelemetryInfo) => { setIsEditModalOpen(true); form.setFieldsValue({ id: info.id, name: info.name, }); }); return (

Telemetry is a technology that reports access data even on pages that are not under your control. As long as the other website allows the insertion of third-party images (e.g., forums, blogs, and various rich-text editors), then the data can be collected and used to analyze the images when they are loaded by the user.

Generally, we will use a one-pixel blank image so that it will not affect the user's normal use.

At the same time, we can also use it in some client-side application scenarios, such as collecting the frequency of cli usage, such as collecting the installation of selfhosted apps, and so on.

} action={
} /> handleAddTelemetry()} onCancel={() => setIsEditModalOpen(false)} >
{contextHolder} ); }); TelemetryList.displayName = 'TelemetryList'; const TelemetryListTable: React.FC<{ onEdit: (info: TelemetryInfo) => void; onShowUsage: (info: TelemetryInfo) => void; }> = React.memo((props) => { const workspaceId = useCurrentWorkspaceId(); const { data = [], isLoading, refetch, } = trpc.telemetry.all.useQuery({ workspaceId, }); const navigate = useNavigate(); const deleteMutation = trpc.telemetry.delete.useMutation({ onSuccess: defaultSuccessHandler, onError: defaultErrorHandler, }); const columns = useMemo((): ColumnsType => { return [ { dataIndex: 'name', title: t('Name'), }, { dataIndex: 'id', title: t('Count'), align: 'center', width: 130, render: (id) => { return ; }, }, { key: 'action', title: t('Actions'), align: 'right', width: 240, render: (_, record) => { return (
{ await deleteMutation.mutateAsync({ telemetryId: record.id, workspaceId, }); await refetch(); }} >
); }, }, ] as ColumnsType; }, []); return ( ); }); TelemetryListTable.displayName = 'TelemetryListTable';