Merge pull request #1730 from appwrite/fix-analytic-events

Fix analytic events
This commit is contained in:
Ernst Mulders
2025-03-06 15:35:49 +01:00
committed by GitHub
86 changed files with 450 additions and 151 deletions
+65 -1
View File
@@ -138,6 +138,59 @@ export function isTrackingAllowed() {
}
}
export enum Click {
BackupRestoreClick = 'click_backup_restore',
BreadcrumbClick = 'click_breadcrumb',
ConnectRepositoryClick = 'click_connect_repository',
CreditsRedeemClick = 'click_credits_redeem',
CloudSignupClick = 'click_cloud_signup',
DatabaseAttributeDelete = 'click_attribute_delete',
DatabaseIndexDelete = 'click_index_delete',
DatabaseCollectionDelete = 'click_collection_delete',
DatabaseDatabaseDelete = 'click_database_delete',
DomainCreateClick = 'click_domain_create',
DomainDeleteClick = 'click_domain_delete',
DomainRetryDomainVerificationClick = 'click_domain_retry_domain_verification',
FeedbackSubmitClick = 'click_leave_feedback',
FilterApplyClick = 'click_apply_filter',
FunctionsRedeployClick = 'click_function_redeploy',
FunctionsDeploymentDeleteClick = 'click_deployment_delete',
KeyCreateClick = 'click_key_create',
MenuDropDownClick = 'click_menu_dropdown',
MenuOverviewClick = 'click_menu_overview',
ModalCloseClick = 'click_close_modal',
MessagingScheduleClick = 'click_messaging_schedule',
MessagingTopicCreateClick = 'click_messaging_topic_create',
MessagingTargetCreateClick = 'click_messaging_target_create',
MembershipDeleteClick = 'click_delete_membership',
PlatformCreateClick = 'click_platform_create',
OrganizationClickCreate = 'click_create_organization',
OrganizationClickUpgrade = 'click_organization_upgrade',
OnboardingSetupDatabaseClick = 'click_onboarding_setup_database',
OnboardingApiReferencesClick = 'click_onboarding_api_references',
OnboardingTutorialsClick = 'click_onboarding_tutorials',
OnboardingStorageQuickstartClick = 'click_onboarding_storage_quickstart',
OnboardingFunctionsQuickstartClick = 'click_onboarding_functions_quickstart',
OnboardingAuthEmailPasswordClick = 'click_onboarding_auth_email_password',
OnboardingAuthOauth2Click = 'click_onboarding_auth_oauth2',
OnboardingAuthAllMethodsClick = 'click_onboarding_auth_all_methods',
OnboardingDiscordClick = 'click_onboarding_discord',
StorageBucketDeleteClick = 'click_bucket_delete',
SettingsWebhookUpdateSignatureClick = 'click_webhook_update_signature',
SettingsWebhookDeleteClick = 'click_webhook_delete',
SettingsInstallProviderClick = 'click_install_provider',
SettingsStartMigrationClick = 'click_start_migration',
SubmitFormClick = 'click_submit_form',
ShowCustomIdClick = 'click_show_custom_id',
SupportOpenClick = 'click_open_support_menu',
PromoClick = 'click_promo',
PolicyDeleteClick = 'click_policy_delete',
VariablesCreateClick = 'click_variable_create',
VariablesUpdateClick = 'click_variable_update',
VariablesImportClick = 'click_variable_import',
WebsiteOpenClick = 'click_open_website'
}
export enum Submit {
DownloadDPA = 'submit_download_dpa',
Error = 'submit_error',
@@ -158,6 +211,9 @@ export enum Submit {
AccountRecoveryCodesCreate = 'submit_account_recovery_codes_create',
AccountRecoveryCodesUpdate = 'submit_account_recovery_codes_update',
AccountDeleteIdentity = 'submit_account_delete_identity',
FeedbackSubmit = 'submit_leave_feedback',
FilterClear = 'submit_clear_filter',
FilterApply = 'submit_filter_apply',
UserCreate = 'submit_user_create',
UserDelete = 'submit_user_delete',
UserUpdateEmail = 'submit_user_update_email',
@@ -165,6 +221,7 @@ export enum Submit {
UserUpdateName = 'submit_user_update_name',
UserUpdatePassword = 'submit_user_update_password',
UserUpdatePhone = 'submit_user_update_phone',
UserUpdateMfa = 'submit_user_update_mfa',
UserUpdatePreferences = 'submit_user_update_preferences',
UserUpdateStatus = 'submit_user_update_status',
UserUpdateVerificationEmail = 'submit_user_update_verification_email',
@@ -186,9 +243,12 @@ export enum Submit {
MemberDelete = 'submit_member_delete',
MembershipUpdate = 'submit_membership_update',
MembershipUpdateStatus = 'submit_membership_update_status',
MessagingTargetUpdate = 'submit_messaging_target_update',
MessagingUpdateHtmlMode = 'submit_update_html_mode',
ProviderUpdate = 'submit_provider_update',
TeamCreate = 'submit_team_create',
TeamDelete = 'submit_team_delete',
TeamUpdatePreferences = 'submit_team_update_preferences',
TeamUpdateName = 'submit_team_update_name',
AuthLimitUpdate = 'submit_auth_limit_update',
AuthStatusUpdate = 'submit_auth_status_update',
@@ -231,6 +291,7 @@ export enum Submit {
FunctionUpdateTimeout = 'submit_function_update_timeout',
FunctionUpdateEvents = 'submit_function_update_events',
FunctionUpdateScopes = 'submit_function_key_update_scopes',
FunctionUpdateRuntime = 'submit_function_update_runtime',
FunctionConnectRepo = 'submit_function_connect_repo',
FunctionDisconnectRepo = 'submit_function_disconnect_repo',
FunctionRedeploy = 'submit_function_redeploy',
@@ -249,9 +310,11 @@ export enum Submit {
KeyUpdateName = 'submit_key_update_name',
KeyUpdateScopes = 'submit_key_update_scopes',
KeyUpdateExpire = 'submit_key_update_expire',
PlatformCreate = 'submit_platform_create',
PlatformDelete = 'submit_platform_delete',
PlatformUpdate = 'submit_platform_update',
DomainCreate = 'submit_domain_create',
DomainDelete = 'submit_domain_delete',
DomainUpdateVerification = 'submit_domain_update_verification',
@@ -344,5 +407,6 @@ export enum Submit {
SiteActivateDeployment = 'submit_site_activate_deployment',
RecordCreate = 'submit_dns_record_create',
RecordUpdate = 'submit_dns_record_update',
RecordDelete = 'submit_dns_record_delete'
RecordDelete = 'submit_dns_record_delete',
SearchClear = 'submit_clear_search'
}
@@ -10,6 +10,7 @@
import { clearSubPanels, popSubPanel, subPanels } from '../subPanels';
import { IconArrowSmRight } from '@appwrite.io/pink-icons-svelte';
import { Icon, Keyboard, Layout } from '@appwrite.io/pink-svelte';
import { Submit, trackEvent } from '$lib/actions/analytics';
/* eslint no-undef: "off" */
type Option = $$Generic<Omit<Command, 'group'> & { group?: string }>;
@@ -22,6 +23,7 @@
let selected = 0;
let usingKeyboard = false;
let contentEl: HTMLElement;
let didSearch = false;
async function triggerOption(option: Option) {
const prevPanels = $subPanels.length;
@@ -43,6 +45,14 @@
if (!open) return;
usingKeyboard = true;
if (search.length > 0) {
didSearch = true;
}
if (search === '' && didSearch) {
trackEvent(Submit.SearchClear);
}
let canceled = false;
dispatch('keydown', {
originalEvent: event,
@@ -1,7 +1,7 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { BillingPlan } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { HeaderAlert } from '$lib/layout';
@@ -26,7 +26,7 @@
<Button
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'limit_reached_banner'
});
@@ -1,7 +1,7 @@
<script lang="ts">
import { base } from '$app/paths';
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { BillingPlan } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { organization } from '$lib/stores/organization';
@@ -31,7 +31,7 @@
class="u-line-height-1"
href={`${base}/apply-credit?code=appw50&org=${$organization.$id}`}
on:click={() => {
trackEvent('click_credits_redeem', {
trackEvent(Click.CreditsRedeemClick, {
from: 'button',
source: 'cloud_credits_banner',
campaign: 'WelcomeManual'
@@ -1,5 +1,5 @@
<script lang="ts">
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { BillingPlan } from '$lib/constants';
import { Button } from '$lib/elements/forms';
import { tierToPlan, upgradeURL } from '$lib/stores/billing';
@@ -23,7 +23,7 @@
fullWidthMobile
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: eventSource
});
+3 -3
View File
@@ -15,7 +15,7 @@
import { addBottomModalAlerts } from '$routes/(console)/bottomAlerts';
import { project } from '$routes/(console)/project-[project]/store';
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
let currentIndex = 0;
let openModalOnMobile = false;
@@ -170,7 +170,7 @@
external={!!currentModalAlert.cta.external}
fullWidthMobile
on:click={() => {
trackEvent('click_promo', {
trackEvent(Click.PromoClick, {
promo: currentModalAlert.id,
type: shouldShowUpgrade ? 'upgrade' : 'try_now'
});
@@ -282,7 +282,7 @@
fullWidthMobile
on:click={() => {
openModalOnMobile = false;
trackEvent('click_promo', {
trackEvent(Click.PromoClick, {
promo: currentModalAlert.id,
type: shouldShowUpgrade ? 'upgrade' : 'try_now'
});
+2
View File
@@ -13,6 +13,7 @@
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { newOrgModal } from '$lib/stores/organization';
import { Click, trackEvent } from '$lib/actions/analytics';
type Project = {
name: string;
@@ -68,6 +69,7 @@
let projectsBottomSheetOpen = false;
function createOrg() {
trackEvent(Click.OrganizationClickCreate, { source: 'breadcrumbs' });
if (isCloud) {
goto(`${base}/create-organization`);
} else newOrgModal.set(true);
+7 -1
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import { Button } from '$lib/elements/forms';
import { upgradeURL } from '$lib/stores/billing';
import { Click, trackEvent } from '$lib/actions/analytics';
export let service: string;
</script>
@@ -8,6 +9,11 @@
<article class="card u-grid u-cross-center u-width-full-line">
<div class="u-flex u-flex-vertical u-gap-24 u-main-center u-cross-center">
<p class="text u-text-center">Upgrade your plan to add more {service}</p>
<Button secondary href={$upgradeURL}>Change plan</Button>
<Button
secondary
href={$upgradeURL}
on:click={() => {
trackEvent(Click.OrganizationClickUpgrade, { source: 'card_plan_limit' });
}}>Change plan</Button>
</div>
</article>
+2 -2
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { InputId } from '$lib/elements/forms';
import { InputProjectId } from '$lib/elements/forms';
import Button from '$lib/elements/forms/button.svelte';
@@ -20,7 +20,7 @@
}
$: if (show) {
trackEvent('click_show_custom_id');
trackEvent(Click.ShowCustomIdClick);
}
</script>
+4 -4
View File
@@ -2,7 +2,7 @@
import { Alert } from '$lib/components';
import { onMount } from 'svelte';
import Form from '$lib/elements/forms/form.svelte';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { clickOnEnter } from '$lib/helpers/a11y';
export let show = false;
@@ -23,7 +23,7 @@
function handleBLur(event: MouseEvent) {
if (event.target === backdrop) {
trackEvent('click_close_modal', {
trackEvent(Click.ModalCloseClick, {
from: 'backdrop'
});
closeModal();
@@ -38,7 +38,7 @@
function handleKeydown(event: KeyboardEvent) {
if (event.key === 'Escape') {
event.preventDefault();
trackEvent('click_close_modal', {
trackEvent(Click.ModalCloseClick, {
from: 'escape'
});
closeModal();
@@ -100,7 +100,7 @@
aria-label="Close Modal"
title="Close Modal"
on:click={() =>
trackEvent('click_close_modal', {
trackEvent(Click.ModalCloseClick, {
from: 'button'
})}
on:click={closeModal}>
+11 -1
View File
@@ -16,6 +16,7 @@
import { createEventDispatcher } from 'svelte';
import { Icon, Layout, Popover } from '@appwrite.io/pink-svelte';
import { IconFilter, IconFilterLine } from '@appwrite.io/pink-icons-svelte';
import { Click, Submit, trackEvent } from '$lib/actions/analytics';
export let query = '[]';
export let columns: Writable<Column[]>;
@@ -25,6 +26,7 @@
export let clearOnClick = false; // When enabled the user doesn't have to click apply to clear the filters
export let enableApply = false;
export let quickFilters = false;
export let analyticsSource = '';
let displayQuickFilters = quickFilters;
const dispatch = createEventDispatcher();
@@ -53,12 +55,14 @@
selectedColumn = null;
queries.clearAll();
if (clearOnClick) {
trackEvent(Submit.FilterClear, { source: analyticsSource });
queries.apply();
}
}
function apply() {
if (quickFilters && displayQuickFilters) {
trackEvent(Submit.FilterApply, { source: analyticsSource });
dispatch('apply');
} else if (
selectedColumn &&
@@ -118,7 +122,13 @@
<div class="is-not-mobile">
<Popover let:toggle placement="bottom-start">
<Button secondary on:click={toggle} {disabled}>
<Button
secondary
on:click={(event) => {
toggle(event);
trackEvent(Click.FilterApplyClick, { source: analyticsSource });
}}
{disabled}>
<Icon icon={IconFilterLine} slot="start" size="s" />
Filters
{#if applied > 0}
@@ -10,10 +10,10 @@
}
await sdk.forConsole.account.updateMfaChallenge(challenge.$id, code);
await invalidate(Dependencies.ACCOUNT);
trackEvent(Submit.AccountCreate);
trackEvent(Submit.AccountLogin, { mfa_used: true });
} catch (error) {
inputDigitFields?.clearInputsAndRefocus();
trackError(error, Submit.AccountCreate);
trackError(error, Submit.AccountLogin);
throw error;
}
}
+2 -2
View File
@@ -4,7 +4,7 @@
import { disableCommands } from '$lib/commandCenter';
import { beforeNavigate } from '$app/navigation';
import { Layout, Modal } from '@appwrite.io/pink-svelte';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
export let show = false;
export let error: string = null;
@@ -28,7 +28,7 @@
event.preventDefault();
if (show) {
formComponent.triggerSubmit();
trackEvent('click_submit_form', { from: 'enter' });
trackEvent(Click.SubmitFormClick, { from: 'enter' });
}
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import { ModalWrapper } from '$lib/components';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
export let show = false;
export let title = '';
@@ -28,7 +28,7 @@
aria-label="Close Modal"
title="Close Modal"
on:click={() =>
trackEvent('click_close_modal', {
trackEvent(Click.ModalCloseClick, {
from: 'button'
})}
on:click={close}>
+3 -3
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { disableCommands } from '$lib/commandCenter';
export let show = false;
@@ -23,7 +23,7 @@
function handleBLur(event: MouseEvent) {
if (event.target === dialog) {
trackEvent('click_close_modal', {
trackEvent(Click.ModalCloseClick, {
from: 'backdrop'
});
closeModal();
@@ -50,7 +50,7 @@
function handleKeydown(event: KeyboardEvent) {
if (event.key === 'Escape') {
event.preventDefault();
trackEvent('click_close_modal', {
trackEvent(Click.ModalCloseClick, {
from: 'escape'
});
closeModal();
+6 -5
View File
@@ -44,7 +44,7 @@
import { isTabletViewport } from '$lib/stores/viewport';
import { isCloud } from '$lib/system.js';
import { user } from '$lib/stores/user';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
let showSupport = false;
@@ -80,6 +80,7 @@
}
function toggleFeedback() {
trackEvent(Click.FeedbackSubmitClick);
feedback.toggleFeedback();
if ($feedback.notification) {
feedback.toggleNotification();
@@ -138,7 +139,7 @@
size="s"
variant="primary"
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'top_nav'
});
@@ -153,7 +154,7 @@
variant="compact"
on:click={() => {
toggleFeedback();
trackEvent('click_menu_feedback', { source: 'top_nav' });
trackEvent(Click.FeedbackSubmitClick, { source: 'top_nav' });
}}
>Feedback
</Button.Button>
@@ -173,7 +174,7 @@
type="button"
on:click={() => {
showSupport = !showSupport;
trackEvent('click_menu_support', { source: 'top_nav' });
trackEvent(Click.SupportOpenClick, { source: 'top_nav' });
}}>
Support
</Button.Button>
@@ -199,7 +200,7 @@
showAccountMenu = !showAccountMenu;
shouldAnimateThemeToggle = false;
if (showAccountMenu) {
trackEvent('click_menu_dropdown');
trackEvent(Click.MenuDropDownClick);
}
}}>
<div style:user-select="none">
+6 -5
View File
@@ -34,7 +34,7 @@
import MobileFeedbackModal from '$routes/(console)/wizard/feedback/mobileFeedbackModal.svelte';
import { getSidebarState, updateSidebarState } from '$lib/helpers/sidebar';
import { isTabletViewport } from '$lib/stores/viewport';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
type $$Props = HTMLElement & {
state?: 'closed' | 'open' | 'icons';
@@ -58,6 +58,7 @@
export let subNavigation = undefined;
function toggleFeedback() {
trackEvent(Click.FeedbackSubmitClick);
feedback.toggleFeedback();
if ($feedback.notification) {
feedback.toggleNotification();
@@ -139,7 +140,7 @@
class="link"
class:active={pathname.includes('overview')}
on:click={() => {
trackEvent('click_menu_overview');
trackEvent(Click.MenuOverviewClick);
sideBarIsOpen = false;
}}
><span class="link-icon"
@@ -243,7 +244,7 @@
size="s"
on:click={() => {
toggleFeedback();
trackEvent('click_menu_feedback', { source: 'side_nav' });
trackEvent(Click.FeedbackSubmitClick, { source: 'side_nav' });
}}
>Feedback
</Button.Button>
@@ -258,7 +259,7 @@
size="s"
on:click={() => {
$showSupportModal = true;
trackEvent('click_menu_support', { source: 'side_nav' });
trackEvent(Click.SupportOpenClick, { source: 'side_nav' });
}}>
<span>Support</span>
@@ -318,7 +319,7 @@
size="s"
on:click={() => {
$showSupportModal = true;
trackEvent('click_menu_support', { source: 'side_nav' });
trackEvent(Click.SupportOpenClick, { source: 'side_nav' });
}}>
<span>Support</span>
+3 -3
View File
@@ -3,7 +3,7 @@
import { wizard } from '$lib/stores/wizard';
import SupportWizard from '$routes/(console)/supportWizard.svelte';
import { isSupportOnline, showSupportModal } from '$routes/(console)/wizard/support/store';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { localeShortTimezoneName, utcHourToLocaleHour } from '$lib/helpers/date';
import { upgradeURL } from '$lib/stores/billing';
import { Card } from '$lib/components/index';
@@ -82,7 +82,7 @@
<Button
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'support_menu'
});
@@ -119,7 +119,7 @@
secondary
class="secondary-button u-flex u-cross-center u-gap-6"
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'support_menu'
});
+2 -2
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { getServiceLimit, upgradeURL, type PlanServices } from '$lib/stores/billing';
import { isCloud } from '$lib/system';
import { Button } from '../forms';
@@ -41,7 +41,7 @@
secondary
href={$upgradeURL}
on:click={() =>
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: event ?? 'table_row_limit_reached'
})}>Upgrade plan</Button>
+2 -2
View File
@@ -6,12 +6,12 @@
</script>
<script lang="ts">
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
export let breadcrumbs: Breadcrumb[];
function track() {
trackEvent('click_breadcrumb');
trackEvent(Click.BreadcrumbClick);
}
</script>
+2
View File
@@ -17,6 +17,7 @@
export let buttonMethod: () => void | Promise<void>;
export let buttonHref: string = null;
export let buttonEvent: string = buttonText?.toLocaleLowerCase();
export let buttonEventData: Record<string, unknown> = {};
export let icon = 'plus';
export let showIcon = true;
export let buttonType: 'primary' | 'secondary' | 'text' = 'primary';
@@ -29,6 +30,7 @@
secondary={buttonType === 'secondary'}
on:click={buttonMethod}
event={buttonEvent}
eventData={buttonEventData}
{disabled}
href={buttonHref}>
{#if showIcon}
+2
View File
@@ -29,6 +29,7 @@
export let buttonMethod: () => void = null;
export let buttonHref: string = null;
export let buttonEvent: string = buttonText?.toLocaleLowerCase();
export let buttonEventData: Record<string, unknown> = {};
export let buttonDisabled = false;
let showDropdown = false;
@@ -172,6 +173,7 @@
disabled={isButtonDisabled}
{buttonText}
{buttonEvent}
{buttonEventData}
{buttonMethod}
{buttonHref} />
{/if}
+4 -3
View File
@@ -6,7 +6,7 @@
import { user } from '$lib/stores/user';
import { organizationList, organization, newOrgModal } from '$lib/stores/organization';
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { tooltip } from '$lib/actions/tooltip';
import { toggleCommandCenter } from '$lib/commandCenter/commandCenter.svelte';
import Button from '$lib/elements/forms/button.svelte';
@@ -30,6 +30,7 @@
function toggleFeedback() {
feedback.toggleFeedback();
trackEvent(Click.FeedbackSubmitClick);
if ($feedback.notification) {
feedback.toggleNotification();
feedback.addVisualization();
@@ -53,7 +54,7 @@
}
$: if (showDropdown) {
trackEvent('click_menu_dropdown');
trackEvent(Click.MenuDropDownClick);
}
const slideFade: typeof slide = (node, options) => {
@@ -97,7 +98,7 @@
disabled={$organization?.markedForDeletion}
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'top_nav'
});
+2 -2
View File
@@ -26,7 +26,7 @@ import { BillingPlan } from '$lib/constants';
import PaymentMandate from '$lib/components/billing/alerts/paymentMandate.svelte';
import MissingPaymentMethod from '$lib/components/billing/alerts/missingPaymentMethod.svelte';
import LimitReached from '$lib/components/billing/alerts/limitReached.svelte';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import newDevUpgradePro from '$lib/components/billing/alerts/newDevUpgradePro.svelte';
import { last } from '$lib/helpers/array';
import { sizeToBytes, type Size } from '$lib/helpers/sizeConvertion';
@@ -313,7 +313,7 @@ export async function checkForUsageLimit(org: Organization) {
name: 'Upgrade plan',
method: () => {
goto(`${base}/organization-${org.$id}/change-plan`);
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'limit_reached_notification'
});
+2
View File
@@ -4,6 +4,7 @@ import { get, writable } from 'svelte/store';
import type { SvelteComponent } from 'svelte';
import FeedbackGeneral from '$lib/components/feedback/feedbackGeneral.svelte';
import FeedbackNps from '$lib/components/feedback/feedbackNPS.svelte';
import { Submit, trackEvent } from '$lib/actions/analytics';
export type Feedback = {
elapsed: number;
@@ -118,6 +119,7 @@ function createFeedbackStore() {
value?: number
) => {
if (!VARS.GROWTH_ENDPOINT) return;
trackEvent(Submit.FeedbackSubmit);
const response = await fetch(`${VARS.GROWTH_ENDPOINT}/feedback`, {
method: 'POST',
headers: {
@@ -10,6 +10,7 @@
import { addNotification } from '$lib/stores/notifications.js';
import { Icon, Layout } from '@appwrite.io/pink-svelte';
import { IconChevronLeft } from '@appwrite.io/pink-icons-svelte';
import { Submit, trackEvent } from '$lib/actions/analytics';
export let data;
@@ -51,10 +51,10 @@
type: 'success',
message: `Address has been added`
});
trackEvent(Submit.BillingAddressCreate);
trackEvent(Submit.BillingAddressUpdate);
} catch (e) {
error = e.message;
trackError(e, Submit.BillingAddressCreate);
trackError(e, Submit.BillingAddressUpdate);
}
}
</script>
@@ -20,7 +20,7 @@
import AddCreditModal from './addCreditModal.svelte';
import { formatCurrency } from '$lib/helpers/numbers';
import { BillingPlan } from '$lib/constants';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { upgradeURL } from '$lib/stores/billing';
import { Pill } from '$lib/elements';
import { Icon, Tooltip } from '@appwrite.io/pink-svelte';
@@ -179,7 +179,7 @@
secondary
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'billing_add_credits'
});
@@ -1,6 +1,6 @@
<script lang="ts">
import { invalidate } from '$app/navigation';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Alert, CardGrid } from '$lib/components';
import { BillingPlan, Dependencies } from '$lib/constants';
import { tierToPlan, upgradeURL } from '$lib/stores/billing';
@@ -161,7 +161,7 @@
secondary
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'billing_alerts_card'
});
@@ -1,6 +1,6 @@
<script lang="ts">
import { invalidate } from '$app/navigation';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Alert, CardGrid } from '$lib/components';
import { BillingPlan, Dependencies } from '$lib/constants';
import { Button, Form, FormList, InputNumber, InputSwitch } from '$lib/elements/forms';
@@ -97,7 +97,7 @@
secondary
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'billing_budget_cap'
});
@@ -9,7 +9,7 @@
import { abbreviateNumber, formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers';
import { humanFileSize } from '$lib/helpers/sizeConvertion';
import { BillingPlan } from '$lib/constants';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { type Models } from '@appwrite.io/console';
import { Tooltip } from '@appwrite.io/pink-svelte';
@@ -212,7 +212,7 @@
disabled={$organization?.markedForDeletion}
href={$upgradeURL}
on:click={() =>
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'billing_tab'
})}>
@@ -29,6 +29,7 @@
import SearchQuery from '$lib/components/searchQuery.svelte';
import { app } from '$lib/stores/app';
import type { Domain } from '$lib/sdk/domains';
import { Click, trackEvent } from '$lib/actions/analytics';
export let data;
@@ -42,7 +43,13 @@
<Container>
<Layout.Stack direction="row" justifyContent="space-between">
<SearchQuery search={data.search} placeholder="Search domains" />
<Button href={`${base}/organization-${$page.params.organization}/domains/add-domain`}>
<Button
on:click={() => {
trackEvent(Click.DomainCreateClick, {
source: 'organization_domain_overview'
});
}}
href={`${base}/organization-${$page.params.organization}/domains/add-domain`}>
<Icon icon={IconPlus} size="s" />
Add domain
</Button>
@@ -107,6 +114,9 @@
selectedDomain = domain;
showRetry = true;
toggle(e);
trackEvent(Click.DomainRetryDomainVerificationClick, {
source: 'organization_domain_overview'
});
}}>
Retry
</ActionMenu.Item.Button>
@@ -119,6 +129,9 @@
selectedDomain = domain;
showDelete = true;
toggle(e);
trackEvent(Click.DomainDeleteClick, {
source: 'organization_domain_overview'
});
}}>
Delete
</ActionMenu.Item.Button>
@@ -166,6 +179,11 @@
<Button
secondary
on:click={() => {
trackEvent(Click.DomainCreateClick, {
source: 'organization_domain_overview'
});
}}
href={`${base}/organization-${$page.params.organization}/domains/add-domain`}
size="s">
Add domain
@@ -16,7 +16,7 @@
import { accumulateFromEndingTotal, total } from '$lib/layout/usage.svelte';
import type { OrganizationUsage } from '$lib/sdk/billing';
import { BillingPlan } from '$lib/constants';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import TotalMembers from './totalMembers.svelte';
import { tooltip } from '$lib/actions/tooltip';
import { formatCurrency, formatNumberWithCommas } from '$lib/helpers/numbers';
@@ -45,7 +45,7 @@
<Button
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'organization_usage'
});
@@ -1,5 +1,5 @@
<script lang="ts">
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { CardGrid } from '$lib/components';
import { InputPhone, InputOTP } from '$lib/elements/forms';
import { Button, Form } from '$lib/elements/forms';
@@ -136,7 +136,7 @@
external={isSelfHosted}
href={isCloud ? $upgradeURL : 'https://cloud.appwrite.io/register'}
on:click={() => {
trackEvent('click_cloud_signup', {
trackEvent(Click.CloudSignupClick, {
from: 'button',
source
});
@@ -11,7 +11,7 @@
import CreateMember from '../createMembership.svelte';
import DeleteMembership from '../deleteMembership.svelte';
import { Dependencies } from '$lib/constants';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { Table, Layout, Icon } from '@appwrite.io/pink-svelte';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
@@ -66,7 +66,7 @@
on:click|preventDefault={() => {
selectedMembership = membership;
showDelete = true;
trackEvent('click_delete_membership');
trackEvent(Click.MembershipDeleteClick);
}}>
<span class="icon-trash" aria-hidden="true" />
</button>
@@ -45,13 +45,13 @@
message: 'Preferences have been updated',
type: 'success'
});
trackEvent(Submit.UserUpdatePreferences);
trackEvent(Submit.TeamUpdatePreferences);
} catch (error) {
addNotification({
message: error.message,
type: 'error'
});
trackError(error, Submit.UserUpdatePreferences);
trackError(error, Submit.TeamUpdatePreferences);
}
}
</script>
@@ -1,5 +1,5 @@
<script lang="ts">
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { CardGrid, EmptyCardImageCloud } from '$lib/components';
import Button from '$lib/elements/forms/button.svelte';
import { app } from '$lib/stores/app';
@@ -60,7 +60,7 @@
fullWidth
href={$upgradeURL}
on:click={() => {
trackEvent('click_organization_upgrade', {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source
});
@@ -27,13 +27,13 @@
message: `Multi-factor authentication has been ${userMfa ? 'enabled' : 'disabled'}`,
type: 'success'
});
trackEvent(Submit.UserUpdateEmail);
trackEvent(Submit.UserUpdateMfa);
} catch (error) {
addNotification({
message: error.message,
type: 'error'
});
trackError(error, Submit.UserUpdateEmail);
trackError(error, Submit.UserUpdateMfa);
}
}
</script>
@@ -15,7 +15,7 @@
import EmptyLight from '$lib/images/backups/backups-light.png';
import type { BackupPolicy, BackupPolicyList } from '$lib/sdk/backups';
import { backupFrequencies } from '$lib/helpers/backups';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { Icon, Tooltip } from '@appwrite.io/pink-svelte';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
@@ -168,7 +168,7 @@
showDelete = true;
selectedPolicy = policy;
showDropdown[index] = false;
trackEvent('click_policy_delete');
trackEvent(Click.PolicyDeleteClick);
}}>
Delete
</DropListItem>
@@ -1,6 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { InnerModal } from '$lib/components';
import TextCounter from '$lib/elements/forms/textCounter.svelte';
@@ -35,7 +35,7 @@
};
$: if (show) {
trackEvent('click_show_custom_id');
trackEvent(Click.ShowCustomIdClick);
}
$: if (id === databaseId) {
@@ -22,7 +22,7 @@
import { ID } from '@appwrite.io/console';
import { database } from '../store';
import type { BackupArchive } from '$lib/sdk/backups';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { copy } from '$lib/helpers/copy';
import { LabelCard } from '$lib/components/index.js';
import { Dependencies } from '$lib/constants';
@@ -219,7 +219,7 @@
showRestore = true;
selectedBackup = backup;
showDropdown[index] = false;
trackEvent('click_backup_restore');
trackEvent(Click.BackupRestoreClick);
}}>
Restore
</DropListItem>
@@ -17,6 +17,7 @@
import Table from './table.svelte';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
import { base } from '$app/paths';
import { Submit, trackEvent } from '$lib/actions/analytics';
export let data: PageData;
@@ -45,7 +46,8 @@
<Filters
query={data.query}
{columns}
disabled={!(hasAttributes && hasValidAttributes)} />
disabled={!(hasAttributes && hasValidAttributes)}
analyticsSource="database_documents" />
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
<ViewSelector view={data.view} {columns} hideView allowNoColumns />
<Button
@@ -80,6 +82,9 @@
on:click={() => {
queries.clearAll();
queries.apply();
trackEvent(Submit.FilterClear, {
source: 'database_documents'
});
}}>
Clear filters
</Button>
@@ -35,6 +35,7 @@
IconTrash
} from '@appwrite.io/pink-icons-svelte';
import type { ComponentProps } from 'svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
const projectId = $page.params.project;
const databaseId = $page.params.database;
@@ -179,6 +180,7 @@
selectedAttribute = attribute;
showDelete = true;
showDropdown[index] = false;
trackEvent(Click.DatabaseAttributeDelete);
}}>
Delete
</ActionMenu.Item.Button>
@@ -31,6 +31,7 @@
IconTrash
} from '@appwrite.io/pink-icons-svelte';
import type { ComponentProps } from 'svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
let showDropdown = [];
let selectedIndex: Models.Index = null;
@@ -128,6 +129,7 @@
on:click={() => {
selectedIndex = index;
showDelete = true;
trackEvent(Click.DatabaseIndexDelete);
}}>Delete</ActionMenu.Item.Button>
</ActionMenu.Root>
</Popover>
@@ -4,6 +4,7 @@
import { toLocaleDateTime } from '$lib/helpers/date';
import { collection } from '../store';
import Delete from './deleteCollection.svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
let showDelete = false;
</script>
@@ -22,7 +23,12 @@
</svelte:fragment>
<svelte:fragment slot="actions">
<Button secondary on:click={() => (showDelete = true)}>Delete</Button>
<Button
secondary
on:click={() => {
trackEvent(Click.DatabaseCollectionDelete);
showDelete = true;
}}>Delete</Button>
</svelte:fragment>
</CardGrid>
@@ -1,7 +1,7 @@
<script lang="ts">
import { invalidate } from '$app/navigation';
import { page } from '$app/stores';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { BoxAvatar, Card, CardGrid } from '$lib/components';
import { Dependencies } from '$lib/constants';
import { Button, Form, Helper, InputText } from '$lib/elements/forms';
@@ -113,7 +113,12 @@
</svelte:fragment>
<svelte:fragment slot="actions">
<Button secondary on:click={() => (showDelete = true)}>Delete</Button>
<Button
secondary
on:click={() => {
showDelete = true;
trackEvent(Click.DatabaseDatabaseDelete);
}}>Delete</Button>
</svelte:fragment>
</CardGrid>
</Container>
@@ -77,6 +77,7 @@
title="Functions"
buttonText={$canWriteFunctions ? 'Create function' : ''}
buttonEvent="create_function"
buttonEventData={{ source: 'functions_overview' }}
buttonHref={`${base}/project-${project}/functions/create-function`}
total={data.functions.total} />
@@ -2,7 +2,7 @@
import { base } from '$app/paths';
import { AvatarGroup, SvgIcon } from '$lib/components';
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import type { Models } from '@appwrite.io/console';
import { isSelfHosted } from '$lib/system';
import { consoleVariables } from '$routes/(console)/store';
@@ -56,7 +56,7 @@
);
function connect(e: CustomEvent<Models.ProviderRepository>) {
trackEvent('click_connect_repository', { from: 'cover' });
trackEvent(Click.ConnectRepositoryClick, { from: 'cover' });
repository.set(e.detail);
goto(
`${wizardBase}/create-function/repository-${e.detail.id}?installation=${$installation.$id}`
@@ -109,6 +109,7 @@
trackEvent(Submit.FunctionCreate, {
source: 'repository',
runtime: runtime,
framework: runtime.key
});
@@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Card } from '$lib/components';
import { Button, Form } from '$lib/elements/forms';
import { Wizard } from '$lib/layout';
@@ -149,6 +149,7 @@
);
trackEvent(Submit.FunctionCreate, {
runtime: runtime,
source: 'template',
framework: data.template.name
});
@@ -267,7 +268,7 @@
product="sites"
action="button"
on:connect={(e) => {
trackEvent('click_connect_repository', {
trackEvent(Click.ConnectRepositoryClick, {
from: 'template-wizard'
});
repository.set(e.detail);
@@ -54,6 +54,7 @@
type: 'success'
});
trackEvent(Submit.FunctionCreate, {
runtime: $createFunction.runtime,
customId: !!$createFunction.id
});
wizard.hide();
@@ -22,6 +22,7 @@
import { onMount } from 'svelte';
import { canWriteFunctions } from '$lib/stores/roles';
import { Typography } from '@appwrite.io/pink-svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
export let data;
@@ -186,6 +187,7 @@
on:click={() => {
selectedDeployment = activeDeployment;
showRedeploy = true;
trackEvent(Click.FunctionsRedeployClick);
}}>
Redeploy
</Button>
@@ -243,7 +245,13 @@
<div class="u-flex u-main-space-between is-not-mobile u-margin-block-start-16">
<div class="u-flex u-gap-8 u-cross-center u-flex-wrap">
<QuickFilters {columns} />
<Filters query={data.query} {columns} let:disabled let:toggle singleCondition>
<Filters
query={data.query}
{columns}
let:disabled
let:toggle
singleCondition
analyticsSource="function_filters">
<div class="u-flex u-gap-4">
<Button
text
@@ -286,7 +294,11 @@
class=" u-gap-8 u-flex-wrap u-margin-block-start-16">
<QuickFilters {columns} />
<Filters query={data.query} {columns} clearOnClick>
<Filters
query={data.query}
{columns}
clearOnClick
analyticsSource="function_filters">
<svelte:fragment slot="mobile" let:disabled let:toggle>
<Pill
button
@@ -192,7 +192,13 @@
<div class="u-flex u-main-space-between is-not-mobile u-margin-block-start-16">
<div class="u-flex u-gap-8 u-cross-center u-flex-wrap">
<QuickFilters {columns} />
<Filters query={data.query} {columns} let:disabled let:toggle clearOnClick>
<Filters
query={data.query}
{columns}
let:disabled
let:toggle
clearOnClick
analyticsSource="executions_filters">
<div class="u-flex u-gap-4">
<Button
text
@@ -248,7 +254,7 @@
class=" u-gap-8 u-flex-wrap u-margin-block-start-16">
<QuickFilters {columns} />
<Filters query={data.query} {columns} clearOnClick>
<Filters query={data.query} {columns} clearOnClick analyticsSource="executions_filters">
<svelte:fragment slot="mobile" let:disabled let:toggle>
<Pill
button
@@ -20,7 +20,7 @@
import { invalidate } from '$app/navigation';
import { Alert } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { Typography } from '@appwrite.io/pink-svelte';
export let data;
@@ -62,7 +62,7 @@
<svelte:fragment slot="buttons">
<Button
on:click={() =>
trackEvent('click_open_website', {
trackEvent(Click.WebsiteOpenClick, {
from: 'button',
source: 'function_keys_card',
destination: 'docs'
@@ -89,7 +89,8 @@
{sdkDeleteVariable}
isGlobal={false}
globalVariableList={data.globalVariables}
variableList={data.variables} />
variableList={data.variables}
analyticsSource="function_settings" />
<UpdateTimeout />
<UpdateScopes />
<DangerZone />
@@ -75,13 +75,13 @@
message: 'Runtime settings have been updated',
type: 'success'
});
trackEvent(Submit.FunctionUpdateName);
trackEvent(Submit.FunctionUpdateRuntime, { runtime });
} catch (error) {
addNotification({
message: error.message,
type: 'error'
});
trackError(error, Submit.FunctionUpdateName);
trackError(error, Submit.FunctionUpdateRuntime);
}
}
@@ -20,6 +20,7 @@
import { sdk } from '$lib/stores/sdk';
import { base } from '$app/paths';
import { Table } from '@appwrite.io/pink-svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
export let columns: Column[];
export let data: PageData;
@@ -126,6 +127,7 @@
selectedDeployment = deployment;
showRedeploy = true;
showDropdown = [];
trackEvent(Click.FunctionsRedeployClick);
}}>
Redeploy
</DropListItem>
@@ -170,6 +172,7 @@
selectedDeployment = deployment;
showDropdown = [];
showDelete = true;
trackEvent(Click.FunctionsDeploymentDeleteClick);
}}>
Delete
</DropListItem>
@@ -262,6 +262,7 @@
buttonMethod={() => connectTemplate(template)}
showIcon={false}
buttonText="Create function"
buttonEventData={{ source: 'functions_template' }}
buttonEvent="create_function" />
{/if}
</div>
@@ -100,7 +100,7 @@
placeholder="Search by message ID, description, type, or status" />
</Layout.Stack>
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
<Filters query={data.query} {columns} />
<Filters query={data.query} {columns} analyticsSource="messaging_messages" />
<ViewSelector view={data.view} {columns} hideView allowNoColumns showColsTextMobile />
{#if $canWriteMessages}
<CreateMessageDropdown bind:showCreateDropdown={showCreateDropdownMobile} />
@@ -73,7 +73,13 @@
></InputText>
<InputTextarea id="message" label="Message" disabled={!isDraft} bind:value={content}
></InputTextarea>
<InputSwitch label="HTML mode" id="html" bind:value={html}>
<InputSwitch
label="HTML mode"
id="html"
bind:value={html}
on:change={() => {
trackEvent(Submit.MessagingUpdateHtmlMode);
}}>
<svelte:fragment slot="description">
Enable the HTML mode if your message contains HTML tags.
</svelte:fragment>
@@ -10,6 +10,7 @@
import ScheduleModal from './scheduleModal.svelte';
import CancelModal from './cancelModal.svelte';
import { Typography } from '@appwrite.io/pink-svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
export let message: Models.Message & { data: Record<string, string> };
export let topics: Models.Topic[];
@@ -49,7 +50,12 @@
<svelte:fragment slot="actions">
{#if message.status === 'draft'}
<div class="u-flex u-gap-16">
<Button text on:click={() => (showSchedule = true)}>Schedule</Button>
<Button
text
on:click={() => {
showSchedule = true;
trackEvent(Click.MessagingScheduleClick);
}}>Schedule</Button>
<Button secondary on:click={() => (showSend = true)}>Send message</Button>
</div>
{:else if message.status === 'scheduled'}
@@ -33,7 +33,7 @@
<SearchQuery search={data.search} placeholder="Search providers" />
</Layout.Stack>
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
<Filters query={data.query} {columns} />
<Filters query={data.query} {columns} analyticsSource="messaging_providers" />
<ViewSelector view={View.Table} {columns} hideView allowNoColumns showColsTextMobile />
{#if $canWriteProviders}
<CreateProviderDropdown bind:showCreateDropdown={showCreateDropdownDesktop} />
@@ -24,6 +24,7 @@
import { Icon, Layout } from '@appwrite.io/pink-svelte';
import { View } from '$lib/helpers/load';
import { IconPlus } from '@appwrite.io/pink-icons-svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
export let data: PageData;
@@ -56,10 +57,15 @@
<SearchQuery search={data.search} placeholder="Search by name or ID" />
</Layout.Stack>
<Layout.Stack direction="row" alignItems="center" justifyContent="flex-end">
<Filters query={data.query} {columns} />
<Filters query={data.query} {columns} analyticsSource="messaging_topics_filter" />
<ViewSelector view={View.Table} {columns} hideView allowNoColumns showColsTextMobile />
{#if $canWriteTopics}
<Button on:click={() => ($showCreate = true)} event="create_topic">
<Button
on:click={() => {
$showCreate = true;
trackEvent(Click.MessagingTopicCreateClick);
}}
event="create_topic">
<Icon icon={IconPlus} slot="start" size="s" />
Create topic
</Button>
@@ -14,7 +14,7 @@
import type { PageData } from './$types';
import { sdk } from '$lib/stores/sdk';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import Table from './table.svelte';
@@ -91,7 +91,12 @@
<div class="u-flex u-main-space-between">
<Typography.Title>Subscribers</Typography.Title>
<div class="is-only-mobile">
<Button on:click={() => (showAdd = true)} event="create_subscriber">
<Button
on:click={() => {
showAdd = true;
trackEvent(Click.MessagingTargetCreateClick);
}}
event="create_subscriber">
<Icon icon={IconPlus} slot="start" size="s" />
Add subscriber
</Button>
@@ -102,7 +107,7 @@
search={data.search}
placeholder="Search by subscriber ID, target ID, user ID, or type">
<div class="u-flex u-gap-16 is-not-mobile">
<Filters query={data.query} {columns} />
<Filters query={data.query} {columns} analyticsSource="messaging_topics" />
<ViewSelector
view={View.Table}
{columns}
@@ -127,7 +132,7 @@
</div>
<div class="u-flex-basis-50-percent">
<!-- TODO: fix width -->
<Filters query={data.query} {columns} />
<Filters query={data.query} {columns} analyticsSource="messaging_topics" />
</div>
</div>
</div>
@@ -11,6 +11,7 @@
import { Query, type Models, MessagingProviderType } from '@appwrite.io/console';
import { createEventDispatcher } from 'svelte';
import ProviderType from './providerType.svelte';
import { Submit, trackEvent } from '$lib/actions/analytics';
export let title: string;
export let show: boolean;
@@ -35,6 +36,7 @@
function submit() {
dispatch('update', selected);
trackEvent(Submit.MessagingTargetUpdate);
reset();
}
@@ -15,6 +15,7 @@
import { clickOnEnter } from '$lib/helpers/a11y';
import { ID, MessagingProviderType } from '@appwrite.io/console';
import { sdk } from '$lib/stores/sdk';
import { Submit, trackEvent } from '$lib/actions/analytics';
let showCustomId = false;
let showTest = false;
@@ -101,7 +102,13 @@
</svelte:fragment>
</Modal>
</div>
<InputSwitch label="HTML mode" id="html" bind:value={$messageParams[$providerType]['html']}>
<InputSwitch
label="HTML mode"
id="html"
bind:value={$messageParams[$providerType]['html']}
on:change={() => {
trackEvent(Submit.MessagingUpdateHtmlMode);
}}>
<svelte:fragment slot="description">
Enable the HTML mode if your message contains HTML tags.
</svelte:fragment>
@@ -35,13 +35,12 @@
import { AvatarGroup } from '$lib/components';
import type { Models } from '@appwrite.io/console';
import { getPlatformInfo } from '$lib/helpers/platform';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { goto } from '$app/navigation';
function createKey() {
trackEvent('onboarding_hub_platform', {
platform: 'server',
state: 'add'
trackEvent(Click.KeyCreateClick, {
source: 'onboarding'
});
goto(`${base}/project-${projectId}/overview/keys/create`, {
replaceState: true
@@ -56,6 +55,7 @@
if (platform) {
continuePlatform(type, platform.name, platform.key, platform.type);
} else {
trackEvent(Click.PlatformCreateClick, { source: 'onboarding' });
addPlatform(type);
}
}
@@ -392,7 +392,7 @@
direction={$isSmallViewport ? 'column' : 'row'}>
<Card.Button
on:click={() => {
trackEvent('onboarding_hub_setup_databases');
trackEvent(Click.OnboardingSetupDatabaseClick);
goto(`${base}/project-${projectId}/databases`);
}}
padding="s"
@@ -430,7 +430,7 @@
href="https://appwrite.io/docs/references"
on:click={() => {
trackEvent(
'onboarding_hub_api_references'
Click.OnboardingApiReferencesClick
);
}}
target="_blank">API references</Link.Anchor>
@@ -438,7 +438,9 @@
variant="quiet-muted"
href="https://appwrite.io/docs/tutorials"
on:click={() => {
trackEvent('onboarding_hub_tutorials');
trackEvent(
Click.OnboardingTutorialsClick
);
}}
target="_blank">Tutorials</Link.Anchor>
<Link.Anchor
@@ -446,7 +448,7 @@
href="https://appwrite.io/docs/products/storage/quick-start"
on:click={() => {
trackEvent(
'onboarding_hub_storage_quick_start'
Click.OnboardingStorageQuickstartClick
);
}}
target="_blank"
@@ -457,7 +459,7 @@
href="https://appwrite.io/docs/products/functions/quick-start"
on:click={() => {
trackEvent(
'onboarding_hub_functions_quick_start'
Click.OnboardingFunctionsQuickstartClick
);
}}
target="_blank"
@@ -487,7 +489,7 @@
href={`${base}/project-${projectId}/auth/settings`}
on:click={() => {
trackEvent(
'onboarding_hub_auth_email_password'
Click.OnboardingAuthEmailPasswordClick
);
}}
>E-mail and password
@@ -497,7 +499,7 @@
href={`${base}/project-${projectId}/auth/settings`}
on:click={() => {
trackEvent(
'onboarding_hub_auth_oauth2'
Click.OnboardingAuthOauth2Click
);
}}>OAuth 2</Link.Anchor>
<Link.Anchor
@@ -505,7 +507,7 @@
href={`${base}/project-${projectId}/auth/settings`}
on:click={() => {
trackEvent(
'onboarding_hub_auth_all_methods'
Click.OnboardingAuthAllMethodsClick
);
}}>View all methods</Link.Anchor>
</Layout.Stack>
@@ -525,7 +527,7 @@
href="https://appwrite.io/discord"
padding="s"
on:click={() => {
trackEvent('onboarding_hub_discord');
trackEvent(Click.OnboardingDiscordClick);
}}>
<div class="full-height-card">
<Layout.Stack gap="xs" justifyContent="space-between">
@@ -6,7 +6,7 @@
import CreateReactNative from './createReactNative.svelte';
import CreateWeb from './createWeb.svelte';
import { createPlatform, versions } from './wizard/store';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
export enum Platform {
Web,
@@ -19,9 +19,9 @@
export async function addPlatform(type: Platform) {
await versions.load();
createPlatform.reset();
trackEvent('onboarding_hub_platform', {
trackEvent(Click.PlatformCreateClick, {
platform: platforms[type],
state: 'add'
source: 'platforms_page'
});
wizard.start(platforms[type]);
}
@@ -38,7 +38,7 @@
key: key,
type: type
});
trackEvent('onboarding_hub_platform', {
trackEvent(Click.PlatformCreateClick, {
platform: platforms[platform],
state: 'continue'
});
@@ -85,7 +85,8 @@
{sdkUpdateVariable}
{sdkDeleteVariable}
isGlobal={true}
variableList={data.variables} />
variableList={data.variables}
analyticsSource="project_settings" />
<CardGrid>
<svelte:fragment slot="title">Transfer project</svelte:fragment>
Transfer your project to another organization that you own.
@@ -28,6 +28,7 @@
} from '@appwrite.io/pink-icons-svelte';
import { Icon, Layout, Link, Status, Table } from '@appwrite.io/pink-svelte';
import { capitalize } from '$lib/helpers/string';
import { Click, trackEvent } from '$lib/actions/analytics';
export let data;
let migration: Models.Migration = null;
@@ -249,7 +250,12 @@
</Avatar>
</Layout.Stack>
<div>
<Button secondary on:click={() => (showExport = true)}>Export data</Button>
<Button
secondary
on:click={() => {
showExport = true;
trackEvent(Click.SettingsStartMigrationClick);
}}>Export data</Button>
</div>
</Layout.Stack>
</svelte:fragment>
@@ -8,7 +8,7 @@
import { invalidate } from '$app/navigation';
import { BillingPlan, Dependencies } from '$lib/constants';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import InputNumber from '$lib/elements/forms/inputNumber.svelte';
import { base } from '$app/paths';
import deepEqual from 'deep-equal';
@@ -127,7 +127,14 @@
status="info"
title="Custom SMTP is a Pro plan feature. Upgrade to enable custom SMTP sever.">
<svelte:fragment slot="actions">
<Button compact href={$upgradeURL}>Upgrade plan</Button>
<Button
compact
href={$upgradeURL}
on:click={() => {
trackEvent(Click.OrganizationClickUpgrade, {
source: 'project_settings'
});
}}>Upgrade plan</Button>
</svelte:fragment>
</Alert.Inline>
{:else}
@@ -25,6 +25,7 @@
IconPlus,
IconXCircle
} from '@appwrite.io/pink-icons-svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
export let total: number;
export let limit: number;
@@ -84,7 +85,12 @@
<div class="u-flex u-flex-vertical-mobile u-main-end u-padding-block-end-16">
<ul class="buttons-list">
<li class="buttons-list-item">
<Button secondary on:click={() => (showGitIstall = true)}>
<Button
secondary
on:click={() => {
showGitIstall = true;
trackEvent(Click.SettingsInstallProviderClick);
}}>
<Icon icon={IconPlus} slot="start" size="s" />
Add installation
</Button>
@@ -5,6 +5,7 @@
import Delete from './delete.svelte';
import { toLocaleDateTime } from '$lib/helpers/date';
import { Card, Typography } from '@appwrite.io/pink-svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
let showDelete = false;
</script>
@@ -20,7 +21,12 @@
</svelte:fragment>
<svelte:fragment slot="actions">
<Button secondary on:click={() => (showDelete = true)}>Delete</Button>
<Button
secondary
on:click={() => {
showDelete = true;
trackEvent(Click.SettingsWebhookDeleteClick);
}}>Delete</Button>
</svelte:fragment>
</CardGrid>
@@ -4,6 +4,7 @@
import { Link } from '@appwrite.io/pink-svelte';
import Regenerate from './regenerate.svelte';
import { webhook } from './store';
import { Click, trackEvent } from '$lib/actions/analytics';
let showRegenerate = false;
</script>
@@ -22,7 +23,13 @@
</div>
</svelte:fragment>
<svelte:fragment slot="actions">
<Button on:click={() => (showRegenerate = true)} secondary submit>Regenerate key</Button>
<Button
on:click={() => {
showRegenerate = true;
trackEvent(Click.SettingsWebhookUpdateSignatureClick);
}}
secondary
submit>Regenerate key</Button>
</svelte:fragment>
</CardGrid>
@@ -11,7 +11,7 @@
import ConnectGit from '$lib/components/git/connectGit.svelte';
import { Adapter, BuildRuntime, Framework, type Models } from '@appwrite.io/console';
import { addNotification } from '$lib/stores/notifications';
import { trackEvent } from '$lib/actions/analytics';
import { Click, trackEvent } from '$lib/actions/analytics';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import RepositoryBehaviour from '$lib/components/git/repositoryBehaviour.svelte';
@@ -114,7 +114,7 @@
action="button"
{callbackState}
on:connect={(e) => {
trackEvent('click_connect_repository', {
trackEvent(Click.ConnectRepositoryClick, {
from: 'sites'
});
repository.set(e.detail);
@@ -32,6 +32,7 @@
import CreateVariableModal from './createVariableModal.svelte';
import DeleteVariableModal from './deleteVariableModal.svelte';
import UpdateVariableModal from './updateVariableModal.svelte';
import { Click, trackEvent } from '$lib/actions/analytics';
export let frameworks: Models.Framework[];
export let selectedFramework: Models.Framework;
@@ -134,18 +135,36 @@
<Button
secondary
size="s"
on:mousedown={() => (showEditorModal = true)}>
on:mousedown={() => {
showEditorModal = true;
trackEvent(Click.VariablesUpdateClick, {
source: 'site_configuration'
});
}}>
<Icon slot="start" icon={IconCode} /> Editor
</Button>
<Button
secondary
size="s"
on:mousedown={() => (showImportModal = true)}>
on:mousedown={() => {
showImportModal = true;
trackEvent(Click.VariablesImportClick, {
source: 'site_configuration'
});
}}>
<Icon slot="start" icon={IconUpload} /> Import .env
</Button>
</Layout.Stack>
{#if variables?.length}
<Button secondary size="s" on:mousedown={() => (showCreate = true)}>
<Button
secondary
size="s"
on:mousedown={() => {
showCreate = true;
trackEvent(Click.VariablesCreateClick, {
source: 'site_settings'
});
}}>
<Icon slot="start" icon={IconPlus} /> Create variable
</Button>
{/if}
@@ -12,6 +12,7 @@
import { onMount } from 'svelte';
import AddCollaboratorModal from '../../(components)/addCollaboratorModal.svelte';
import { protocol } from '$routes/(console)/store';
import { Click, trackEvent } from '$lib/actions/analytics';
export let data;
@@ -91,6 +92,11 @@
<Card.Link
radius="s"
padding="s"
on:click={() => {
trackEvent(Click.DomainCreateClick, {
source: 'sites_create_finish'
});
}}
href={`${base}/project-${$page.params.project}/sites/site-${data.site.$id}/domains`}>
<Layout.Stack gap="s" style="height: 100%">
<Layout.Stack
@@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { page } from '$app/stores';
import { trackEvent } from '$lib/actions/analytics.js';
import { Click, trackEvent } from '$lib/actions/analytics.js';
import Card from '$lib/components/card.svelte';
import { Repositories } from '$lib/components/git/index.js';
import Button from '$lib/elements/forms/button.svelte';
@@ -16,7 +16,7 @@
let selectedRepository: string = null;
function onConnect(e: CustomEvent<Models.ProviderRepository>) {
trackEvent('click_connect_repository', {
trackEvent(Click.ConnectRepositoryClick, {
from: 'cover'
});
repository.set(e.detail);
@@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { page } from '$app/stores';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Card } from '$lib/components';
import { Button, Form } from '$lib/elements/forms';
import { Wizard } from '$lib/layout';
@@ -296,7 +296,7 @@
product="sites"
action="button"
on:connect={(e) => {
trackEvent('click_connect_repository', {
trackEvent(Click.ConnectRepositoryClick, {
from: 'template-wizard'
});
repository.set(e.detail);
@@ -28,6 +28,7 @@
import SearchQuery from '$lib/components/searchQuery.svelte';
import { app } from '$lib/stores/app';
import { RuleType } from '$lib/stores/sdk';
import { Click, trackEvent } from '$lib/actions/analytics';
import CreateAppwriteDomainModal from './createAppwriteDomainModal.svelte';
export let data;
@@ -44,7 +45,9 @@
<Layout.Stack direction="row" justifyContent="space-between">
<SearchQuery search={data.search} placeholder="Search domain" />
<Popover padding="none" let:toggle placement="bottom-end">
<Button on:click={toggle}>
<Button on:click={(event) => {toggle(event); trackEvent(Click.DomainCreateClick, {
source: 'sites_domain_overview'
});}}>
<Icon icon={IconPlus} size="s" />
Add domain
</Button>
@@ -123,6 +126,9 @@
selectedDomain = domain;
showDelete = true;
toggle(e);
trackEvent(Click.DomainDeleteClick, {
source: 'sites_domain_overview'
});
}}>
Delete
</ActionMenu.Item.Button>
@@ -10,6 +10,7 @@
import { Link } from '$lib/elements';
import { Button } from '$lib/elements/forms';
import { Card, Trim } from '$lib/components';
import { Click, trackEvent } from '$lib/actions/analytics';
export let proxyRuleList: Models.ProxyRuleList;
@@ -54,6 +55,11 @@
<Button
secondary
size="s"
on:click={() => {
trackEvent(Click.DomainCreateClick, {
source: 'sites_domain_overview'
});
}}
href={`${base}/project-${$page.params.project}/sites/site-${$page.params.site}/domains/add-domain`}>
Add domain
</Button>
@@ -65,7 +65,8 @@
isGlobal={false}
globalVariableList={data.globalVariables}
variableList={data.variables}
product="site" />
product="site"
analyticsSource="site_settings" />
<UpdateRuntimeSettings site={data.site} frameworks={data.frameworks.frameworks} />
<UpdateTimeout site={data.site} />
<DangerZone site={data.site} />
@@ -87,6 +87,7 @@
import { GRACE_PERIOD_OVERRIDE } from '$lib/system';
import { isValueOfStringEnum } from '$lib/helpers/types';
import type { PageData } from './$types';
import { Click } from '$lib/actions/analytics';
export let data: PageData;
@@ -442,7 +443,12 @@
</svelte:fragment>
<svelte:fragment slot="actions">
<Button secondary on:click={() => (showDelete = true)}>Delete</Button>
<Button
secondary
on:click={() => {
showDelete = true;
trackEvent(Click.StorageBucketDeleteClick);
}}>Delete</Button>
</svelte:fragment>
</CardGrid>
{/if}
@@ -1,5 +1,5 @@
<script lang="ts">
import { Submit } from '$lib/actions/analytics';
import { Click, Submit, trackEvent } from '$lib/actions/analytics';
import { Alert, CardGrid } from '$lib/components';
import { BillingPlan } from '$lib/constants';
import { Button, Form, InputNumber, InputSelect } from '$lib/elements/forms';
@@ -54,7 +54,14 @@
<svelte:fragment slot="action">
{#if $organization?.billingPlan === BillingPlan.FREE}
<div class="alert-buttons u-flex">
<Button text href={$upgradeURL}>Upgrade plan</Button>
<Button
text
href={$upgradeURL}
on:click={() => {
trackEvent(Click.OrganizationClickUpgrade, {
source: 'bucket_settings'
});
}}>Upgrade plan</Button>
</div>
{/if}
</svelte:fragment>
@@ -5,7 +5,7 @@
import { CardGrid, Empty, Output, PaginationInline } from '$lib/components';
import UploadVariables from './uploadVariablesModal.svelte';
import { invalidate } from '$app/navigation';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Dependencies } from '$lib/constants';
import { addNotification } from '$lib/stores/notifications';
import { project } from '$routes/(console)/project-[project]/store';
@@ -37,7 +37,7 @@
export let variableList: Models.VariableList;
export let globalVariableList: Models.VariableList | undefined = undefined;
export let analyticsSource = '';
export let isGlobal: boolean;
export let sdkCreateVariable: (
key: string,
@@ -222,15 +222,30 @@
<Layout.Stack gap="l">
<Layout.Stack direction="row">
<Layout.Stack direction="row" gap="s">
<Button secondary on:mousedown={() => (showEditorModal = true)}>
<Button
secondary
on:mousedown={() => {
showEditorModal = true;
trackEvent(Click.VariablesUpdateClick, { source: analyticsSource });
}}>
<Icon slot="start" icon={IconCode} /> Editor
</Button>
<Button secondary on:mousedown={() => (showVariablesUpload = true)}>
<Button
secondary
on:mousedown={() => {
showEditorModal = true;
trackEvent(Click.VariablesUpdateClick, { source: analyticsSource });
}}>
<Icon slot="start" icon={IconUpload} /> Import .env
</Button>
</Layout.Stack>
{#if variableList.total}
<Button secondary on:mousedown={() => (showVariablesModal = true)}>
<Button
secondary
on:mousedown={() => {
showVariablesModal = true;
trackEvent(Click.VariablesCreateClick, { source: 'project_settings' });
}}>
<Icon slot="start" icon={IconPlus} /> Create variable
</Button>
{/if}
@@ -22,8 +22,8 @@
disabled = true;
await sdk.forConsole.account.createEmailPasswordSession(mail, pass);
await invalidate(Dependencies.ACCOUNT);
trackEvent(Submit.AccountLogin);
if ($user) {
trackEvent(Submit.AccountLogin, { mfa_used: 'none' });
addNotification({
type: 'success',
message: 'Successfully logged in.'
@@ -61,7 +61,6 @@
} else {
await goto(base);
}
trackEvent(Submit.AccountCreate);
} catch (error) {
disabled = false;
addNotification({