Conversation
…ponents, introducing editable fields and updating backend serializers.
…ges to centralize filtering UI.
…ties, add a development roadmap, and include MCP server configuration.
…configuration, and create a TODO list.
…iting, row details, and drag-and-drop functionality.
…ies, and remove stats cards and column customizer from frontend list pages.
…2M assignment utilities, and introduce new migrations for task and opportunity assignments.
…e editing features from leads page.
…onents, add OpenAPI specification
…icators with supporting backend updates and OpenAPI definition.
…dd OpenAPI specification.
…or frontend lead fields for consistency.
…rove opportunity data handling, and
…S middleware for session scope, add RLS setup documentation, and enhance task UI with parent entity names.
…y files, and update time formatting.
| const newPayload = decodeJwtPayload(switchResult.access_token); | ||
| event.locals.org_settings = newPayload?.org_settings || { | ||
| default_currency: 'USD', | ||
| currency_symbol: '$', |
There was a problem hiding this comment.
Expected an assignment or function call and instead saw an expression.
Missing semicolon.
Too many errors. (81% scanned).
| // Decode new token to get org_settings | ||
| const newPayload = decodeJwtPayload(switchResult.access_token); | ||
| event.locals.org_settings = newPayload?.org_settings || { | ||
| default_currency: 'USD', |
There was a problem hiding this comment.
Label 'default_currency' on USD statement.
| event.locals.org_name = switchResult.current_org?.name || 'Organization'; | ||
| // Decode new token to get org_settings | ||
| const newPayload = decodeJwtPayload(switchResult.access_token); | ||
| event.locals.org_settings = newPayload?.org_settings || { |
There was a problem hiding this comment.
Expected ':' and instead saw 'org_settings'.
Expected an identifier and instead saw '.'.
Expected an identifier and instead saw '||'.
Missing semicolon.
| }; | ||
| event.locals.org_name = switchResult.current_org?.name || 'Organization'; | ||
| // Decode new token to get org_settings | ||
| const newPayload = decodeJwtPayload(switchResult.access_token); |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| org: switchResult.current_org, | ||
| role: 'USER' // Will be in new JWT | ||
| }; | ||
| event.locals.org_name = switchResult.current_org?.name || 'Organization'; |
There was a problem hiding this comment.
Expected ':' and instead saw 'name'.
Expected an assignment or function call and instead saw an expression.
Expected an identifier and instead saw '.'.
Expected an identifier and instead saw '||'.
Missing semicolon.
| }; | ||
| } else { | ||
| // Token doesn't have org context, need to switch (1 API call) | ||
| const switchResult = await switchOrg(token, orgId); |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
Missing semicolon.
| // Profile fetch failed, clear org cookie | ||
| event.cookies.delete('org', { path: '/' }); | ||
| } | ||
| const token = /** @type {string} */ (accessToken); |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| /** @type {UserInfo | null} */ | ||
| let user = null; | ||
| /** @type {JWTPayload | null} */ | ||
| let jwtPayload = null; |
There was a problem hiding this comment.
'let' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| } | ||
| }); | ||
| function verifyTokenLocally(accessToken) { | ||
| const payload = decodeJwtPayload(accessToken); |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| const newPayload = decodeJwtPayload(switchResult.access_token); | ||
| event.locals.org_settings = newPayload?.org_settings || { | ||
| default_currency: 'USD', | ||
| currency_symbol: '$', |
There was a problem hiding this comment.
Expected an assignment or function call and instead saw an expression.
Missing semicolon.
Too many errors. (81% scanned).
| // Decode new token to get org_settings | ||
| const newPayload = decodeJwtPayload(switchResult.access_token); | ||
| event.locals.org_settings = newPayload?.org_settings || { | ||
| default_currency: 'USD', |
There was a problem hiding this comment.
Label 'default_currency' on USD statement.
| event.locals.org_name = switchResult.current_org?.name || 'Organization'; | ||
| // Decode new token to get org_settings | ||
| const newPayload = decodeJwtPayload(switchResult.access_token); | ||
| event.locals.org_settings = newPayload?.org_settings || { |
There was a problem hiding this comment.
Expected ':' and instead saw 'org_settings'.
Expected an identifier and instead saw '.'.
Expected an identifier and instead saw '||'.
Missing semicolon.
| }; | ||
| event.locals.org_name = switchResult.current_org?.name || 'Organization'; | ||
| // Decode new token to get org_settings | ||
| const newPayload = decodeJwtPayload(switchResult.access_token); |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| org: switchResult.current_org, | ||
| role: 'USER' // Will be in new JWT | ||
| }; | ||
| event.locals.org_name = switchResult.current_org?.name || 'Organization'; |
There was a problem hiding this comment.
Expected ':' and instead saw 'name'.
Expected an assignment or function call and instead saw an expression.
Expected an identifier and instead saw '.'.
Expected an identifier and instead saw '||'.
Missing semicolon.
| export { default as FocusBar } from './FocusBar.svelte'; | ||
| export { default as MiniPipeline } from './MiniPipeline.svelte'; | ||
| export { default as PipelineChart } from './PipelineChart.svelte'; | ||
| export { default as TaskList } from './TaskList.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| export { default as ActivityFeed } from './ActivityFeed.svelte'; | ||
| export { default as FocusBar } from './FocusBar.svelte'; | ||
| export { default as MiniPipeline } from './MiniPipeline.svelte'; | ||
| export { default as PipelineChart } from './PipelineChart.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| export { default as KPICard } from './KPICard.svelte'; | ||
| export { default as ActivityFeed } from './ActivityFeed.svelte'; | ||
| export { default as FocusBar } from './FocusBar.svelte'; | ||
| export { default as MiniPipeline } from './MiniPipeline.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,8 @@ | |||
| export { default as KPICard } from './KPICard.svelte'; | |||
| export { default as ActivityFeed } from './ActivityFeed.svelte'; | |||
| export { default as FocusBar } from './FocusBar.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,8 @@ | |||
| export { default as KPICard } from './KPICard.svelte'; | |||
| export { default as ActivityFeed } from './ActivityFeed.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,8 @@ | |||
| export { default as KPICard } from './KPICard.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| export { default as AppShell } from './AppShell.svelte'; | ||
| export { default as AppSidebar } from './AppSidebar.svelte'; | ||
| export { default as FilterPopover } from './FilterPopover.svelte'; | ||
| export { default as PageHeader } from './PageHeader.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
| export { default as AppSidebar } from './AppSidebar.svelte'; | |||
| export { default as FilterPopover } from './FilterPopover.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
| export { default as AppSidebar } from './AppSidebar.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; | ||
| import Header from './alert-dialog-header.svelte'; | ||
| import Footer from './alert-dialog-footer.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Trigger from './alert-dialog-trigger.svelte'; | ||
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; | ||
| import Header from './alert-dialog-header.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | ||
| import Trigger from './alert-dialog-trigger.svelte'; | ||
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,36 @@ | |||
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | |||
| import Trigger from './alert-dialog-trigger.svelte'; | |||
| import Overlay from './alert-dialog-overlay.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,36 @@ | |||
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | |||
| import Trigger from './alert-dialog-trigger.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,8 @@ | |||
| export { default as KPICard } from './KPICard.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| export { default as AppShell } from './AppShell.svelte'; | ||
| export { default as AppSidebar } from './AppSidebar.svelte'; | ||
| export { default as FilterPopover } from './FilterPopover.svelte'; | ||
| export { default as PageHeader } from './PageHeader.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
| export { default as AppSidebar } from './AppSidebar.svelte'; | |||
| export { default as FilterPopover } from './FilterPopover.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
| export { default as AppSidebar } from './AppSidebar.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; | ||
| import Header from './alert-dialog-header.svelte'; | ||
| import Footer from './alert-dialog-footer.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Trigger from './alert-dialog-trigger.svelte'; | ||
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; | ||
| import Header from './alert-dialog-header.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | ||
| import Trigger from './alert-dialog-trigger.svelte'; | ||
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,36 @@ | |||
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | |||
| import Trigger from './alert-dialog-trigger.svelte'; | |||
| import Overlay from './alert-dialog-overlay.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,36 @@ | |||
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | |||
| import Trigger from './alert-dialog-trigger.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,8 @@ | |||
| export { default as KPICard } from './KPICard.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| export { default as AppShell } from './AppShell.svelte'; | ||
| export { default as AppSidebar } from './AppSidebar.svelte'; | ||
| export { default as FilterPopover } from './FilterPopover.svelte'; | ||
| export { default as PageHeader } from './PageHeader.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
| export { default as AppSidebar } from './AppSidebar.svelte'; | |||
| export { default as FilterPopover } from './FilterPopover.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
| export { default as AppSidebar } from './AppSidebar.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as AppShell } from './AppShell.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; | ||
| import Header from './alert-dialog-header.svelte'; | ||
| import Footer from './alert-dialog-footer.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Trigger from './alert-dialog-trigger.svelte'; | ||
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; | ||
| import Header from './alert-dialog-header.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | ||
| import Trigger from './alert-dialog-trigger.svelte'; | ||
| import Overlay from './alert-dialog-overlay.svelte'; | ||
| import Content from './alert-dialog-content.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,36 @@ | |||
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | |||
| import Trigger from './alert-dialog-trigger.svelte'; | |||
| import Overlay from './alert-dialog-overlay.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,36 @@ | |||
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | |||
| import Trigger from './alert-dialog-trigger.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
|
Caution Review failedThe pull request is closed. WalkthroughThis PR represents a major restructuring of the Django CRM codebase, encompassing removal of legacy CI/build infrastructure, modularization of API views from a monolithic file into separate feature modules, comprehensive addition of Row-Level Security (RLS) context propagation across Celery tasks and views, replacement of phone number fields with CharField, addition of currency tracking across multiple models, and database schema migrations to support new fields and relationships. Changes
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120+ minutes
Areas requiring extra attention:
Possibly related PRs
Poem
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (107)
⛔ Files not processed due to max files limit (30)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| max_length=3, choices=CURRENCY_CODES, blank=True, null=True | ||
| ) | ||
| phone = PhoneNumberField(null=True, blank=True) | ||
| phone = models.CharField(max_length=20, null=True, blank=True) |
There was a problem hiding this comment.
| phone = models.CharField(max_length=20, null=True, blank=True) | |
| phone = models.CharField(max_length=20, default="", blank=True) |
null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". Read more.
| max_length=3, choices=CURRENCY_CODES, blank=True, null=True | ||
| ) | ||
| phone = PhoneNumberField(null=True, blank=True) | ||
| phone = models.CharField(max_length=20, null=True, blank=True) |
There was a problem hiding this comment.
| phone = models.CharField(max_length=20, null=True, blank=True) | |
| phone = models.CharField(max_length=20, default="", blank=True) |
Same as above: consider replacing null=True with default="" (and blank=True to pass validation checks).
| description = models.TextField(blank=True, null=True) | ||
| sku = models.CharField(max_length=100, blank=True, null=True) | ||
| price = models.DecimalField(max_digits=12, decimal_places=2, default=0) | ||
| currency = models.CharField(max_length=3, choices=CURRENCY_CODES, blank=True, null=True) |
There was a problem hiding this comment.
Same as above: consider replacing null=True with default="" (and blank=True to pass validation checks).
| { | ||
| "account": ( | ||
| "A task can only be linked to one parent entity " | ||
| f"(Account, Opportunity, Case, or Lead). " |
There was a problem hiding this comment.
| f"(Account, Opportunity, Case, or Lead). " | |
| "(Account, Opportunity, Case, or Lead). " |
f-string is unnecessary here. This can just be a string. More info.
| name = models.CharField(_("Account Name"), max_length=255) | ||
| email = models.EmailField(_("Email"), blank=True, null=True) | ||
| phone = PhoneNumberField(_("Phone"), null=True, blank=True) | ||
| phone = models.CharField(_("Phone"), max_length=20, null=True, blank=True) |
There was a problem hiding this comment.
| phone = models.CharField(_("Phone"), max_length=20, null=True, blank=True) | |
| phone = models.CharField(_("Phone"), max_length=20, default="", blank=True) |
null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". Read more.
| if profiles: | ||
| team_obj.users.add(*profiles) |
There was a problem hiding this comment.
| if profiles: | |
| team_obj.users.add(*profiles) | |
| if profiles.exists(): | |
| team_obj.users.add(*profiles) |
Checking profiles truthiness is less efficient than checking profiles.exists() or profiles is not None. Checking queryset truthiness evaluates the queryset, therefore reading the records from the database. More details.
| if profiles: | ||
| team_obj.users.add(*profiles) |
There was a problem hiding this comment.
| if profiles: | |
| team_obj.users.add(*profiles) | |
| if profiles.exists(): | |
| team_obj.users.add(*profiles) |
Same as above: consider profiles.exists()
| last_name = models.CharField(_("Last name"), max_length=255) | ||
| email = models.EmailField(_("Email"), blank=True, null=True) | ||
| phone = PhoneNumberField(_("Phone"), null=True, blank=True) | ||
| phone = models.CharField(_("Phone"), max_length=20, null=True, blank=True) |
There was a problem hiding this comment.
| phone = models.CharField(_("Phone"), max_length=20, null=True, blank=True) | |
| phone = models.CharField(_("Phone"), max_length=20, default="", blank=True) |
null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". Explained here.
| # Communication Preferences | ||
| do_not_call = models.BooleanField(_("Do Not Call"), default=False) | ||
| linked_in_url = models.URLField(_("LinkedIn URL"), blank=True, null=True) | ||
| linkedin_url = models.URLField(_("LinkedIn URL"), blank=True, null=True) |
There was a problem hiding this comment.
| linkedin_url = models.URLField(_("LinkedIn URL"), blank=True, null=True) | |
| linkedin_url = models.URLField(_("LinkedIn URL"), blank=True, default="") |
Same as above: consider replacing null=True with default="" (and blank=True to pass validation checks).
| salutation = models.CharField( | ||
| _("Salutation"), max_length=64, blank=True, null=True, | ||
| help_text="e.g., Mr, Mrs, Ms, Dr" | ||
| ) |
There was a problem hiding this comment.
| salutation = models.CharField( | |
| _("Salutation"), max_length=64, blank=True, null=True, | |
| help_text="e.g., Mr, Mrs, Ms, Dr" | |
| ) | |
| salutation = models.CharField( | |
| _("Salutation"), | |
| max_length=64, | |
| blank=True, | |
| default="", | |
| help_text="e.g., Mr, Mrs, Ms, Dr", | |
| ) |
null=True on a string field causes inconsistent data types because the value can be either str or None. This adds complexity and maybe bugs, but can be solved by replacing null=True with default="". More details.
| phone = PhoneNumberField(null=True, blank=True) | ||
| contact_title = models.CharField( | ||
| _("Job Title"), max_length=255, blank=True, null=True | ||
| phone = models.CharField(_("Phone"), max_length=50, null=True, blank=True) |
There was a problem hiding this comment.
| phone = models.CharField(_("Phone"), max_length=50, null=True, blank=True) | |
| phone = models.CharField(_("Phone"), max_length=50, default="", blank=True) |
Same as above: consider replacing null=True with default="" (and blank=True to pass validation checks).
| job_title = models.CharField( | ||
| _("Job Title"), max_length=255, blank=True, null=True, | ||
| help_text="Person's job title (e.g., 'VP of Sales', 'CTO')" | ||
| ) |
There was a problem hiding this comment.
| job_title = models.CharField( | |
| _("Job Title"), max_length=255, blank=True, null=True, | |
| help_text="Person's job title (e.g., 'VP of Sales', 'CTO')" | |
| ) | |
| job_title = models.CharField( | |
| _("Job Title"), | |
| max_length=255, | |
| blank=True, | |
| default="", | |
| help_text="Person"s job title (e.g., 'VP of Sales', 'CTO')", | |
| ) |
Again, consider replacing null=True with default="" (and blank=True to pass validation checks).
| opportunity_amount = models.DecimalField( | ||
| _("Deal Value"), decimal_places=2, max_digits=12, blank=True, null=True | ||
| ) | ||
| currency = models.CharField( |
There was a problem hiding this comment.
Same as above: consider replacing null=True with default="" (and blank=True to pass validation checks).
| company_name = models.CharField( | ||
| _("Company Name"), max_length=255, blank=True, null=True | ||
| ) |
There was a problem hiding this comment.
| company_name = models.CharField( | |
| _("Company Name"), max_length=255, blank=True, null=True | |
| ) | |
| company_name = models.CharField( | |
| _("Company Name"), max_length=255, blank=True, default="" | |
| ) |
As above, consider replacing null=True with default="" (and blank=True to pass validation checks).
| @@ -1,15 +1,15 @@ | |||
| import arrow | |||
| from django.core.exceptions import ValidationError | |||
There was a problem hiding this comment.
Boa model prefix is used quite a lot. Maybe split the models into multiple files. Explained here.
| @property | ||
| def created_on_arrow(self): | ||
| return arrow.get(self.created_at).humanize() | ||
| def clean(self): |
There was a problem hiding this comment.
According to Django internal style guide, save should come before clean. More.
There was a problem hiding this comment.
Pull request overview
This pull request represents version "1.0" of the CRM system, implementing a comprehensive refactoring and feature enhancement across the backend. The changes focus on modernizing the codebase, improving security, consolidating functionality, and adding new features.
Key Changes:
- Restructured view architecture by splitting monolithic view files into organized subdirectories
- Removed deprecated dependencies (arrow, phonenumber_field, django_extensions) and replaced with Django built-ins
- Enhanced security with improved CORS/CSRF configuration, token rotation, and org-scoped permissions
- Added comprehensive board/task management system with Kanban-style workflow
- Implemented lead conversion service with support for creating accounts, contacts, and opportunities
Reviewed changes
Copilot reviewed 136 out of 386 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| backend/tasks/views/board_views.py | New comprehensive board management views with columns and tasks |
| backend/tasks/serializer.py | Added schema field decorators and task parent entity validation |
| backend/tasks/models.py | Added parent entity validation and removed deprecated arrow timestamps |
| backend/requirements.txt | Updated Django/Celery versions, removed deprecated packages, added faker/gunicorn |
| backend/crm/settings.py | Enhanced security settings with configurable CORS/CSRF and improved JWT tokens |
| backend/leads/services.py | New lead conversion service extracting complex business logic |
| backend/leads/models.py | Simplified Lead model removing Company FK, added currency support |
| backend/opportunity/models.py | Replaced arrow with timesince for timestamps |
| backend/contacts/models.py | Added account FK relationship and replaced phonenumber field |
| backend/common/views/*.py | Reorganized views into logical modules with improved API documentation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| SECURE_HSTS_SECONDS = 31536000 # 1 year | ||
| SECURE_HSTS_INCLUDE_SUBDOMAINS = True | ||
| SECURE_HSTS_PRELOAD = True |
There was a problem hiding this comment.
HSTS with 1 year duration should only be enabled in production with HTTPS. Consider making this conditional on DEBUG=False to avoid issues in development environments.
| SECURE_HSTS_SECONDS = 31536000 # 1 year | |
| SECURE_HSTS_INCLUDE_SUBDOMAINS = True | |
| SECURE_HSTS_PRELOAD = True | |
| if not DEBUG: | |
| SECURE_HSTS_SECONDS = 31536000 # 1 year | |
| SECURE_HSTS_INCLUDE_SUBDOMAINS = True | |
| SECURE_HSTS_PRELOAD = True | |
| else: | |
| SECURE_HSTS_SECONDS = 0 | |
| SECURE_HSTS_INCLUDE_SUBDOMAINS = False | |
| SECURE_HSTS_PRELOAD = False |
| @@ -0,0 +1,36 @@ | |||
| import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Image from './avatar-image.svelte'; | ||
| import Fallback from './avatar-fallback.svelte'; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './avatar.svelte'; | |||
| import Image from './avatar-image.svelte'; | |||
| import Fallback from './avatar-fallback.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './avatar.svelte'; | |||
| import Image from './avatar-image.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './avatar.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Header from './card-header.svelte'; | ||
| import Title from './card-title.svelte'; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Content from './card-content.svelte'; | ||
| import Description from './card-description.svelte'; | ||
| import Header from './card-header.svelte'; | ||
| import Title from './card-title.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Root from './card.svelte'; | ||
| import Content from './card-content.svelte'; | ||
| import Description from './card-description.svelte'; | ||
| import Header from './card-header.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,19 @@ | |||
| import Root from './card.svelte'; | |||
| import Content from './card-content.svelte'; | |||
| import Description from './card-description.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,19 @@ | |||
| import Root from './card.svelte'; | |||
| import Content from './card-content.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| return (profile.user, None) | ||
|
|
||
| except Org.DoesNotExist: | ||
| logger.warning(f"Invalid API key attempted: {api_key[:8]}...") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
The best way to fix the problem is to avoid logging any portion of the API key in cleartext, even partial substrings. To maintain useful logging for debugging or monitoring, log only metadata (such as the fact that an invalid API key was attempted), possibly with context not involving the API key value itself—such as the requester's IP address, timestamp, etc.
Locate line 49 in backend/common/external_auth.py, which currently logs:
logger.warning(f"Invalid API key attempted: {api_key[:8]}...")Replace it with a log message that omits the API key completely. For example:
logger.warning("Invalid API key attempted for external API access")Optionally, additional non-sensitive context from the request (like remote IP address) could be logged if available and appropriate.
No new imports or method definitions are required.
| @@ -46,7 +46,7 @@ | ||
| return (profile.user, None) | ||
|
|
||
| except Org.DoesNotExist: | ||
| logger.warning(f"Invalid API key attempted: {api_key[:8]}...") | ||
| logger.warning("Invalid API key attempted for external API access") | ||
| raise AuthenticationFailed("Invalid API Key") | ||
|
|
||
|
|
| ) | ||
|
|
||
| except TokenError as e: | ||
| return Response({"error": str(e)}, status=status.HTTP_401_UNAUTHORIZED) |
Check warning
Code scanning / CodeQL
Information exposure through an exception Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the problem:
- The response returned in the
except TokenError as eblock should not include the exception message. Instead, it should respond with a generic error message such as "Invalid or expired refresh token". - No changes to the logic or exception handling are needed, just a change to the error message.
- Only modify lines 395-396 in
backend/common/views/auth_views.py. - No new dependencies are required.
- Only change what is shown in the context.
| @@ -393,7 +393,8 @@ | ||
| ) | ||
|
|
||
| except TokenError as e: | ||
| return Response({"error": str(e)}, status=status.HTTP_401_UNAUTHORIZED) | ||
| # Do not expose internal details or exception string to user. | ||
| return Response({"error": "Invalid or expired refresh token."}, status=status.HTTP_401_UNAUTHORIZED) | ||
| except User.DoesNotExist: | ||
| return Response( | ||
| {"error": "User not found"}, status=status.HTTP_401_UNAUTHORIZED |
| @@ -0,0 +1,19 @@ | |||
| import Root from './card.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Trigger from './collapsible-trigger.svelte'; | ||
| import Content from './collapsible-content.svelte'; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
| import Trigger from './collapsible-trigger.svelte'; | |||
| import Content from './collapsible-content.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
| import Trigger from './collapsible-trigger.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; | ||
| import Content from "./dialog-content.svelte"; | ||
| import Description from "./dialog-description.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; | ||
| import Content from "./dialog-content.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Portal from "./dialog-portal.svelte"; | ||
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Root from "./dialog.svelte"; | ||
| import Portal from "./dialog-portal.svelte"; | ||
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,19 @@ | |||
| import Root from './card.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Trigger from './collapsible-trigger.svelte'; | ||
| import Content from './collapsible-content.svelte'; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
| import Trigger from './collapsible-trigger.svelte'; | |||
| import Content from './collapsible-content.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
| import Trigger from './collapsible-trigger.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; | ||
| import Content from "./dialog-content.svelte"; | ||
| import Description from "./dialog-description.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; | ||
| import Content from "./dialog-content.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Portal from "./dialog-portal.svelte"; | ||
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Root from "./dialog.svelte"; | ||
| import Portal from "./dialog-portal.svelte"; | ||
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,19 @@ | |||
| import Root from './card.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Trigger from './collapsible-trigger.svelte'; | ||
| import Content from './collapsible-content.svelte'; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
| import Trigger from './collapsible-trigger.svelte'; | |||
| import Content from './collapsible-content.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
| import Trigger from './collapsible-trigger.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,13 @@ | |||
| import Root from './collapsible.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; | ||
| import Content from "./dialog-content.svelte"; | ||
| import Description from "./dialog-description.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; | ||
| import Content from "./dialog-content.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; | ||
| import Overlay from "./dialog-overlay.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Portal from "./dialog-portal.svelte"; | ||
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; | ||
| import Header from "./dialog-header.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| import Root from "./dialog.svelte"; | ||
| import Portal from "./dialog-portal.svelte"; | ||
| import Title from "./dialog-title.svelte"; | ||
| import Footer from "./dialog-footer.svelte"; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
| import Title from "./dialog-title.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Separator from './dropdown-menu-separator.svelte'; | ||
| import Trigger from './dropdown-menu-trigger.svelte'; | ||
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | ||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | ||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | ||
| import Content from './dropdown-menu-content.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1 @@ | |||
| export { default as EditableMultiSelect } from './EditableMultiSelect.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
| import Title from "./dialog-title.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Separator from './dropdown-menu-separator.svelte'; | ||
| import Trigger from './dropdown-menu-trigger.svelte'; | ||
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | ||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | ||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | ||
| import Content from './dropdown-menu-content.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1 @@ | |||
| export { default as EditableMultiSelect } from './EditableMultiSelect.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
| import Title from "./dialog-title.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Separator from './dropdown-menu-separator.svelte'; | ||
| import Trigger from './dropdown-menu-trigger.svelte'; | ||
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | ||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | ||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | ||
| import Content from './dropdown-menu-content.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1 @@ | |||
| export { default as EditableMultiSelect } from './EditableMultiSelect.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
| import Title from "./dialog-title.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
| import Portal from "./dialog-portal.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import Root from "./dialog.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; | ||
|
|
||
| export { |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import Separator from './dropdown-menu-separator.svelte'; | ||
| import Trigger from './dropdown-menu-trigger.svelte'; | ||
| const Sub = DropdownMenuPrimitive.Sub; | ||
| const Root = DropdownMenuPrimitive.Root; |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | ||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | ||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | ||
| import Content from './dropdown-menu-content.svelte'; |
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
| import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
| import CheckboxGroup from './dropdown-menu-checkbox-group.svelte'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,34 @@ | |||
| import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1 @@ | |||
| export { default as EditableMultiSelect } from './EditableMultiSelect.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| export { default as SearchInput } from './SearchInput.svelte'; | ||
| export { default as SelectFilter } from './SelectFilter.svelte'; | ||
| export { default as DateRangeFilter } from './DateRangeFilter.svelte'; | ||
| export { default as FilterBar } from './FilterBar.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as SearchInput } from './SearchInput.svelte'; | |||
| export { default as SelectFilter } from './SelectFilter.svelte'; | |||
| export { default as DateRangeFilter } from './DateRangeFilter.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as SearchInput } from './SearchInput.svelte'; | |||
| export { default as SelectFilter } from './SelectFilter.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as SearchInput } from './SearchInput.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,7 @@ | |||
| import Root from './input.svelte'; | |||
|
|
|||
| export { | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import { Popover as PopoverPrimitive } from "bits-ui"; | ||
| import Content from "./popover-content.svelte"; | ||
| import Trigger from "./popover-trigger.svelte"; | ||
| const Root = PopoverPrimitive.Root; |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| @@ -0,0 +1,17 @@ | |||
| import { Popover as PopoverPrimitive } from "bits-ui"; | |||
| import Content from "./popover-content.svelte"; | |||
| import Trigger from "./popover-trigger.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,17 @@ | |||
| import { Popover as PopoverPrimitive } from "bits-ui"; | |||
| import Content from "./popover-content.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,17 @@ | |||
| import { Popover as PopoverPrimitive } from "bits-ui"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,7 @@ | |||
| import Root from "./progress.svelte"; | |||
|
|
|||
| export { | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| export { default as SearchInput } from './SearchInput.svelte'; | ||
| export { default as SelectFilter } from './SelectFilter.svelte'; | ||
| export { default as DateRangeFilter } from './DateRangeFilter.svelte'; | ||
| export { default as FilterBar } from './FilterBar.svelte'; |
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as SearchInput } from './SearchInput.svelte'; | |||
| export { default as SelectFilter } from './SelectFilter.svelte'; | |||
| export { default as DateRangeFilter } from './DateRangeFilter.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as SearchInput } from './SearchInput.svelte'; | |||
| export { default as SelectFilter } from './SelectFilter.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,4 @@ | |||
| export { default as SearchInput } from './SearchInput.svelte'; | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,7 @@ | |||
| import Root from './input.svelte'; | |||
|
|
|||
| export { | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
| import { Popover as PopoverPrimitive } from "bits-ui"; | ||
| import Content from "./popover-content.svelte"; | ||
| import Trigger from "./popover-trigger.svelte"; | ||
| const Root = PopoverPrimitive.Root; |
There was a problem hiding this comment.
'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
| @@ -0,0 +1,17 @@ | |||
| import { Popover as PopoverPrimitive } from "bits-ui"; | |||
| import Content from "./popover-content.svelte"; | |||
| import Trigger from "./popover-trigger.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,17 @@ | |||
| import { Popover as PopoverPrimitive } from "bits-ui"; | |||
| import Content from "./popover-content.svelte"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,17 @@ | |||
| import { Popover as PopoverPrimitive } from "bits-ui"; | |||
There was a problem hiding this comment.
'import' is only available in ES6 (use 'esversion: 6').
| @@ -0,0 +1,7 @@ | |||
| import Root from "./progress.svelte"; | |||
|
|
|||
| export { | |||
There was a problem hiding this comment.
'export' is only available in ES6 (use 'esversion: 6').
Summary by CodeRabbit
Release Notes
New Features
Documentation
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.