chore: remove posthog integration and analytics scaffold (#9634)

* chore: remove posthog integration and analytics scaffold

Removes the PostHog integration end to end, plus the inert autocapture
scaffold left behind by an earlier partial removal (d61b157929,
"chore: remove posthog events (#8465)").

Backend:
- delete bgtasks/event_tracking_task.py and utils/analytics_events.py
- drop all 6 track_event.delay call sites
- drop POSTHOG_API_KEY / POSTHOG_HOST settings
- stop returning posthog_api_key / posthog_host from GET /api/instances/
- drop the posthog==3.5.0 dependency

Frontend:
- delete packages/constants/src/event-tracker (all 40 exports were unused)
- remove 42 data-ph-element attributes across 36 files
- remove the dead shouldTrackEvents and trackerElements prop chains
- remove the Microsoft Clarity session-recording tag

Note: GET /api/instances/ no longer returns posthog_api_key/posthog_host.
Nothing in this repo read them and neither do plane-ee or plane-commercial,
but the endpoint is AllowAny and cached for 2h.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HD7dTidmtWWRRiFv3nmW3s

* chore: apply oxfmt formatting

Collapse JSX elements and import statements that were left multi-line
after the tracker props and specifiers were removed. Whitespace only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HD7dTidmtWWRRiFv3nmW3s

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
sriram veeraghanta
2026-08-24 21:07:34 +05:30
committed by GitHub
parent e056bbf9eb
commit e093a22094
63 changed files with 41 additions and 963 deletions

View File

@@ -46,9 +46,7 @@ from plane.app.permissions import ROLE, allow_permission
from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS
from plane.license.utils.instance_value import get_configuration_value
from plane.bgtasks.workspace_seed_task import workspace_seed
from plane.bgtasks.event_tracking_task import track_event
from plane.utils.url import contains_url
from plane.utils.analytics_events import WORKSPACE_CREATED, WORKSPACE_DELETED
from plane.utils.csv_utils import sanitize_csv_row
@@ -138,20 +136,6 @@ class WorkSpaceViewSet(BaseViewSet):
workspace_seed.delay(serializer.data["id"])
track_event.delay(
user_id=request.user.id,
event_name=WORKSPACE_CREATED,
slug=data["slug"],
event_properties={
"user_id": request.user.id,
"workspace_id": data["id"],
"workspace_slug": data["slug"],
"role": "owner",
"workspace_name": data["name"],
"created_at": data["created_at"],
},
)
return Response(data, status=status.HTTP_201_CREATED)
return Response(
[serializer.errors[error][0] for error in serializer.errors],
@@ -185,19 +169,6 @@ class WorkSpaceViewSet(BaseViewSet):
# Get the workspace
workspace = self.get_object()
self.remove_last_workspace_ids_from_user_settings(workspace.id)
track_event.delay(
user_id=request.user.id,
event_name=WORKSPACE_DELETED,
slug=workspace.slug,
event_properties={
"user_id": request.user.id,
"workspace_id": workspace.id,
"workspace_slug": workspace.slug,
"role": "owner",
"workspace_name": workspace.name,
"deleted_at": str(timezone.now().isoformat()),
},
)
return super().destroy(request, *args, **kwargs)

View File

@@ -26,12 +26,10 @@ from plane.app.serializers import (
WorkSpaceMemberSerializer,
)
from plane.app.views.base import BaseAPIView
from plane.bgtasks.event_tracking_task import track_event
from plane.bgtasks.workspace_invitation_task import workspace_invitation
from plane.db.models import User, Workspace, WorkspaceMember, WorkspaceMemberInvite
from plane.utils.cache import invalidate_cache, invalidate_cache_directly
from plane.utils.host import base_host
from plane.utils.analytics_events import USER_JOINED_WORKSPACE, USER_INVITED_TO_WORKSPACE
from .. import BaseViewSet
@@ -126,19 +124,6 @@ class WorkspaceInvitationsViewset(BaseViewSet):
current_site,
request.user.email,
)
track_event.delay(
user_id=request.user.id,
event_name=USER_INVITED_TO_WORKSPACE,
slug=slug,
event_properties={
"user_id": request.user.id,
"workspace_id": workspace.id,
"workspace_slug": workspace.slug,
"invitee_role": invitation.role,
"invited_at": str(timezone.now()),
"invitee_email": invitation.email,
},
)
return Response({"message": "Emails sent successfully"}, status=status.HTTP_200_OK)
@@ -219,18 +204,6 @@ class WorkspaceJoinEndpoint(BaseAPIView):
# Set the user last_workspace_id to the accepted workspace
user.last_workspace_id = workspace_invite.workspace.id
user.save()
track_event.delay(
user_id=user.id,
event_name=USER_JOINED_WORKSPACE,
slug=slug,
event_properties={
"user_id": user.id,
"workspace_id": workspace_invite.workspace.id,
"workspace_slug": workspace_invite.workspace.slug,
"role": workspace_invite.role,
"joined_at": str(timezone.now()),
},
)
# Delete the invitation
workspace_invite.delete()
@@ -290,20 +263,6 @@ class UserWorkspaceInvitationsViewSet(BaseViewSet):
is_active=True, role=invitation.role
)
# Track event
track_event.delay(
user_id=request.user.id,
event_name=USER_JOINED_WORKSPACE,
slug=invitation.workspace.slug,
event_properties={
"user_id": request.user.id,
"workspace_id": invitation.workspace.id,
"workspace_slug": invitation.workspace.slug,
"role": invitation.role,
"joined_at": str(timezone.now()),
},
)
# Bulk create the user for all the workspaces
WorkspaceMember.objects.bulk_create(
[

View File

@@ -2,9 +2,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
# See the LICENSE file for details.
# Django imports
from django.utils import timezone
# Module imports
from plane.db.models import (
ProjectMember,
@@ -13,8 +10,6 @@ from plane.db.models import (
WorkspaceMemberInvite,
)
from plane.utils.cache import invalidate_cache_directly
from plane.bgtasks.event_tracking_task import track_event
from plane.utils.analytics_events import USER_JOINED_WORKSPACE
def process_workspace_project_invitations(user):
@@ -42,18 +37,6 @@ def process_workspace_project_invitations(user):
user=False,
multiple=True,
)
track_event.delay(
user_id=user.id,
event_name=USER_JOINED_WORKSPACE,
slug=workspace_member_invite.workspace.slug,
event_properties={
"user_id": user.id,
"workspace_id": workspace_member_invite.workspace.id,
"workspace_slug": workspace_member_invite.workspace.slug,
"role": workspace_member_invite.role,
"joined_at": str(timezone.now().isoformat()),
},
)
# Check if user has any project invites
project_member_invites = ProjectMemberInvite.objects.filter(email=user.email, accepted=True)

View File

@@ -1,81 +0,0 @@
# Copyright (c) 2023-present Plane Software, Inc. and contributors
# SPDX-License-Identifier: AGPL-3.0-only
# See the LICENSE file for details.
import logging
import os
import uuid
from typing import Dict, Any
# third party imports
from celery import shared_task
from posthog import Posthog
# module imports
from plane.license.utils.instance_value import get_configuration_value
from plane.utils.exception_logger import log_exception
from plane.db.models import Workspace
from plane.utils.analytics_events import USER_INVITED_TO_WORKSPACE, WORKSPACE_DELETED
logger = logging.getLogger("plane.worker")
def posthogConfiguration():
POSTHOG_API_KEY, POSTHOG_HOST = get_configuration_value(
[
{
"key": "POSTHOG_API_KEY",
"default": os.environ.get("POSTHOG_API_KEY", None),
},
{
"key": "POSTHOG_HOST",
"default": os.environ.get("POSTHOG_HOST", None),
},
]
)
if POSTHOG_API_KEY and POSTHOG_HOST:
return POSTHOG_API_KEY, POSTHOG_HOST
else:
return None, None
def preprocess_data_properties(
user_id: uuid.UUID, event_name: str, slug: str, data_properties: Dict[str, Any]
) -> Dict[str, Any]:
if event_name == USER_INVITED_TO_WORKSPACE or event_name == WORKSPACE_DELETED:
try:
# Check if the current user is the workspace owner
workspace = Workspace.objects.get(slug=slug)
if str(workspace.owner_id) == str(user_id):
data_properties["role"] = "owner"
else:
data_properties["role"] = "admin"
except Workspace.DoesNotExist:
logger.warning(f"Workspace {slug} does not exist while sending event {event_name} for user {user_id}")
data_properties["role"] = "unknown"
return data_properties
@shared_task
def track_event(user_id: uuid.UUID, event_name: str, slug: str, event_properties: Dict[str, Any]):
POSTHOG_API_KEY, POSTHOG_HOST = posthogConfiguration()
if not (POSTHOG_API_KEY and POSTHOG_HOST):
logger.warning("Event tracking is not configured")
return
try:
# preprocess the data properties for massaging the payload
# in the correct format for posthog
data_properties = preprocess_data_properties(user_id, event_name, slug, event_properties)
groups = {
"workspace": slug,
}
# track the event using posthog
posthog = Posthog(POSTHOG_API_KEY, host=POSTHOG_HOST)
posthog.capture(distinct_id=str(user_id), event=event_name, properties=data_properties, groups=groups)
except Exception as e:
log_exception(e)
return False

View File

@@ -59,8 +59,6 @@ class InstanceEndpoint(BaseAPIView):
ENABLE_MAGIC_LINK_LOGIN,
ENABLE_EMAIL_PASSWORD,
SLACK_CLIENT_ID,
POSTHOG_API_KEY,
POSTHOG_HOST,
UNSPLASH_ACCESS_KEY,
LLM_API_KEY,
) = get_configuration_value(
@@ -106,14 +104,6 @@ class InstanceEndpoint(BaseAPIView):
"key": "SLACK_CLIENT_ID",
"default": os.environ.get("SLACK_CLIENT_ID", None),
},
{
"key": "POSTHOG_API_KEY",
"default": os.environ.get("POSTHOG_API_KEY", None),
},
{
"key": "POSTHOG_HOST",
"default": os.environ.get("POSTHOG_HOST", None),
},
{
"key": "UNSPLASH_ACCESS_KEY",
"default": os.environ.get("UNSPLASH_ACCESS_KEY", ""),
@@ -142,10 +132,6 @@ class InstanceEndpoint(BaseAPIView):
# Slack client
data["slack_client_id"] = SLACK_CLIENT_ID
# Posthog
data["posthog_api_key"] = POSTHOG_API_KEY
data["posthog_host"] = POSTHOG_HOST
# Unsplash
data["has_unsplash_configured"] = bool(UNSPLASH_ACCESS_KEY)

View File

@@ -361,10 +361,6 @@ GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", False)
ANALYTICS_SECRET_KEY = os.environ.get("ANALYTICS_SECRET_KEY", False)
ANALYTICS_BASE_API = os.environ.get("ANALYTICS_BASE_API", False)
# Posthog settings
POSTHOG_API_KEY = os.environ.get("POSTHOG_API_KEY", False)
POSTHOG_HOST = os.environ.get("POSTHOG_HOST", False)
# Skip environment variable configuration
SKIP_ENV_VAR = os.environ.get("SKIP_ENV_VAR", "1") == "1"

View File

@@ -1,8 +0,0 @@
# Copyright (c) 2023-present Plane Software, Inc. and contributors
# SPDX-License-Identifier: AGPL-3.0-only
# See the LICENSE file for details.
USER_JOINED_WORKSPACE = "user_joined_workspace"
USER_INVITED_TO_WORKSPACE = "user_invited_to_workspace"
WORKSPACE_CREATED = "workspace_created"
WORKSPACE_DELETED = "workspace_deleted"

View File

@@ -46,8 +46,6 @@ openpyxl==3.1.2
python-json-logger==4.0.0
# html parser
beautifulsoup4==4.12.3
# analytics
posthog==3.5.0
# crypto
cryptography==50.0.0
# html validator

View File

@@ -8,7 +8,7 @@ import { useCallback, useRef, useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EmptyStateCompact } from "@plane/propel/empty-state";
import { PlusIcon, SearchIcon } from "@plane/propel/icons";
@@ -117,7 +117,6 @@ export const ExtendedProjectSidebar = observer(function ExtendedProjectSidebar()
<Tooltip tooltipHeading={t("create_project")} tooltipContent="">
<button
type="button"
data-ph-element={PROJECT_TRACKER_ELEMENTS.EXTENDED_SIDEBAR_ADD_BUTTON}
className="flex-shrink-0 rounded-sm p-0.5 text-tertiary transition-colors hover:bg-layer-1 hover:text-secondary"
onClick={() => {
setIsProjectModalOpen(true);

View File

@@ -15,7 +15,6 @@ import {
EUserPermissions,
EUserPermissionsLevel,
ISSUE_DISPLAY_FILTERS_BY_PAGE,
WORK_ITEM_TRACKER_ELEMENTS,
} from "@plane/constants";
import { usePlatformOS } from "@plane/hooks";
import { useTranslation } from "@plane/i18n";
@@ -246,7 +245,6 @@ export const CycleIssuesHeader = observer(function CycleIssuesHeader() {
onClick={() => {
toggleCreateIssueModal(true, EIssuesStoreType.CYCLE);
}}
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.CYCLE}
>
{t("issue.add.label")}
</Button>

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// ui
import { EUserPermissions, EUserPermissionsLevel, CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { CycleIcon } from "@plane/propel/icons";
@@ -63,7 +63,6 @@ export const CyclesListHeader = observer(function CyclesListHeader() {
<Button
variant="primary"
size="lg"
data-ph-element={CYCLE_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
onClick={() => {
toggleCreateCycleModal(true);
}}

View File

@@ -8,7 +8,7 @@ import { useState } from "react";
import { observer } from "mobx-react";
// plane imports
import { useTheme } from "next-themes";
import { EUserPermissionsLevel, CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EmptyStateDetailed } from "@plane/propel/empty-state";
import type { TCycleFilters } from "@plane/types";
@@ -113,7 +113,6 @@ function ProjectCyclesPage({ params }: Route.ComponentProps) {
onClick: () => setCreateModal(true),
variant: "primary",
disabled: !hasMemberLevelPermission,
"data-ph-element": CYCLE_TRACKER_ELEMENTS.EMPTY_STATE_ADD_BUTTON,
},
]}
/>

View File

@@ -15,7 +15,6 @@ import {
ISSUE_DISPLAY_FILTERS_BY_PAGE,
EUserPermissions,
EUserPermissionsLevel,
WORK_ITEM_TRACKER_ELEMENTS,
} from "@plane/constants";
import { Button } from "@plane/propel/button";
import { ModuleIcon } from "@plane/propel/icons";
@@ -241,7 +240,6 @@ export const ModuleIssuesHeader = observer(function ModuleIssuesHeader() {
onClick={() => {
toggleCreateIssueModal(true, EIssuesStoreType.MODULE);
}}
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.MODULE}
>
Add work item
</Button>

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EUserPermissions, EUserPermissionsLevel, MODULE_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { Button } from "@plane/propel/button";
@@ -67,7 +67,6 @@ export const ModulesListHeader = observer(function ModulesListHeader() {
{canUserCreateModule ? (
<Button
variant="primary"
data-ph-element={MODULE_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
onClick={() => {
toggleCreateModuleModal(true);
}}

View File

@@ -14,7 +14,6 @@ import {
ISSUE_DISPLAY_FILTERS_BY_PAGE,
EUserPermissions,
EUserPermissionsLevel,
WORK_ITEM_TRACKER_ELEMENTS,
} from "@plane/constants";
import { Button } from "@plane/propel/button";
import { LockIcon, ViewsIcon } from "@plane/propel/icons";
@@ -203,7 +202,6 @@ export const ProjectViewIssuesHeader = observer(function ProjectViewIssuesHeader
onClick={() => {
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT_VIEW);
}}
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.PROJECT_VIEW}
>
Add work item
</Button>

View File

@@ -7,7 +7,6 @@
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// ui
import { PROJECT_VIEW_TRACKER_ELEMENTS } from "@plane/constants";
import { Button } from "@plane/propel/button";
import { ViewsIcon } from "@plane/propel/icons";
import { Breadcrumbs, Header } from "@plane/ui";
@@ -48,12 +47,7 @@ export const ProjectViewsHeader = observer(function ProjectViewsHeader() {
<Header.RightItem>
<ViewListHeader />
<div>
<Button
data-ph-element={PROJECT_VIEW_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
variant="primary"
size="lg"
onClick={() => toggleCreateViewModal(true)}
>
<Button variant="primary" size="lg" onClick={() => toggleCreateViewModal(true)}>
Add view
</Button>
</div>

View File

@@ -8,12 +8,7 @@ import { useCallback, useMemo, useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import {
EIssueFilterType,
ISSUE_DISPLAY_FILTERS_BY_PAGE,
GLOBAL_VIEW_TRACKER_ELEMENTS,
DEFAULT_GLOBAL_VIEWS_LIST,
} from "@plane/constants";
import { EIssueFilterType, ISSUE_DISPLAY_FILTERS_BY_PAGE, DEFAULT_GLOBAL_VIEWS_LIST } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { ViewsIcon } from "@plane/propel/icons";
@@ -148,12 +143,7 @@ export const GlobalIssuesHeader = observer(function GlobalIssuesHeader() {
/>
</FiltersDropdown>
)}
<Button
variant="primary"
size="lg"
data-ph-element={GLOBAL_VIEW_TRACKER_ELEMENTS.RIGHT_HEADER_ADD_BUTTON}
onClick={() => setCreateViewModal(true)}
>
<Button variant="primary" size="lg" onClick={() => setCreateViewModal(true)}>
{t("workspace_views.add_view")}
</Button>
<div className="hidden md:block">

View File

@@ -8,7 +8,6 @@ import { observer } from "mobx-react";
import Link from "next/link";
import { useTheme } from "next-themes";
// plane imports
import { PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { Button, getButtonStyling } from "@plane/propel/button";
import { cn } from "@plane/utils";
// assets
@@ -35,12 +34,7 @@ function ProjectSettingsPage() {
<Link href="https://plane.so/" target="_blank" className={cn(getButtonStyling("secondary", "base"))}>
Learn more about projects
</Link>
<Button
onClick={() => toggleCreateProjectModal(true)}
data-ph-element={PROJECT_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_PROJECT_BUTTON}
>
Start your first project
</Button>
<Button onClick={() => toggleCreateProjectModal(true)}>Start your first project</Button>
</div>
</div>
);

View File

@@ -4,8 +4,6 @@
* See the LICENSE file for details.
*/
import Script from "next/script";
// styles
import "@/styles/globals.css";
@@ -56,8 +54,6 @@ export const meta = () => [
];
export default function RootLayout({ children }: { children: React.ReactNode }) {
const isSessionRecorderEnabled = parseInt(process.env.VITE_ENABLE_SESSION_RECORDER || "0");
return (
<html lang="en">
<head>
@@ -87,15 +83,6 @@ export default function RootLayout({ children }: { children: React.ReactNode })
</div>
</AppProvider>
</body>
{!!isSessionRecorderEnabled && process.env.VITE_SESSION_RECORDER_KEY && (
<Script id="clarity-tracking">
{`(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];if(y){y.parentNode.insertBefore(t,y);}
})(window, document, "clarity", "script", "${process.env.VITE_SESSION_RECORDER_KEY}");`}
</Script>
)}
</html>
);
}

View File

@@ -5,7 +5,6 @@
*/
import type { ReactNode } from "react";
import Script from "next/script";
import { Links, Meta, Outlet, Scripts } from "react-router";
import type { LinksFunction } from "react-router";
import { ThemeProvider, useTheme } from "next-themes";
@@ -57,8 +56,6 @@ export const links: LinksFunction = () => [
];
export function Layout({ children }: { children: ReactNode }) {
const isSessionRecorderEnabled = parseInt(process.env.VITE_ENABLE_SESSION_RECORDER || "0");
return (
<html lang="en" suppressHydrationWarning>
<head>
@@ -82,15 +79,6 @@ export function Layout({ children }: { children: ReactNode }) {
{children}
</ThemeProvider>
<Scripts />
{!!isSessionRecorderEnabled && process.env.VITE_SESSION_RECORDER_KEY && (
<Script id="clarity-tracking">
{`(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];if(y){y.parentNode.insertBefore(t,y);}
})(window, document, "clarity", "script", "${process.env.VITE_SESSION_RECORDER_KEY}");`}
</Script>
)}
</body>
</html>
);

View File

@@ -10,7 +10,7 @@ import Link from "next/link";
// icons
import { Eye, EyeOff, Info, XCircle } from "lucide-react";
// plane imports
import { API_BASE_URL, E_PASSWORD_STRENGTH, AUTH_TRACKER_ELEMENTS } from "@plane/constants";
import { API_BASE_URL, E_PASSWORD_STRENGTH } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { CloseIcon } from "@plane/propel/icons";
@@ -86,7 +86,6 @@ export const AuthPasswordForm = observer(function AuthPasswordForm(props: Props)
<div className="w-full">
{isSMTPConfigured ? (
<Link
data-ph-element={AUTH_TRACKER_ELEMENTS.FORGOT_PASSWORD_FROM_SIGNIN}
href={`/accounts/forgot-password?email=${encodeURIComponent(email)}`}
className="text-11 font-medium text-accent-primary"
>
@@ -292,7 +291,6 @@ export const AuthPasswordForm = observer(function AuthPasswordForm(props: Props)
{isSMTPConfigured && (
<Button
type="button"
data-ph-element={AUTH_TRACKER_ELEMENTS.SIGN_IN_WITH_UNIQUE_CODE}
onClick={redirectToUniqueCodeSignIn}
variant="secondary"
className="w-full"

View File

@@ -7,7 +7,6 @@
import { useState } from "react";
import { XCircle } from "lucide-react";
// plane imports
import { PROFILE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
import { Tooltip } from "@plane/propel/tooltip";
import type { IApiToken } from "@plane/types";
import { renderFormattedDate, calculateTimeAgo, renderFormattedTime } from "@plane/utils";
@@ -35,7 +34,6 @@ export function ApiTokenListItem(props: Props) {
<button
onClick={() => setDeleteModalOpen(true)}
className="absolute right-4 hidden place-items-center group-hover:grid"
data-ph-element={PROFILE_SETTINGS_TRACKER_ELEMENTS.LIST_ITEM_DELETE_ICON}
>
<XCircle className="h-4 w-4 text-danger-primary" />
</button>

View File

@@ -7,7 +7,6 @@
import React from "react";
import { observer } from "mobx-react";
import Link from "next/link";
import { AUTH_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { PlaneLockup } from "@plane/propel/icons";
import { PageHead } from "@/components/core/page-title";
@@ -48,7 +47,6 @@ export const AuthHeader = observer(function AuthHeader({ type }: AuthHeaderProps
<div className="flex flex-col items-end text-center text-13 font-medium text-tertiary sm:flex-row sm:items-center sm:gap-2">
<span className="text-body-sm-regular text-tertiary">{t(authContentMap[type].text)}</span>
<Link
data-ph-element={AUTH_TRACKER_ELEMENTS.NAVIGATE_TO_SIGN_UP}
href={authContentMap[type].linkHref}
className="text-body-sm-semibold text-accent-primary hover:underline"
>

View File

@@ -5,7 +5,6 @@
*/
import { observer } from "mobx-react";
import { PROJECT_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
import { TrashIcon } from "@plane/propel/icons";
type TEstimateListItem = {
@@ -26,7 +25,6 @@ export const EstimateListItemButtons = observer(function EstimateListItemButtons
<button
className="relative flex h-6 w-6 flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-sm transition-colors hover:bg-layer-1"
onClick={() => onDeleteClick && onDeleteClick(estimateId)}
data-ph-element={PROJECT_SETTINGS_TRACKER_ELEMENTS.ESTIMATES_LIST_ITEM}
>
<TrashIcon width={12} height={12} />
</button>

View File

@@ -4,7 +4,6 @@
* See the LICENSE file for details.
*/
import { USER_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { getButtonStyling } from "@plane/propel/button";
@@ -29,7 +28,6 @@ export function ProductUpdatesFooter() {
<circle cx={1} cy={1} r={1} />
</svg>
<a
data-ph-element={USER_TRACKER_ELEMENTS.CHANGELOG_REDIRECTED}
href="https://go.plane.so/p-changelog"
target="_blank"
className="text-13 text-secondary underline-offset-1 outline-none hover:text-primary hover:underline"

View File

@@ -9,13 +9,7 @@ import { useParams } from "next/navigation";
// icons
import { Circle } from "lucide-react";
// plane imports
import {
EUserPermissions,
EUserPermissionsLevel,
SPACE_BASE_PATH,
SPACE_BASE_URL,
WORK_ITEM_TRACKER_ELEMENTS,
} from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel, SPACE_BASE_PATH, SPACE_BASE_URL } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { NewTabIcon, WorkItemsIcon } from "@plane/propel/icons";
@@ -125,7 +119,6 @@ export const IssuesHeader = observer(function IssuesHeader() {
onClick={() => {
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT);
}}
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.WORK_ITEMS}
>
<div className="block sm:hidden">{t("issue.label", { count: 1 })}</div>
<div className="hidden sm:block">{t("issue.add.label")}</div>

View File

@@ -9,7 +9,7 @@ import { isEmpty } from "lodash-es";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EUserPermissionsLevel, WORK_ITEM_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EmptyStateDetailed } from "@plane/propel/empty-state";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
@@ -116,14 +116,12 @@ export const CycleEmptyState = observer(function CycleEmptyState() {
},
disabled: !canPerformEmptyStateActions,
variant: "primary",
"data-ph-element": WORK_ITEM_TRACKER_ELEMENTS.EMPTY_STATE_ADD_BUTTON.CYCLE,
},
{
label: t("project_empty_state.cycle_work_items.cta_secondary"),
onClick: () => setCycleIssuesListModal(true),
disabled: !canPerformEmptyStateActions,
variant: "secondary",
"data-ph-element": WORK_ITEM_TRACKER_ELEMENTS.EMPTY_STATE_ADD_BUTTON.CYCLE,
},
]}
/>

View File

@@ -9,7 +9,7 @@ import { observer } from "mobx-react";
import { useParams, useSearchParams } from "next/navigation";
import useSWR from "swr";
// plane imports
import { GLOBAL_VIEW_TRACKER_ELEMENTS, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { EmptyStateDetailed } from "@plane/propel/empty-state";
import type { EIssueLayoutTypes } from "@plane/types";
import { EIssuesStoreType, STATIC_VIEW_TYPES } from "@plane/types";
@@ -148,14 +148,7 @@ export const AllIssueLayoutRoot = observer(function AllIssueLayoutRoot(props: Pr
{({ filter: globalWorkItemsFilter }) => (
<div className="h-full overflow-hidden bg-surface-1">
<div className="flex h-full w-full flex-col border-b border-strong">
{globalWorkItemsFilter && (
<WorkItemFiltersRow
filter={globalWorkItemsFilter}
trackerElements={{
saveView: GLOBAL_VIEW_TRACKER_ELEMENTS.HEADER_SAVE_VIEW_BUTTON,
}}
/>
)}
{globalWorkItemsFilter && <WorkItemFiltersRow filter={globalWorkItemsFilter} />}
<WorkspaceActiveLayout
activeLayout={activeLayout}
isDefaultView={isDefaultView}

View File

@@ -10,7 +10,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import useSWR from "swr";
// plane constants
import { ISSUE_DISPLAY_FILTERS_BY_PAGE, PROJECT_VIEW_TRACKER_ELEMENTS } from "@plane/constants";
import { ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { EIssuesStoreType, EIssueLayoutTypes } from "@plane/types";
// components
import { TransferIssues } from "@/components/cycles/transfer-issues";
@@ -111,14 +111,7 @@ export const CycleLayoutRoot = observer(function CycleLayoutRoot() {
disabled={!isEmpty(cycleDetails?.progress_snapshot)}
/>
)}
{cycleWorkItemsFilter && (
<WorkItemFiltersRow
filter={cycleWorkItemsFilter}
trackerElements={{
saveView: PROJECT_VIEW_TRACKER_ELEMENTS.CYCLE_HEADER_SAVE_AS_VIEW_BUTTON,
}}
/>
)}
{cycleWorkItemsFilter && <WorkItemFiltersRow filter={cycleWorkItemsFilter} />}
<div className="h-full w-full overflow-auto">
<CycleIssueLayout activeLayout={activeLayout} cycleId={cycleId} isCompletedCycle={isCompletedCycle} />
</div>

View File

@@ -9,7 +9,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import useSWR from "swr";
// plane imports
import { ISSUE_DISPLAY_FILTERS_BY_PAGE, PROJECT_VIEW_TRACKER_ELEMENTS } from "@plane/constants";
import { ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { EIssuesStoreType, EIssueLayoutTypes } from "@plane/types";
import { Row, ERowVariant } from "@plane/ui";
// hooks
@@ -81,14 +81,7 @@ export const ModuleLayoutRoot = observer(function ModuleLayoutRoot() {
>
{({ filter: moduleWorkItemsFilter }) => (
<div className="relative flex h-full w-full flex-col overflow-hidden">
{moduleWorkItemsFilter && (
<WorkItemFiltersRow
filter={moduleWorkItemsFilter}
trackerElements={{
saveView: PROJECT_VIEW_TRACKER_ELEMENTS.MODULE_HEADER_SAVE_AS_VIEW_BUTTON,
}}
/>
)}
{moduleWorkItemsFilter && <WorkItemFiltersRow filter={moduleWorkItemsFilter} />}
<Row variant={ERowVariant.HUGGING} className="h-full w-full overflow-auto">
<ModuleIssueLayout activeLayout={activeLayout} moduleId={moduleId} />
</Row>

View File

@@ -8,7 +8,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import useSWR from "swr";
// plane constants
import { ISSUE_DISPLAY_FILTERS_BY_PAGE, PROJECT_VIEW_TRACKER_ELEMENTS } from "@plane/constants";
import { ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/types";
import { Spinner } from "@plane/ui";
// components
@@ -78,14 +78,7 @@ export const ProjectLayoutRoot = observer(function ProjectLayoutRoot() {
>
{({ filter: projectWorkItemsFilter }) => (
<div className="relative flex h-full w-full flex-col overflow-hidden">
{projectWorkItemsFilter && (
<WorkItemFiltersRow
filter={projectWorkItemsFilter}
trackerElements={{
saveView: PROJECT_VIEW_TRACKER_ELEMENTS.PROJECT_HEADER_SAVE_AS_VIEW_BUTTON,
}}
/>
)}
{projectWorkItemsFilter && <WorkItemFiltersRow filter={projectWorkItemsFilter} />}
<div className="relative h-full w-full overflow-auto bg-surface-1">
{/* mutation loader */}
{issues?.getIssueLoader() === "mutation" && (

View File

@@ -9,7 +9,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import useSWR from "swr";
// plane constants
import { ISSUE_DISPLAY_FILTERS_BY_PAGE, PROJECT_VIEW_TRACKER_ELEMENTS } from "@plane/constants";
import { ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { EIssuesStoreType, EIssueLayoutTypes } from "@plane/types";
// hooks
import { ProjectLevelWorkItemFiltersHOC } from "@/components/work-item-filters/filters-hoc/project-level";
@@ -101,14 +101,7 @@ export const ProjectViewLayoutRoot = observer(function ProjectViewLayoutRoot() {
>
{({ filter: projectViewWorkItemsFilter }) => (
<div className="relative flex h-full w-full flex-col overflow-hidden">
{projectViewWorkItemsFilter && (
<WorkItemFiltersRow
filter={projectViewWorkItemsFilter}
trackerElements={{
saveView: PROJECT_VIEW_TRACKER_ELEMENTS.HEADER_SAVE_VIEW_BUTTON,
}}
/>
)}
{projectViewWorkItemsFilter && <WorkItemFiltersRow filter={projectViewWorkItemsFilter} />}
<div className="relative h-full w-full overflow-auto">
<ProjectViewIssueLayout activeLayout={activeLayout} viewId={viewId.toString()} />
</div>

View File

@@ -8,7 +8,6 @@ import type { MutableRefObject } from "react";
import { useRef, useState } from "react";
import type { LucideIcon } from "lucide-react";
// plane helpers
import { PROJECT_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
import { useOutsideClickDetector } from "@plane/hooks";
import type { ISvgIcons } from "@plane/propel/icons";
import { CloseIcon } from "@plane/propel/icons";
@@ -101,7 +100,6 @@ export function LabelItemBlock(props: ILabelItemBlock) {
onClick={() => {
handleLabelDelete(label);
}}
data-ph-element={PROJECT_SETTINGS_TRACKER_ELEMENTS.LABELS_DELETE_BUTTON}
>
<CloseIcon className="size-3.5 flex-shrink-0 text-tertiary" />
</button>

View File

@@ -6,7 +6,6 @@
import { observer } from "mobx-react";
import { MODULE_TRACKER_ELEMENTS } from "@plane/constants";
import { CopyIcon, EditIcon, TrashIcon } from "@plane/propel/icons";
// plane types
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
@@ -67,7 +66,6 @@ export const ModulesLinksListItem = observer(function ModulesLinksListItem(props
<button
type="button"
className="grid place-items-center rounded-sm p-1 text-secondary hover:bg-layer-transparent-hover"
data-ph-element={MODULE_TRACKER_ELEMENTS.LIST_ITEM}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
@@ -88,7 +86,6 @@ export const ModulesLinksListItem = observer(function ModulesLinksListItem(props
<button
type="button"
className="grid place-items-center rounded-sm p-1 text-secondary hover:bg-layer-transparent-hover"
data-ph-element={MODULE_TRACKER_ELEMENTS.LIST_ITEM}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import { useParams, useSearchParams } from "next/navigation";
// components
import { EUserPermissionsLevel, MODULE_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EmptyStateDetailed } from "@plane/propel/empty-state";
import { EUserProjectRoles } from "@plane/types";
@@ -65,7 +65,6 @@ export const ModulesListView = observer(function ModulesListView() {
onClick: () => toggleCreateModuleModal(true),
disabled: !canPerformEmptyStateActions,
variant: "primary",
"data-ph-element": MODULE_TRACKER_ELEMENTS.EMPTY_STATE_ADD_BUTTON,
},
]}
/>

View File

@@ -8,7 +8,6 @@ import { useState, useRef } from "react";
import { useNavigate } from "react-router";
import { LogOut, MoreHorizontal, Settings, Share2, ArchiveIcon } from "lucide-react";
// plane imports
import { MEMBER_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { LinkIcon } from "@plane/propel/icons";
import { CustomMenu } from "@plane/ui";
@@ -103,10 +102,7 @@ export function ProjectActionsMenu({
</CustomMenu.MenuItem>
{/* Leave project */}
{!isAuthorized && (
<CustomMenu.MenuItem
onClick={onLeaveProject}
data-ph-element={MEMBER_TRACKER_ELEMENTS.SIDEBAR_PROJECT_QUICK_ACTIONS}
>
<CustomMenu.MenuItem onClick={onLeaveProject}>
<div className="flex items-center justify-start gap-2">
<LogOut className="h-3.5 w-3.5 stroke-[1.5]" />
<span>{t("leave_project")}</span>

View File

@@ -14,7 +14,6 @@ import { StateForm } from "@/components/project-states";
type TStateCreate = {
groupKey: TStateGroups;
shouldTrackEvents?: boolean;
createStateCallback: TStateOperationsCallbacks["createState"];
handleClose: () => void;
};

View File

@@ -14,7 +14,6 @@ import { StateForm } from "@/components/project-states";
type TStateUpdate = {
state: IState;
updateStateCallback: TStateOperationsCallbacks["updateState"];
shouldTrackEvents: boolean;
handleClose: () => void;
};

View File

@@ -8,7 +8,7 @@ import { useState, useRef } from "react";
import { observer } from "mobx-react";
// plane imports
import { EIconSize, STATE_TRACKER_ELEMENTS } from "@plane/constants";
import { EIconSize } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { PlusIcon, StateGroupIcon, ChevronDownIcon } from "@plane/propel/icons";
import type { IState, TStateGroups, TStateOperationsCallbacks } from "@plane/types";
@@ -23,7 +23,6 @@ type TGroupItem = {
states: IState[];
stateOperationsCallbacks: TStateOperationsCallbacks;
isEditable: boolean;
shouldTrackEvents: boolean;
groupItemClassName?: string;
stateItemClassName?: string;
handleGroupCollapse: (groupKey: TStateGroups) => void;
@@ -38,7 +37,6 @@ export const GroupItem = observer(function GroupItem(props: TGroupItem) {
groupsExpanded,
isEditable,
stateOperationsCallbacks,
shouldTrackEvents,
groupItemClassName,
stateItemClassName,
handleExpand,
@@ -82,7 +80,6 @@ export const GroupItem = observer(function GroupItem(props: TGroupItem) {
</div>
<button
type="button"
data-ph-element={STATE_TRACKER_ELEMENTS.STATE_GROUP_ADD_BUTTON}
className={cn(
"flex h-6 w-6 flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-sm text-accent-primary/80 transition-colors hover:bg-layer-1 hover:text-accent-primary",
(!isEditable || createState) && "cursor-not-allowed text-placeholder hover:text-placeholder"
@@ -114,7 +111,6 @@ export const GroupItem = observer(function GroupItem(props: TGroupItem) {
states={states}
disabled={!isEditable}
stateOperationsCallbacks={stateOperationsCallbacks}
shouldTrackEvents={shouldTrackEvents}
stateItemClassName={stateItemClassName}
/>
</div>
@@ -126,7 +122,6 @@ export const GroupItem = observer(function GroupItem(props: TGroupItem) {
groupKey={groupKey}
handleClose={() => setCreateState(false)}
createStateCallback={stateOperationsCallbacks.createState}
shouldTrackEvents={shouldTrackEvents}
/>
</div>
)}

View File

@@ -16,7 +16,6 @@ type TGroupList = {
groupedStates: Record<string, IState[]>;
stateOperationsCallbacks: TStateOperationsCallbacks;
isEditable: boolean;
shouldTrackEvents: boolean;
groupListClassName?: string;
groupItemClassName?: string;
stateItemClassName?: string;
@@ -27,7 +26,6 @@ export const GroupList = observer(function GroupList(props: TGroupList) {
groupedStates,
stateOperationsCallbacks,
isEditable,
shouldTrackEvents,
groupListClassName,
groupItemClassName,
stateItemClassName,
@@ -72,7 +70,6 @@ export const GroupList = observer(function GroupList(props: TGroupList) {
groupsExpanded={groupsExpanded}
stateOperationsCallbacks={stateOperationsCallbacks}
isEditable={isEditable}
shouldTrackEvents={shouldTrackEvents}
handleGroupCollapse={handleGroupCollapse}
handleExpand={handleExpand}
groupItemClassName={groupItemClassName}

View File

@@ -21,7 +21,6 @@ type TStateDelete = {
totalStates: number;
state: IState;
deleteStateCallback: TStateOperationsCallbacks["deleteState"];
shouldTrackEvents?: boolean;
};
export const StateDelete = observer(function StateDelete(props: TStateDelete) {

View File

@@ -71,7 +71,6 @@ export const ProjectStateRoot = observer(function ProjectStateRoot(props: TProje
groupedStates={groupedProjectStates}
stateOperationsCallbacks={stateOperationsCallbacks}
isEditable={isEditable}
shouldTrackEvents
/>
);
});

View File

@@ -7,7 +7,7 @@
import type { SetStateAction } from "react";
import { observer } from "mobx-react";
import { GripVertical } from "lucide-react";
import { EIconSize, STATE_TRACKER_ELEMENTS } from "@plane/constants";
import { EIconSize } from "@plane/constants";
// plane imports
import { EditIcon, StateGroupIcon } from "@plane/propel/icons";
import type { IState, TStateOperationsCallbacks } from "@plane/types";
@@ -25,7 +25,6 @@ type TBaseStateItemTitleProps = {
type TEnabledStateItemTitleProps = TBaseStateItemTitleProps & {
disabled: false;
stateOperationsCallbacks: Pick<TStateOperationsCallbacks, "markStateAsDefault" | "deleteState">;
shouldTrackEvents: boolean;
};
type TDisabledStateItemTitleProps = TBaseStateItemTitleProps & {
@@ -76,7 +75,6 @@ export const StateItemTitle = observer(function StateItemTitle(props: TStateItem
<button
className="flex h-5 w-5 flex-shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-sm text-secondary transition-colors hover:bg-layer-1 hover:text-primary"
onClick={() => setUpdateStateModal(true)}
data-ph-element={STATE_TRACKER_ELEMENTS.STATE_LIST_EDIT_BUTTON}
>
<EditIcon className="h-3 w-3" />
</button>
@@ -84,7 +82,6 @@ export const StateItemTitle = observer(function StateItemTitle(props: TStateItem
totalStates={stateCount}
state={state}
deleteStateCallback={props.stateOperationsCallbacks.deleteState}
shouldTrackEvents={props.shouldTrackEvents}
/>
</div>
</div>

View File

@@ -23,7 +23,6 @@ type TStateItem = {
totalStates: number;
state: IState;
stateOperationsCallbacks: TStateOperationsCallbacks;
shouldTrackEvents: boolean;
disabled?: boolean;
stateItemClassName?: string;
};
@@ -35,7 +34,6 @@ export const StateItem = observer(function StateItem(props: TStateItem) {
totalStates,
state,
stateOperationsCallbacks,
shouldTrackEvents,
disabled = false,
stateItemClassName,
} = props;
@@ -123,7 +121,6 @@ export const StateItem = observer(function StateItem(props: TStateItem) {
<StateUpdate
state={state}
updateStateCallback={stateOperationsCallbacks.updateState}
shouldTrackEvents={shouldTrackEvents}
handleClose={() => setUpdateStateModal(false)}
/>
);
@@ -151,7 +148,6 @@ export const StateItem = observer(function StateItem(props: TStateItem) {
markStateAsDefault: stateOperationsCallbacks.markStateAsDefault,
deleteState: stateOperationsCallbacks.deleteState,
}}
shouldTrackEvents={shouldTrackEvents}
/>
)}
</div>

View File

@@ -14,21 +14,12 @@ type TStateList = {
groupedStates: Record<string, IState[]>;
states: IState[];
stateOperationsCallbacks: TStateOperationsCallbacks;
shouldTrackEvents: boolean;
disabled?: boolean;
stateItemClassName?: string;
};
export const StateList = observer(function StateList(props: TStateList) {
const {
groupKey,
groupedStates,
states,
stateOperationsCallbacks,
shouldTrackEvents,
disabled = false,
stateItemClassName,
} = props;
const { groupKey, groupedStates, states, stateOperationsCallbacks, disabled = false, stateItemClassName } = props;
return (
<>
@@ -41,7 +32,6 @@ export const StateList = observer(function StateList(props: TStateList) {
state={state}
disabled={disabled}
stateOperationsCallbacks={stateOperationsCallbacks}
shouldTrackEvents={shouldTrackEvents}
stateItemClassName={stateItemClassName}
/>
))}

View File

@@ -7,7 +7,7 @@
import { observer } from "mobx-react";
import { usePathname } from "next/navigation";
// i18n
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { Button } from "@plane/propel/button";
@@ -65,7 +65,6 @@ export const ProjectsBaseHeader = observer(function ProjectsBaseHeader() {
onClick={() => {
toggleCreateProjectModal(true);
}}
data-ph-element={PROJECT_TRACKER_ELEMENTS.CREATE_HEADER_BUTTON}
className="items-center gap-1"
>
<span className="hidden sm:inline-block">{t("workspace_projects.create.label")}</span>

View File

@@ -7,7 +7,7 @@
import { useState } from "react";
import { observer } from "mobx-react";
// plane imports
import { EUserPermissions, EUserPermissionsLevel, MEMBER_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { SearchIcon } from "@plane/propel/icons";
@@ -105,7 +105,6 @@ export const ProjectMemberList = observer(function ProjectMemberList(props: TPro
onClick={() => {
setInviteModal(true);
}}
data-ph-element={MEMBER_TRACKER_ELEMENTS.HEADER_ADD_BUTTON}
>
{t("add_member")}
</Button>

View File

@@ -8,7 +8,6 @@ import { useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "react-router";
// plane imports
import { PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
// components
@@ -73,11 +72,7 @@ export const GeneralProjectSettingsControlSection = observer(function GeneralPro
title={t("delete")}
description="When deleting a project, all of the data and resources within that project will be permanently removed and cannot be recovered."
control={
<Button
variant="error-outline"
onClick={() => setSelectedProject(currentProjectDetails.id ?? null)}
data-ph-element={PROJECT_TRACKER_ELEMENTS.DELETE_PROJECT_BUTTON}
>
<Button variant="error-outline" onClick={() => setSelectedProject(currentProjectDetails.id ?? null)}>
{t("delete")}
</Button>
}

View File

@@ -5,7 +5,6 @@
*/
import Link from "next/link";
import { PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { ChevronRightIcon } from "@plane/propel/icons";
import { EPillVariant, Pill, EPillSize } from "@plane/propel/pill";
import { ToggleSwitch } from "@plane/ui";
@@ -41,7 +40,6 @@ export function ProjectFeatureToggle(props: Props) {
onChange={() => handleSubmit(featureItem?.key, featureItem?.property)}
disabled={disabled}
size="sm"
data-ph-element={PROJECT_TRACKER_ELEMENTS.TOGGLE_FEATURE}
/>
);
}

View File

@@ -10,7 +10,7 @@ import { Controller, useForm } from "react-hook-form";
import { CircleMinus } from "lucide-react";
import { Disclosure } from "@headlessui/react";
// plane imports
import { ROLE, EUserPermissions, MEMBER_TRACKER_ELEMENTS } from "@plane/constants";
import { ROLE, EUserPermissions } from "@plane/constants";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { EUserProjectRoles, IUser, IWorkspaceMember, TProjectMembership } from "@plane/types";
import { CustomMenu, CustomSelect } from "@plane/ui";
@@ -78,7 +78,6 @@ export function NameColumn(props: NameProps) {
<CustomMenu.MenuItem>
<div
className="flex cursor-pointer items-center gap-x-1 font-medium text-danger-primary"
data-ph-element={MEMBER_TRACKER_ELEMENTS.PROJECT_MEMBER_TABLE_CONTEXT_MENU}
onClick={() => setRemoveMemberModal(rowData)}
>
<CircleMinus className="size-3.5 flex-shrink-0" />

View File

@@ -23,23 +23,12 @@ export type TFiltersRowProps<K extends TFilterProperty, E extends TExternalFilte
disabledAllOperations?: boolean;
filter: IFilterInstance<K, E>;
variant?: "modal" | "header";
trackerElements?: {
clearFilter?: string;
saveView?: string;
updateView?: string;
};
};
export const FiltersRow = observer(function FiltersRow<K extends TFilterProperty, E extends TExternalFilter>(
props: TFiltersRowProps<K, E>
) {
const {
buttonConfig,
disabledAllOperations: disabledAllOperationsProp = false,
filter,
variant = "header",
trackerElements,
} = props;
const { buttonConfig, disabledAllOperations: disabledAllOperationsProp = false, filter, variant = "header" } = props;
// states
const [isUpdating, setIsUpdating] = useState(false);
// derived values
@@ -90,22 +79,12 @@ export const FiltersRow = observer(function FiltersRow<K extends TFilterProperty
const rightContent = !disabledAllOperations && (
<>
<ElementTransition show={filter.canClearFilters}>
<Button
variant="secondary"
className={COMMON_OPERATION_BUTTON_CLASSNAME}
onClick={filter.clearFilters}
data-ph-element={trackerElements?.clearFilter}
>
<Button variant="secondary" className={COMMON_OPERATION_BUTTON_CLASSNAME} onClick={filter.clearFilters}>
{filter.clearFilterOptions?.label ?? "Clear all"}
</Button>
</ElementTransition>
<ElementTransition show={filter.canSaveView}>
<Button
variant="secondary"
className={COMMON_OPERATION_BUTTON_CLASSNAME}
onClick={filter.saveView}
data-ph-element={trackerElements?.saveView}
>
<Button variant="secondary" className={COMMON_OPERATION_BUTTON_CLASSNAME} onClick={filter.saveView}>
{filter.saveViewOptions?.label ?? "Save view"}
</Button>
</ElementTransition>
@@ -116,7 +95,6 @@ export const FiltersRow = observer(function FiltersRow<K extends TFilterProperty
onClick={handleUpdate}
loading={isUpdating}
disabled={isUpdating}
data-ph-element={trackerElements?.updateView}
>
{isUpdating ? "Confirming" : (filter.updateViewOptions?.label ?? "Update view")}
</Button>

View File

@@ -5,7 +5,6 @@
*/
import { Disclosure, Transition } from "@headlessui/react";
import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
import { Button } from "@plane/propel/button";
import { ChevronDownIcon, ChevronUpIcon } from "@plane/propel/icons";
@@ -41,12 +40,7 @@ export function WebhookDeleteSection(props: Props) {
webhook.
</span>
<div>
<Button
variant="error-fill"
size="lg"
onClick={openDeleteModal}
data-ph-element={WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_DELETE_BUTTON}
>
<Button variant="error-fill" size="lg" onClick={openDeleteModal}>
Delete webhook
</Button>
</div>

View File

@@ -7,7 +7,6 @@
import React, { useEffect, useState } from "react";
import { observer } from "mobx-react";
import { Controller, useForm } from "react-hook-form";
import { WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import type { IWebhook, TWebhookEventTypes } from "@plane/types";
@@ -98,12 +97,7 @@ export const WebhookForm = observer(function WebhookForm(props: Props) {
{data ? (
<div className="space-y-5 pt-0">
<WebhookSecretKey data={data} />
<Button
size="lg"
type="submit"
loading={isSubmitting}
data-ph-element={WORKSPACE_SETTINGS_TRACKER_ELEMENTS.WEBHOOK_UPDATE_BUTTON}
>
<Button size="lg" type="submit" loading={isSubmitting}>
{isSubmitting ? t("updating") : t("update")}
</Button>
</div>

View File

@@ -7,7 +7,6 @@
import { useState } from "react";
import { observer } from "mobx-react";
// plane imports
import { WORKSPACE_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import type { IWorkspace } from "@plane/types";
@@ -38,11 +37,7 @@ export const DeleteWorkspaceSection = observer(function DeleteWorkspaceSection(p
title={t("workspace_settings.settings.general.delete_workspace")}
description={t("workspace_settings.settings.general.delete_workspace_description")}
control={
<Button
variant="error-outline"
onClick={() => setDeleteWorkspaceModal(true)}
data-ph-element={WORKSPACE_TRACKER_ELEMENTS.DELETE_WORKSPACE_BUTTON}
>
<Button variant="error-outline" onClick={() => setDeleteWorkspaceModal(true)}>
{t("delete")}
</Button>
}

View File

@@ -10,7 +10,7 @@ import { Controller, useForm } from "react-hook-form";
import { Disclosure } from "@headlessui/react";
// plane imports
import { ROLE, EUserPermissions, EUserPermissionsLevel, MEMBER_TRACKER_ELEMENTS } from "@plane/constants";
import { ROLE, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { TrashIcon, SuspendedUserIcon } from "@plane/propel/icons";
import { Pill, EPillVariant, EPillSize } from "@plane/propel/pill";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
@@ -98,7 +98,6 @@ export function NameColumn(props: NameProps) {
setRemoveMemberModal(rowData);
}
}}
data-ph-element={MEMBER_TRACKER_ELEMENTS.WORKSPACE_MEMBER_TABLE_CONTEXT_MENU}
>
<TrashIcon className="size-3.5 align-middle" /> {id === currentUser?.id ? "Leave " : "Remove "}
</div>

View File

@@ -17,7 +17,7 @@ import scrollIntoView from "smooth-scroll-into-view-if-needed";
import { Settings, Share2, LogOut, MoreHorizontal } from "lucide-react";
import { Disclosure, Transition } from "@headlessui/react";
// plane imports
import { EUserPermissions, EUserPermissionsLevel, MEMBER_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useOutsideClickDetector } from "@plane/hooks";
import { useTranslation } from "@plane/i18n";
import { Logo } from "@plane/propel/emoji-icon-picker";
@@ -434,10 +434,7 @@ export const SidebarProjectsListItem = observer(function SidebarProjectsListItem
</CustomMenu.MenuItem>
{/* leave project */}
{!isAuthorized && (
<CustomMenu.MenuItem
onClick={handleLeaveProject}
data-ph-element={MEMBER_TRACKER_ELEMENTS.SIDEBAR_PROJECT_QUICK_ACTIONS}
>
<CustomMenu.MenuItem onClick={handleLeaveProject}>
<div className="flex items-center justify-start gap-2">
<LogOut className="h-3.5 w-3.5 stroke-[1.5]" />
<span>{t("leave_project")}</span>

View File

@@ -12,7 +12,7 @@ import { useParams, usePathname } from "next/navigation";
import { Ellipsis } from "lucide-react";
import { Disclosure, Transition } from "@headlessui/react";
// plane imports
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { PlusIcon, ChevronRightIcon } from "@plane/propel/icons";
import { IconButton } from "@plane/propel/icon-button";
@@ -195,7 +195,6 @@ export const SidebarProjectsList = observer(function SidebarProjectsList() {
onClick={() => {
setIsProjectModalOpen(true);
}}
data-ph-element={PROJECT_TRACKER_ELEMENTS.SIDEBAR_CREATE_PROJECT_TOOLTIP}
className="hidden text-placeholder group-hover:inline-flex"
aria-label={t("aria_labels.projects_sidebar.create_new_project")}
/>
@@ -277,7 +276,6 @@ export const SidebarProjectsList = observer(function SidebarProjectsList() {
{isAuthorizedUser && joinedProjects?.length === 0 && (
<button
type="button"
data-ph-element={PROJECT_TRACKER_ELEMENTS.SIDEBAR_CREATE_PROJECT_BUTTON}
className="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-13 leading-5 font-medium text-secondary hover:bg-surface-2"
onClick={() => {
toggleCreateProjectModal(true);

View File

@@ -8,7 +8,7 @@ import { useRef, useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EUserPermissions, EUserPermissionsLevel, SIDEBAR_TRACKER_ELEMENTS } from "@plane/constants";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { AddWorkItemIcon } from "@plane/propel/icons";
import type { TIssue } from "@plane/types";
@@ -89,7 +89,6 @@ export const SidebarQuickActions = observer(function SidebarQuickActions() {
disabled={disabled}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
data-ph-element={SIDEBAR_TRACKER_ELEMENTS.CREATE_WORK_ITEM_BUTTON}
/>
</div>
</>