Compare commits

..
Author SHA1 Message Date
Jayash Tripathy 4ef8de4722 chore: done base setup of propel chart stories 2025-10-07 16:25:11 +05:30
303 changed files with 744 additions and 8493 deletions
-7
View File
@@ -1,7 +0,0 @@
[codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
skip = .git*,*.svg,i18n,*-lock.yaml,*.css,.codespellrc,migrations,*.js,*.map,*.mjs
check-hidden = true
# ignore all CamelCase and camelCase
ignore-regex = \b[A-Za-z][a-z]+[A-Z][a-zA-Z]+\b
ignore-words-list = tread
-25
View File
@@ -1,25 +0,0 @@
# Codespell configuration is within .codespellrc
---
name: Codespell
on:
push:
branches: [preview]
pull_request:
branches: [preview]
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Annotate locations with typos
uses: codespell-project/codespell-problem-matcher@v1
- name: Codespell
uses: codespell-project/actions-codespell@v2
-2
View File
@@ -99,5 +99,3 @@ dev-editor
*.rdb.gz
storybook-static
CLAUDE.md
+1 -1
View File
@@ -3,8 +3,8 @@ import { FC } from "react";
import { useForm } from "react-hook-form";
import { Lightbulb } from "lucide-react";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IFormattedInstanceConfiguration, TInstanceAIConfigurationKeys } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ControllerInput, TControllerInputFormField } from "@/components/common/controller-input";
// hooks
@@ -8,9 +8,8 @@ import { Monitor } from "lucide-react";
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import { Button, getButtonStyling } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IFormattedInstanceConfiguration, TInstanceGithubAuthenticationConfigurationKeys } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
import { cn } from "@plane/utils";
// components
import { CodeBlock } from "@/components/common/code-block";
@@ -6,8 +6,7 @@ import Image from "next/image";
import { useTheme } from "next-themes";
import useSWR from "swr";
// plane internal packages
import { setPromiseToast } from "@plane/propel/toast";
import { Loader, ToggleSwitch } from "@plane/ui";
import { Loader, ToggleSwitch, setPromiseToast } from "@plane/ui";
import { resolveGeneralTheme } from "@plane/utils";
// components
import { AuthenticationMethodCard } from "@/components/authentication/authentication-method-card";
@@ -5,8 +5,8 @@ import { useForm } from "react-hook-form";
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import { Button, getButtonStyling } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IFormattedInstanceConfiguration, TInstanceGitlabAuthenticationConfigurationKeys } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
import { cn } from "@plane/utils";
// components
import { CodeBlock } from "@/components/common/code-block";
@@ -4,8 +4,7 @@ import { useState } from "react";
import { observer } from "mobx-react";
import Image from "next/image";
import useSWR from "swr";
import { setPromiseToast } from "@plane/propel/toast";
import { Loader, ToggleSwitch } from "@plane/ui";
import { Loader, ToggleSwitch, setPromiseToast } from "@plane/ui";
// components
import { AuthenticationMethodCard } from "@/components/authentication/authentication-method-card";
// hooks
@@ -7,8 +7,8 @@ import { Monitor } from "lucide-react";
// plane internal packages
import { API_BASE_URL } from "@plane/constants";
import { Button, getButtonStyling } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IFormattedInstanceConfiguration, TInstanceGoogleAuthenticationConfigurationKeys } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
import { cn } from "@plane/utils";
// components
import { CodeBlock } from "@/components/common/code-block";
@@ -4,8 +4,7 @@ import { useState } from "react";
import { observer } from "mobx-react";
import Image from "next/image";
import useSWR from "swr";
import { setPromiseToast } from "@plane/propel/toast";
import { Loader, ToggleSwitch } from "@plane/ui";
import { Loader, ToggleSwitch, setPromiseToast } from "@plane/ui";
// components
import { AuthenticationMethodCard } from "@/components/authentication/authentication-method-card";
// hooks
@@ -4,9 +4,8 @@ import { useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
// plane internal packages
import { setPromiseToast } from "@plane/propel/toast";
import { TInstanceConfigurationKeys } from "@plane/types";
import { Loader, ToggleSwitch } from "@plane/ui";
import { Loader, ToggleSwitch, setPromiseToast } from "@plane/ui";
import { cn } from "@plane/utils";
// hooks
import { useInstance } from "@/hooks/store";
@@ -4,10 +4,9 @@ import React, { FC, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
// types
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IFormattedInstanceConfiguration, TInstanceEmailConfigurationKeys } from "@plane/types";
// ui
import { CustomSelect } from "@plane/ui";
import { CustomSelect, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ControllerInput, TControllerInputFormField } from "@/components/common/controller-input";
// hooks
@@ -3,8 +3,7 @@
import { useEffect, useState } from "react";
import { observer } from "mobx-react";
import useSWR from "swr";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Loader, ToggleSwitch } from "@plane/ui";
import { Loader, setToast, TOAST_TYPE, ToggleSwitch } from "@plane/ui";
// hooks
import { useInstance } from "@/hooks/store";
// components
@@ -5,10 +5,9 @@ import { Controller, useForm } from "react-hook-form";
import { Telescope } from "lucide-react";
// types
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IInstance, IInstanceAdmin } from "@plane/types";
// ui
import { Input, ToggleSwitch } from "@plane/ui";
import { Input, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
// components
import { ControllerInput } from "@/components/common/controller-input";
import { useInstance } from "@/hooks/store";
@@ -2,8 +2,8 @@
import { FC } from "react";
import { useForm } from "react-hook-form";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IFormattedInstanceConfiguration, TInstanceImageConfigurationKeys } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { ControllerInput } from "@/components/common/controller-input";
// hooks
@@ -5,11 +5,10 @@ import { Controller, useForm } from "react-hook-form";
// plane imports
import { WEB_BASE_URL, ORGANIZATION_SIZE, RESTRICTED_URLS } from "@plane/constants";
import { Button, getButtonStyling } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { InstanceWorkspaceService } from "@plane/services";
import { IWorkspace } from "@plane/types";
// components
import { CustomSelect, Input } from "@plane/ui";
import { CustomSelect, Input, setToast, TOAST_TYPE } from "@plane/ui";
// hooks
import { useWorkspace } from "@/hooks/store";
@@ -7,10 +7,8 @@ import useSWR from "swr";
import { Loader as LoaderIcon } from "lucide-react";
// types
import { Button, getButtonStyling } from "@plane/propel/button";
import { setPromiseToast } from "@plane/propel/toast";
import { TInstanceConfigurationKeys } from "@plane/types";
import { Loader, ToggleSwitch } from "@plane/ui";
import { Loader, setPromiseToast, ToggleSwitch } from "@plane/ui";
import { cn } from "@plane/utils";
// components
import { WorkspaceListItem } from "@/components/workspace/list-item";
+1 -1
View File
@@ -1,7 +1,7 @@
"use client";
import { useTheme } from "next-themes";
import { Toast } from "@plane/propel/toast";
import { Toast } from "@plane/ui";
import { resolveGeneralTheme } from "@plane/utils";
export const ToastWithTheme = () => {
@@ -4,7 +4,8 @@ import React from "react";
// ui
import { Copy } from "lucide-react";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TOAST_TYPE, setToast } from "@plane/ui";
// icons
type Props = {
label: string;
+21 -21
View File
@@ -111,27 +111,6 @@
--color-sidebar-shadow-2xl: var(--color-shadow-2xl);
--color-sidebar-shadow-3xl: var(--color-shadow-3xl);
--color-sidebar-shadow-4xl: var(--color-shadow-4xl);
/* toast theme */
--color-toast-success-text: 178, 221, 181;
--color-toast-error-text: 206, 44, 49;
--color-toast-warning-text: 255, 186, 24;
--color-toast-info-text: 141, 164, 239;
--color-toast-loading-text: 255, 255, 255;
--color-toast-secondary-text: 185, 187, 198;
--color-toast-tertiary-text: 139, 141, 152;
--color-toast-success-background: 46, 46, 46;
--color-toast-error-background: 46, 46, 46;
--color-toast-warning-background: 46, 46, 46;
--color-toast-info-background: 46, 46, 46;
--color-toast-loading-background: 46, 46, 46;
--color-toast-success-border: 42, 126, 59;
--color-toast-error-border: 100, 23, 35;
--color-toast-warning-border: 79, 52, 34;
--color-toast-info-border: 58, 91, 199;
--color-toast-loading-border: 96, 100, 108;
}
[data-theme="light"],
@@ -242,6 +221,27 @@
--color-border-200: 38, 38, 38; /* subtle border- 2 */
--color-border-300: 46, 46, 46; /* strong border- 1 */
--color-border-400: 58, 58, 58; /* strong border- 2 */
/* toast theme */
--color-toast-success-text: 178, 221, 181;
--color-toast-error-text: 206, 44, 49;
--color-toast-warning-text: 255, 186, 24;
--color-toast-info-text: 141, 164, 239;
--color-toast-loading-text: 255, 255, 255;
--color-toast-secondary-text: 185, 187, 198;
--color-toast-tertiary-text: 139, 141, 152;
--color-toast-success-background: 46, 46, 46;
--color-toast-error-background: 46, 46, 46;
--color-toast-warning-background: 46, 46, 46;
--color-toast-info-background: 46, 46, 46;
--color-toast-loading-background: 46, 46, 46;
--color-toast-success-border: 42, 126, 59;
--color-toast-error-border: 100, 23, 35;
--color-toast-warning-border: 79, 52, 34;
--color-toast-info-border: 58, 91, 199;
--color-toast-loading-border: 96, 100, 108;
}
[data-theme="dark-contrast"] {
+1 -12
View File
@@ -4,7 +4,7 @@ from rest_framework import serializers
# Module imports
from .base import BaseSerializer
from plane.db.models import Cycle, CycleIssue, User
from plane.db.models import Cycle, CycleIssue
from plane.utils.timezone_converter import convert_to_utc
@@ -16,13 +16,6 @@ class CycleCreateSerializer(BaseSerializer):
and UTC normalization for time-bound iteration planning and sprint management.
"""
owned_by = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(),
required=False,
allow_null=True,
help_text="User who owns the cycle. If not provided, defaults to the current user.",
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
project = self.context.get("project")
@@ -79,10 +72,6 @@ class CycleCreateSerializer(BaseSerializer):
date=str(data.get("end_date", None).date()),
project_id=project_id,
)
if not data.get("owned_by"):
data["owned_by"] = self.context["request"].user
return data
+1 -1
View File
@@ -1,4 +1,4 @@
# Module imports
# Module improts
from .base import BaseSerializer
from .issue import IssueExpandSerializer
from plane.db.models import IntakeIssue, Issue
+3 -4
View File
@@ -307,8 +307,7 @@ class CycleListCreateAPIEndpoint(BaseAPIView):
if (request.data.get("start_date", None) is None and request.data.get("end_date", None) is None) or (
request.data.get("start_date", None) is not None and request.data.get("end_date", None) is not None
):
serializer = CycleCreateSerializer(data=request.data, context={"request": request})
serializer = CycleCreateSerializer(data=request.data)
if serializer.is_valid():
if (
request.data.get("external_id")
@@ -333,7 +332,7 @@ class CycleListCreateAPIEndpoint(BaseAPIView):
},
status=status.HTTP_409_CONFLICT,
)
serializer.save(project_id=project_id)
serializer.save(project_id=project_id, owned_by=request.user)
# Send the model activity
model_activity.delay(
model_name="cycle",
@@ -519,7 +518,7 @@ class CycleDetailAPIEndpoint(BaseAPIView):
status=status.HTTP_400_BAD_REQUEST,
)
serializer = CycleUpdateSerializer(cycle, data=request.data, partial=True, context={"request": request})
serializer = CycleUpdateSerializer(cycle, data=request.data, partial=True)
if serializer.is_valid():
if (
request.data.get("external_id")
+1 -1
View File
@@ -1196,7 +1196,7 @@ class CycleAnalyticsEndpoint(BaseAPIView):
if the issues were transferred to the new cycle, then the progress_snapshot will be present
return the progress_snapshot data in the analytics for each date
else issues were not transferred to the new cycle then generate the stats from the cycle issue bridge tables
else issues were not transferred to the new cycle then generate the stats from the cycle isssue bridge tables
"""
if cycle.progress_snapshot:
+1 -1
View File
@@ -48,7 +48,7 @@ class ProjectMemberViewSet(BaseViewSet):
# Check if the members array is empty
if not len(members):
return Response(
{"error": "At least one member is required"},
{"error": "Atleast one member is required"},
status=status.HTTP_400_BAD_REQUEST,
)
+1 -1
View File
@@ -99,7 +99,7 @@ class TimezoneEndpoint(APIView):
("Tunis", "Africa/Tunis"), # UTC+01:00
(
"Eastern European Time (Cairo, Helsinki, Kyiv)",
"Europe/Kyiv",
"Europe/Kiev",
), # UTC+02:00 (DST: UTC+03:00)
("Athens", "Europe/Athens"), # UTC+02:00 (DST: UTC+03:00)
("Jerusalem", "Asia/Jerusalem"), # UTC+02:00 (DST: UTC+03:00)
@@ -48,7 +48,7 @@ AUTHENTICATION_ERROR_CODES = {
"INCORRECT_OLD_PASSWORD": 5135,
"MISSING_PASSWORD": 5138,
"INVALID_NEW_PASSWORD": 5140,
# set password
# set passowrd
"PASSWORD_ALREADY_SET": 5145,
# Admin
"ADMIN_ALREADY_EXIST": 5150,
@@ -31,4 +31,4 @@ class Command(BaseCommand):
user.is_active = True
user.save()
self.stdout.write(self.style.SUCCESS("User activated successfully"))
self.stdout.write(self.style.SUCCESS("User activated succesfully"))
@@ -59,4 +59,4 @@ class Command(BaseCommand):
user.is_password_autoset = False
user.save()
self.stdout.write(self.style.SUCCESS("User password updated successfully"))
self.stdout.write(self.style.SUCCESS("User password updated succesfully"))
@@ -70,7 +70,7 @@ class Command(BaseCommand):
try:
s3_client.delete_object(Bucket=bucket_name, Key="test_permission_check.txt")
except ClientError:
self.stdout.write("Couldn't delete test object")
self.stdout.write("Coudn't delete test object")
# 4. Test s3:PutBucketPolicy (attempt to put a bucket policy)
try:
@@ -1,382 +0,0 @@
import pytest
from rest_framework import status
from django.db import IntegrityError
from django.utils import timezone
from datetime import datetime, timedelta
from uuid import uuid4
from plane.db.models import Cycle, Project, ProjectMember
@pytest.fixture
def project(db, workspace, create_user):
"""Create a test project with the user as a member"""
project = Project.objects.create(
name="Test Project",
identifier="TP",
workspace=workspace,
created_by=create_user,
)
ProjectMember.objects.create(
project=project,
member=create_user,
role=20, # Admin role
is_active=True,
)
return project
@pytest.fixture
def cycle_data():
"""Sample cycle data for tests"""
return {
"name": "Test Cycle",
"description": "A test cycle for unit tests",
}
@pytest.fixture
def draft_cycle_data():
"""Sample draft cycle data (no dates)"""
return {
"name": "Draft Cycle",
"description": "A draft cycle without dates",
}
@pytest.fixture
def create_cycle(db, project, create_user):
"""Create a test cycle"""
return Cycle.objects.create(
name="Existing Cycle",
description="An existing cycle",
start_date=timezone.now() + timedelta(days=1),
end_date=timezone.now() + timedelta(days=7),
project=project,
workspace=project.workspace,
owned_by=create_user,
)
@pytest.mark.contract
class TestCycleListCreateAPIEndpoint:
"""Test Cycle List and Create API Endpoint"""
def get_cycle_url(self, workspace_slug, project_id):
"""Helper to get cycle endpoint URL"""
return f"/api/v1/workspaces/{workspace_slug}/projects/{project_id}/cycles/"
@pytest.mark.django_db
def test_create_cycle_success(self, api_key_client, workspace, project, cycle_data):
"""Test successful cycle creation"""
url = self.get_cycle_url(workspace.slug, project.id)
response = api_key_client.post(url, cycle_data, format="json")
assert response.status_code == status.HTTP_201_CREATED
assert Cycle.objects.count() == 1
created_cycle = Cycle.objects.first()
assert created_cycle.name == cycle_data["name"]
assert created_cycle.description == cycle_data["description"]
assert created_cycle.project == project
assert created_cycle.owned_by_id is not None
@pytest.mark.django_db
def test_create_cycle_invalid_data(self, api_key_client, workspace, project):
"""Test cycle creation with invalid data"""
url = self.get_cycle_url(workspace.slug, project.id)
# Test with empty data
response = api_key_client.post(url, {}, format="json")
assert response.status_code == status.HTTP_400_BAD_REQUEST
# Test with missing name
response = api_key_client.post(url, {"description": "Test cycle"}, format="json")
assert response.status_code == status.HTTP_400_BAD_REQUEST
@pytest.mark.django_db
def test_create_cycle_invalid_date_combination(self, api_key_client, workspace, project):
"""Test cycle creation with invalid date combination (only start_date)"""
url = self.get_cycle_url(workspace.slug, project.id)
invalid_data = {
"name": "Invalid Cycle",
"start_date": (timezone.now() + timedelta(days=1)).isoformat(),
# Missing end_date
}
response = api_key_client.post(url, invalid_data, format="json")
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert "Both start date and end date are either required or are to be null" in response.data["error"]
@pytest.mark.django_db
def test_create_cycle_with_external_id(self, api_key_client, workspace, project):
"""Test creating cycle with external ID"""
url = self.get_cycle_url(workspace.slug, project.id)
cycle_data = {
"name": "External Cycle",
"description": "A cycle with external ID",
"external_id": "ext-123",
"external_source": "github",
}
response = api_key_client.post(url, cycle_data, format="json")
assert response.status_code == status.HTTP_201_CREATED
created_cycle = Cycle.objects.first()
assert created_cycle.external_id == "ext-123"
assert created_cycle.external_source == "github"
@pytest.mark.django_db
def test_create_cycle_duplicate_external_id(self, api_key_client, workspace, project, create_user):
"""Test creating cycle with duplicate external ID"""
url = self.get_cycle_url(workspace.slug, project.id)
# Create first cycle
Cycle.objects.create(
name="First Cycle",
project=project,
workspace=workspace,
external_id="ext-123",
external_source="github",
owned_by=create_user,
)
# Try to create second cycle with same external ID
cycle_data = {
"name": "Second Cycle",
"external_id": "ext-123",
"external_source": "github",
"owned_by": create_user.id,
}
response = api_key_client.post(url, cycle_data, format="json")
assert response.status_code == status.HTTP_409_CONFLICT
assert "same external id" in response.data["error"]
@pytest.mark.django_db
def test_list_cycles_success(self, api_key_client, workspace, project, create_cycle, create_user):
"""Test successful cycle listing"""
url = self.get_cycle_url(workspace.slug, project.id)
# Create additional cycles
Cycle.objects.create(
name="Cycle 2",
project=project,
workspace=workspace,
start_date=timezone.now() + timedelta(days=10),
end_date=timezone.now() + timedelta(days=17),
owned_by=create_user,
)
Cycle.objects.create(
name="Cycle 3",
project=project,
workspace=workspace,
start_date=timezone.now() + timedelta(days=20),
end_date=timezone.now() + timedelta(days=27),
owned_by=create_user,
)
response = api_key_client.get(url)
assert response.status_code == status.HTTP_200_OK
assert "results" in response.data
assert len(response.data["results"]) == 3 # Including create_cycle fixture
@pytest.mark.django_db
def test_list_cycles_with_view_filter(self, api_key_client, workspace, project, create_user):
"""Test cycle listing with different view filters"""
url = self.get_cycle_url(workspace.slug, project.id)
# Create cycles in different states
now = timezone.now()
# Current cycle (started but not ended)
Cycle.objects.create(
name="Current Cycle",
project=project,
workspace=workspace,
start_date=now - timedelta(days=1),
end_date=now + timedelta(days=6),
owned_by=create_user,
)
# Upcoming cycle
Cycle.objects.create(
name="Upcoming Cycle",
project=project,
workspace=workspace,
start_date=now + timedelta(days=1),
end_date=now + timedelta(days=8),
owned_by=create_user,
)
# Completed cycle
Cycle.objects.create(
name="Completed Cycle",
project=project,
workspace=workspace,
start_date=now - timedelta(days=10),
end_date=now - timedelta(days=3),
owned_by=create_user,
)
# Draft cycle
Cycle.objects.create(
name="Draft Cycle",
project=project,
workspace=workspace,
owned_by=create_user,
)
# Test current cycles
response = api_key_client.get(url, {"cycle_view": "current"})
assert response.status_code == status.HTTP_200_OK
assert len(response.data) == 1
assert response.data[0]["name"] == "Current Cycle"
# Test upcoming cycles
response = api_key_client.get(url, {"cycle_view": "upcoming"})
assert response.status_code == status.HTTP_200_OK
assert len(response.data["results"]) == 1
assert response.data["results"][0]["name"] == "Upcoming Cycle"
# Test completed cycles
response = api_key_client.get(url, {"cycle_view": "completed"})
assert response.status_code == status.HTTP_200_OK
assert len(response.data["results"]) == 1
assert response.data["results"][0]["name"] == "Completed Cycle"
# Test draft cycles
response = api_key_client.get(url, {"cycle_view": "draft"})
assert response.status_code == status.HTTP_200_OK
assert len(response.data["results"]) == 1
assert response.data["results"][0]["name"] == "Draft Cycle"
@pytest.mark.contract
class TestCycleDetailAPIEndpoint:
"""Test Cycle Detail API Endpoint"""
def get_cycle_detail_url(self, workspace_slug, project_id, cycle_id):
"""Helper to get cycle detail endpoint URL"""
return f"/api/v1/workspaces/{workspace_slug}/projects/{project_id}/cycles/{cycle_id}/"
@pytest.mark.django_db
def test_get_cycle_success(self, api_key_client, workspace, project, create_cycle):
"""Test successful cycle retrieval"""
url = self.get_cycle_detail_url(workspace.slug, project.id, create_cycle.id)
response = api_key_client.get(url)
assert response.status_code == status.HTTP_200_OK
assert str(response.data["id"]) == str(create_cycle.id)
assert response.data["name"] == create_cycle.name
assert response.data["description"] == create_cycle.description
@pytest.mark.django_db
def test_get_cycle_not_found(self, api_key_client, workspace, project):
"""Test getting non-existent cycle"""
fake_id = uuid4()
url = self.get_cycle_detail_url(workspace.slug, project.id, fake_id)
response = api_key_client.get(url)
assert response.status_code == status.HTTP_404_NOT_FOUND
@pytest.mark.django_db
def test_update_cycle_success(self, api_key_client, workspace, project, create_cycle):
"""Test successful cycle update"""
url = self.get_cycle_detail_url(workspace.slug, project.id, create_cycle.id)
update_data = {
"name": f"Updated Cycle {uuid4()}",
"description": "Updated description",
}
response = api_key_client.patch(url, update_data, format="json")
assert response.status_code == status.HTTP_200_OK
create_cycle.refresh_from_db()
assert create_cycle.name == update_data["name"]
assert create_cycle.description == update_data["description"]
@pytest.mark.django_db
def test_update_cycle_invalid_data(self, api_key_client, workspace, project, create_cycle):
"""Test cycle update with invalid data"""
url = self.get_cycle_detail_url(workspace.slug, project.id, create_cycle.id)
update_data = {"name": ""}
response = api_key_client.patch(url, update_data, format="json")
# This might be 400 if name is required, or 200 if empty names are allowed
assert response.status_code in [status.HTTP_400_BAD_REQUEST, status.HTTP_200_OK]
@pytest.mark.django_db
def test_update_cycle_with_external_id_conflict(self, api_key_client, workspace, project, create_cycle, create_user ):
"""Test cycle update with conflicting external ID"""
url = self.get_cycle_detail_url(workspace.slug, project.id, create_cycle.id)
# Create another cycle with external ID
Cycle.objects.create(
name="Another Cycle",
project=project,
workspace=workspace,
external_id="ext-456",
external_source="github",
owned_by=create_user,
)
# Try to update cycle with same external ID
update_data = {
"external_id": "ext-456",
"external_source": "github",
}
response = api_key_client.patch(url, update_data, format="json")
assert response.status_code == status.HTTP_409_CONFLICT
assert "same external id" in response.data["error"]
@pytest.mark.django_db
def test_delete_cycle_success(self, api_key_client, workspace, project, create_cycle):
"""Test successful cycle deletion"""
url = self.get_cycle_detail_url(workspace.slug, project.id, create_cycle.id)
response = api_key_client.delete(url)
assert response.status_code == status.HTTP_204_NO_CONTENT
assert not Cycle.objects.filter(id=create_cycle.id).exists()
@pytest.mark.django_db
def test_cycle_metrics_annotation(self, api_key_client, workspace, project, create_cycle):
"""Test that cycle includes issue metrics annotations"""
url = self.get_cycle_detail_url(workspace.slug, project.id, create_cycle.id)
response = api_key_client.get(url)
assert response.status_code == status.HTTP_200_OK
# Check that metrics are included in response
cycle_data = response.data
assert "total_issues" in cycle_data
assert "completed_issues" in cycle_data
assert "cancelled_issues" in cycle_data
assert "started_issues" in cycle_data
assert "unstarted_issues" in cycle_data
assert "backlog_issues" in cycle_data
# All should be 0 for a new cycle
assert cycle_data["total_issues"] == 0
assert cycle_data["completed_issues"] == 0
assert cycle_data["cancelled_issues"] == 0
assert cycle_data["started_issues"] == 0
assert cycle_data["unstarted_issues"] == 0
assert cycle_data["backlog_issues"] == 0
@@ -5,9 +5,9 @@ import { observer } from "mobx-react";
import { useForm, Controller } from "react-hook-form";
// plane imports
import { EditorRefApi } from "@plane/editor";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { SitesFileService } from "@plane/services";
import { TIssuePublicComment } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
// editor components
import { LiteTextEditor } from "@/components/editor/lite-text-editor";
// hooks
@@ -6,7 +6,7 @@ import { Link2, MoveRight } from "lucide-react";
import { Listbox, Transition } from "@headlessui/react";
// ui
import { CenterPanelIcon, FullScreenPanelIcon, SidePanelIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { setToast, TOAST_TYPE } from "@plane/ui";
// helpers
import { copyTextToClipboard } from "@/helpers/string.helper";
// hooks
@@ -6,7 +6,7 @@ import { CalendarCheck2, Signal } from "lucide-react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { DoubleCircleIcon, StateGroupIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TOAST_TYPE, setToast } from "@plane/ui";
import { cn, getIssuePriorityFilters } from "@plane/utils";
// components
import { Icon } from "@/components/ui";
+1 -1
View File
@@ -3,7 +3,7 @@
import { ReactNode } from "react";
import { useTheme } from "next-themes";
// plane imports
import { Toast } from "@plane/propel/toast";
import { Toast } from "@plane/ui";
import { resolveGeneralTheme } from "@plane/utils";
export const ToastProvider = ({ children }: { children: ReactNode }) => {
+1 -1
View File
@@ -66,7 +66,7 @@ export enum EAuthenticationErrorCodes {
INCORRECT_OLD_PASSWORD = "5135",
MISSING_PASSWORD = "5138",
INVALID_NEW_PASSWORD = "5140",
// set password
// set passowrd
PASSWORD_ALREADY_SET = "5145",
// Admin
ADMIN_ALREADY_EXIST = "5150",
+21 -21
View File
@@ -100,27 +100,6 @@
--color-sidebar-shadow-2xl: var(--color-shadow-2xl);
--color-sidebar-shadow-3xl: var(--color-shadow-3xl);
--color-sidebar-shadow-4xl: var(--color-shadow-4xl);
/* toast theme */
--color-toast-success-text: 178, 221, 181;
--color-toast-error-text: 206, 44, 49;
--color-toast-warning-text: 255, 186, 24;
--color-toast-info-text: 141, 164, 239;
--color-toast-loading-text: 255, 255, 255;
--color-toast-secondary-text: 185, 187, 198;
--color-toast-tertiary-text: 139, 141, 152;
--color-toast-success-background: 46, 46, 46;
--color-toast-error-background: 46, 46, 46;
--color-toast-warning-background: 46, 46, 46;
--color-toast-info-background: 46, 46, 46;
--color-toast-loading-background: 46, 46, 46;
--color-toast-success-border: 42, 126, 59;
--color-toast-error-border: 100, 23, 35;
--color-toast-warning-border: 79, 52, 34;
--color-toast-info-border: 58, 91, 199;
--color-toast-loading-border: 96, 100, 108;
}
[data-theme="light"],
@@ -274,6 +253,27 @@
--color-onboarding-border-300: 34, 35, 38, 0.5;
--color-onboarding-shadow-sm: 0px 4px 20px 0px rgba(39, 44, 56, 0.1);
/* toast theme */
--color-toast-success-text: 178, 221, 181;
--color-toast-error-text: 206, 44, 49;
--color-toast-warning-text: 255, 186, 24;
--color-toast-info-text: 141, 164, 239;
--color-toast-loading-text: 255, 255, 255;
--color-toast-secondary-text: 185, 187, 198;
--color-toast-tertiary-text: 139, 141, 152;
--color-toast-success-background: 46, 46, 46;
--color-toast-error-background: 46, 46, 46;
--color-toast-warning-background: 46, 46, 46;
--color-toast-info-background: 46, 46, 46;
--color-toast-loading-background: 46, 46, 46;
--color-toast-success-border: 42, 126, 59;
--color-toast-error-border: 100, 23, 35;
--color-toast-warning-border: 79, 52, 34;
--color-toast-info-border: 58, 91, 199;
--color-toast-loading-border: 96, 100, 108;
}
[data-theme="dark-contrast"] {
@@ -7,8 +7,8 @@ import { useParams } from "next/navigation";
import { Plus, Search } from "lucide-react";
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { setToast, TOAST_TYPE } from "@plane/ui";
import { copyUrlToClipboard, orderJoinedProjects } from "@plane/utils";
// components
import { CreateProjectModal } from "@/components/project/create-project-modal";
@@ -12,10 +12,9 @@ import {
} from "@plane/constants";
// plane types
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TPage } from "@plane/types";
// plane ui
import { Breadcrumbs, Header } from "@plane/ui";
import { Breadcrumbs, Header, setToast, TOAST_TYPE } from "@plane/ui";
// helpers
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
// hooks
@@ -13,8 +13,9 @@ import {
} from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IWorkspaceBulkInviteFormData } from "@plane/types";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
import { cn } from "@plane/utils";
// components
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
@@ -5,9 +5,9 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import useSWR from "swr";
import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IWebhook } from "@plane/types";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { LogoSpinner } from "@/components/common/logo-spinner";
import { PageHead } from "@/components/core/page-title";
@@ -8,8 +8,7 @@ import { Eye, EyeOff } from "lucide-react";
import { E_PASSWORD_STRENGTH } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Input, PasswordStrengthIndicator } from "@plane/ui";
import { Input, PasswordStrengthIndicator, TOAST_TYPE, setToast } from "@plane/ui";
import { getPasswordStrength } from "@plane/utils";
// components
import { PageHead } from "@/components/core/page-title";
@@ -5,9 +5,9 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IProject } from "@plane/types";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
import { AutoArchiveAutomation, AutoCloseAutomation } from "@/components/automation";
+2 -1
View File
@@ -12,8 +12,9 @@ import { useTranslation } from "@plane/i18n";
// types
import { Button } from "@plane/propel/button";
import { PlaneLogo } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { IWorkspaceMemberInvitation } from "@plane/types";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
import { truncateText } from "@plane/utils";
// components
import { EmptyState } from "@/components/common/empty-state";
@@ -6,8 +6,8 @@ import { useTheme } from "next-themes";
// plane imports
import { I_THEME_OPTION, THEME_OPTIONS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { setPromiseToast } from "@plane/propel/toast";
import { IUserTheme } from "@plane/types";
import { setPromiseToast } from "@plane/ui";
// components
import { applyTheme, unsetCustomCssVariables } from "@plane/utils";
import { LogoSpinner } from "@/components/common/logo-spinner";
+1 -2
View File
@@ -8,8 +8,7 @@ import { Eye, EyeOff } from "lucide-react";
import { E_PASSWORD_STRENGTH } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Input, PasswordStrengthIndicator } from "@plane/ui";
import { Input, PasswordStrengthIndicator, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { getPasswordStrength } from "@plane/utils";
import { PageHead } from "@/components/core/page-title";
+1 -1
View File
@@ -21,8 +21,8 @@ import {
import { PROFILE_ACTION_LINKS } from "@plane/constants";
import { useOutsideClickDetector } from "@plane/hooks";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { TOAST_TYPE, setToast } from "@plane/ui";
import { cn, getFileURL } from "@plane/utils";
// components
import { SidebarNavItem } from "@/components/sidebar/sidebar-navigation";
+1 -1
View File
@@ -8,7 +8,7 @@ import { SWRConfig } from "swr";
// Plane Imports
import { WEB_SWR_CONFIG } from "@plane/constants";
import { TranslationProvider } from "@plane/i18n";
import { Toast } from "@plane/propel/toast";
import { Toast } from "@plane/ui";
//helpers
import { resolveGeneralTheme } from "@plane/utils";
// polyfills
@@ -1,10 +1,10 @@
import { FC } from "react";
import { observer } from "mobx-react";
// types
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { IIssueDisplayProperties } from "@plane/types";
// ui
import { setToast, TOAST_TYPE } from "@plane/ui";
// helpers
import { cn } from "@plane/utils";
// hooks
@@ -4,7 +4,7 @@ import React from "react";
import { observer } from "mobx-react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import type { TIssueOperations } from "@/components/issues/issue-detail";
import { IssueParentSelect } from "@/components/issues/issue-detail/parent-select";
@@ -6,8 +6,8 @@ import { useTheme } from "next-themes";
// plane imports
import { I_THEME_OPTION, THEME_OPTIONS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { setPromiseToast } from "@plane/propel/toast";
import { IUserTheme } from "@plane/types";
import { setPromiseToast } from "@plane/ui";
import { applyTheme, unsetCustomCssVariables } from "@plane/utils";
// components
import { CustomThemeSelector } from "@/components/core/theme/custom-theme-selector";
@@ -6,7 +6,7 @@ import { FormProvider, useForm } from "react-hook-form";
import { DEFAULT_PROJECT_FORM_VALUES, PROJECT_TRACKER_EVENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { setToast, TOAST_TYPE } from "@plane/ui";
// constants
import ProjectCommonAttributes from "@/components/project/create/common-attributes";
import ProjectCreateHeader from "@/components/project/create/header";
@@ -313,7 +313,7 @@ export class BaseTimeLineStore implements IBaseTimelineStore {
});
/**
* updates the block's position such as marginLeft and width while dragging
* updates the block's position such as marginLeft and width wile dragging
* @param id
* @param deltaLeft
* @param deltaWidth
@@ -10,8 +10,7 @@ import { CircleCheck } from "lucide-react";
import { AUTH_TRACKER_EVENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button, getButtonStyling } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Input } from "@plane/ui";
import { Input, TOAST_TYPE, setToast } from "@plane/ui";
import { cn, checkEmailValidity } from "@plane/utils";
// helpers
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
@@ -9,8 +9,7 @@ import { Eye, EyeOff } from "lucide-react";
import { AUTH_TRACKER_ELEMENTS, AUTH_TRACKER_EVENTS, E_PASSWORD_STRENGTH } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Input, PasswordStrengthIndicator } from "@plane/ui";
import { Input, PasswordStrengthIndicator, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { getPasswordStrength } from "@plane/utils";
// helpers
@@ -7,7 +7,7 @@ import { PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// ui
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
import { useUser } from "@/hooks/store/user";
@@ -5,11 +5,10 @@ import { mutate } from "swr";
// types
import { PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { APITokenService } from "@plane/services";
import { IApiToken } from "@plane/types";
// ui
import { AlertModalCore } from "@plane/ui";
import { AlertModalCore, TOAST_TYPE, setToast } from "@plane/ui";
// fetch-keys
import { API_TOKENS_LIST } from "@/constants/fetch-keys";
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
@@ -4,10 +4,9 @@ import React, { useState } from "react";
import { mutate } from "swr";
// plane imports
import { PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { APITokenService } from "@plane/services";
import { IApiToken } from "@plane/types";
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
import { EModalPosition, EModalWidth, ModalCore, TOAST_TYPE, setToast } from "@plane/ui";
import { renderFormattedDate, csvDownload } from "@plane/utils";
// constants
import { API_TOKENS_LIST } from "@/constants/fetch-keys";
@@ -7,10 +7,9 @@ import { Calendar } from "lucide-react";
// types
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IApiToken } from "@plane/types";
// ui
import { CustomSelect, Input, TextArea, ToggleSwitch } from "@plane/ui";
import { CustomSelect, Input, TextArea, ToggleSwitch, TOAST_TYPE, setToast } from "@plane/ui";
import { cn, renderFormattedDate, renderFormattedTime } from "@plane/utils";
// components
import { DateDropdown } from "@/components/dropdowns/date";
@@ -3,10 +3,10 @@
import { Copy } from "lucide-react";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { IApiToken } from "@plane/types";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
import { renderFormattedDate, renderFormattedTime, copyTextToClipboard } from "@plane/utils";
// helpers
// types
@@ -5,9 +5,9 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { LinkIcon, Signal, Trash2, UserMinus2, UserPlus2, Users } from "lucide-react";
import { DoubleCircleIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EIssueServiceType, TIssue } from "@plane/types";
// hooks
import { TOAST_TYPE, setToast } from "@plane/ui";
// helpers
import { copyTextToClipboard } from "@plane/utils";
// hooks
@@ -8,7 +8,7 @@ import { Settings } from "lucide-react";
// plane imports
import { THEME_OPTIONS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { useUserProfile } from "@/hooks/store/user";
@@ -6,7 +6,7 @@ import { useParams } from "next/navigation";
import useSWR from "swr";
// ui
import { COMMAND_PALETTE_TRACKER_ELEMENTS, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { copyTextToClipboard } from "@plane/utils";
import { CommandModal, ShortcutsModal } from "@/components/command-palette";
@@ -12,9 +12,8 @@ import { Tab, Popover } from "@headlessui/react";
import { ACCEPTED_COVER_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants";
import { useOutsideClickDetector } from "@plane/hooks";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EFileAssetType } from "@plane/types";
import { Input, Loader } from "@plane/ui";
import { Input, Loader, TOAST_TYPE, setToast } from "@plane/ui";
// helpers
import { getFileURL } from "@plane/utils";
// hooks
@@ -9,9 +9,8 @@ import { Combobox, Dialog, Transition } from "@headlessui/react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EIssuesStoreType, ISearchIssueResponse, IUser } from "@plane/types";
import { Loader } from "@plane/ui";
import { Loader, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { SimpleEmptyState } from "@/components/empty-state/simple-empty-state-root";
// hooks
@@ -7,11 +7,10 @@ import { Combobox, Dialog, Transition } from "@headlessui/react";
import { useTranslation } from "@plane/i18n";
// types
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { ISearchIssueResponse, TProjectIssuesSearchParams } from "@plane/types";
// ui
import { Loader, ToggleSwitch } from "@plane/ui";
import { Loader, ToggleSwitch, TOAST_TYPE, setToast } from "@plane/ui";
import { generateWorkItemLink, getTabIndex } from "@plane/utils";
// helpers
// hooks
@@ -9,8 +9,7 @@ import { Popover, Transition } from "@headlessui/react";
// plane imports
import type { EditorRefApi } from "@plane/editor";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Input } from "@plane/ui";
import { Input, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { RichTextEditor } from "@/components/editor/rich-text";
// services
@@ -8,9 +8,10 @@ import { Transition, Dialog } from "@headlessui/react";
// plane imports
import { ACCEPTED_AVATAR_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EFileAssetType } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
import { getAssetIdFromUrl, getFileURL, checkURLValidity } from "@plane/utils";
// helpers
// services
import { FileService } from "@/services/file.service";
const fileService = new FileService();
@@ -8,9 +8,10 @@ import { Transition, Dialog } from "@headlessui/react";
// plane imports
import { ACCEPTED_AVATAR_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EFileAssetType } from "@plane/types";
import { TOAST_TYPE, setToast } from "@plane/ui";
import { getAssetIdFromUrl, getFileURL, checkURLValidity } from "@plane/utils";
// helpers
// hooks
import { useWorkspace } from "@/hooks/store/use-workspace";
// services
@@ -7,10 +7,9 @@ import { Controller, useForm } from "react-hook-form";
import { PROFILE_SETTINGS_TRACKER_ELEMENTS, PROFILE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { setPromiseToast } from "@plane/propel/toast";
import { IUserTheme } from "@plane/types";
// ui
import { InputColorPicker } from "@plane/ui";
import { InputColorPicker, setPromiseToast } from "@plane/ui";
// hooks
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
import { useUserProfile } from "@/hooks/store/user";
@@ -13,8 +13,8 @@ import {
CYCLE_TRACKER_ELEMENTS,
} from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { ICycle } from "@plane/types";
import { setToast, TOAST_TYPE } from "@plane/ui";
import { getDate, renderFormattedPayloadDate } from "@plane/utils";
// components
import { DateRangeDropdown } from "@/components/dropdowns/date-range";
@@ -5,7 +5,7 @@ import { Dialog, Transition } from "@headlessui/react";
// ui
import { CYCLE_TRACKER_EVENTS } from "@plane/constants";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
import { useCycle } from "@/hooks/store/use-cycle";
@@ -6,10 +6,9 @@ import { useParams, useSearchParams } from "next/navigation";
// types
import { PROJECT_ERROR_MESSAGES, CYCLE_TRACKER_EVENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { ICycle } from "@plane/types";
// ui
import { AlertModalCore } from "@plane/ui";
import { AlertModalCore, TOAST_TYPE, setToast } from "@plane/ui";
// helpers
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
// hooks
@@ -16,10 +16,9 @@ import {
import { useLocalStorage } from "@plane/hooks";
import { useTranslation } from "@plane/i18n";
import { LayersIcon, TransferIcon } from "@plane/propel/icons";
import { setPromiseToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { ICycle, TCycleGroups } from "@plane/types";
import { Avatar, AvatarGroup, FavoriteStar } from "@plane/ui";
import { Avatar, AvatarGroup, FavoriteStar, setPromiseToast } from "@plane/ui";
import { getDate, getFileURL, generateQueryParams } from "@plane/utils";
// components
import { DateRangeDropdown } from "@/components/dropdowns/date-range";
+1 -2
View File
@@ -3,10 +3,9 @@ import React, { useEffect, useState } from "react";
import { mutate } from "swr";
// types
import { CYCLE_TRACKER_EVENTS } from "@plane/constants";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { CycleDateCheckData, ICycle, TCycleTabOptions } from "@plane/types";
// ui
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
import { EModalPosition, EModalWidth, ModalCore, TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { renderFormattedPayloadDate } from "@plane/utils";
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
@@ -14,8 +14,7 @@ import {
} from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { ArchiveIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { ContextMenu, CustomMenu, TContextMenuItem } from "@plane/ui";
import { ContextMenu, CustomMenu, TContextMenuItem, TOAST_TYPE, setToast } from "@plane/ui";
import { copyUrlToClipboard, cn } from "@plane/utils";
// helpers
// hooks
@@ -224,7 +223,9 @@ export const CycleQuickActions: React.FC<Props> = observer((props) => {
return (
<CustomMenu.MenuItem
key={item.key}
onClick={() => {
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
captureClick({
elementName: CYCLE_TRACKER_ELEMENTS.QUICK_ACTIONS,
});
@@ -6,8 +6,11 @@ import { useParams } from "next/navigation";
import { AlertCircle, Search, X } from "lucide-react";
import { Dialog, Transition } from "@headlessui/react";
import { ContrastIcon, TransferIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EIssuesStoreType } from "@plane/types";
// hooks
// ui
//icons
import { TOAST_TYPE, setToast } from "@plane/ui";
import { useCycle } from "@/hooks/store/use-cycle";
import { useIssues } from "@/hooks/store/use-issues";
//icons
@@ -7,9 +7,8 @@ import { ChevronLeft } from "lucide-react";
import { EEstimateSystem, ESTIMATE_SYSTEMS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IEstimateFormData, TEstimateSystemKeys, TEstimatePointsObject, TEstimateTypeError } from "@plane/types";
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
import { EModalPosition, EModalWidth, ModalCore, TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { useProjectEstimates } from "@/hooks/store/estimates";
// local imports
@@ -5,8 +5,7 @@ import { observer } from "mobx-react";
// ui
import { PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EModalPosition, EModalWidth, ModalCore } from "@plane/ui";
import { EModalPosition, EModalWidth, ModalCore, TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
import { useProjectEstimates } from "@/hooks/store/estimates";
@@ -4,8 +4,7 @@ import { FC } from "react";
import { observer } from "mobx-react";
import { PROJECT_SETTINGS_TRACKER_ELEMENTS, PROJECT_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { ToggleSwitch } from "@plane/ui";
import { TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
// hooks
import { captureElementAndEvent } from "@/helpers/event-tracker.helper";
import { useProjectEstimates } from "@/hooks/store/estimates";
@@ -5,10 +5,9 @@ import { observer } from "mobx-react";
import { Check, Info, X } from "lucide-react";
import { EEstimateSystem, MAX_ESTIMATE_POINT_INPUT_LENGTH } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { TEstimatePointsObject, TEstimateSystemKeys, TEstimateTypeErrorObject } from "@plane/types";
import { Spinner } from "@plane/ui";
import { Spinner, TOAST_TYPE, setToast } from "@plane/ui";
import { cn, isEstimatePointValuesRepeated } from "@plane/utils";
import { EstimateInputRoot } from "@/components/estimates/inputs/root";
// helpers
@@ -5,10 +5,9 @@ import { observer } from "mobx-react";
import { Check, Info, X } from "lucide-react";
import { EEstimateSystem, MAX_ESTIMATE_POINT_INPUT_LENGTH } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { TEstimatePointsObject, TEstimateSystemKeys, TEstimateTypeErrorObject } from "@plane/types";
import { Spinner } from "@plane/ui";
import { Spinner, TOAST_TYPE, setToast } from "@plane/ui";
import { cn, isEstimatePointValuesRepeated } from "@plane/utils";
import { EstimateInputRoot } from "@/components/estimates/inputs/root";
// helpers
@@ -10,8 +10,7 @@ import {
} from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { CustomSearchSelect, CustomSelect } from "@plane/ui";
import { CustomSearchSelect, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui";
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
import { useProject } from "@/hooks/store/use-project";
import { useUser, useUserPermissions } from "@/hooks/store/user";
@@ -8,10 +8,9 @@ import { Dialog, Transition } from "@headlessui/react";
// types
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IUser, IImporterService } from "@plane/types";
// ui
import { CustomSearchSelect } from "@plane/ui";
import { CustomSearchSelect, TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { useProject } from "@/hooks/store/use-project";
import { useUser } from "@/hooks/store/user";
@@ -1,7 +1,7 @@
import { useRef, useState } from "react";
// Plane
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { IBlockUpdateDependencyData, IGanttBlock } from "@plane/types";
import { setToast, TOAST_TYPE } from "@plane/ui";
// hooks
import { useTimeLineChartStore } from "@/hooks/use-timeline-chart";
//
@@ -6,8 +6,7 @@ import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-d
import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
import { observer } from "mobx-react";
import { useOutsideClickDetector } from "@plane/hooks";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { DropIndicator } from "@plane/ui";
import { DropIndicator, TOAST_TYPE, setToast } from "@plane/ui";
import { HIGHLIGHT_WITH_LINE, highlightIssueOnDrop } from "@/components/issues/issue-layouts/utils";
type Props = {
@@ -4,8 +4,7 @@ import { FC, useCallback, useMemo } from "react";
import { observer } from "mobx-react";
import { Pencil, ExternalLink, Link, Trash2 } from "lucide-react";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TContextMenuItem, LinkItemBlock } from "@plane/ui";
import { TOAST_TYPE, setToast, TContextMenuItem, LinkItemBlock } from "@plane/ui";
// plane utils
import { copyTextToClipboard } from "@plane/utils";
// hooks
@@ -1,7 +1,7 @@
import { useMemo } from "react";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TProjectLink } from "@plane/types";
import { setToast, TOAST_TYPE } from "@plane/ui";
import { useHome } from "@/hooks/store/use-home";
export type TLinkOperations = {
@@ -5,7 +5,7 @@ import {
} from "@atlaskit/pragmatic-drag-and-drop/dist/types/internal-types";
import { observer } from "mobx-react";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { setToast, TOAST_TYPE } from "@plane/ui";
import { useHome } from "@/hooks/store/use-home";
import { WidgetItem } from "./widget-item";
import { getInstructionFromPayload, TargetData } from "./widget.helpers";
@@ -19,9 +19,8 @@ import {
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EInboxIssueStatus, TNameDescriptionLoader } from "@plane/types";
import { ControlLink, CustomMenu, Row } from "@plane/ui";
import { ControlLink, CustomMenu, Row, TOAST_TYPE, setToast } from "@plane/ui";
import { copyUrlToClipboard, findHowManyDaysLeft, generateWorkItemLink } from "@plane/utils";
// components
import { CreateUpdateIssueModal } from "@/components/issues/issue-modal/modal";
@@ -5,9 +5,8 @@ import { observer } from "mobx-react";
// plane imports
import { WORK_ITEM_TRACKER_EVENTS } from "@plane/constants";
import type { EditorRefApi } from "@plane/editor";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EInboxIssueSource, TIssue, TNameDescriptionLoader } from "@plane/types";
import { Loader } from "@plane/ui";
import { Loader, TOAST_TYPE, setToast } from "@plane/ui";
import { getTextContent } from "@plane/utils";
// components
import { DescriptionVersionsRoot } from "@/components/core/description-versions";
@@ -7,9 +7,8 @@ import { ETabIndices, WORK_ITEM_TRACKER_EVENTS } from "@plane/constants";
import type { EditorRefApi } from "@plane/editor";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TIssue } from "@plane/types";
import { ToggleSwitch } from "@plane/ui";
import { ToggleSwitch, TOAST_TYPE, setToast } from "@plane/ui";
import { renderFormattedPayloadDate, getTabIndex } from "@plane/utils";
// helpers
import { captureError, captureSuccess } from "@/helpers/event-tracker.helper";
@@ -3,10 +3,9 @@ import { observer } from "mobx-react";
// types
import { PROJECT_ERROR_MESSAGES } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { TIssue } from "@plane/types";
// ui
import { AlertModalCore } from "@plane/ui";
import { AlertModalCore, setToast, TOAST_TYPE } from "@plane/ui";
// constants
// hooks
import { useProject } from "@/hooks/store/use-project";
@@ -6,9 +6,8 @@ import { Search } from "lucide-react";
import { Combobox, Dialog, Transition } from "@headlessui/react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { ISearchIssueResponse } from "@plane/types";
import { Loader } from "@plane/ui";
import { Loader, TOAST_TYPE, setToast } from "@plane/ui";
// components
import { SimpleEmptyState } from "@/components/empty-state/simple-empty-state-root";
// hooks
@@ -5,26 +5,29 @@ import Image from "next/image";
import Link from "next/link";
import { useTheme } from "next-themes";
import { GOD_MODE_URL } from "@plane/constants";
import { PlaneLockup } from "@plane/propel/icons";
import { Button } from "@plane/propel/button";
// helpers
// images
// assets
import PlaneBackgroundPatternDark from "@/public/auth/background-pattern-dark.svg";
import PlaneBackgroundPattern from "@/public/auth/background-pattern.svg";
import BlackHorizontalLogo from "@/public/plane-logos/black-horizontal-with-blue-logo.png";
import WhiteHorizontalLogo from "@/public/plane-logos/white-horizontal-with-blue-logo.png";
import PlaneTakeOffImage from "@/public/plane-takeoff.png";
export const InstanceNotReady: FC = () => {
const { resolvedTheme } = useTheme();
const patternBackground = resolvedTheme === "dark" ? PlaneBackgroundPatternDark : PlaneBackgroundPattern;
const logo = resolvedTheme === "light" ? BlackHorizontalLogo : WhiteHorizontalLogo;
return (
<div className="relative">
<div className="h-screen w-full overflow-hidden overflow-y-auto flex flex-col">
<div className="container h-[110px] flex-shrink-0 mx-auto px-5 lg:px-0 flex items-center justify-between gap-5 z-50">
<div className="flex items-center gap-x-2 py-10">
<Link href={`/`}>
<PlaneLockup className="h-7 w-auto text-custom-text-100" />
<Link href={`/`} className="h-[30px] w-[133px]">
<Image src={logo} alt="Plane logo" />
</Link>
</div>
</div>
@@ -11,9 +11,8 @@ import { AlertTriangle } from "lucide-react";
import { Dialog, Transition } from "@headlessui/react";
// services
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IUser, IImporterService } from "@plane/types";
import { Input } from "@plane/ui";
import { Input, TOAST_TYPE, setToast } from "@plane/ui";
import { IMPORTER_SERVICES_LIST } from "@/constants/fetch-keys";
import { IntegrationService } from "@/services/integrations/integration.service";
// ui
@@ -8,9 +8,9 @@ import { useForm } from "react-hook-form";
import useSWR, { mutate } from "swr";
import { ArrowLeft, Check, List, Settings, UploadCloud, Users } from "lucide-react";
// types
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IGithubRepoCollaborator, IGithubServiceImportFormData } from "@plane/types";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import {
GithubImportConfigure,
@@ -8,11 +8,10 @@ import useSWR, { mutate } from "swr";
import { CheckCircle } from "lucide-react";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { Tooltip } from "@plane/propel/tooltip";
import { IAppIntegration, IWorkspaceIntegration } from "@plane/types";
// ui
import { Loader } from "@plane/ui";
import { Loader, TOAST_TYPE, setToast } from "@plane/ui";
// constants
import { WORKSPACE_INTEGRATIONS } from "@/constants/fetch-keys";
// hooks
@@ -6,8 +6,9 @@ import { Dialog, Transition } from "@headlessui/react";
import { useTranslation } from "@plane/i18n";
// types
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TDeDupeIssue, TIssue } from "@plane/types";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { useIssues } from "@/hooks/store/use-issues";
import { useProject } from "@/hooks/store/use-project";
@@ -3,9 +3,9 @@ import { observer } from "mobx-react";
import { FileRejection, useDropzone } from "react-dropzone";
import { UploadCloud } from "lucide-react";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { EIssueServiceType, TIssueServiceType } from "@plane/types";
// hooks
import { TOAST_TYPE, setToast } from "@plane/ui";
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
// plane web hooks
import { useFileSize } from "@/plane-web/hooks/use-file-size";

Some files were not shown because too many files have changed in this diff Show More