Compare commits

...
Author SHA1 Message Date
edc47bd458 i18n - docs translations (#19677)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-14 12:45:12 +02:00
WeikoandGitHub 47bdcb11d8 Move is active to fe (#19649)
## Context
Moving isActive filtering to the frontend for page layout tabs and
widgets, hiding inactive entities from the UI while keeping them in
state for future reactivation

Next we will implement deactivated standard tab re-activation during tab
creation (cc @Devessier)
<img width="234" height="303" alt="📋 Menu (Slots)"
src="https://github.com/user-attachments/assets/17a25ac6-55e2-4778-b7f0-e7554ed69704"
/>
2026-04-14 10:18:09 +00:00
Baptiste DevessierandGitHub b817bdca02 Rpl various fixes (#19668) 2026-04-14 09:46:15 +00:00
EtienneandGitHub 9c07ecd363 Fix view filter/sort deletion (#19567)
fixes https://github.com/twentyhq/twenty/issues/19543

+ bonus bug : when deleting an advanced filter, it triggers a destroy
which cascade-deletes associated view filters. Then, view filters
deletion throws.
2026-04-14 09:43:52 +00:00
Raphaël BosiandGitHub eb13378760 Fix Quick Lead command menu item not appearing (#19635)
- Refactored prefillWorkflowCommandMenuItems and
prefillFrontComponentCommandMenuItems to use
validateBuildAndRunWorkspaceMigration instead of raw TypeORM
createQueryBuilder inserts
- This ensures the flat entity cache is properly updated when seeding
command menu items, fixing the Quick Lead item not appearing after
workspace creation
- Moved command menu item prefill calls outside the transaction since
they now go through the migration pipeline
2026-04-14 09:30:31 +00:00
Paul RastoinandGitHub 3e699c4458 Fix upgrade commands discovery outside of cli (#19671)
# Introduction
We were allowing the sequence to be empty in the worker context that was
facing an edge case importing the UpgradeModule through the
WorkspaceModule god module, no commands were discovered and it was
throwing as the sequence must have at least one workspace commands to
allow a workspace creation

Though the issue was also applicable to the twenty-server `AppModule`
too that was not discovering any commands

## Integration tests were passing
The integration test were importing the `CommandModule` at the nest
testing app creating leading to asymmetric testing context
It was a requirement for a legacy commands import and global assignation

## Fix
The `UpgradeModule` now import both `WorkspaceCommandsProviderModule`
and `InstanceCommandProviderModule` which ships the commands directly in
the module
We could consider moving the commands into the `engine/upgrade` folder

## Concern
Bootstrap could become more and more long to load at both server and
worker start
When this becomes a problem we will have to only import the latest
workspace command or whatever
For the moment this is not worth it the risk to import not the latest
workspace command
2026-04-14 09:20:33 +00:00
EtienneandGitHub f738961127 Add gql operationName metadata in sentry (#19564) 2026-04-14 08:55:54 +00:00
49aac04b84 fix: edit button not coming up on avatar right after image upload (#19596)
## Summary

After uploading an image/file to the empty avatar field in the person
tab, the edit icon next to the field would not appear until the browser
was refreshed or another field was clicked.

### Root cause

- When user clicks over the avatar field,
`recordFieldListCellEditModePosition` is set to `globalIndex`
- That is fine when a avatar already exists. But when there is no avatar
already set, the native file picker is opened with no `onClose` handler
attached.
- So after the file upload is completed,
`recordFieldListCellEditModePosition` is never reset to null.
- `FieldsWidgetCellEditModePortal` stays anchored to the avatar file
element
- When the user hovers over the same field again, its hover portal tries
to compete to anchor for the same element
- So, `RecordInlineCellDisplayMode ` (the edit button) doesn't render

### Fix

- Pass the `onClose` function through `openFieldInput` to
`openFilesFieldInput`
- `onClose` resets `recordFieldListCellEditModePosition` back to null,
when the upload completes.

## Before


https://github.com/user-attachments/assets/ac9318e9-5471-434c-8af3-5c20d0112460

## After


https://github.com/user-attachments/assets/0d064a7f-95ad-4b92-a9ee-d9570f360972

Fixes #19595

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-14 08:54:14 +00:00
40c6c63bf5 i18n - docs translations (#19672)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-14 10:54:27 +02:00
d583984bf0 fix(api-key): batch role resolution with DataLoader to fix N+1 (#19590)
## Summary

The `role` @ResolveField on `ApiKeyResolver` calls `getRolesByApiKeys`
with a single-element array per API key. When a query returns N API
keys, this produces N separate DB queries to resolve their roles.

This adds an `apiKeyRoleLoader` to the existing DataLoader
infrastructure. All API key IDs in a single GraphQL request are
collected and resolved in one batched query.

- Before: N queries (one per API key)
- After: 1 query (batched via DataLoader)

## Changes

- `dataloader.service.ts` - new `createApiKeyRoleLoader` method,
delegates to `ApiKeyRoleService.getRolesByApiKeys`
- `dataloader.interface.ts` - `apiKeyRoleLoader` added to `IDataloaders`
- `dataloader.module.ts` - import `ApiKeyModule` so `ApiKeyRoleService`
is available
- `api-key.resolver.ts` - `role()` now uses
`context.loaders.apiKeyRoleLoader.load()` instead of calling the service
directly

## Test plan

- [ ] Verify `apiKeys { id role { label } }` query returns the same
results as before
- [ ] Confirm only 1 role_target query fires regardless of how many API
keys are returned

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-14 08:43:31 +00:00
Paul RastoinandGitHub 714f149b0c Move backfill page layout to 1.23 (#19670) 2026-04-14 08:39:24 +00:00
martmullandGitHub 194f0963dc Remove 'twenty-app' keyword by default (#19669)
as title
2026-04-14 08:26:45 +00:00
5fa3094800 test: fix failing useColorScheme test and remove FIXME (#19593)
Summary
This PR fixes a bug in the `useColorScheme` test suite and removes a
lingering `FIXME` comment where the color scheme was unexpectedly
unsetting during state updates.

Root Cause
Previously, the Jotai state was being initialized *inside* the
`renderHook` callback using `useSetAtomState`. When the `setColorScheme`
function was called, it triggered a hook re-render, which caused the
callback to execute again and overwrite the new state with the hardcoded
`'System'` initial state.

The Fix
- Removed the state initialization from inside the render cycle.
- Bootstrapped the state on a fresh store using `resetJotaiStore()` and
`store.set()` *before* rendering the hook.
- Updated the mock `workspaceMember` to correctly use the
`CurrentWorkspaceMember` type.
- Removed the `FIXME` comment and successfully asserted that the color
scheme updates to `'Dark'`.

Testing
Ran tests locally to confirm the fix works as expected:
`corepack yarn jest --config packages/twenty-front/jest.config.mjs
--testPathPattern=useColorScheme.test.tsx`

---------

Co-authored-by: Srabani Ghorai <subhojit04ghorai@gmail.com>
2026-04-14 06:40:40 +00:00
87f8e5ca19 few website updates (#19663)
## Summary
- refresh pricing page content, plan cards, CTA styling, and Salesforce
comparison visuals
- update partner and hero/testimonial visuals, including pulled
carousel-compatible partner testimonial data
- improve halftone export and illustration mounting flows, plus related
button and hydration fixes
- add updated website illustration and pricing assets

## Testing
- Not run (not requested)

---------

Co-authored-by: Abdullah <125115953+mabdullahabaid@users.noreply.github.com>
2026-04-14 06:23:20 +00:00
e041125426 fix: return 404 for deleted workspace webhook race (#19439)
Handle late TwentyORM workspace-not-found exceptions in the workflow
webhook REST exception filter so deleted workspaces return a 404 instead
of surfacing as internal errors.

Also add a focused regression spec covering the deleted-workspace ORM
codes and the existing workflow-trigger status mappings.

Closes #15544

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-13 22:38:36 +00:00
d88fb2bd65 Clean event creation exception (#19561)
https://twenty-v7.sentry.io/issues/7351816489/?environment=prod&project=4507072499810304&query=is%3Aunresolved&referrer=issue-stream

Those are expected error that should not reach sentry. These happen when
stream TTL expires or user session ends

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-13 22:11:57 +00:00
Abdullah.andGitHub cdc7339da1 Fix testimonials background, faq clickability and some case-studies page edits. (#19657)
As title. Also copied release-notes related files from `twenty-website`
to `twenty-website-new`.
2026-04-13 21:19:41 +00:00
69d228d8a1 Deprecate IS_RECORD_TABLE_WIDGET_ENABLED feature flag (#19662)
## Summary
- Removes the `IS_RECORD_TABLE_WIDGET_ENABLED` feature flag, making the
record table widget unconditionally available in dashboard widget type
selection
- The flag was already seeded as `true` for all new workspaces and only
gated UI visibility in one component
(`SidePanelPageLayoutDashboardWidgetTypeSelect`)
- Cleans up the flag from `FeatureFlagKey` enum, dev seeder, and test
mocks

## Analysis
The flag only controlled whether the "View" (Record Table) widget option
appeared in the dashboard widget type selector. The entire record table
widget infrastructure (rendering, creation hooks, GraphQL types,
`RECORD_TABLE` enum in `WidgetType`) is independent of the flag and
fully implemented. No backend logic depends on this flag.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-13 21:13:15 +00:00
455022f652 Add ClickHouse-backed metered credit cap enforcement (#19586)
## Summary
Implements a ClickHouse-backed polling system to enforce metered-credit
caps for workflow executions, replacing reliance on Stripe billing
alerts. The system re-evaluates tier caps against live pricing on every
poll cycle, allowing price/tier changes to propagate immediately without
recreating Stripe alert objects.

## Key Changes

- **BillingUsageCapService**: New service that queries ClickHouse for
current-period credit usage and evaluates whether a subscription has
reached its metered-credit allowance (tier cap + credit balance)
  - `isClickHouseEnabled()`: Checks if ClickHouse is configured
- `getCurrentPeriodCreditsUsed()`: Sums creditsUsedMicro from usageEvent
table for a workspace within a billing period
- `evaluateCap()`: Determines if usage has reached the allowance by
reading live pricing from the subscription

- **EnforceUsageCapJob**: Cron job that polls all active subscriptions
and updates `hasReachedCurrentPeriodCap` on metered items
  - Runs every 2 minutes to keep cap enforcement in sync with live usage
- Supports shadow mode (log-only) via
`BILLING_USAGE_CAP_CLICKHOUSE_ENABLED` flag for safe rollout
- Continues processing after per-subscription errors with detailed
logging

- **EnforceUsageCapCronCommand**: CLI command to register the
enforcement cron job

- **MeteredCreditService**: Extracted
`extractMeteredPricingInfoFromSubscription()` as a pure function for
callers that already hold the subscription with pricing loaded, avoiding
redundant DB queries

- **Configuration**: Added `BILLING_USAGE_CAP_CLICKHOUSE_ENABLED` flag
to control enforcement mode (active vs. shadow)

- **Constants**: Added `METERED_OPERATION_TYPES` to define which
operation types count toward the metered product's credit cap

## Implementation Details

- The service queries ClickHouse for the sum of `creditsUsedMicro` in
the current billing period, matching Stripe meter semantics
- Pricing is re-read on every evaluation, so tier changes propagate
within one poll cycle without Stripe alert recreation
- The cron job only updates the database when the cap state actually
changes (no-op if already in the correct state)
- Shadow mode allows safe validation before enabling enforcement;
transitions are logged but not persisted
- Comprehensive test coverage for both the service and cron job,
including error handling and state transitions

https://claude.ai/code/session_01VksTSrYLXJVCPVBQhQdBTe

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-13 21:17:41 +02:00
Charles BochetandGitHub fa354b4c1c Remove orphaned workspaceId column from BillingSubscriptionItemEntity (#19660)
## Summary
- Removes the `workspaceId` column, `@Index()`, and `@ManyToOne`
workspace relation from `BillingSubscriptionItemEntity`
- The entity defined these fields but they don't exist in the actual
database table, causing `column X.workspaceId does not exist` errors at
runtime
- The workspace relationship is already accessible through the parent
`BillingSubscriptionEntity`
2026-04-13 17:53:33 +00:00
martmullandGitHub 0894f2004b Remove app record if first install fails (#19659)
If application install fails, and if app was created, uninstall app

fixes
https://discord.com/channels/1130383047699738754/1491822937462804590
2026-04-13 17:39:59 +00:00
665db83bb5 i18n - translations (#19661)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-13 19:45:10 +02:00
martmullGitHubcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
64a7725ac7 Add banner for not vetted apps (#19655)
https://github.com/user-attachments/assets/4038e21a-d5d9-4b93-8589-7a4baf35ef5b

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-04-13 17:28:50 +00:00
76d3e4ad2e i18n - translations (#19656)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-13 18:30:08 +02:00
Raphaël BosiandGitHub fb772c7695 Sync command menu with main context store (#19650)
## PR description

- The command menu in the side panel now reads directly from
`MAIN_CONTEXT_STORE_INSTANCE_ID` instead of snapshotting the main
context store into a separate side-panel instance when opening. This
keeps the command menu always in sync with the current page state
(selection, filters, view, etc.).
- Removed the broadening/reset-to-selection feature (Backspace to clear
context, "Reset to" button) since the command menu no longer maintains
its own copy of the context.

## Video QA


https://github.com/user-attachments/assets/5d5bc664-b6d4-431d-a271-6ce23d8a4ae0
2026-04-13 16:08:15 +00:00
Paul RastoinandGitHub 123d6241d7 Fix AddPermissionFlagRoleIdIndexFastInstanceCommand (#19654)
# Introduction
Index seemed to be missing in production only, as it's blocking the
whole migration release on other env that already implements the index
2026-04-13 18:14:31 +02:00
neo773andGitHub d2a99ef72d Fix VariablePicker and Fullscreen Icon overlap in FormAdvancedTextFieldInput (#19614)
fixes 

<img width="659" height="386" alt="image"
src="https://github.com/user-attachments/assets/c9755574-6830-464d-8abf-7741188f84dd"
/>
2026-04-13 16:01:50 +00:00
Abdul RahmanandGitHub 96959b43ba Fix: Filter out deactivated objects from navigation sidebar (#19620) 2026-04-13 15:54:30 +00:00
Abdul RahmanandGitHub 3f495124a5 Fix navbar folder not opening on page refresh when it has an active child item (#19619)
### Before


https://github.com/user-attachments/assets/b76e6184-0299-4240-a1f7-8651b69885ec

### After


https://github.com/user-attachments/assets/e7e9061b-98a1-4781-b882-eef87b83597a
2026-04-13 15:53:28 +00:00
353d1e89d5 Fix merge with null value + reset data virtualization before init load (#19633)
**Merge records fix:**

selectPriorityFieldValue throws when merging records if the priority
record has no value for a field (e.g., null/empty) but 2+ other records
do. The recordsWithValues array is pre-filtered to only records with
non-empty values, so the priority record isn't in the list. The fix:
instead of throwing, fall back to null since this is the priority record
actual value


**Duplicated IDs fix**


https://github.com/user-attachments/assets/bd6d7d08-d079-49a5-aad4-740b59a3c246


When applying a filter that reduces the record count, the virtualized
table's record ID array keeps stale entries from the previous larger
result set. loadRecordsToVirtualRows clones the old array (e.g., 60
entries) and only overwrites the first N positions (e.g., 9) with the
new filtered results, leaving positions 9-59 with old IDs. If any old ID
matches a new one, it appears twice in the selection, causing "-> 2
selected" for a single click and a duplicate ID in the merge mutation
payload. The fix: clear the record IDs array in
useTriggerInitialRecordTableDataLoad before repopulating it with fresh
data.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-13 15:50:58 +00:00
Paul RastoinandGitHub 87f5c0083f Prevent cross version upgrade mismatch in 1.22 (#19627)
## Introduction
As the new upgrade sequence engine is released in `1.22` it requires all
workspaces to be in `1.21.0` which mean they will have a cursor on the
sequence

As if if someone upgrades from `1.20` to `1.22` no `upgradeMigration`
will exist and throw a pretty basic `Could not find any cursor, database
might not been initialized correctly`

Here we allow a meaningful error
2026-04-13 14:53:12 +00:00
neo773andGitHub 7dfc556250 refactor messaging jobs (#19626)
Cleans up the code quality by migrating from Raw SQL to TypeORM
entities. The previous implementation was necessary to do cross‑schema
table joins but since we've migrated to the core schema we don't need it
anymore.

- Also extracted `toIsoStringOrNull` to a utility it was duplicated
several times
- Moved `isThrottled` logic from job handler to cron enqueuer
2026-04-13 14:39:52 +00:00
9f6855e7dd i18n - translations (#19652)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-13 16:54:50 +02:00
33c74c4d28 i18n - docs translations (#19651)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2026-04-13 16:48:44 +02:00
Paul RastoinandGitHub ce2723d6cf Move view field label identifier deletion validation into the cross entity validation (#19642)
## Introduction
In the same validate build and run we should be able to delete a view
field targetting a label identifier and at the same create one that
repoints to it again without failing any validation

Leading for this valdiation rule to be moved in the cross entity
validation steps
2026-04-13 14:38:27 +00:00
Thomas des FrancsandGitHub 12233e6c47 few fixes (#19648)
## Summary
- refresh the partner hero visual and testimonial presentation,
including the partner-specific carousel and illustration assets
- switch the testimonials top notch to the masked rendering approach
used elsewhere for more precise shape control
- extend halftone studio/export support and related geometry/state
handling used by the updated partner visuals
- include supporting website UI adjustments across navigation, pricing,
plans, and Salesforce-related sections

## Testing
- Not run (not requested)
2026-04-13 14:36:03 +00:00
647 changed files with 11144 additions and 10812 deletions
+4 -3
View File
@@ -69,13 +69,14 @@ jobs:
- name: Server / Start
run: |
npx nx start twenty-server &
npx nx run twenty-server:start:ci &
echo "Waiting for server to be ready..."
timeout 60 bash -c 'until curl -s http://localhost:3000/health; do sleep 2; done'
timeout 60 bash -c 'until curl -sf http://localhost:3000/healthz; do sleep 2; done'
- name: Start worker
working-directory: packages/twenty-server
run: |
npx nx run twenty-server:worker &
NODE_ENV=development node dist/queue-worker/queue-worker.js &
echo "Worker started"
- name: Zapier / Build
@@ -7,9 +7,7 @@
"npm": "please-use-yarn",
"yarn": ">=4.0.2"
},
"keywords": [
"twenty-app"
],
"keywords": [],
"packageManager": "yarn@4.9.2",
"scripts": {
"twenty": "twenty",
@@ -583,6 +583,7 @@ type ViewField {
workspaceId: UUID!
createdAt: DateTime!
updatedAt: DateTime!
isActive: Boolean!
deletedAt: DateTime
isOverridden: Boolean @deprecated(reason: "isOverridden is deprecated")
}
@@ -691,6 +692,7 @@ type ViewFieldGroup {
workspaceId: UUID!
createdAt: DateTime!
updatedAt: DateTime!
isActive: Boolean!
deletedAt: DateTime
viewFields: [ViewField!]!
isOverridden: Boolean! @deprecated(reason: "isOverridden is deprecated")
@@ -899,6 +901,7 @@ type PageLayoutWidget {
conditionalAvailabilityExpression: String
createdAt: DateTime!
updatedAt: DateTime!
isActive: Boolean!
deletedAt: DateTime
isOverridden: Boolean @deprecated(reason: "isOverridden is deprecated")
}
@@ -1234,6 +1237,7 @@ type PageLayoutTab {
layoutMode: PageLayoutTabLayoutMode
createdAt: DateTime!
updatedAt: DateTime!
isActive: Boolean!
deletedAt: DateTime
isOverridden: Boolean @deprecated(reason: "isOverridden is deprecated")
}
@@ -1592,7 +1596,6 @@ enum FeatureFlagKey {
IS_CONNECTED_ACCOUNT_MIGRATED
IS_RICH_TEXT_V1_MIGRATED
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED
IS_RECORD_TABLE_WIDGET_ENABLED
IS_DATASOURCE_MIGRATED
}
@@ -2194,30 +2197,18 @@ type DeletedWorkspaceMember {
userWorkspaceId: UUID
}
type BillingEntitlement {
key: BillingEntitlementKey!
value: Boolean!
type Relation {
type: RelationType!
sourceObjectMetadata: Object!
targetObjectMetadata: Object!
sourceFieldMetadata: Field!
targetFieldMetadata: Field!
}
enum BillingEntitlementKey {
SSO
CUSTOM_DOMAIN
RLS
AUDIT_LOGS
}
type DomainRecord {
validationType: String!
type: String!
status: String!
key: String!
value: String!
}
type DomainValidRecords {
id: UUID!
domain: String!
records: [DomainRecord!]!
"""Relation type"""
enum RelationType {
ONE_TO_MANY
MANY_TO_ONE
}
type IndexEdge {
@@ -2319,25 +2310,6 @@ type ObjectFieldsConnection {
edges: [FieldEdge!]!
}
type UpsertRowLevelPermissionPredicatesResult {
predicates: [RowLevelPermissionPredicate!]!
predicateGroups: [RowLevelPermissionPredicateGroup!]!
}
type Relation {
type: RelationType!
sourceObjectMetadata: Object!
targetObjectMetadata: Object!
sourceFieldMetadata: Field!
targetFieldMetadata: Field!
}
"""Relation type"""
enum RelationType {
ONE_TO_MANY
MANY_TO_ONE
}
type FieldConnection {
"""Paging information"""
pageInfo: PageInfo!
@@ -2346,6 +2318,37 @@ type FieldConnection {
edges: [FieldEdge!]!
}
type BillingEntitlement {
key: BillingEntitlementKey!
value: Boolean!
}
enum BillingEntitlementKey {
SSO
CUSTOM_DOMAIN
RLS
AUDIT_LOGS
}
type DomainRecord {
validationType: String!
type: String!
status: String!
key: String!
value: String!
}
type DomainValidRecords {
id: UUID!
domain: String!
records: [DomainRecord!]!
}
type UpsertRowLevelPermissionPredicatesResult {
predicates: [RowLevelPermissionPredicate!]!
predicateGroups: [RowLevelPermissionPredicateGroup!]!
}
type AuthToken {
token: String!
expiresAt: DateTime!
@@ -415,6 +415,7 @@ export interface ViewField {
workspaceId: Scalars['UUID']
createdAt: Scalars['DateTime']
updatedAt: Scalars['DateTime']
isActive: Scalars['Boolean']
deletedAt?: Scalars['DateTime']
/** @deprecated isOverridden is deprecated */
isOverridden?: Scalars['Boolean']
@@ -492,6 +493,7 @@ export interface ViewFieldGroup {
workspaceId: Scalars['UUID']
createdAt: Scalars['DateTime']
updatedAt: Scalars['DateTime']
isActive: Scalars['Boolean']
deletedAt?: Scalars['DateTime']
viewFields: ViewField[]
/** @deprecated isOverridden is deprecated */
@@ -674,6 +676,7 @@ export interface PageLayoutWidget {
conditionalAvailabilityExpression?: Scalars['String']
createdAt: Scalars['DateTime']
updatedAt: Scalars['DateTime']
isActive: Scalars['Boolean']
deletedAt?: Scalars['DateTime']
/** @deprecated isOverridden is deprecated */
isOverridden?: Scalars['Boolean']
@@ -959,6 +962,7 @@ export interface PageLayoutTab {
layoutMode?: PageLayoutTabLayoutMode
createdAt: Scalars['DateTime']
updatedAt: Scalars['DateTime']
isActive: Scalars['Boolean']
deletedAt?: Scalars['DateTime']
/** @deprecated isOverridden is deprecated */
isOverridden?: Scalars['Boolean']
@@ -1289,7 +1293,7 @@ export interface FeatureFlag {
__typename: 'FeatureFlag'
}
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_RECORD_TABLE_WIDGET_ENABLED' | 'IS_DATASOURCE_MIGRATED'
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_DATASOURCE_MIGRATED'
export interface WorkspaceUrls {
customUrl?: Scalars['String']
@@ -1879,29 +1883,18 @@ export interface DeletedWorkspaceMember {
__typename: 'DeletedWorkspaceMember'
}
export interface BillingEntitlement {
key: BillingEntitlementKey
value: Scalars['Boolean']
__typename: 'BillingEntitlement'
export interface Relation {
type: RelationType
sourceObjectMetadata: Object
targetObjectMetadata: Object
sourceFieldMetadata: Field
targetFieldMetadata: Field
__typename: 'Relation'
}
export type BillingEntitlementKey = 'SSO' | 'CUSTOM_DOMAIN' | 'RLS' | 'AUDIT_LOGS'
export interface DomainRecord {
validationType: Scalars['String']
type: Scalars['String']
status: Scalars['String']
key: Scalars['String']
value: Scalars['String']
__typename: 'DomainRecord'
}
export interface DomainValidRecords {
id: Scalars['UUID']
domain: Scalars['String']
records: DomainRecord[]
__typename: 'DomainValidRecords'
}
/** Relation type */
export type RelationType = 'ONE_TO_MANY' | 'MANY_TO_ONE'
export interface IndexEdge {
/** The node containing the Index */
@@ -2001,25 +1994,6 @@ export interface ObjectFieldsConnection {
__typename: 'ObjectFieldsConnection'
}
export interface UpsertRowLevelPermissionPredicatesResult {
predicates: RowLevelPermissionPredicate[]
predicateGroups: RowLevelPermissionPredicateGroup[]
__typename: 'UpsertRowLevelPermissionPredicatesResult'
}
export interface Relation {
type: RelationType
sourceObjectMetadata: Object
targetObjectMetadata: Object
sourceFieldMetadata: Field
targetFieldMetadata: Field
__typename: 'Relation'
}
/** Relation type */
export type RelationType = 'ONE_TO_MANY' | 'MANY_TO_ONE'
export interface FieldConnection {
/** Paging information */
pageInfo: PageInfo
@@ -2028,6 +2002,36 @@ export interface FieldConnection {
__typename: 'FieldConnection'
}
export interface BillingEntitlement {
key: BillingEntitlementKey
value: Scalars['Boolean']
__typename: 'BillingEntitlement'
}
export type BillingEntitlementKey = 'SSO' | 'CUSTOM_DOMAIN' | 'RLS' | 'AUDIT_LOGS'
export interface DomainRecord {
validationType: Scalars['String']
type: Scalars['String']
status: Scalars['String']
key: Scalars['String']
value: Scalars['String']
__typename: 'DomainRecord'
}
export interface DomainValidRecords {
id: Scalars['UUID']
domain: Scalars['String']
records: DomainRecord[]
__typename: 'DomainValidRecords'
}
export interface UpsertRowLevelPermissionPredicatesResult {
predicates: RowLevelPermissionPredicate[]
predicateGroups: RowLevelPermissionPredicateGroup[]
__typename: 'UpsertRowLevelPermissionPredicatesResult'
}
export interface AuthToken {
token: Scalars['String']
expiresAt: Scalars['DateTime']
@@ -3631,6 +3635,7 @@ export interface ViewFieldGenqlSelection{
workspaceId?: boolean | number
createdAt?: boolean | number
updatedAt?: boolean | number
isActive?: boolean | number
deletedAt?: boolean | number
/** @deprecated isOverridden is deprecated */
isOverridden?: boolean | number
@@ -3705,6 +3710,7 @@ export interface ViewFieldGroupGenqlSelection{
workspaceId?: boolean | number
createdAt?: boolean | number
updatedAt?: boolean | number
isActive?: boolean | number
deletedAt?: boolean | number
viewFields?: ViewFieldGenqlSelection
/** @deprecated isOverridden is deprecated */
@@ -3879,6 +3885,7 @@ export interface PageLayoutWidgetGenqlSelection{
conditionalAvailabilityExpression?: boolean | number
createdAt?: boolean | number
updatedAt?: boolean | number
isActive?: boolean | number
deletedAt?: boolean | number
/** @deprecated isOverridden is deprecated */
isOverridden?: boolean | number
@@ -4191,6 +4198,7 @@ export interface PageLayoutTabGenqlSelection{
layoutMode?: boolean | number
createdAt?: boolean | number
updatedAt?: boolean | number
isActive?: boolean | number
deletedAt?: boolean | number
/** @deprecated isOverridden is deprecated */
isOverridden?: boolean | number
@@ -5149,27 +5157,12 @@ export interface DeletedWorkspaceMemberGenqlSelection{
__scalar?: boolean | number
}
export interface BillingEntitlementGenqlSelection{
key?: boolean | number
value?: boolean | number
__typename?: boolean | number
__scalar?: boolean | number
}
export interface DomainRecordGenqlSelection{
validationType?: boolean | number
export interface RelationGenqlSelection{
type?: boolean | number
status?: boolean | number
key?: boolean | number
value?: boolean | number
__typename?: boolean | number
__scalar?: boolean | number
}
export interface DomainValidRecordsGenqlSelection{
id?: boolean | number
domain?: boolean | number
records?: DomainRecordGenqlSelection
sourceObjectMetadata?: ObjectGenqlSelection
targetObjectMetadata?: ObjectGenqlSelection
sourceFieldMetadata?: FieldGenqlSelection
targetFieldMetadata?: FieldGenqlSelection
__typename?: boolean | number
__scalar?: boolean | number
}
@@ -5284,23 +5277,6 @@ export interface ObjectFieldsConnectionGenqlSelection{
__scalar?: boolean | number
}
export interface UpsertRowLevelPermissionPredicatesResultGenqlSelection{
predicates?: RowLevelPermissionPredicateGenqlSelection
predicateGroups?: RowLevelPermissionPredicateGroupGenqlSelection
__typename?: boolean | number
__scalar?: boolean | number
}
export interface RelationGenqlSelection{
type?: boolean | number
sourceObjectMetadata?: ObjectGenqlSelection
targetObjectMetadata?: ObjectGenqlSelection
sourceFieldMetadata?: FieldGenqlSelection
targetFieldMetadata?: FieldGenqlSelection
__typename?: boolean | number
__scalar?: boolean | number
}
export interface FieldConnectionGenqlSelection{
/** Paging information */
pageInfo?: PageInfoGenqlSelection
@@ -5310,6 +5286,38 @@ export interface FieldConnectionGenqlSelection{
__scalar?: boolean | number
}
export interface BillingEntitlementGenqlSelection{
key?: boolean | number
value?: boolean | number
__typename?: boolean | number
__scalar?: boolean | number
}
export interface DomainRecordGenqlSelection{
validationType?: boolean | number
type?: boolean | number
status?: boolean | number
key?: boolean | number
value?: boolean | number
__typename?: boolean | number
__scalar?: boolean | number
}
export interface DomainValidRecordsGenqlSelection{
id?: boolean | number
domain?: boolean | number
records?: DomainRecordGenqlSelection
__typename?: boolean | number
__scalar?: boolean | number
}
export interface UpsertRowLevelPermissionPredicatesResultGenqlSelection{
predicates?: RowLevelPermissionPredicateGenqlSelection
predicateGroups?: RowLevelPermissionPredicateGroupGenqlSelection
__typename?: boolean | number
__scalar?: boolean | number
}
export interface AuthTokenGenqlSelection{
token?: boolean | number
expiresAt?: boolean | number
@@ -8232,26 +8240,10 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
const BillingEntitlement_possibleTypes: string[] = ['BillingEntitlement']
export const isBillingEntitlement = (obj?: { __typename?: any } | null): obj is BillingEntitlement => {
if (!obj?.__typename) throw new Error('__typename is missing in "isBillingEntitlement"')
return BillingEntitlement_possibleTypes.includes(obj.__typename)
}
const DomainRecord_possibleTypes: string[] = ['DomainRecord']
export const isDomainRecord = (obj?: { __typename?: any } | null): obj is DomainRecord => {
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainRecord"')
return DomainRecord_possibleTypes.includes(obj.__typename)
}
const DomainValidRecords_possibleTypes: string[] = ['DomainValidRecords']
export const isDomainValidRecords = (obj?: { __typename?: any } | null): obj is DomainValidRecords => {
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainValidRecords"')
return DomainValidRecords_possibleTypes.includes(obj.__typename)
const Relation_possibleTypes: string[] = ['Relation']
export const isRelation = (obj?: { __typename?: any } | null): obj is Relation => {
if (!obj?.__typename) throw new Error('__typename is missing in "isRelation"')
return Relation_possibleTypes.includes(obj.__typename)
}
@@ -8352,22 +8344,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
const UpsertRowLevelPermissionPredicatesResult_possibleTypes: string[] = ['UpsertRowLevelPermissionPredicatesResult']
export const isUpsertRowLevelPermissionPredicatesResult = (obj?: { __typename?: any } | null): obj is UpsertRowLevelPermissionPredicatesResult => {
if (!obj?.__typename) throw new Error('__typename is missing in "isUpsertRowLevelPermissionPredicatesResult"')
return UpsertRowLevelPermissionPredicatesResult_possibleTypes.includes(obj.__typename)
}
const Relation_possibleTypes: string[] = ['Relation']
export const isRelation = (obj?: { __typename?: any } | null): obj is Relation => {
if (!obj?.__typename) throw new Error('__typename is missing in "isRelation"')
return Relation_possibleTypes.includes(obj.__typename)
}
const FieldConnection_possibleTypes: string[] = ['FieldConnection']
export const isFieldConnection = (obj?: { __typename?: any } | null): obj is FieldConnection => {
if (!obj?.__typename) throw new Error('__typename is missing in "isFieldConnection"')
@@ -8376,6 +8352,38 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
const BillingEntitlement_possibleTypes: string[] = ['BillingEntitlement']
export const isBillingEntitlement = (obj?: { __typename?: any } | null): obj is BillingEntitlement => {
if (!obj?.__typename) throw new Error('__typename is missing in "isBillingEntitlement"')
return BillingEntitlement_possibleTypes.includes(obj.__typename)
}
const DomainRecord_possibleTypes: string[] = ['DomainRecord']
export const isDomainRecord = (obj?: { __typename?: any } | null): obj is DomainRecord => {
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainRecord"')
return DomainRecord_possibleTypes.includes(obj.__typename)
}
const DomainValidRecords_possibleTypes: string[] = ['DomainValidRecords']
export const isDomainValidRecords = (obj?: { __typename?: any } | null): obj is DomainValidRecords => {
if (!obj?.__typename) throw new Error('__typename is missing in "isDomainValidRecords"')
return DomainValidRecords_possibleTypes.includes(obj.__typename)
}
const UpsertRowLevelPermissionPredicatesResult_possibleTypes: string[] = ['UpsertRowLevelPermissionPredicatesResult']
export const isUpsertRowLevelPermissionPredicatesResult = (obj?: { __typename?: any } | null): obj is UpsertRowLevelPermissionPredicatesResult => {
if (!obj?.__typename) throw new Error('__typename is missing in "isUpsertRowLevelPermissionPredicatesResult"')
return UpsertRowLevelPermissionPredicatesResult_possibleTypes.includes(obj.__typename)
}
const AuthToken_possibleTypes: string[] = ['AuthToken']
export const isAuthToken = (obj?: { __typename?: any } | null): obj is AuthToken => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAuthToken"')
@@ -9470,7 +9478,6 @@ export const enumFeatureFlagKey = {
IS_CONNECTED_ACCOUNT_MIGRATED: 'IS_CONNECTED_ACCOUNT_MIGRATED' as const,
IS_RICH_TEXT_V1_MIGRATED: 'IS_RICH_TEXT_V1_MIGRATED' as const,
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED: 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' as const,
IS_RECORD_TABLE_WIDGET_ENABLED: 'IS_RECORD_TABLE_WIDGET_ENABLED' as const,
IS_DATASOURCE_MIGRATED: 'IS_DATASOURCE_MIGRATED' as const
}
@@ -9577,6 +9584,11 @@ export const enumQueueMetricsTimeRange = {
OneHour: 'OneHour' as const
}
export const enumRelationType = {
ONE_TO_MANY: 'ONE_TO_MANY' as const,
MANY_TO_ONE: 'MANY_TO_ONE' as const
}
export const enumBillingEntitlementKey = {
SSO: 'SSO' as const,
CUSTOM_DOMAIN: 'CUSTOM_DOMAIN' as const,
@@ -9584,11 +9596,6 @@ export const enumBillingEntitlementKey = {
AUDIT_LOGS: 'AUDIT_LOGS' as const
}
export const enumRelationType = {
ONE_TO_MANY: 'ONE_TO_MANY' as const,
MANY_TO_ONE: 'MANY_TO_ONE' as const
}
export const enumEmailingDomainDriver = {
AWS_SES: 'AWS_SES' as const
}
@@ -63,7 +63,7 @@ export default {
209,
221,
238,
255,
253,
292,
293,
303,
@@ -789,10 +789,10 @@ export default {
3
],
"relation": [
254
237
],
"morphRelations": [
254
237
],
"object": [
46
@@ -851,7 +851,7 @@ export default {
36
],
"objectMetadata": [
247,
245,
{
"paging": [
39,
@@ -864,7 +864,7 @@ export default {
}
],
"indexFieldMetadatas": [
245,
243,
{
"paging": [
39,
@@ -1109,7 +1109,7 @@ export default {
37
],
"fields": [
252,
250,
{
"paging": [
39,
@@ -1122,7 +1122,7 @@ export default {
}
],
"indexMetadatas": [
250,
248,
{
"paging": [
39,
@@ -1283,6 +1283,9 @@ export default {
"updatedAt": [
4
],
"isActive": [
6
],
"deletedAt": [
4
],
@@ -1456,6 +1459,9 @@ export default {
"updatedAt": [
4
],
"isActive": [
6
],
"deletedAt": [
4
],
@@ -1703,7 +1709,7 @@ export default {
131
],
"billingEntitlements": [
237
252
],
"hasValidEnterpriseKey": [
6
@@ -1903,6 +1909,9 @@ export default {
"updatedAt": [
4
],
"isActive": [
6
],
"deletedAt": [
4
],
@@ -2561,6 +2570,9 @@ export default {
"updatedAt": [
4
],
"isActive": [
6
],
"deletedAt": [
4
],
@@ -4419,9 +4431,179 @@ export default {
1
]
},
"Relation": {
"type": [
238
],
"sourceObjectMetadata": [
46
],
"targetObjectMetadata": [
46
],
"sourceFieldMetadata": [
34
],
"targetFieldMetadata": [
34
],
"__typename": [
1
]
},
"RelationType": {},
"IndexEdge": {
"node": [
37
],
"cursor": [
40
],
"__typename": [
1
]
},
"PageInfo": {
"hasNextPage": [
6
],
"hasPreviousPage": [
6
],
"startCursor": [
40
],
"endCursor": [
40
],
"__typename": [
1
]
},
"IndexConnection": {
"pageInfo": [
240
],
"edges": [
239
],
"__typename": [
1
]
},
"IndexFieldEdge": {
"node": [
36
],
"cursor": [
40
],
"__typename": [
1
]
},
"IndexIndexFieldMetadatasConnection": {
"pageInfo": [
240
],
"edges": [
242
],
"__typename": [
1
]
},
"ObjectEdge": {
"node": [
46
],
"cursor": [
40
],
"__typename": [
1
]
},
"IndexObjectMetadataConnection": {
"pageInfo": [
240
],
"edges": [
244
],
"__typename": [
1
]
},
"ObjectRecordCount": {
"objectNamePlural": [
1
],
"totalCount": [
21
],
"__typename": [
1
]
},
"ObjectConnection": {
"pageInfo": [
240
],
"edges": [
244
],
"__typename": [
1
]
},
"ObjectIndexMetadatasConnection": {
"pageInfo": [
240
],
"edges": [
239
],
"__typename": [
1
]
},
"FieldEdge": {
"node": [
34
],
"cursor": [
40
],
"__typename": [
1
]
},
"ObjectFieldsConnection": {
"pageInfo": [
240
],
"edges": [
249
],
"__typename": [
1
]
},
"FieldConnection": {
"pageInfo": [
240
],
"edges": [
249
],
"__typename": [
1
]
},
"BillingEntitlement": {
"key": [
238
253
],
"value": [
6
@@ -4459,145 +4641,7 @@ export default {
1
],
"records": [
239
],
"__typename": [
1
]
},
"IndexEdge": {
"node": [
37
],
"cursor": [
40
],
"__typename": [
1
]
},
"PageInfo": {
"hasNextPage": [
6
],
"hasPreviousPage": [
6
],
"startCursor": [
40
],
"endCursor": [
40
],
"__typename": [
1
]
},
"IndexConnection": {
"pageInfo": [
242
],
"edges": [
241
],
"__typename": [
1
]
},
"IndexFieldEdge": {
"node": [
36
],
"cursor": [
40
],
"__typename": [
1
]
},
"IndexIndexFieldMetadatasConnection": {
"pageInfo": [
242
],
"edges": [
244
],
"__typename": [
1
]
},
"ObjectEdge": {
"node": [
46
],
"cursor": [
40
],
"__typename": [
1
]
},
"IndexObjectMetadataConnection": {
"pageInfo": [
242
],
"edges": [
246
],
"__typename": [
1
]
},
"ObjectRecordCount": {
"objectNamePlural": [
1
],
"totalCount": [
21
],
"__typename": [
1
]
},
"ObjectConnection": {
"pageInfo": [
242
],
"edges": [
246
],
"__typename": [
1
]
},
"ObjectIndexMetadatasConnection": {
"pageInfo": [
242
],
"edges": [
241
],
"__typename": [
1
]
},
"FieldEdge": {
"node": [
34
],
"cursor": [
40
],
"__typename": [
1
]
},
"ObjectFieldsConnection": {
"pageInfo": [
242
],
"edges": [
251
254
],
"__typename": [
1
@@ -4614,38 +4658,6 @@ export default {
1
]
},
"Relation": {
"type": [
255
],
"sourceObjectMetadata": [
46
],
"targetObjectMetadata": [
46
],
"sourceFieldMetadata": [
34
],
"targetFieldMetadata": [
34
],
"__typename": [
1
]
},
"RelationType": {},
"FieldConnection": {
"pageInfo": [
242
],
"edges": [
251
],
"__typename": [
1
]
},
"AuthToken": {
"token": [
1
@@ -5975,7 +5987,7 @@ export default {
},
"AgentChatThreadConnection": {
"pageInfo": [
242
240
],
"edges": [
335
@@ -6582,7 +6594,7 @@ export default {
}
],
"objectRecordCounts": [
248
246
],
"object": [
46,
@@ -6594,7 +6606,7 @@ export default {
}
],
"objects": [
249,
247,
{
"paging": [
39,
@@ -6616,7 +6628,7 @@ export default {
}
],
"indexMetadatas": [
243,
241,
{
"paging": [
39,
@@ -6665,7 +6677,7 @@ export default {
}
],
"fields": [
256,
251,
{
"paging": [
39,
@@ -8340,7 +8352,7 @@ export default {
}
],
"upsertRowLevelPermissionPredicates": [
253,
256,
{
"input": [
456,
@@ -9082,7 +9094,7 @@ export default {
66
],
"checkCustomDomainValidRecords": [
240
255
],
"createOIDCIdentityProvider": [
232,
@@ -9415,7 +9427,7 @@ export default {
}
],
"checkPublicDomainValidRecords": [
240,
255,
{
"domain": [
1,
@@ -87,7 +87,7 @@ Publishing to npm makes your app discoverable in the Twenty marketplace. Any Twe
### Requirements
- An [npm](https://www.npmjs.com) account
- The `twenty-app` keyword in your `package.json` `keywords` array (already included when you scaffold with `create-twenty-app`)
- The `twenty-app` keyword in your `package.json` `keywords` array (add it manually — it is not included by default in the `create-twenty-app` template)
```json filename="package.json"
{
@@ -476,7 +476,7 @@ export default defineLogicFunction({
httpRouteTriggerSettings: {
path: '/post-card/create',
httpMethod: 'GET',
isAuthRequired: false,
isAuthRequired: true,
},
/*databaseEventTriggerSettings: {
eventName: 'people.created',
@@ -87,7 +87,7 @@ yarn twenty deploy
### المتطلبات
* حساب على [npm](https://www.npmjs.com)
* الكلمة المفتاحية `twenty-app` في مصفوفة `keywords` في `package.json` (موجودة مسبقًا عند تهيئة المشروع باستخدام `create-twenty-app`)
* الكلمة المفتاحية `twenty-app` في مصفوفة `keywords` في `package.json` (أضفها يدويًا — فهي غير مضمنة افتراضيًا في قالب `create-twenty-app`)
```json filename="package.json"
{
@@ -476,7 +476,7 @@ export default defineLogicFunction({
httpRouteTriggerSettings: {
path: '/post-card/create',
httpMethod: 'GET',
isAuthRequired: false,
isAuthRequired: true,
},
/*databaseEventTriggerSettings: {
eventName: 'people.created',
@@ -87,7 +87,7 @@ Publikování na npm zajistí, že bude vaše aplikace dohledatelná v Marketpla
### Požadavky
* Účet na [npm](https://www.npmjs.com)
* Klíčové slovo `twenty-app` ve vašem poli `keywords` v souboru `package.json` (již je zahrnuto, když založíte projekt pomocí `create-twenty-app`)
* Klíčové slovo `twenty-app` ve vašem poli `keywords` v souboru `package.json` (přidejte je ručně — ve výchozím nastavení není zahrnuto v šabloně `create-twenty-app`)
```json filename="package.json"
{
@@ -476,7 +476,7 @@ export default defineLogicFunction({
httpRouteTriggerSettings: {
path: '/post-card/create',
httpMethod: 'GET',
isAuthRequired: false,
isAuthRequired: true,
},
/*databaseEventTriggerSettings: {
eventName: 'people.created',
@@ -87,7 +87,7 @@ Die Veröffentlichung auf npm macht Ihre App im Twenty-Marktplatz auffindbar. Je
### Anforderungen
* Ein [npm](https://www.npmjs.com)-Konto
* Das Schlüsselwort `twenty-app` in Ihrem `package.json`-Array `keywords` (bereits enthalten, wenn Sie mit `create-twenty-app` ein Gerüst erstellen)
* Das Schlüsselwort `twenty-app` in Ihrem `package.json`-Array `keywords` (manuell hinzufügen — es ist in der `create-twenty-app`-Vorlage standardmäßig nicht enthalten)
```json filename="package.json"
{
@@ -476,7 +476,7 @@ export default defineLogicFunction({
httpRouteTriggerSettings: {
path: '/post-card/create',
httpMethod: 'GET',
isAuthRequired: false,
isAuthRequired: true,
},
/*databaseEventTriggerSettings: {
eventName: 'people.created',
@@ -87,7 +87,7 @@ La pubblicazione su npm rende la tua app scopribile nel marketplace di Twenty. Q
### Requisiti
* Un account [npm](https://www.npmjs.com)
* La parola chiave `twenty-app` nell'array `keywords` del tuo `package.json` (già inclusa quando inizializzi con `create-twenty-app`)
* La parola chiave `twenty-app` nell'array `keywords` del tuo `package.json` (aggiungila manualmente — non è inclusa per impostazione predefinita nel template `create-twenty-app`)
```json filename="package.json"
{
@@ -476,7 +476,7 @@ export default defineLogicFunction({
httpRouteTriggerSettings: {
path: '/post-card/create',
httpMethod: 'GET',
isAuthRequired: false,
isAuthRequired: true,
},
/*databaseEventTriggerSettings: {
eventName: 'people.created',
@@ -87,7 +87,7 @@ Publicar no npm torna seu aplicativo descobrível no Marketplace da Twenty. Qual
### Requisitos
* Uma conta no [npm](https://www.npmjs.com)
* A palavra-chave `twenty-app` no array `keywords` do seu `package.json` (já incluída quando você cria o projeto com `create-twenty-app`)
* A palavra-chave `twenty-app` no array `keywords` do seu `package.json` (adicione-a manualmente — não é incluída por padrão no template `create-twenty-app`)
```json filename="package.json"
{
@@ -476,7 +476,7 @@ export default defineLogicFunction({
httpRouteTriggerSettings: {
path: '/post-card/create',
httpMethod: 'GET',
isAuthRequired: false,
isAuthRequired: true,
},
/*databaseEventTriggerSettings: {
eventName: 'people.created',
@@ -87,7 +87,7 @@ When updating an already deployed tarball app, the server requires the `version`
### Требования
* Учётная запись [npm](https://www.npmjs.com)
* Ключевое слово `twenty-app` в массиве `keywords` вашего `package.json` (уже добавлено при создании проекта с помощью `create-twenty-app`)
* Ключевое слово `twenty-app` в массиве `keywords` вашего `package.json` (добавьте его вручную — по умолчанию оно не включено в шаблон `create-twenty-app`)
```json filename="package.json"
{
@@ -476,7 +476,7 @@ export default defineLogicFunction({
httpRouteTriggerSettings: {
path: '/post-card/create',
httpMethod: 'GET',
isAuthRequired: false,
isAuthRequired: true,
},
/*databaseEventTriggerSettings: {
eventName: 'people.created',
@@ -87,7 +87,7 @@ npmye yayımlamak, uygulamanızın Twenty pazaryerinde keşfedilebilir olmas
### Gereksinimler
* Bir [npm](https://www.npmjs.com) hesabı
* `package.json` içindeki `keywords` dizinizdeki `twenty-app` anahtar sözcüğü (`create-twenty-app` ile iskelet oluşturduğunuzda zaten eklenir)
* `package.json` içindeki `keywords` dizinizdeki `twenty-app` anahtar sözcüğü (elle ekleyin — varsayılan olarak `create-twenty-app` şablonunda yer almaz)
```json filename="package.json"
{
+2 -2
View File
@@ -61,8 +61,8 @@ const jestConfig = {
extensionsToTreatAsEsm: ['.ts', '.tsx'],
coverageThreshold: {
global: {
statements: 48.4,
lines: 47.0,
statements: 48,
lines: 46,
functions: 39.5,
},
},
File diff suppressed because one or more lines are too long
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Oor hierdie gebruiker"
msgid "About this workspace"
msgstr "Oor hierdie werkruimte"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Inhoud"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Konteks"
@@ -12037,11 +12040,6 @@ msgstr "Herstel 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Herstel na"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Daar is geen gekoppelde aktiwiteit by hierdie rekord nie."
msgid "There was an error while updating password."
msgstr "Daar was 'n fout terwyl die wagwoord opgedateer is."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "حول هذا المستخدم"
msgid "About this workspace"
msgstr "عن مساحة العمل هذه"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "المحتوى"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "السياق"
@@ -12037,11 +12040,6 @@ msgstr "إعادة تعيين المصادقة الثنائية"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "\\\\"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "لا توجد أنشطة مرتبطة بهذا السجل."
msgid "There was an error while updating password."
msgstr "حدث خطأ أثناء تحديث كلمة المرور."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Sobre aquest usuari"
msgid "About this workspace"
msgstr "Sobre aquest espai de treball"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Contingut"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Context"
@@ -12037,11 +12040,6 @@ msgstr "Reinicia 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Reinicia a"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "No hi ha cap activitat associada amb aquest registre."
msgid "There was an error while updating password."
msgstr "S'ha produït un error en actualitzar la contrasenya."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "O tomto uživateli"
msgid "About this workspace"
msgstr "O tomto pracovním prostoru"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Obsah"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Kontext"
@@ -12037,11 +12040,6 @@ msgstr "Obnovit 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Obnovit na"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "S tímto záznamem není spojena žádná aktivita."
msgid "There was an error while updating password."
msgstr "Během aktualizace hesla došlo k chybě."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Om denne bruger"
msgid "About this workspace"
msgstr "Om dette arbejdsområde"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Indhold"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Kontekst"
@@ -12037,11 +12040,6 @@ msgstr "Nulstil 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Nulstil til"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Der er ingen aktivitet tilknyttet denne post."
msgid "There was an error while updating password."
msgstr "Der opstod en fejl under opdatering af adgangskoden."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Über diesen Benutzer"
msgid "About this workspace"
msgstr "Über diesen Arbeitsbereich"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Inhalt"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Kontext"
@@ -12037,11 +12040,6 @@ msgstr "2FA zurücksetzen"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Zurücksetzen auf"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Mit diesem Datensatz ist keine Aktivität verknüpft."
msgid "There was an error while updating password."
msgstr "Beim Aktualisieren des Passworts ist ein Fehler aufgetreten."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Σχετικά με αυτόν τον χρήστη"
msgid "About this workspace"
msgstr "Σχετικά με αυτό το χώρο εργασίας"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Περιεχόμενο"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Περιβάλλον"
@@ -12037,11 +12040,6 @@ msgstr "Επαναφορά 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Επαναφορά σε"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14202,6 +14200,11 @@ msgstr "Δεν υπάρχει δραστηριότητα που να σχετί
msgid "There was an error while updating password."
msgstr "Παρουσιάστηκε σφάλμα κατά την ενημέρωση του κωδικού πρόσβασης."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -672,6 +672,11 @@ msgstr "About this user"
msgid "About this workspace"
msgstr "About this workspace"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr "Access"
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3564,9 +3569,7 @@ msgid "Content"
msgstr "Content"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Context"
@@ -12032,11 +12035,6 @@ msgstr "Reset 2FA"
msgid "Reset label to default"
msgstr "Reset label to default"
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Reset to"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14195,6 +14193,11 @@ msgstr "There is no activity associated with this record."
msgid "There was an error while updating password."
msgstr "There was an error while updating password."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr "These apps are not vetted. Use at your own risk."
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Sobre este usuario"
msgid "About this workspace"
msgstr "Sobre este espacio de trabajo"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Contenido"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Contexto"
@@ -12037,11 +12040,6 @@ msgstr "Restablecer 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Restablecer a"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "No hay actividad asociada con este registro."
msgid "There was an error while updating password."
msgstr "Hubo un error al actualizar la contraseña."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Tietoa tästä käyttäjästä"
msgid "About this workspace"
msgstr "Tietoa tästä työtilasta"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Sisältö"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Yhteys"
@@ -12037,11 +12040,6 @@ msgstr "Nollaa 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Palauta"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Tähän tietueeseen ei liity aktiivisuutta."
msgid "There was an error while updating password."
msgstr "Salasanan päivityksessä tapahtui virhe."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "À propos de cet utilisateur"
msgid "About this workspace"
msgstr "À propos de cet espace de travail"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Contenu"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Contexte"
@@ -12037,11 +12040,6 @@ msgstr "Réinitialiser 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Réinitialiser à"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Aucune activité n'est associée à cet enregistrement."
msgid "There was an error while updating password."
msgstr "Une erreur est survenue lors de la mise à jour du mot de passe."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "אודות משתמש זה"
msgid "About this workspace"
msgstr "אודות סביבת עבודה זו"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "תוכן"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "הקשר"
@@ -12037,11 +12040,6 @@ msgstr "אתחל אימות דו-שלבי"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "\\"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "אין פעילות מקושרת לרשומה זו."
msgid "There was an error while updating password."
msgstr "אירעה תקלה בעדכון הסיסמה."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Erről a felhasználóról"
msgid "About this workspace"
msgstr "Erről a munkaterületről"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Tartalom"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Összefüggés"
@@ -12037,11 +12040,6 @@ msgstr "2FA visszaállítása"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Visszaállítás"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Ehhez a rekordhoz nem tartozik tevékenység."
msgid "There was an error while updating password."
msgstr "Hiba történt a jelszó frissítése közben."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Informazioni su questo utente"
msgid "About this workspace"
msgstr "Informazioni su questo spazio di lavoro"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Contenuto"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Contesto"
@@ -12037,11 +12040,6 @@ msgstr "Reimposta 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Reimposta a"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Non ci sono attività associate a questo record."
msgid "There was an error while updating password."
msgstr "Errore durante l'aggiornamento della password."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "このユーザーについて"
msgid "About this workspace"
msgstr "このワークスペースについて"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "コンテンツ"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "コンテキスト"
@@ -12037,11 +12040,6 @@ msgstr "2FAをリセット"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "リセット"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "このレコードに関連付けられたアクティビティはあり
msgid "There was an error while updating password."
msgstr "パスワードの更新中にエラーが発生しました"
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "이 사용자에 대해"
msgid "About this workspace"
msgstr "이 작업공간에 대해"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "내용"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "컨텍스트"
@@ -12037,11 +12040,6 @@ msgstr "이중 인증 재설정"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "다음으로 재설정"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "이 레코드와 연결된 활동이 없습니다."
msgid "There was an error while updating password."
msgstr "비밀번호 업데이트 중 오류가 발생했습니다."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Over deze gebruiker"
msgid "About this workspace"
msgstr "Over deze werkruimte"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Inhoud"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Context"
@@ -12037,11 +12040,6 @@ msgstr "Reset 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Reset naar"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Er is geen activiteit gekoppeld aan dit record."
msgid "There was an error while updating password."
msgstr "Er was een fout bij het bijwerken van het wachtwoord."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Om denne brukeren"
msgid "About this workspace"
msgstr "Om dette arbeidsområdet"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Innhold"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Kontekst"
@@ -12037,11 +12040,6 @@ msgstr "Tilbakestill 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Tilbakestill til"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Det finnes ingen aktivitet knyttet til denne oppføringen."
msgid "There was an error while updating password."
msgstr "Det var en feil under oppdatering av passord."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "O tym użytkowniku"
msgid "About this workspace"
msgstr "O tej przestrzeni roboczej"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Zawartość"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Kontekst"
@@ -12037,11 +12040,6 @@ msgstr "Resetuj 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Zresetuj do"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Z tym rekordem nie jest powiązana żadna aktywność."
msgid "There was an error while updating password."
msgstr "Wystąpił błąd podczas aktualizacji hasła."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -672,6 +672,11 @@ msgstr ""
msgid "About this workspace"
msgstr ""
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3564,9 +3569,7 @@ msgid "Content"
msgstr ""
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr ""
@@ -12032,11 +12035,6 @@ msgstr ""
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr ""
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14195,6 +14193,11 @@ msgstr ""
msgid "There was an error while updating password."
msgstr ""
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Sobre este usuário"
msgid "About this workspace"
msgstr "Sobre este espaço de trabalho"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Conteúdo"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Contexto"
@@ -12037,11 +12040,6 @@ msgstr "Redefinir 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Redefinir para"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Não há atividade associada a este registro."
msgid "There was an error while updating password."
msgstr "Ocorreu um erro ao atualizar a senha."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Sobre este usuário"
msgid "About this workspace"
msgstr "Sobre este espaço de trabalho"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Conteúdo"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Contexto"
@@ -12037,11 +12040,6 @@ msgstr "Redefinir 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Redefinir para"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Não há atividade associada a este registo."
msgid "There was an error while updating password."
msgstr "Ocorreu um erro ao atualizar a palavra-passe."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Despre acest utilizator"
msgid "About this workspace"
msgstr "Despre acest spațiu de lucru"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Conținut"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Context"
@@ -12037,11 +12040,6 @@ msgstr "Resetează 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Resetează la"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Nu există activitate asociată acestei înregistrări."
msgid "There was an error while updating password."
msgstr "A apărut o eroare în timpul actualizării parolei."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
Binary file not shown.
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "О овом кориснику"
msgid "About this workspace"
msgstr "О овом радном простору"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Садржај"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Контекст"
@@ -12037,11 +12040,6 @@ msgstr "Ресетујте 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Ресетујте на"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Са овим записом нема повезаних активно
msgid "There was an error while updating password."
msgstr "Дошло је до грешке при ажурирању лозинке."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Om den här användaren"
msgid "About this workspace"
msgstr "Om den här arbetsytan"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Innehåll"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Sammanhang"
@@ -12039,11 +12042,6 @@ msgstr "Återställ 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Återställ till"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14206,6 +14204,11 @@ msgstr "Det finns ingen aktivitet kopplad till den här posten."
msgid "There was an error while updating password."
msgstr "Det uppstod ett fel vid uppdatering av lösenordet."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Bu kullanıcı hakkında"
msgid "About this workspace"
msgstr "Bu çalışma alanı hakkında"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "İçerik"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Bağlam"
@@ -12037,11 +12040,6 @@ msgstr "2FA Sıfırla"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Sıfırla"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Bu kayıtla ilişkili etkinlik yok."
msgid "There was an error while updating password."
msgstr "Şifre güncelleme sırasında bir hata oluştu."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Про цього користувача"
msgid "About this workspace"
msgstr "Про цей робочий простір"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Вміст"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Контекст"
@@ -12037,11 +12040,6 @@ msgstr "Скинути 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Скинути до"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "З цим записом не пов’язана жодна актив
msgid "There was an error while updating password."
msgstr "Сталася помилка під час оновлення пароля."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "Về người dùng này"
msgid "About this workspace"
msgstr "Giới thiệu về không gian làm việc này"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "Nội dung"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "Ngữ cảnh"
@@ -12037,11 +12040,6 @@ msgstr "Đặt lại 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "Đặt lại thành"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "Không có hoạt động nào liên kết với bản ghi này."
msgid "There was an error while updating password."
msgstr "Đã có lỗi xảy ra trong quá trình cập nhật mật khẩu."
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "关于此用户"
msgid "About this workspace"
msgstr "关于此工作区"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "内容"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "上下文"
@@ -12037,11 +12040,6 @@ msgstr "重置 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "重置为"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "此记录没有关联的活动。"
msgid "There was an error while updating password."
msgstr "更新密码时出错。"
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
+10 -7
View File
@@ -677,6 +677,11 @@ msgstr "關於此使用者"
msgid "About this workspace"
msgstr "關於此工作區"
#. js-lingui-id: LuXP9q
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "Access"
msgstr ""
#. js-lingui-id: pNW+Rt
#: src/pages/settings/admin-panel/SettingsAdminNewAiProvider.tsx
msgid "Access Key ID"
@@ -3569,9 +3574,7 @@ msgid "Content"
msgstr "內容"
#. js-lingui-id: M73whl
#: src/modules/side-panel/pages/root/components/SidePanelRootPage.tsx
#: src/modules/settings/ai/components/SettingsAiModelHoverCard.tsx
#: src/modules/command-menu-item/display/components/SidePanelCommandMenuItemDisplayPage.tsx
#: src/modules/ai/components/RoutingDebugDisplay.tsx
msgid "Context"
msgstr "上下文"
@@ -12037,11 +12040,6 @@ msgstr "重置 2FA"
msgid "Reset label to default"
msgstr ""
#. js-lingui-id: 1IWc1n
#: src/modules/side-panel/pages/root/components/SidePanelResetContextToSelectionButton.tsx
msgid "Reset to"
msgstr "重置為"
#. js-lingui-id: L+rMC9
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
#: src/modules/side-panel/pages/page-layout/components/WidgetSettingsManageSection.tsx
@@ -14200,6 +14198,11 @@ msgstr "此記錄沒有相關的活動。"
msgid "There was an error while updating password."
msgstr "更新密碼時出現錯誤。"
#. js-lingui-id: vg1S0X
#: src/pages/settings/applications/tabs/SettingsApplicationsDeveloperTab.tsx
msgid "These apps are not vetted. Use at your own risk."
msgstr ""
#. js-lingui-id: AUV+TY
#: src/modules/ai/components/ThinkingStepsDisplay.tsx
msgid "Thinking"
@@ -4,20 +4,14 @@ import { PINNED_COMMAND_MENU_ITEMS_GAP } from '@/command-menu-item/display/const
import { commandMenuPinnedInlineLayoutState } from '@/command-menu-item/display/states/commandMenuPinnedInlineLayoutState';
import { getVisibleCommandMenuItemCountForContainerWidth } from '@/command-menu-item/display/utils/getVisibleCommandMenuItemCountForContainerWidth';
import { groupCommandMenuItems } from '@/command-menu-item/utils/groupCommandMenuItems';
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
import { SidePanelList } from '@/side-panel/components/SidePanelList';
import { SIDE_PANEL_PREVIOUS_COMPONENT_INSTANCE_ID } from '@/side-panel/constants/SidePanelPreviousComponentInstanceId';
import { SIDE_PANEL_RESET_CONTEXT_TO_SELECTION } from '@/side-panel/constants/SidePanelResetContextToSelection';
import { SidePanelResetContextToSelectionButton } from '@/side-panel/pages/root/components/SidePanelResetContextToSelectionButton';
import { useFilterCommandMenuItemsWithSidePanelSearch } from '@/side-panel/pages/root/hooks/useFilterCommandMenuItemsWithSidePanelSearch';
import { sidePanelSearchState } from '@/side-panel/states/sidePanelSearchState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useLingui } from '@lingui/react/macro';
import { isNumber } from '@sniptt/guards';
import { useContext, useMemo } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { CommandMenuItemAvailabilityType } from '~/generated-metadata/graphql';
export const SidePanelCommandMenuItemDisplayPage = () => {
@@ -99,24 +93,8 @@ export const SidePanelCommandMenuItemDisplayPage = () => {
...(noResults ? fallbackCommandMenuItems : []),
].map((item) => item.id);
// oxlint-disable-next-line twenty/matching-state-variable
const previousContextStoreCurrentObjectMetadataItemId =
useAtomComponentStateValue(
contextStoreCurrentObjectMetadataItemIdComponentState,
SIDE_PANEL_PREVIOUS_COMPONENT_INSTANCE_ID,
);
if (isDefined(previousContextStoreCurrentObjectMetadataItemId)) {
selectableItemIds.unshift(SIDE_PANEL_RESET_CONTEXT_TO_SELECTION);
}
return (
<SidePanelList selectableItemIds={selectableItemIds} noResults={noResults}>
{isDefined(previousContextStoreCurrentObjectMetadataItemId) && (
<SidePanelGroup heading={t`Context`}>
<SidePanelResetContextToSelectionButton />
</SidePanelGroup>
)}
{matchingPinnedItems.length > 0 && (
<SidePanelGroup heading={t`Pinned`}>
{matchingPinnedItems.map((item) => (
@@ -1,195 +0,0 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { SIDE_PANEL_COMPONENT_INSTANCE_ID } from '@/side-panel/constants/SidePanelComponentInstanceId';
import { SIDE_PANEL_PREVIOUS_COMPONENT_INSTANCE_ID } from '@/side-panel/constants/SidePanelPreviousComponentInstanceId';
import { useSetGlobalCommandMenuContext } from '@/command-menu/hooks/useSetGlobalCommandMenuContext';
import { sidePanelPageInfoState } from '@/side-panel/states/sidePanelPageInfoState';
import { hasUserSelectedSidePanelListItemState } from '@/side-panel/states/hasUserSelectedSidePanelListItemState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { getJestMetadataAndApolloMocksAndCommandMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndCommandMenuWrapper';
import { mockedPersonRecords } from '~/testing/mock-data/generated/data/people/mock-people-data';
import { getTestEnrichedObjectMetadataItemsMock } from '~/testing/utils/getTestEnrichedObjectMetadataItemsMock';
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
const personMockObjectMetadataItem =
getTestEnrichedObjectMetadataItemsMock().find(
(item) => item.nameSingular === 'person',
)!;
const peopleMock = [...mockedPersonRecords];
jotaiStore.set(
recordStoreFamilyState.atomFamily(peopleMock[0].id),
peopleMock[0],
);
jotaiStore.set(
recordStoreFamilyState.atomFamily(peopleMock[1].id),
peopleMock[1],
);
const wrapper = getJestMetadataAndApolloMocksAndCommandMenuWrapper({
apolloMocks: [],
componentInstanceId: SIDE_PANEL_COMPONENT_INSTANCE_ID,
contextStoreCurrentObjectMetadataNameSingular:
personMockObjectMetadataItem.nameSingular,
contextStoreCurrentViewId: 'my-view-id',
contextStoreTargetedRecordsRule: {
mode: 'selection',
selectedRecordIds: [peopleMock[0].id, peopleMock[1].id],
},
contextStoreNumberOfSelectedRecords: 2,
contextStoreCurrentViewType: ContextStoreViewType.Table,
});
describe('useSetGlobalCommandMenuContext', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should reset all command menu context states', () => {
const { result } = renderHook(
() => {
const { setGlobalCommandMenuContext } =
useSetGlobalCommandMenuContext();
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
contextStoreTargetedRecordsRuleComponentState,
SIDE_PANEL_COMPONENT_INSTANCE_ID,
);
const contextStoreNumberOfSelectedRecords = useAtomComponentStateValue(
contextStoreNumberOfSelectedRecordsComponentState,
SIDE_PANEL_COMPONENT_INSTANCE_ID,
);
const contextStoreFilters = useAtomComponentStateValue(
contextStoreFiltersComponentState,
SIDE_PANEL_COMPONENT_INSTANCE_ID,
);
const contextStoreFilterGroups = useAtomComponentStateValue(
contextStoreFilterGroupsComponentState,
SIDE_PANEL_COMPONENT_INSTANCE_ID,
);
const contextStoreAnyFieldFilterValue = useAtomComponentStateValue(
contextStoreAnyFieldFilterValueComponentState,
SIDE_PANEL_COMPONENT_INSTANCE_ID,
);
const contextStoreCurrentViewType = useAtomComponentStateValue(
contextStoreCurrentViewTypeComponentState,
SIDE_PANEL_COMPONENT_INSTANCE_ID,
);
return {
setGlobalCommandMenuContext,
contextStoreTargetedRecordsRule,
contextStoreNumberOfSelectedRecords,
contextStoreFilters,
contextStoreFilterGroups,
contextStoreCurrentViewType,
contextStoreAnyFieldFilterValue,
};
},
{
wrapper,
},
);
expect(result.current.contextStoreTargetedRecordsRule).toEqual({
mode: 'selection',
selectedRecordIds: [peopleMock[0].id, peopleMock[1].id],
});
expect(result.current.contextStoreNumberOfSelectedRecords).toBe(2);
expect(result.current.contextStoreFilters).toEqual([]);
expect(result.current.contextStoreAnyFieldFilterValue).toEqual('');
expect(result.current.contextStoreCurrentViewType).toBe(
ContextStoreViewType.Table,
);
const sidePanelPageInfo = jotaiStore.get(sidePanelPageInfoState.atom);
expect(sidePanelPageInfo).toEqual({
title: undefined,
Icon: undefined,
instanceId: '',
});
const hasUserSelectedSidePanelListItem = jotaiStore.get(
hasUserSelectedSidePanelListItemState.atom,
);
expect(hasUserSelectedSidePanelListItem).toBe(false);
act(() => {
result.current.setGlobalCommandMenuContext();
});
expect(result.current.contextStoreTargetedRecordsRule).toEqual({
mode: 'selection',
selectedRecordIds: [],
});
expect(result.current.contextStoreNumberOfSelectedRecords).toBe(0);
expect(result.current.contextStoreFilters).toEqual([]);
expect(result.current.contextStoreAnyFieldFilterValue).toEqual('');
expect(result.current.contextStoreCurrentViewType).toBe(
ContextStoreViewType.Table,
);
const sidePanelPageInfoAfter = jotaiStore.get(sidePanelPageInfoState.atom);
expect(sidePanelPageInfoAfter).toEqual({
title: undefined,
Icon: undefined,
instanceId: '',
});
const hasUserSelectedSidePanelListItemAfter = jotaiStore.get(
hasUserSelectedSidePanelListItemState.atom,
);
expect(hasUserSelectedSidePanelListItemAfter).toBe(false);
});
it('should copy context store states to previous instance before resetting', () => {
const { result } = renderHook(
() => {
const { setGlobalCommandMenuContext } =
useSetGlobalCommandMenuContext();
// oxlint-disable-next-line twenty/matching-state-variable
const previousTargetedRecordsRule = useAtomComponentStateValue(
contextStoreTargetedRecordsRuleComponentState,
SIDE_PANEL_PREVIOUS_COMPONENT_INSTANCE_ID,
);
// oxlint-disable-next-line twenty/matching-state-variable
const previousNumberOfSelectedRecords = useAtomComponentStateValue(
contextStoreNumberOfSelectedRecordsComponentState,
SIDE_PANEL_PREVIOUS_COMPONENT_INSTANCE_ID,
);
return {
setGlobalCommandMenuContext,
previousTargetedRecordsRule,
previousNumberOfSelectedRecords,
};
},
{
wrapper,
},
);
act(() => {
result.current.setGlobalCommandMenuContext();
});
expect(result.current.previousTargetedRecordsRule).toEqual({
mode: 'selection',
selectedRecordIds: [peopleMock[0].id, peopleMock[1].id],
});
expect(result.current.previousNumberOfSelectedRecords).toBe(2);
});
});
@@ -1,7 +1,4 @@
import { useSetGlobalCommandMenuContext } from '@/command-menu/hooks/useSetGlobalCommandMenuContext';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu';
import { SIDE_PANEL_COMPONENT_INSTANCE_ID } from '@/side-panel/constants/SidePanelComponentInstanceId';
import { SIDE_PANEL_FOCUS_ID } from '@/side-panel/constants/SidePanelFocusId';
import { useOpenAskAIPageInSidePanel } from '@/side-panel/hooks/useOpenAskAIPageInSidePanel';
import { useOpenRecordsSearchPageInSidePanel } from '@/side-panel/hooks/useOpenRecordsSearchPageInSidePanel';
@@ -11,7 +8,6 @@ import { sidePanelPageState } from '@/side-panel/states/sidePanelPageState';
import { sidePanelSearchState } from '@/side-panel/states/sidePanelSearchState';
import { useGlobalHotkeys } from '@/ui/utilities/hotkey/hooks/useGlobalHotkeys';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { isNonEmptyString } from '@sniptt/guards';
@@ -29,8 +25,6 @@ export const useCommandMenuHotKeys = () => {
const { goBackFromSidePanel, goBackOneSubPageOrMainPage } =
useSidePanelHistory();
const { setGlobalCommandMenuContext } = useSetGlobalCommandMenuContext();
const sidePanelSearch = useAtomStateValue(sidePanelSearchState);
const { closeKeyboardShortcutMenu } = useKeyboardShortcutMenu();
@@ -39,11 +33,6 @@ export const useCommandMenuHotKeys = () => {
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const contextStoreTargetedRecordsRule = useAtomComponentStateValue(
contextStoreTargetedRecordsRuleComponentState,
SIDE_PANEL_COMPONENT_INSTANCE_ID,
);
useGlobalHotkeys({
keys: ['ctrl+k', 'meta+k'],
callback: () => {
@@ -99,27 +88,12 @@ export const useCommandMenuHotKeys = () => {
return;
}
if (
sidePanelPage === SidePanelPages.CommandMenuDisplay &&
!(
contextStoreTargetedRecordsRule.mode === 'selection' &&
contextStoreTargetedRecordsRule.selectedRecordIds.length === 0
)
) {
setGlobalCommandMenuContext();
}
if (sidePanelPage !== SidePanelPages.CommandMenuDisplay) {
goBackOneSubPageOrMainPage();
}
},
focusId: SIDE_PANEL_FOCUS_ID,
dependencies: [
sidePanelPage,
sidePanelSearch,
contextStoreTargetedRecordsRule,
goBackOneSubPageOrMainPage,
setGlobalCommandMenuContext,
],
dependencies: [sidePanelPage, sidePanelSearch, goBackOneSubPageOrMainPage],
options: {
preventDefault: false,
enableOnFormTags: false,
@@ -1,144 +0,0 @@
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { useCallback } from 'react';
import { useStore } from 'jotai';
export const useCopyContextStoreStates = () => {
const store = useStore();
const copyContextStoreStates = useCallback(
({
instanceIdToCopyFrom,
instanceIdToCopyTo,
}: {
instanceIdToCopyFrom: string;
instanceIdToCopyTo: string;
}) => {
const contextStoreCurrentObjectMetadataItemId = store.get(
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreCurrentObjectMetadataItemId,
);
const contextStoreTargetedRecordsRule = store.get(
contextStoreTargetedRecordsRuleComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreTargetedRecordsRuleComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreTargetedRecordsRule,
);
const contextStoreNumberOfSelectedRecords = store.get(
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreNumberOfSelectedRecords,
);
const contextStoreFilters = store.get(
contextStoreFiltersComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreFiltersComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreFilters,
);
const contextStoreFilterGroups = store.get(
contextStoreFilterGroupsComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreFilterGroupsComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreFilterGroups,
);
const contextStoreAnyFieldFilterValue = store.get(
contextStoreAnyFieldFilterValueComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreAnyFieldFilterValueComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreAnyFieldFilterValue,
);
const contextStoreCurrentViewId = store.get(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreCurrentViewId,
);
const contextStoreCurrentViewType = store.get(
contextStoreCurrentViewTypeComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreCurrentViewTypeComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreCurrentViewType,
);
const contextStoreIsFullTabWidgetInEditMode = store.get(
contextStoreIsPageInEditModeComponentState.atomFamily({
instanceId: instanceIdToCopyFrom,
}),
);
store.set(
contextStoreIsPageInEditModeComponentState.atomFamily({
instanceId: instanceIdToCopyTo,
}),
contextStoreIsFullTabWidgetInEditMode,
);
},
[store],
);
return { copyContextStoreStates };
};
@@ -1,71 +0,0 @@
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { useCallback } from 'react';
import { useStore } from 'jotai';
export const useResetContextStoreStates = () => {
const store = useStore();
const resetContextStoreStates = useCallback(
(instanceId: string) => {
store.set(
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
instanceId,
}),
undefined,
);
store.set(
contextStoreTargetedRecordsRuleComponentState.atomFamily({
instanceId,
}),
{
mode: 'selection',
selectedRecordIds: [],
},
);
store.set(
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
instanceId,
}),
0,
);
store.set(
contextStoreFiltersComponentState.atomFamily({
instanceId,
}),
[],
);
store.set(
contextStoreFilterGroupsComponentState.atomFamily({
instanceId,
}),
[],
);
store.set(
contextStoreAnyFieldFilterValueComponentState.atomFamily({
instanceId,
}),
'',
);
store.set(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId,
}),
undefined,
);
},
[store],
);
return { resetContextStoreStates };
};
@@ -1,182 +0,0 @@
import { SIDE_PANEL_COMPONENT_INSTANCE_ID } from '@/side-panel/constants/SidePanelComponentInstanceId';
import { SIDE_PANEL_PREVIOUS_COMPONENT_INSTANCE_ID } from '@/side-panel/constants/SidePanelPreviousComponentInstanceId';
import { sidePanelPageInfoState } from '@/side-panel/states/sidePanelPageInfoState';
import { hasUserSelectedSidePanelListItemState } from '@/side-panel/states/hasUserSelectedSidePanelListItemState';
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreIsPageInEditModeComponentState } from '@/context-store/states/contextStoreIsPageInEditModeComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ContextStoreViewType } from '@/context-store/types/ContextStoreViewType';
import { atom, useStore } from 'jotai';
import { useCallback } from 'react';
export const useSetGlobalCommandMenuContext = () => {
const store = useStore();
const setGlobalCommandMenuContext = useCallback(() => {
store.set(
atom(null, (get, batchSet) => {
const fromId = SIDE_PANEL_COMPONENT_INSTANCE_ID;
const toId = SIDE_PANEL_PREVIOUS_COMPONENT_INSTANCE_ID;
batchSet(
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreCurrentObjectMetadataItemIdComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreTargetedRecordsRuleComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreTargetedRecordsRuleComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreFiltersComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreFiltersComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreFilterGroupsComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreFilterGroupsComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreAnyFieldFilterValueComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreAnyFieldFilterValueComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreCurrentViewIdComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreCurrentViewTypeComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreCurrentViewTypeComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreIsPageInEditModeComponentState.atomFamily({
instanceId: toId,
}),
get(
contextStoreIsPageInEditModeComponentState.atomFamily({
instanceId: fromId,
}),
),
);
batchSet(
contextStoreTargetedRecordsRuleComponentState.atomFamily({
instanceId: fromId,
}),
{ mode: 'selection', selectedRecordIds: [] },
);
batchSet(
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
instanceId: fromId,
}),
0,
);
batchSet(
contextStoreFiltersComponentState.atomFamily({
instanceId: fromId,
}),
[],
);
batchSet(
contextStoreFilterGroupsComponentState.atomFamily({
instanceId: fromId,
}),
[],
);
batchSet(
contextStoreAnyFieldFilterValueComponentState.atomFamily({
instanceId: fromId,
}),
'',
);
batchSet(
contextStoreCurrentViewTypeComponentState.atomFamily({
instanceId: fromId,
}),
ContextStoreViewType.Table,
);
batchSet(sidePanelPageInfoState.atom, {
title: undefined,
Icon: undefined,
instanceId: '',
});
batchSet(hasUserSelectedSidePanelListItemState.atom, false);
}),
);
}, [store]);
return {
setGlobalCommandMenuContext,
};
};
@@ -14,6 +14,7 @@ export const PAGE_LAYOUT_TAB_FRAGMENT = gql`
...PageLayoutWidgetFragment
}
pageLayoutId
isActive
createdAt
updatedAt
}
@@ -79,7 +79,9 @@ export const splitViewWithRelated = (
const { viewFields: _viewFields, ...viewFieldGroupProperties } =
viewFieldGroup;
flatViewFieldGroups.push(viewFieldGroupProperties);
flatViewFieldGroups.push({
...viewFieldGroupProperties,
});
}
}
@@ -13,6 +13,7 @@ describe('filterAndSortNavigationMenuItems', () => {
namePlural: 'people',
labelPlural: 'People',
icon: 'IconUser',
isActive: true,
} as EnrichedObjectMetadataItem;
const mockView: Pick<View, 'id' | 'objectMetadataId' | 'key'> = {
@@ -223,6 +224,57 @@ describe('filterAndSortNavigationMenuItems', () => {
expect(result).toEqual([]);
});
it('should filter out items for deactivated objects', () => {
const inactiveObjectMetadataItem = {
...mockObjectMetadataItem,
id: 'inactive-metadata-id',
isActive: false,
} as EnrichedObjectMetadataItem;
const result = filterAndSortNavigationMenuItems(
[
{
id: 'obj-1',
type: NavigationMenuItemType.OBJECT,
targetObjectMetadataId: 'inactive-metadata-id',
position: 1,
} as NavigationMenuItem,
],
[],
[inactiveObjectMetadataItem],
);
expect(result).toEqual([]);
});
it('should filter out view items for deactivated objects', () => {
const inactiveObjectMetadataItem = {
...mockObjectMetadataItem,
id: 'inactive-metadata-id',
isActive: false,
} as EnrichedObjectMetadataItem;
const viewForInactiveObject: Pick<View, 'id' | 'objectMetadataId' | 'key'> =
{
id: 'view-for-inactive',
objectMetadataId: 'inactive-metadata-id',
key: ViewKey.INDEX,
};
const result = filterAndSortNavigationMenuItems(
[
{
id: 'view-item-1',
type: NavigationMenuItemType.VIEW,
viewId: 'view-for-inactive',
position: 1,
} as NavigationMenuItem,
],
[viewForInactiveObject],
[inactiveObjectMetadataItem],
);
expect(result).toEqual([]);
});
it('should keep folder items', () => {
const result = filterAndSortNavigationMenuItems(
[
@@ -7,8 +7,12 @@ import { type NavigationMenuItem } from '~/generated-metadata/graphql';
export const filterAndSortNavigationMenuItems = (
navigationMenuItems: NavigationMenuItem[],
views: Pick<View, 'id' | 'objectMetadataId' | 'key'>[],
objectMetadataItems: Pick<EnrichedObjectMetadataItem, 'id'>[],
objectMetadataItems: Pick<EnrichedObjectMetadataItem, 'id' | 'isActive'>[],
): NavigationMenuItem[] => {
const activeObjectMetadataItems = objectMetadataItems.filter(
(meta) => meta.isActive,
);
return navigationMenuItems
.filter((item) => {
if (item.type === NavigationMenuItemType.FOLDER) {
@@ -20,7 +24,7 @@ export const filterAndSortNavigationMenuItems = (
if (item.type === NavigationMenuItemType.OBJECT) {
return (
isDefined(item.targetObjectMetadataId) &&
objectMetadataItems.some(
activeObjectMetadataItems.some(
(meta) => meta.id === item.targetObjectMetadataId,
)
);
@@ -32,7 +36,9 @@ export const filterAndSortNavigationMenuItems = (
const view = views.find((view) => view.id === item.viewId);
return (
isDefined(view) &&
objectMetadataItems.some((meta) => meta.id === view.objectMetadataId)
activeObjectMetadataItems.some(
(meta) => meta.id === view.objectMetadataId,
)
);
}
if (item.type === NavigationMenuItemType.RECORD) {
@@ -40,7 +46,7 @@ export const filterAndSortNavigationMenuItems = (
isDefined(item.targetRecordId) &&
isDefined(item.targetObjectMetadataId) &&
isDefined(item.targetRecordIdentifier) &&
objectMetadataItems.some(
activeObjectMetadataItems.some(
(meta) => meta.id === item.targetObjectMetadataId,
)
);
@@ -1,15 +1,15 @@
import { isNonEmptyString } from '@sniptt/guards';
import { useLocation, useNavigate } from 'react-router-dom';
import { NavigationMenuItemType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { useIsMobile } from 'twenty-ui/utilities';
import { isNonEmptyString } from '@sniptt/guards';
import { type NavigationMenuItem } from '~/generated-metadata/graphql';
import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/common/states/openNavigationMenuItemFolderIdsState';
import { getNavigationMenuItemComputedLink } from '@/navigation-menu-item/display/utils/getNavigationMenuItemComputedLink';
import { isLocationMatchingNavigationMenuItem } from '@/navigation-menu-item/common/utils/isLocationMatchingNavigationMenuItem';
import { objectMetadataItemsSelector } from '@/object-metadata/states/objectMetadataItemsSelector';
import { currentNavigationMenuItemFolderIdState } from '@/navigation-menu-item/common/states/currentNavigationMenuItemFolderIdState';
import { openNavigationMenuItemFolderIdsState } from '@/navigation-menu-item/common/states/openNavigationMenuItemFolderIdsState';
import { isLocationMatchingNavigationMenuItem } from '@/navigation-menu-item/common/utils/isLocationMatchingNavigationMenuItem';
import { getNavigationMenuItemComputedLink } from '@/navigation-menu-item/display/utils/getNavigationMenuItemComputedLink';
import { objectMetadataItemsSelector } from '@/object-metadata/states/objectMetadataItemsSelector';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
@@ -38,7 +38,25 @@ export const useNavigationMenuItemFolderOpenState = ({
currentNavigationMenuItemFolderIdState,
);
const isOpen = openNavigationMenuItemFolderIds.includes(folderId);
const selectedNavigationMenuItemIndex = navigationMenuItems.findIndex(
(item) => {
const computedLink = getNavigationMenuItemComputedLink(
item,
objectMetadataItems,
views,
);
return isLocationMatchingNavigationMenuItem(
currentPath,
currentViewPath,
item.type,
computedLink,
);
},
);
const isExplicitlyOpen = openNavigationMenuItemFolderIds.includes(folderId);
const hasActiveChild = selectedNavigationMenuItemIndex >= 0;
const isOpen = isExplicitlyOpen || hasActiveChild;
const handleToggle = () => {
if (isMobile) {
@@ -47,7 +65,7 @@ export const useNavigationMenuItemFolderOpenState = ({
);
} else {
setOpenNavigationMenuItemFolderIds((current) =>
isOpen
current.includes(folderId)
? current.filter((id) => id !== folderId)
: [...current, folderId],
);
@@ -78,22 +96,6 @@ export const useNavigationMenuItemFolderOpenState = ({
}
};
const selectedNavigationMenuItemIndex = navigationMenuItems.findIndex(
(item) => {
const computedLink = getNavigationMenuItemComputedLink(
item,
objectMetadataItems,
views,
);
return isLocationMatchingNavigationMenuItem(
currentPath,
currentViewPath,
item.type,
computedLink,
);
},
);
return {
isOpen,
handleToggle,
@@ -48,6 +48,7 @@ export const RecordBoardCardCellHoveredPortalContent = () => {
fieldDefinition,
recordId,
prefix: RECORD_BOARD_CARD_INPUT_ID_PREFIX,
onFileUploadClose: () => setRecordBoardCardEditModePosition(null),
});
}
};
@@ -48,6 +48,7 @@ export const RecordCalendarCardCellHoveredPortalContent = () => {
fieldDefinition,
recordId,
prefix: RECORD_CALENDAR_CARD_INPUT_ID_PREFIX,
onFileUploadClose: () => setRecordCalendarCardEditModePosition(null),
});
}
};
@@ -52,6 +52,7 @@ export const RecordFieldListCellHoveredPortalContent = () => {
fieldDefinition,
recordId,
prefix: instanceId,
onFileUploadClose: () => setRecordFieldListCellEditModePosition(null),
});
}
};
@@ -46,10 +46,15 @@ const StyledAdvancedTextFieldInnerContainer = styled.div`
width: 100%;
`;
const StyledEditorActionButtonContainer = styled.div`
const StyledEditorActionButtonContainer = styled.div<{
hasVariablePicker?: boolean;
}>`
margin-top: ${themeCssVariables.spacing[1]};
position: absolute;
right: ${themeCssVariables.spacing[1]};
right: ${({ hasVariablePicker }) =>
hasVariablePicker
? `calc(${themeCssVariables.spacing[7]} + ${themeCssVariables.spacing[2]})`
: themeCssVariables.spacing[1]};
top: ${themeCssVariables.spacing[0]};
z-index: 1;
`;
@@ -214,7 +219,9 @@ export const FormAdvancedTextFieldInput = ({
)}
{enableFullScreen && (
<StyledEditorActionButtonContainer>
<StyledEditorActionButtonContainer
hasVariablePicker={isDefined(VariablePicker) && !readonly}
>
{!readonly && !isFullScreen && (
<LightIconButton
Icon={IconMaximize}
@@ -66,10 +66,12 @@ export const useOpenFieldInputEditMode = () => {
fieldDefinition,
recordId,
prefix,
onFileUploadClose,
}: {
fieldDefinition: FieldDefinition<FieldMetadata>;
recordId: string;
prefix?: string;
onFileUploadClose?: () => void;
}) => {
const objectMetadataItems = store.get(objectMetadataItemsSelector.atom);
@@ -106,6 +108,7 @@ export const useOpenFieldInputEditMode = () => {
updateOneRecordInput: updateInput,
});
},
onFileUploadClose,
fieldDefinition: {
metadata: {
settings: fieldDefinition.metadata.settings ?? undefined,

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