Compare commits

..
189 Commits
Author SHA1 Message Date
Charles BochetandGitHub f1c2ac33b3 Remove failing workflow when already started (#16301)
This is a temporary fix that needs to be revisited.

It seems that with the new enqueue system we are enqueuing jobs multiple
times due to race condition. We likely want to only consider job that
have been created more than x secs ago
2025-12-03 20:49:33 +01:00
Abhishek KumarandGitHub 6fe3d586cd fix(workflow): clicking on 'See runs' shows executions from all workflows (#16300)
Fixes: #16229 and #16286

This PR fixes the bug where click on 'See All Runs' button for a
specific workflow was not filtering the runs for that speciific
workflow.

**Reason** : The filter logic in `getFilterFilterableFieldMetadataItems`
was excluding ALL system fields(except field id) from being filterable,
which prevented these essential business relations from being used in
filters.

**Fix** : Added a targeted exception to allow specific system relation
fields (`workflow` and `workflowVersion`) to be filterable, similar to
how the `id` system field is already whitelisted.


### Before



https://github.com/user-attachments/assets/50b98626-ccdc-468a-96f9-0c911fec9a39

<img width="1511" height="587" alt="Screenshot 2025-12-03 at 11 52
50 PM"
src="https://github.com/user-attachments/assets/db6ea12b-8441-41c0-8a53-b9786b5c543a"
/>

### After



https://github.com/user-attachments/assets/856bbd61-4958-43de-8fa5-3f52ca9e7260



<img width="835" height="562" alt="Screenshot 2025-12-04 at 12 33 32 AM"
src="https://github.com/user-attachments/assets/bdcb43c7-d4ce-4932-8317-f0736d880784"
/>
2025-12-03 20:46:41 +01:00
WeikoandGitHub 3d95d6ca00 Add local only cache to cache service and cache typeorm entity metadata (#16287)
## Problem

buildEntityMetadatas in GlobalWorkspaceOrmManager is computationally
expensive and was running on every executeInWorkspaceContext call. This
method uses
TypeORM's EntitySchemaTransformer and EntityMetadataBuilder to build
metadata for all workspace entities (30-50+ objects with many fields
each).

The resulting EntityMetadata[] is not serialisable which means it cannot
be cached in Redis because they contain:
- Circular references
- Functions/methods
- References to the DataSource instance

## Solution

Extended the workspace cache system to support local-only caching, then
created a cache provider for entityMetadatas.

## Implementation details
Updated @WorkspaceCache decorator (workspace-cache.decorator.ts)
- Added localOnly?: boolean option to skip Redis storage for
non-serializable data
Created WorkspaceEntityMetadatasCacheService
- Computes entity metadatas from DB to avoid race condition, this is
acceptable
Simplified GlobalWorkspaceOrmManager
- Now fetches entityMetadatas from cache instead of rebuilding on every
call
Updated Workspace migration runner - the only entry point where metadata
can change
- Now invalidate the new 'entityMetadata' local cache when
shouldIncrementMetadataGraphqlSchemaVersion is true (== field/object
mutations)
2025-12-03 19:50:40 +01:00
9c334b5f03 fixed: Links in note preview not visible #16043 (#16267)
This PR fixes an issue where links added inside a note were not
appearing in the preview shown under Company -> Notes. The link would
only appear after opening the note, which led to inconsistent behavior.

Issue:
Blocknote represents text and links using different node types:
1. { "type": "text", "text": "Welcome to this demo!" }
2. {
  "type": "link",
  "content": { "type": "text", "text": "Example" },
  "href": "https://example.com"
}


The existing preview function only handled plain text nodes and
completely ignored link nodes.
As a result:
- Links did not appear in the preview
- Links appeared only inside the full note view


Steps to Reproduce:
- Add a link inside a note
- Go to Company / People and view the note preview -> the link is
missing
- Open the note -> the link appears correctly


How I fixed it:
- A new recursive text extraction function (extractText) was added to
correctly read.
- Text nodes
- Link nodes (including inner content and the href)
- Nested child content
- Link previews now appear in the following format:
DisplayText (https://example.com)



Edit : closes https://github.com/twentyhq/twenty/issues/16043

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2025-12-03 19:23:04 +01:00
Thomas des FrancsandGitHub 35319ee13f Clean changelog from bullet points (#16294)
Was ugly
2025-12-03 18:32:49 +01:00
Thomas des FrancsandGitHub 2e7dbe6b90 Update 1.12 changelog images (#16293)
(Better image quality for changelog)
2025-12-03 18:31:46 +01:00
nitinandGitHub 6c9abedc96 [Dashboards] new line area colors (#16272)
before - 


https://github.com/user-attachments/assets/a507809a-2a01-4aa6-940d-7d273e5fc8a7




after - 


https://github.com/user-attachments/assets/7c4d2a50-2ba6-4b91-b526-a87c609129c8
2025-12-03 15:51:44 +00:00
martmullandGitHub 267bfcadf8 Twenty sdk follow up (#16290)
as title
2025-12-03 15:50:16 +00:00
Paul RastoinandGitHub a829ae62e2 Remove IS_WORKSPACE_MIGRATION_V2_ENABLED feature flag (#16280)
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/1911
2025-12-03 15:47:08 +00:00
Abhishek KumarandGitHub c62bd396f7 fix(Workflow): Search bar to select object is not working as expected (#16255)
Fixes Issue: #16188

**Bug:** 
Object Selection Dropdown was not working correctly when searching by
object's name.
This was happening only when `Search Records` action is selected. 
Other actions(Create, Delete, Update, Upsert) were working
correclty(object search was working).

**Reason:** 
`Search Records` action uses `WorkflowObjectDropdownContent` component
which only filters based on `nameSingular` field in metadata (and doesnt
search based on lable text).
All other record action uses the `Select` component which filters by the
label property (set to `labelProperty`).

**Fix:** 
Updated the filtering logic of `WorkflowObjectDropdownContent` component
to match the search text with label field also.


I could't find any unit tests for the `WorkflowObjectDropdownContent`
component (or any other component in workflow module). Let me know if I
missed it and if tests need to be added for this.


**Screenshot of working object search in Search Record**
<img width="2056" height="1220" alt="image"
src="https://github.com/user-attachments/assets/678d9806-899a-470c-9e82-b9f975d65950"
/>
2025-12-03 16:19:56 +01:00
Paul RastoinandGitHub 3e75e39650 Upgrade command remove duplicated role target (#16281)
# Introduction
On production facing a migration error with
UpdateRoleTargetsUniqueConstraint1764329720503
```ts
Migration "UpdateRoleTargetsUniqueConstraint1764329720503" failed, error: could not create unique index "IDX_ROLE_TARGETS_UNIQUE_AGENT"
query: ROLLBACK
Error during migration run:
QueryFailedError: could not create unique index "IDX_ROLE_TARGETS_UNIQUE_AGENT"
    at PostgresQueryRunner.query (/Users/paulrastoin/ws/twenty/node_modules/typeorm/driver/postgres/PostgresQueryRunner.js:219:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async UpdateRoleTargetsUniqueConstraint1764329720503.up (/Users/paulrastoin/ws/twenty/packages/twenty-server/dist/database/typeorm/core/migrations/common/1764329720503-update-role-targets-unique-constraint.js:15:9)
    at async MigrationExecutor.executePendingMigrations (/Users/paulrastoin/ws/twenty/node_modules/typeorm/migration/MigrationExecutor.js:225:17)
    at async DataSource.runMigrations (/Users/paulrastoin/ws/twenty/node_modules/typeorm/data-source/DataSource.js:265:35)
    at async Object.handler (/Users/paulrastoin/ws/twenty/node_modules/typeorm/commands/MigrationRunCommand.js:68:13) {
  query: 'ALTER TABLE "core"."roleTargets" ADD CONSTRAINT "IDX_ROLE_TARGETS_UNIQUE_AGENT" UNIQUE ("workspaceId", "agentId")',
  parameters: undefined,
  driverError: error: could not create unique index "IDX_ROLE_TARGETS_UNIQUE_AGENT"
      at /Users/paulrastoin/ws/twenty/node_modules/pg/lib/client.js:526:17
      at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
      at async PostgresQueryRunner.query (/Users/paulrastoin/ws/twenty/node_modules/typeorm/driver/postgres/PostgresQueryRunner.js:184:25)
      at async UpdateRoleTargetsUniqueConstraint1764329720503.up (/Users/paulrastoin/ws/twenty/packages/twenty-server/dist/database/typeorm/core/migrations/common/1764329720503-update-role-targets-unique-constraint.js:15:9)
      at async MigrationExecutor.executePendingMigrations (/Users/paulrastoin/ws/twenty/node_modules/typeorm/migration/MigrationExecutor.js:225:17)
      at async DataSource.runMigrations (/Users/paulrastoin/ws/twenty/node_modules/typeorm/data-source/DataSource.js:265:35)
      at async Object.handler (/Users/paulrastoin/ws/twenty/node_modules/typeorm/commands/MigrationRunCommand.js:68:13) {
    length: 314,
    severity: 'ERROR',
    code: '23505',
```

As several agent has duplicated role target in database
```sql
SELECT constraint_name, COUNT(*) AS duplicate_groups, SUM(duplicate_count - 1) AS rows_to_delete
FROM (
    SELECT 'IDX_ROLE_TARGET_UNIQUE_API_KEY' AS constraint_name, COUNT(*) AS duplicate_count
    FROM "core"."roleTargets" rt
    WHERE rt."apiKeyId" IS NOT NULL
    GROUP BY rt."workspaceId", rt."apiKeyId"
    HAVING COUNT(*) > 1
    
    UNION ALL
    
    SELECT 'IDX_ROLE_TARGET_UNIQUE_AGENT', COUNT(*)
    FROM "core"."roleTargets" rt
    WHERE rt."agentId" IS NOT NULL
    GROUP BY rt."workspaceId", rt."agentId"
    HAVING COUNT(*) > 1
    
    UNION ALL
    
    SELECT 'IDX_ROLE_TARGET_UNIQUE_USER_WORKSPACE', COUNT(*)
    FROM "core"."roleTargets" rt
    WHERE rt."userWorkspaceId" IS NOT NULL
    GROUP BY rt."workspaceId", rt."userWorkspaceId"
    HAVING COUNT(*) > 1
) AS all_duplicates
GROUP BY constraint_name;
```

with constraint name, duplicated_groups, row_to_delete
`IDX_ROLE_TARGET_UNIQUE_AGENT	 2507	7229`

Please note that only active or suspended workspaces contains duplicated
role target

## Fix
Introduced an upgrade command that will only keep the latest inserted
role target
Swallowing migration error on typeorm atomic migration ( still required
for self host new instances etc )

```ts
[Nest] 91886  - 12/03/2025, 2:56:28 PM     LOG [DeduplicateRoleTargetsCommand] Running command on workspace SOME_WORKSPACE_ID 2587/2587
flatFieldMetadataMaps,flatIndexMaps,flatObjectMetadataMaps out of 298
query: SELECT version();
[Nest] 91886  - 12/03/2025, 2:56:29 PM     LOG [DeduplicateRoleTargetsCommand] Command completed!
```

## Test
Tested through an extract in local, tested both the upgrade command and
the swallowed migration
test
2025-12-03 16:17:46 +01:00
Félix MalfaitandGitHub 578aa9d5ca Fix view disappearing when switching from WORKSPACE to UNLISTED visibility (#16289)
## Description

When switching a view's visibility from WORKSPACE to UNLISTED, the code
in `view-v2.service.ts` correctly sets `createdByUserWorkspaceId` to the
current user (to prevent the view from disappearing). However, this
property was not included in `FLAT_VIEW_EDITABLE_PROPERTIES`, which
meant:

1. The comparison logic didn't detect the change
2. No update action was created for the property  
3. The value was never persisted to the database
4. The view disappeared because it became UNLISTED with no owner

This fix adds `createdByUserWorkspaceId` to the editable properties so
the change is properly detected and persisted.

Might fix https://github.com/twentyhq/twenty/issues/15955
2025-12-03 15:56:31 +01:00
735855d7b1 i18n - docs translations (#16288)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-03 15:21:13 +01:00
martmullandGitHub ea79425fc0 Fix twenty sdk and create twenty app (#16282)
As title
2025-12-03 15:12:34 +01:00
e79046618b i18n - translations (#16283)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-03 14:42:21 +01:00
Thomas TrompetteandGitHub 21a433dd93 Upsert based on ID field (#16275)
<img width="225" height="187" alt="Capture d’écran 2025-12-03 à 11 49
39"
src="https://github.com/user-attachments/assets/042daa56-71d1-4f6c-811b-c626adde4ceb"
/>


- Split CreateRecordBody in two, there are too many differences with
CreateRecord
- Add ID field to the upsert multiselect
- Provide the Record id field in upsert action so the user can edit

Fixes https://github.com/twentyhq/twenty/issues/15929
2025-12-03 12:54:37 +00:00
9b0e8d3232 i18n - docs translations (#16279)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-03 13:23:13 +01:00
2378a91d8f i18n - translations (#16278)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-03 12:33:22 +01:00
59672e3e34 Migrate agent v2 (#16214)
# Introduction
Closes https://github.com/twentyhq/core-team-issues/issues/1980

In this PR we migrate the agent from v1 to v2.

## New FlatRoleTargetByAgentIdMaps
Derivated the `flatRoleTargetMaps` to be building a
`flatRoleTargetByAgentIdMaps` to ease retrieving a roleId to associate
to an agent

## Coverage
Added strong coverage on both failing and successful CRU agents
operations

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-12-03 11:51:19 +01:00
Paul RastoinandGitHub a7c5969ede [create-twenty-app] Use vite config lib (#16273) 2025-12-03 10:47:37 +00:00
a892462c05 fix(#15950): mobile favorites folder navigation with proper back button (#16118)
## What’s done
- Clicking a favorite folder on mobile now opens a clean drill-down
layer with only its contents
- Added a back button (icon + folder name) — visually 100% identical to
`NavigationDrawerBackButton`
- Sidebar no longer collapses when opening a folder
- Tree line is removed on mobile (consistent with current Twenty design)

## Intentional deviations from the mockup
1. **Back button does not replace `MultiWorkspaceDropdownButton`**  
Kept `NavigationDrawerHeader` untouched — it’s responsible for the
hamburger menu and workspace name.
   Added the back button as a separate block below.  
→ This feels cleaner architecturally and avoids breaking other places
that use `NavigationDrawerHeader`.

2. **Vertical spacing between items is slightly tighter than in the
mockup**
Used `NavigationDrawerSubItem` — the standard component for nested items
in Twenty.
Current production spacing matches this exactly, so I preferred
consistency over pixel-perfect mockup matching.

Happy to adjust either point if the team prefers to follow the mockup
1:1.

Closes #15950

---------

Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
2025-12-03 11:08:52 +01:00
Félix MalfaitandGitHub e18262cfa6 Change cookie storage duration (#16271)
Set it to 180 days like Notion does.

Currently **Access Token Expires In** is set to 90 days but this setting
is ignored because the cookie is cleared after 7 days
2025-12-03 10:04:35 +01:00
Thomas TrompetteGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
a0f196e871 Improve workflow throttling logic (#16260)
- if >5000 workflows per hour, new ones should failed
- if >100 workflow per min, new ones should be set as not started.
Except manual trigger
- when enqueued, we check if there a not started workflows that may be
queued. If yes, we call the associated job

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-12-03 09:01:36 +00:00
288db78abd i18n - docs translations (#16269)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-03 07:22:22 +01:00
Abdul RahmanandGitHub f248b3f7f4 refactor: move agent evaluation to background jobs for non-blocking execution (#16234) 2025-12-03 05:55:47 +01:00
Lucas BordeauandGitHub 05b30554c3 Add back first column shrink on mobile (#16244)
This PR fixes https://github.com/twentyhq/twenty/issues/14829

I created two states because one was needed for the table and the other
for the ChipFieldDisplay, which can appear anywhere.

The states tell if the first column and the ChipFieldDisplay should be
shrinked.

I also removed the usage of `useRecordTableLastColumnWidthToFill` to
avoid unnecessary re-renders of the whole table on scroll.

## Before


https://github.com/user-attachments/assets/8b6886b3-8976-41c2-9937-5d7ea396ec56

## After


https://github.com/user-attachments/assets/dc3b5ff9-59c4-4954-a973-57f6edc2508e
2025-12-02 17:51:06 +00:00
3274c18a90 Fix command menu focus (#16264)
CommandMenu did not push its own focus item to the focus stack when
focused. (See NavigationDrawerInput)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-12-02 18:19:07 +01:00
Raphaël BosiandGitHub 900401c101 16248 follow ups (#16262)
Follow ups on https://github.com/twentyhq/twenty/pull/16248
2025-12-02 17:33:39 +01:00
5edb5e2d53 i18n - docs translations (#16263)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-02 17:22:08 +01:00
Lucas BordeauandGitHub 21c023c6d6 Fixed create new optimistic (#16257)
This PR fixes create new optimistic on boards, which was broken due to a
recent refactor of the query system for boards in : #16063
2025-12-02 16:37:53 +01:00
Lucas BordeauandGitHub bf818b7d8d Fixed sample CSV file generation (#16261)
This PR fixes a bug that created a deletedAt column in sample CSV file
generated for import, that when used afterwards for import, would create
soft deleted records, which gives the impression that the CSV import
does not work.
2025-12-02 16:32:51 +01:00
77409b6eb2 [Requires "warm" cache flush (no immediate downtime before flush)] Migrate viewGroup.fieldMetadataId -> view.mainGroupByFieldMetadataId (1/3) (#16206)
In this PR (1/3)
- introduce view.mainGroupByFieldMetadataId as the new reference
determining which fieldMetadataId is used in a grouped view, in order to
deprecate viewGroup.fieldMetadataId which creates inconsistencies.
view.mainGroupByFieldMetadataId is now filled at every view creation,
though not in use yet.
- Introduce a command to backfill view.mainGroupByFieldMetadataId for
existing views + delete all viewGroup.fieldMetadataId with a
fieldMetadataId that is not view.mainGroupByFieldMetadataId. (It should
concern 37 active workspaces)
- Temporarily disable the option to change a grouped view's
fieldMetadataId as for now it creates inconsistencies. This feature can
be reintroduced when we have done the full migration.

In a next PR
- (2/3) use view.mainGroupByFieldMetadataId instead of
viewGroup.fieldMetadataId. In FE we may keep viewGroup.fieldMetadataId
as a state (TBD). View groups will now be created / deleted as a side
effect of view's mainGroupByFieldMetadataId update.
- (3/3) remove viewGroup.fieldMetadataId

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-12-02 16:31:07 +01:00
aa729a2a0a i18n - translations (#16259)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-02 16:01:10 +01:00
nitinandGitHub 0158c6fb3c fix incorrect date formatting being applied to non-date fields in graph widgets (#16254)
before - 


https://github.com/user-attachments/assets/d8d7dee3-ce09-4a04-8054-41bb302c69f4




after - 



https://github.com/user-attachments/assets/2d563c51-6700-4b71-8997-de5e87f1df68
2025-12-02 15:26:41 +01:00
Abdullah.andGitHub eecc7aaed3 Workspace member permission tab. (#16233)
Introduce a read-only view of permissions similar to agent roles tab.
The role selector in the following image feels as if it would lead to a
new page, which is not what we want.

<img width="1281" height="813" alt="Permissions (If easier V1)"
src="https://github.com/user-attachments/assets/7b272f5a-40ef-43ad-83d8-f9e588b1cd6e"
/>

Therefore, I added a Select component for now and would love some
clarity on what's ideal.

<img width="554" height="651" alt="image"
src="https://github.com/user-attachments/assets/91575208-66b1-4ed1-86cd-f3aa528ad0dc"
/>

Also, the "Add Rule" button changes to enabled when we switch the role
from `Admin` to `Member` and clicking it redirects to
`/settings/roles/:role-id/add-object-permission`. Do we want to disable
the button completely?

One final thing: SettingsAgentRoleTab already re-uses
SettingsRolePermissions. I created MemberPermissionsTab to do the same.
I don't think we need an abstracted shared component here since both
tabs rely on the same shared child anyway. However, if we need a
refactor, I can use some direction on how the code should look.

Creating this PR as draft since I think there might be a couple
suggested changes on this.
2025-12-02 15:21:17 +01:00
12babba6f6 i18n - translations (#16256)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-02 15:20:01 +01:00
WeikoandGitHub 13e283fc3a Rename roleTargets -> roleTarget (#16247) 2025-12-02 14:39:54 +01:00
9cfcc114de i18n - translations (#16252)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-02 14:39:16 +01:00
Raphaël BosiandGitHub 1038efa3dd [DASHBOARDS] Add cumulative setting for bar chart and line chart (#16248)
## Description

- Add cumulative setting
- This setting is only present for dates
- It is preserved when switching from a date field to another date field
but it is reset when switching to another field type

## Video QA


https://github.com/user-attachments/assets/a070bf54-8ef6-4e35-9378-a514fe1c3848


https://github.com/user-attachments/assets/07edfe87-253c-45a5-b582-06f2df9a2dfc
2025-12-02 14:00:58 +01:00
EtienneandGitHub 00e970bdf4 Null - Second command - Cleaning remaining empty values (#16241)
Because of [this code I forget to
clean](https://github.com/twentyhq/twenty/pull/16217),
- __workspace created between 1.12.0 and 1.12.2 (from friday 28 nov PM >
monday 1 dec PM)__ have standard objects with empty string default value
set on related TEXT type column (but default value null on field
metadata) (ex: jobTitle on person)
- __custom objects created between 1.12.0 and 1.12.2 (from friday 28 nov
PM > monday 1 dec PM)__ have "name" TEXT field with empty string default
value set + NOT NULL constraint on column

Command cleans data and updates table structure
2025-12-02 13:39:39 +01:00
f880ab086c i18n - docs translations (#16251)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-02 13:23:17 +01:00
WeikoandGitHub 4ed8c8ed32 Fix SDK/CreateApp CI changed-files-check (#16249) 2025-12-02 13:11:23 +01:00
martmullandGitHub 6ea817dd6c Add base application project yarn release file (#16238)
As title
2025-12-02 13:10:50 +01:00
5d4170d4c3 i18n - translations (#16250)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-02 12:46:24 +01:00
Paul RastoinandGitHub eedb163131 Field metadata and object metadata v1 relicas (#16230)
# Introduction

Related https://github.com/twentyhq/core-team-issues/issues/1911

Nearly done with all functional v1 implemen removal
Will remain dead code methods that I will detect using knip
2025-12-02 12:06:28 +01:00
Thomas des FrancsandGitHub 59f0f6f9db Release 1.12.0 (#16246)
## Release 1.12.0

This release includes:

- Revamped Side Panel - Now opens next to content instead of above it
- Granular Email Folder Sync - Choose which Gmail labels or Outlook
folders to sync

Changelog file:
`packages/twenty-website/src/content/releases/1.12.0.mdx`
Release date: 2025-12-02
2025-12-02 11:55:25 +01:00
Carson YangandGitHub 2922a1ee5a Add community Sealos template in self-hosted cloud provider docs (#16235)
Added deployment instructions for Twenty on Sealos.
2025-12-02 11:46:05 +01:00
Raphaël BosiandGitHub 269135e8c5 Add allow same origin to the iFrame widget (#16239)
Some iFrames were unusable because of this
2025-12-02 11:36:47 +01:00
martmullandGitHub 5abab1feb2 Fix yarn lock (#16242) 2025-12-02 11:35:19 +01:00
Lucas BordeauandGitHub 2691222d5f Improve board experience 🖼️ (#16063)
This PR improves the general UX and DX of boards, by modifying the query
effect to only use paged group by queries.

In this PR we implement two more things in the backend for group by
queries :
- Fixed ORDER BY in the PARTITION BY sub-query (this wasn't working
because it was applied in the main query, so it sorted randomly picked
records, which was a correct sort on an incorrect dataset returned by
the sub-query)
- Added offset paging in PARTITION BY

Miscellaneous, various bug fixes and improvements along the way : 
- Throttled loading of cards to avoid React freeze
- Handling of drag & drop
- Handling of create / delete / update
- Reworked skeleton (the library slows down a lot with hundreds of
skeleton for a spinning effect that is hardly noticed)
- Fixed refetch of aggregate queries (I included the new group by
aggregates query we use in the existing refetch mechanism)
- Re-trigger queries on filters and sorts changes
- Unselect all record ids when deleting / restoring / detroying
- Fetch only groups that still have records to lighten the group by
query.

# What remains to be done 

This is still a naïve fetch more implementation that will work for a few
fetch more rounds, but if you scroll and load say 200 cards per column
on a board, React will re-render all 200 cards of each column each time.

We would probably need to virtualize the board with paged queries as we
did for the table, this could be done after this PR but seems less
urgent.

What's nice is that this new query pattern is well designed for
virtualization also, drawing from our experience with table
virtualization, and adapted to a multi-column request pattern, like a
2:2 matrix of records, for our boards.

So the remaining work would be to design a UI solution for virtualizing
this matrix of records, which could be quite different from our table
virtualization mechanism.
2025-12-02 10:09:29 +00:00
EtienneandGitHub 68c429a54a Null equivalence - remove feature flag (#16222) 2025-12-01 19:06:24 +01:00
da7536124e i18n - translations (#16227)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-01 19:01:09 +01:00
670d6ce3ec i18n - translations (#16223)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-01 18:21:13 +01:00
Ansh GroverandGitHub 2cdf5ae75b fix(theme): prevent forced light mode switch after login (#16221)
### Description

This pull request resolves an issue where the application switched to
light mode after login even when the user’s system was set to dark mode.
Before authentication the app correctly followed system preferences
through CSS media queries, but that behavior broke once the user logged
in.



**Before**


https://github.com/user-attachments/assets/75e73712-9cb2-42f9-9e25-3a22dc911b8d




**After**



https://github.com/user-attachments/assets/6bba45ce-3817-4e3d-9b45-ff0c7725cf82
2025-12-01 17:58:36 +01:00
nitinandGitHub a8e7d4dfc3 unlock relation date fields on dashboards (#16207) 2025-12-01 17:48:52 +01:00
Raphaël BosiandGitHub 32f387a966 [DASHBOARDS] Add prefix and suffix setting to the aggregate chart (#16216)
https://github.com/user-attachments/assets/0103cebe-e426-42d0-a8e4-b82494ef8503
2025-12-01 17:45:25 +01:00
c51a4a188d i18n - translations (#16220)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-01 17:40:20 +01:00
nitinandGitHub d39a7e809b [Dashboards] - fast follows - inverse default value for centre metric and filter count on chart settings (#16211) 2025-12-01 21:49:57 +05:30
EtienneandGitHub 5e00893c37 Null equivalence - Empty string default value cleaning (#16217)
- on name standard field on custom object (field metadata + db)
- on text standard fields on standard object (db only)
2025-12-01 17:10:45 +01:00
WeikoandGitHub 1eb2e44058 Refactor workspace cache service (#16208)
## Context
We've recently introduced a new workspace cache service which now acts
as a cache access and local storage for all workspace related data,
deprecating the individual specific services.
- Better performance through multiple caching/fetching strategies
- Consistent data access patterns across the codebase
- Reduced redis queries through MGET/MSET/PIPELINE with multiple cache
keys
2025-12-01 17:08:21 +01:00
4e0545ebc5 i18n - translations (#16218)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-01 16:46:21 +01:00
Ansh GroverandGitHub 425a3814e9 feat: Add prominent "Download sample" button to CSV import upload step (#16193)
## Description
Improves discoverability of the "Download sample" feature in the CSV
import flow by replacing the text link with a prominent button,
addressing customer feedback that the option was hard to find.

Closes #16028


## Screenshots

### Before

<img width="2504" height="1716" alt="image"
src="https://github.com/user-attachments/assets/7b134634-45e6-4e10-9c49-810b529d6fb0"
/>



### After

<img width="2504" height="1716" alt="image"
src="https://github.com/user-attachments/assets/b0d7b28e-7a3b-4895-81b4-b04297d6ef64"
/>
2025-12-01 16:31:02 +01:00
79e2602790 Remove IS_MESSAGE_FOLDER_CONTROL_ENABLED feature flag (#16183)
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-12-01 16:29:09 +01:00
spiderman3000andGitHub af23fddfa2 Move to record page for mobile view (#16195)
Summary

- Move record open behavior to record page for mobile view.


https://github.com/user-attachments/assets/cbf87ec7-8232-4d15-b767-b38097593a5a


Closes #15960
2025-12-01 16:09:29 +01:00
ee08060798 Improve deactivated objects & fields behaviors. (#16090)
Closes [1918](https://github.com/twentyhq/core-team-issues/issues/1918).

- For the first point in the issue, we just show the deactivated entries
along with the deactivated text.

---

- For the second point, we show a banner and control the
enabled/disabled state of save button depending on whether we're
allowing the user to create table with the typed name.
- For example, we do not want to allow the user to create a table with
reserved name, so we disable the save button without showing a banner.
- Similarly, we do not want the user to create a table with a name that
already exists in the database. In this case, we show a banner and we
also disable the save button.
- Finally, we do not want to allow the user to create a table where
singular and plural name are the same. Therefore, we disable the save
button for names like `works`.

---

- For the third point, if we add the delete button, it logically means
that we allow the user to delete a custom object/field even it has not
been deactivated yet, so did that.
- Upon deleting the object/field, if we wait for the metadata to refetch
before we navigate, this is what we see because the path does not exist
any longer after deletion and we're waiting for refetch on the path
until we navigate away.


https://github.com/user-attachments/assets/dbe0569c-db88-4285-851f-22551b1ca81e

- To avoid this page from appearing, I replaced awaiting refetch to not
awaiting refetch and redirecting while the refetch happens in the
background.
- Therefore, when we delete something, there is a slight delay for when
it is actually cleared out from the list, but the Not Found view does
not appear on the screen.


https://github.com/user-attachments/assets/47f49579-ce51-4d6a-b857-72046247bb4b

- I tried optimistically removing the object/field from the metadata,
but it leads to some issues (crashes the app) and I have not been able
to find a solution for it yet.
- Therefore, instead of getting stuck at perfection and blocking myself,
I stopped getting into the issue further and created this PR by ensuring
that the desired functionality works.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Display deactivated objects/fields by default, add delete actions with
confirmation, and unify metadata name computation (auto-suffix reserved
keywords) across front/back with conflict checks in object creation.
> 
> - **Frontend (Settings/Data Model)**:
> - **Visibility/UX**: Show `Deactivated` labels for objects/fields;
filters default to include inactive (`showDeactivated`/`showInactive`
true); replace field action dropdown with chevron link.
> - **Delete flows**: Add delete buttons for custom objects/fields with
confirmation modals and background refetch to avoid Not Found flashes.
> - **Creation/Edit validation**: Add name conflict detection banner in
`SettingsDataModelObjectAboutForm` and disable Save on conflicts;
simplify `metadataLabelSchema` to use computed name; form fields
validate on change and sync API names.
> - **Shared (twenty-shared/metadata)**:
> - Add `computeMetadataNameFromLabel` util (slugify+camelCase) and
`RESERVED_METADATA_NAME_KEYWORDS`; auto-append `Custom` to reserved
names; export constants/utilities.
> - **Backend**:
> - Migrate to shared `computeMetadataNameFromLabel`; update validators
to use shared reserved keywords with new messages; allow deletion of
active custom fields/objects (keep standard guards); adjust
services/decorators accordingly.
> - **Tests/Stories**:
> - Update unit/integration snapshots for new reserved-name messages and
behaviors; add missing i18n/router decorators in stories.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5b12615560. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-12-01 15:04:36 +00:00
1fcb8b464c fix: move vite plugins into the packages that use them (#16134)
I was looking into [Dependabot Alert
107](https://github.com/twentyhq/twenty/security/dependabot/107) and
figured that the alert is caused by `vite-plugin-dts`, which is a
development dependency and does not make it into the production build
for it to be dangerous.

However, while at it, I also saw that some packages used plugins from
root package.json while others had them defined in their local
package.json. Therefore, I refactored to move plugins where they're
required and removed a redundant package.

Builds for the following succeed as intended:
- twenty-ui
- twenty-emails
- twenty-website
- twenty-front

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-12-01 14:44:19 +00:00
EtienneandGitHub 638d4015a1 Null equivalence - Activate FF for all (#16209) 2025-12-01 15:43:28 +01:00
19fc20173b fix: lagging issue in ask AI during message streaming (#16201)
## Changes

### 1. Fixed streaming lag with throttle parameter

**Problem:** The AI chat was experiencing lag during message streaming
because the messages array was being updated too frequently, causing all
messages to re-render too quickly.

**Solution:** Added the `experimental_throttle: 100` parameter to the
`useChat` hook configuration. This throttles message updates during
streaming to prevent excessive re-renders and improve performance.

### 2. Cleaned up useAgentChat hook return values

**Context:** The `useAgentChat` hook primarily returns values from the
underlying `useChat` hook, so there wasn't significant room for
improvement regarding the "umbrella hook" pattern. However, some
unnecessary values were being returned that weren't needed.

**Solution:**
- Removed `input` and `handleInputChange` from the `useAgentChat` hook
return. These weren't needed since input state is already managed
directly via Recoil state (`agentChatInputState`) in components.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Throttle message streaming updates and switch AI chat input management
from context to Recoil; minor scroll behavior tweak.
> 
> - **AI Chat performance**:
> - Add `experimental_throttle: 100` to `useChat` in `useAgentChat` to
reduce re-render frequency during streaming.
> - **State management**:
> - Migrate input handling to Recoil via `agentChatInputState`; remove
`input` and `handleInputChange` from `AgentChatContext` and
`useAgentChat` returns.
> - Update `AIChatTab` and `SendMessageButton` to read/write input from
Recoil and adjust hotkeys/disabled state accordingly.
> - **UX behavior**:
>   - Remove smooth scroll behavior in `useAgentChatScrollToBottom`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
911b341ea1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-12-01 15:31:20 +01:00
b5ec6df62f Improve command menu animation (#16197)
https://github.com/user-attachments/assets/c9ff288d-0e68-4877-af6b-8685a6bbeeaf


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Removes legacy layout and refactors `CommandMenuPageLayout` to use
width-based animation with shared constants and close-animation cleanup.
> 
> - **UI/Command Menu**:
>   - **Refactor `CommandMenuPageLayout`**:
> - Switch to width/margin animation on `StyledSidePanelWrapper`; remove
side panel `x` translate animation.
>     - Use shared `COMMAND_MENU_SIDE_PANEL_WIDTH` constant.
> - Add close-state handling via `isCommandMenuClosingState` and
`useCommandMenuCloseAnimationCompleteCleanup` on animation completion.
> - Simplify props: remove `isSidePanelOpen`; rely on
`isCommandMenuOpenedState` and internal `shouldRenderContent`.
>   - **Cleanup**:
>     - Remove obsolete `CommandMenuLayout.tsx`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d6cb01114c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-12-01 15:27:29 +01:00
martmullandGitHub f489bbdbab Fix main (#16215)
fix yarn.lock not up to date
2025-12-01 14:37:05 +01:00
martmullandGitHub e498367e2f Merge twenty-cli into twenty-sdk (#16150)
- Moves twenty-cli content into twenty-sdk
- add a new twenty-sdk:0.1.0 version
- this new twenty-sdk exports a cli command called 'twenty' (like
twenty-cli before)
- deprecates twenty-cli
- simplify app init command base-project
- use `twenty-sdk:0.1.0` in base project
- move the "twenty-sdk/application" barrel to "twenty-sdk"
- add `create-twenty-app` package

<img width="1512" height="919" alt="image"
src="https://github.com/user-attachments/assets/007bef45-4e71-419a-9213-cebed376adbf"
/>

<img width="1506" height="929" alt="image"
src="https://github.com/user-attachments/assets/3de2fec6-1624-4923-ae13-f4e1cf165eb5"
/>
2025-12-01 11:44:35 +01:00
3f08a0c901 i18n - translations (#16192)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-28 19:21:54 +01:00
dedb191cae i18n - translations (#16190)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-28 18:45:42 +01:00
EtienneandGitHub 63afed6400 Security - add throttle in message resend (#16070)
closes https://github.com/twentyhq/private-issues/issues/356
2025-11-28 17:33:05 +00:00
Paul RastoinandGitHub 9f62188ba6 Field and object metadata naming does not refer to v2 (#16187)
Related https://github.com/twentyhq/core-team-issues/issues/1911
2025-11-28 18:06:44 +01:00
ea3c5d2d45 Migrate role and role target to v2 (#16009)
# Introduction
close https://github.com/twentyhq/core-team-issues/issues/1930
close https://github.com/twentyhq/core-team-issues/issues/1929
Migrating role and roleTarget entities to the v2 core engine, allowing
v2 caching leverage and allow migrating agent to v2 that needs role
target in prior
After agent we should be able to pass twenty standard app totally though
workspace migration

## Role target assignation
Please note that role target have 3 creation entrypoints:
- Agent
- User workspace
- ApiKey

Refactored all 3 of them to pass through a new role-target.service.ts
that consumes the v2 under the hood.

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-11-28 17:06:11 +00:00
Thomas des FrancsandGitHub 23a7611aac revert to align center as we add an issue on edit mode. Fixed the inp… (#16179)
# Current Behavior

<img width="441" height="81" alt="image"
src="https://github.com/user-attachments/assets/cc3301b1-c92a-44c3-b452-49264ff5d323"
/>

Revert behavior to align center
fixed input size (24px)

<img width="670" height="202" alt="CleanShot 2025-11-28 at 16 05 30@2x"
src="https://github.com/user-attachments/assets/5c7ca79f-53d7-45c1-a2a6-7c3b1b78524c"
/>
2025-11-28 18:01:06 +01:00
EtienneandGitHub cd699cbda1 Fix message sync (#16186)
Follow up
https://twenty-v7.sentry.io/issues/7072565676/events/2068bcd0b5b642dca1215b015ac74cfd/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=previous-event&sort=date
and
https://github.com/twentyhq/twenty/pull/16144/files#diff-3adef01a601936cd060128fd08874cf5938d477bfde39f306aa5070a068e07aa
2025-11-28 17:49:57 +01:00
Raphaël BosiandGitHub 4d7965c058 Augment chart limits and improve padding on bar chart (#16184)
- Maximum from 50 to 100
- Reduce padding
- Make inner padding dynamic
2025-11-28 17:40:44 +01:00
neo773andGitHub f2cdf8a6e1 message folder ui enhancement (#16181) 2025-11-28 17:25:21 +01:00
df20c52293 i18n - docs translations (#16185)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-28 17:21:43 +01:00
Paul RastoinandGitHub 5016c25daa Remove viewGroup v1 implem (#16178)
# Introduction
Removing v1 implementation of view groups and both view group and view
field relicas front fetchers

Related https://github.com/twentyhq/core-team-issues/issues/1911
2025-11-28 16:36:28 +01:00
Thomas des FrancsandGitHub 7bf68e5f31 fixed the horizontal padding on Navbar (#16088)
Was 12px. Changed it to 8px to match Figma

<img width="550" height="301" alt="CleanShot 2025-11-26 at 12 05 10"
src="https://github.com/user-attachments/assets/edec07bd-74ee-4dd7-b433-20a5bb636e6b"
/>
2025-11-28 15:12:02 +01:00
Charles BochetandGitHub 9387680020 Rollback standard id removal on relation object creation (#16177) 2025-11-28 15:11:45 +01:00
Ansh GroverandGitHub 7620e1b0a6 Fix markdown link formatting in CONTRIBUTING.md (#16176)
CC: @FelixMalfait 

Before: 
<img width="1293" height="170" alt="image"
src="https://github.com/user-attachments/assets/dc02afea-2781-4a5b-885a-2617709d9e36"
/>

After: 
<img width="1293" height="170" alt="image"
src="https://github.com/user-attachments/assets/acbc5c0b-bb96-4cd7-8c02-892cc4745f70"
/>
2025-11-28 13:53:45 +01:00
f2f1204af6 i18n - docs translations (#16175)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-28 13:23:00 +01:00
Félix MalfaitandGitHub fc6b136c2f fix: resolve GitHub Actions security vulnerabilities (#16174)
## 🔒 Security Fixes

This PR addresses security vulnerabilities identified by GitHub CodeQL
security scanning.

### Changes

#### 1. Fix Shell Command Injection (High Severity)
**File:** `.github/workflows/docs-i18n-pull.yaml`

**Issue:** Direct interpolation of `${{ github.head_ref }}` in shell
command was susceptible to command injection attacks.

**Fix:** Assign GitHub context variable to environment variable first:
```yaml
run: |
  git push origin "HEAD:$HEAD_REF"
env:
  HEAD_REF: ${{ github.head_ref }}
```

This prevents malicious input from being executed as shell commands.

#### 2. Add Missing Workflow Permissions (Medium Severity)
**File:** `.github/workflows/ci-test-docker-compose.yaml`

**Issue:** Workflow did not explicitly define GITHUB_TOKEN permissions,
running with overly broad defaults.

**Fix:** Added explicit minimal permissions:
```yaml
permissions:
  contents: read
```

This applies to all 3 jobs in the workflow:
- `changed-files-check`
- `test`
- `ci-test-docker-compose-status-check`

### Security Impact

-  Prevents potential shell injection attacks via pull request branch
names
-  Follows principle of least privilege for GitHub Actions tokens
-  Aligns with GitHub Actions security best practices
-  Resolves all CodeQL security alerts for these workflows

### References

- [GitHub Actions: Security hardening for GitHub
Actions](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions)
- [GitHub Actions: Permissions for the
GITHUB_TOKEN](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
- Related attacks: 2025 Nx supply chain attack, 2024 ultralytics/actions
attack
2025-11-28 13:15:33 +01:00
WeikoandGitHub 470888a23a Fix missing metadata version in legacy datasource (#16173) 2025-11-28 11:54:54 +00:00
5cea3d4358 i18n - translations (#16172)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-28 12:01:06 +01:00
Thomas des FrancsandGitHub e712eb01fb fix: update side panel header title to base font size with baseline alignment (#16095)
## Summary
1. Changed the side panel header title font size from small (0.92rem) to
base (1rem)
2. Added baseline alignment between the title and subtitle text while
keeping the icon centered

## Changes
- Updated `StyledPageInfoTitleContainer` font size from
`theme.font.size.sm` to `theme.font.size.md`
- Added `StyledPageInfoTextContainer` wrapper to baseline-align title
and subtitle independently from the icon

<img width="448" height="191" alt="image"
src="https://github.com/user-attachments/assets/b022a89c-a68f-4449-b01a-2ec029ce995b"
/>
2025-11-28 11:46:14 +01:00
GuillimandGitHub f2d9400e22 increase chunk fro release (#16169)
1.12
2025-11-28 10:23:11 +00:00
4d223e3ad3 i18n - docs translations (#16170)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-28 11:21:17 +01:00
Raphaël BosiandGitHub 9bc58a4ef9 Release line chart and pie chart (#16166)
- Remove the feature flag for these two charts.
- Reorder the charts
- Hide gauge chart
2025-11-28 10:17:03 +00:00
eb362c6d5f Update workspace entities to make all TEXT nullable (#16144)
Follow up on #15926

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: guillim <guigloo@msn.com>
2025-11-28 10:50:38 +01:00
WeikoandGitHub 9620a4b0ba Optimize EntityMetadata caching in GlobalWorkspaceDataSource (#16146)
## Context
EntityMetadata was being rebuilt from scratch on every
findMetadata()/getMetadata() call (~20 times per request). This involved
running EntitySchemaTransformer.transform() and
EntityMetadataBuilder.build() repeatedly, causing unnecessary CPU
overhead.

## Implementation
Cache entityMetadatas in ORMWorkspaceContext: Build EntityMetadata once
during workspace context initialization instead of on every metadata
lookup
Remove redundant entitySchemas caching: Since flatMetadata is already
cached, the additional Redis cache for entitySchemaOptions was
unnecessary overhead
Remove WorkspaceEntitiesStorage: Replaced with direct lookup from
FlatObjectMetadataMap
Simplify getObjectMetadataFromEntityTarget: Now only accepts string
targets, using flat metadata maps directly

Also:
Removed unused injections in some services
2025-11-28 10:09:52 +01:00
MarieandGitHub fd9ea2f5ee [groupBy] Fix order by nested date field (#16135)
Fixes https://github.com/twentyhq/core-team-issues/issues/1935
2025-11-28 09:02:06 +00:00
1e98e4da4d i18n - translations (#16163)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-28 10:01:52 +01:00
04b01170ed Introduce a workspace member page. (#16031)
- Refactored workspace member details into a focused Infos-only page.
- Aligned the flow with SettingsProfile, including controlled name
inputs, debounced saves, and stable instance IDs.
- Added a dedicated member-picture upload flow. Introduced the
MemberPictureUploader, connected to the
uploadWorkspaceMemberProfilePicture mutation.
- Backend now includes a workspace-member resolver/module for
profile-picture uploads. The endpoint is permission-guarded, streams
files through FileUploadService, and returns the signed file without
modifying the member entity.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds a workspace member detail page with picture/name management,
integrates a new avatar upload mutation, and updates list routing;
replaces the old profile picture uploader across profile and onboarding.
> 
> - **Frontend**
>   - **Settings Members**:
> - Add `pages/settings/members/SettingsWorkspaceMember` with
`MemberInfosTab`, `MemberNameFields`, and `MemberEmailField` for
viewing/editing member info.
> - Update routes in `SettingsRoutes` and add
`SettingsPath.WorkspaceMemberPage`.
> - Update `SettingsWorkspaceMembers` to navigate to member detail on
row click and simplify row actions (remove dropdown menu).
>   - **Avatar Upload**:
> - Introduce `WorkspaceMemberPictureUploader` using
`uploadWorkspaceMemberProfilePicture` mutation.
> - Replace `ProfilePictureUploader` in `SettingsProfile` and
`onboarding/CreateProfile`.
>   - **GraphQL (client)**:
> - Add `uploadWorkspaceMemberProfilePicture` mutation types/hooks in
`generated(-metadata)/graphql.ts`.
> - **Backend**
> - Add `UserWorkspaceResolver` with
`uploadWorkspaceMemberProfilePicture` mutation guarded by
`WorkspaceAuthGuard` and `SettingsPermissionGuard` (WORKSPACE_MEMBERS),
using `FileUploadService`.
> - Register resolver and `PermissionsModule` in `UserWorkspaceModule`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
359652f8c9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-28 08:23:51 +00:00
Paul RastoinandGitHub e53e0d266d Remove view filter v1 implem (#16154)
# Introduction
Removing view filter v1 implem 

Related https://github.com/twentyhq/core-team-issues/issues/1911
2025-11-28 00:17:17 +01:00
b1ef395627 i18n - docs translations (#16160)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 23:20:41 +01:00
a77b9d4a95 i18n - translations (#16159)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 23:01:00 +01:00
Abdul RahmanandGitHub a343bc1aee feat: workflow agent node permissions tab (#16092) 2025-11-28 02:57:33 +05:30
41a07006ef i18n - docs translations (#16158)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 21:20:50 +01:00
f3dc81217e i18n - translations (#16157)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 21:01:04 +01:00
nitinandGitHub fa87603fd8 [Dashboards] Relation fields groupby (#16093) 2025-11-27 19:28:53 +00:00
f23aa632a7 i18n - docs translations (#16156)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 19:21:56 +01:00
d09cb7c66b i18n - translations (#16155)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 19:01:53 +01:00
eaac569812 Fix variable usage in Search Record workflow action (#16147)
Closes https://github.com/twentyhq/twenty/issues/16141

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-11-27 18:56:56 +01:00
Raphaël BosiandGitHub 2f25922f4c [DASHBOARDS] Use aggregate for pie chart center metric (#16153)
## Description

The pie chart center metric wasn't implemented the right way.
It always calculated the sum of the values, but this only make sense for
additive aggregate operations (count, sum ...).
What we should do instead is calculate the right aggregate value.
This PR fixes this.

## Video QA


https://github.com/user-attachments/assets/2190da5a-e608-4732-86a2-478c9cf1477a
2025-11-27 17:26:14 +00:00
nitinandGitHub 32a876bbd4 part 4 of filter/sort drilldown onChartDatum click (#16142) 2025-11-27 18:03:10 +01:00
d4b3a8978d i18n - docs translations (#16151)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 17:21:45 +01:00
3b8db734a5 fix: glob CLI command injection via -c/--cmd executes matches with shell:true (#16139)
Resolves [Dependabot Alert
318](https://github.com/twentyhq/twenty/security/dependabot/318),
[Dependabot Alert
321](https://github.com/twentyhq/twenty/security/dependabot/321) and
[Dependabot Alert
322](https://github.com/twentyhq/twenty/security/dependabot/322).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Bumps glob to 10.5.0 across packages and adds @types/node and
twenty-sdk to rollup-engine dependencies.
> 
> - **Dependencies**:
>   - Upgrade `glob` to `10.5.0` across multiple `yarn.lock` files.
>   - In `packages/twenty-apps/community/rollup-engine`:
>     - Add `@types/node@^24.7.2` (adds `undici-types`).
>     - Add `twenty-sdk@0.0.3`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0aee78e0fa. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-11-27 16:36:36 +01:00
4fed51b7d8 i18n - translations (#16145)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 16:21:06 +01:00
Raphaël BosiandGitHub accd55d7cb [DASHBOARDS] Add default order by and date granularity when choosing field (#16143)
## QA


https://github.com/user-attachments/assets/b512eea0-26d1-4e1c-b8b9-f993a5c0d0fb



https://github.com/user-attachments/assets/0222600b-8a9a-44dc-a992-2a234712c913
2025-11-27 16:13:06 +01:00
EtienneandGitHub 65480eb492 Currency input field - fix (#16140)
Currency field used to have default value, but default value on field is
not mandatory. Defaulf default value logic has been removed.

Also test all field type input when empty. 
2025-11-27 14:53:42 +00:00
Raphaël BosiandGitHub ec53302ba8 Update chart limit error message (#16133)
## Description

- Display days, weeks, months or years instead of bars in the error
message
- Update the banner position
- Add translations on section titles

## Before
<img width="824" height="1378" alt="CleanShot 2025-11-27 at 14 51 40@2x"
src="https://github.com/user-attachments/assets/b2d7d1e6-e6d9-419b-8d7a-21f43e951898"
/>


## After
<img width="832" height="1382" alt="CleanShot 2025-11-27 at 14 51 15@2x"
src="https://github.com/user-attachments/assets/fe66d202-71be-45dc-8dff-502946e33aac"
/>
2025-11-27 15:32:12 +01:00
d217767600 i18n - docs translations (#16138)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 15:20:54 +01:00
EtienneandGitHub 3590bf1e83 Null equivalence - fix on dashboard entity (#16136) 2025-11-27 14:18:43 +00:00
nitinandGitHub 26ec6729c0 [Dashboards]: polish week on date granularity (#16128)
https://github.com/user-attachments/assets/2b7ef230-49e2-4882-9029-6df3d01f5f20
2025-11-27 15:04:44 +01:00
WeikoandGitHub da626f70b7 optimize buildFieldMapsFromFlatObjectMetadata usages (#16132)
This newly introduced util can be a bit expensive especially when done
recursively.
This PR improves that


File | Pattern Fixed | Impact
-- | -- | --
format-result.util.ts | Recursive array/object processing | N array
items → 1 call
format-data.util.ts | Recursive array processing | N array items → 1
call
process-nested-relations-v2.helper.ts | Duplicate call in call chain | 2
calls → 1 call
common-result-getters.service.ts | Per-record processing in array | N
records → 1 call
compute-relation-connect-query-configs.util.ts | Nested loop (entities ×
connect fields) | N×M calls → 1 call
2025-11-27 15:01:51 +01:00
nitinandGitHub 27547fd445 restore color on pie chart item and populate it on data transformation (#16131) 2025-11-27 13:41:30 +00:00
EtienneandGitHub 57ae12ff7c Null equivalence - update filter (#16123) 2025-11-27 13:31:39 +00:00
76ed82b598 i18n - translations (#16130)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 14:23:42 +01:00
ca5bd76c6a Null equivalence - migration command (#16018)
Awaiting https://github.com/twentyhq/twenty/pull/15926 approval, before
un-drafting it

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-11-27 13:18:56 +00:00
nitinandGitHub 97a8beb3f9 on pie chart, slice should not be clickable when in edit mode (#16129) 2025-11-27 13:05:24 +00:00
Abdullah.andGitHub 46ce9eca3f fix: node-forge is vulnerable to ASN.1 OID integer truncation (#16124)
Resolves [Dependabot Alert
328](https://github.com/twentyhq/twenty/security/dependabot/328).

Used `yarn up node-forge --recursive` to bump up the patch version from
1.3.1 to 1.3.2.
2025-11-27 17:49:10 +05:00
WeikoandGitHub 1607aebcc6 Deprecate object metadata maps in favor of flat entities (#16080)
## Context
Deprecating the old objectMetadataMap type in favour of split flat
entities to match with our new caching.
In the long run, trying to achieve:
- Better performance through caching
- Consistent data access patterns across the codebase
- Reduced database queries

Now that everything is based on flat entities, which are cached, we can
finish the refactoring of workspace context cache which should already
improve performances.
Then the last step will be to consume that new cache in the new global
datasource to get rid of the many workspace datasources stored in the
server
2025-11-27 13:43:34 +01:00
Abdullah.andGitHub 978c0acb90 fix: sentry's sensitive headers are leaked when sendDefaultPii is set to true (#16122)
Resolves [Dependabot Alert
323](https://github.com/twentyhq/twenty/security/dependabot/323),
[Dependabot Alert
324](https://github.com/twentyhq/twenty/security/dependabot/324) and
[Dependabot Alert
325](https://github.com/twentyhq/twenty/security/dependabot/325).

It updates Sentry's packages on the server from 10.21.0 to 10.27.0.

I also moved @sentry/react to twenty-front package.json and updated the
version from 9.26.0 to 10.27.0 - no breaking changes were introduced in
the major upgrade in regards to the API exposed by the dependency.

Since @sentry/profiling-node was redundant in the root package.json, I
removed it - twenty-server has it already and is the only package
dependent on @sentry/profiling-node.
2025-11-27 17:28:59 +05:00
Abdullah.andGitHub afd5ccc775 fix: body-parser is vulnerable to denial of service when url encoding is used (#16126)
Resolves [Dependabot Alert
326](https://github.com/twentyhq/twenty/security/dependabot/326).

Used `yarn up body-parser --recursive` to bump up the patch version from
2.2.0 to 2.2.1.
2025-11-27 17:28:33 +05:00
f3a796e17e i18n - docs translations (#16127)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 13:23:11 +01:00
44f4203d58 i18n - translations (#16125)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 13:01:57 +01:00
Raphaël BosiandGitHub 20e6f130d1 Update pie chart inner padding (#16121)
## Before

<img width="2548" height="1024" alt="CleanShot 2025-11-27 at 12 13
24@2x"
src="https://github.com/user-attachments/assets/f2182821-1398-4f29-a5ee-2ffc5653d416"
/>

## After

<img width="2558" height="1034" alt="CleanShot 2025-11-27 at 12 13
04@2x"
src="https://github.com/user-attachments/assets/147ba875-0432-4525-b847-e1f2426849ed"
/>
2025-11-27 11:24:59 +00:00
nitinandGitHub db6456b1af fix legend toggle for line and bar charts (#16120) 2025-11-27 11:21:55 +00:00
d7f8c2d338 Center metric layer on pie chart + cleanup (#16105)
https://github.com/user-attachments/assets/bb48bebe-d0be-4006-8f63-e686c70c0011

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
2025-11-27 11:15:48 +00:00
1a45576990 Morph-add-new-object-destination (#16027)
Add new object target to an existing morph relation (backend only)

Fixes https://github.com/twentyhq/core-team-issues/issues/1898

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-11-27 11:10:13 +00:00
7001c91a7d i18n - translations (#16119)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 12:01:05 +01:00
MarieandGitHub 9c9a01d55a [groupBy][Requires cache flush] Add WEEK date granularity (#16099)
Closes https://github.com/twentyhq/core-team-issues/issues/1921

https://github.com/user-attachments/assets/bf400ec1-ce25-4d9e-b875-774168452514
2025-11-27 10:22:57 +00:00
7e90dd888c i18n - docs translations (#16114)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 09:22:02 +01:00
9f939eb4c3 i18n - translations (#16113)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-27 09:01:26 +01:00
Félix MalfaitandGitHub 4f20fd35c5 feat: Add Agent Evaluation System and Refactor AI Modules (#16111)
## Summary

This PR introduces a comprehensive agent evaluation system and refactors
the AI module structure for better organization.

## Key Changes

### 🎯 Agent Evaluation System
- Added **Agent Turn Evaluation** entities, DTOs, and database schema
- New GraphQL mutations: `evaluateAgentTurn` and `runEvaluationInput`
- Added `evaluationInputs` field to Agent entity for storing test inputs
- New `AgentTurnGraderService` for automatic turn evaluation
- Added evaluation UI with new **Evals** and **Logs** tabs in agent
detail pages

### 🏗️ Entity & Module Refactoring
- Renamed `AgentChatMessage` → `AgentMessage` for clarity
- Consolidated chat entities: `AgentMessage`, `AgentTurn`, and
`AgentChatThread`
- Reorganized AI modules under `ai/` subdirectory structure
- Updated imports across codebase to reflect new module paths

### 🤖 New Agents & Roles
- Added **Dashboard Builder Agent** for dashboard creation and
management
- Added **Dashboard Manager Role** with appropriate permissions
- Updated role permissions to be more granular (users vs agents vs API
keys)

### 🔐 Permission System Updates
- Added `HTTP_REQUEST_TOOL` permission flag
- Updated Workflow Manager role permissions (restricted tool access)
- Enhanced permission flag types to differentiate between user/agent/API
key contexts
- Added `isRelevantForAgents`, `isRelevantForApiKeys`,
`isRelevantForUsers` to permission flags

### 📨 Message Role Enhancement
- Added `system` role to `AgentMessageRole` enum (alongside
user/assistant)
- Updated message handling to support system prompts

### 🎨 UI/UX Improvements
- New tabs in agent detail: **Evals** and **Logs**
- Added turn detail page: `/ai/agents/:agentId/turns/:turnId`
- Fixed text overflow in `SettingsListItemCardContent`
- Updated role applicability labels ("Assignable to Workspace Members")

### 🛠️ Technical Improvements
- Fixed Zod schema validation for UUID and Date fields (use string
validators)
- Updated `ToolRegistryService` to properly register HTTP tool with
permission flag
- Enhanced error handling in agent execution services
- Updated database migrations for new entity schema

## Database Migrations
- `1764210000000-add-system-role-to-agent-message.ts`
- `1764220000000-add-evaluation-inputs-to-agent.ts`
- `1764200000000-add-agent-turn-evaluation.ts`
- `1764100000000-refactor-agent-chat-entities.ts`

## Testing
- [ ] Agent evaluation flow tested
- [ ] Dashboard Builder agent tested
- [ ] Permission system validated
- [ ] UI tabs and navigation tested
- [ ] Database migrations run successfully

## Breaking Changes
⚠️ **Entity Rename**: `AgentChatMessage` renamed to `AgentMessage` -
GraphQL queries need updating

## Related Issues
<!-- Link any related issues here -->

## Screenshots
<!-- Add screenshots if applicable -->
2025-11-27 08:25:40 +01:00
Thomas des FrancsandGitHub 35f81805b8 Fix options menu button height in side panel footer (#16107)
## Description
Fixed the height of the options menu button in the side panel footer to
be 24px instead of 32px, matching the height of other buttons in the
footer.

## Changes
- Added `size="small"` prop to the `Button` component in
`OptionsDropdownMenu.tsx`
- This ensures consistent button sizing across the side panel footer

## Before
The options menu button was 32px high (medium size), making it larger
than other footer buttons.

<img width="543" height="421" alt="image"
src="https://github.com/user-attachments/assets/3c4fdfd0-73d1-4884-a639-3382090dfe15"
/>


## After
The options menu button is now 24px high (small size), consistent with
other side panel footer buttons.

<img width="1000" height="824" alt="CleanShot 2025-11-26 at 18 50 43@2x"
src="https://github.com/user-attachments/assets/798e7975-a7a8-4c00-b2e7-c0d1261249f8"
/>
2025-11-27 09:43:42 +05:30
Charles BochetandGitHub b1d1bcb712 Fix messaging import (#16112) 2025-11-26 23:13:12 +01:00
Thomas des FrancsandGitHub 5d1c2a3348 Let single notes take the full width (both side panel & desktop) (#16108)
# Current behavior

<img width="932" height="1040" alt="CleanShot 2025-11-26 at 19 10 32@2x"
src="https://github.com/user-attachments/assets/309fc2f4-b9ef-481c-b550-74c1c5cfeaf4"
/>

<img width="2618" height="1352" alt="CleanShot 2025-11-26 at 19 10
56@2x"
src="https://github.com/user-attachments/assets/f57348e9-2e09-4c91-bcf6-e776aa26598a"
/>


# Desired Behavior

<img width="2634" height="1304" alt="CleanShot 2025-11-26 at 19 11
32@2x"
src="https://github.com/user-attachments/assets/d8e13ab5-65d7-4449-9d8d-7a2356f71160"
/>

<img width="1048" height="1146" alt="CleanShot 2025-11-26 at 19 11
50@2x"
src="https://github.com/user-attachments/assets/8a062717-18c1-41c7-a52c-1904738cd145"
/>
2025-11-26 22:34:44 +01:00
ee6ac6bb4c i18n - docs translations (#16109)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-26 19:22:05 +01:00
3c658b209d i18n - translations (#16106)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-26 18:46:23 +01:00
EtienneandGitHub 70f48ba445 Security - Add complexity max on gql queries (#16069)
closes https://github.com/twentyhq/private-issues/issues/348
closes https://github.com/twentyhq/private-issues/issues/352
closes https://github.com/twentyhq/private-issues/issues/353
closes https://github.com/twentyhq/private-issues/issues/354
2025-11-26 18:36:21 +01:00
Charles BochetandGitHub 5202e2b2db Refactor error messages messaging (#16094)
We should try catch locally gmail errors when:
- fetching message list
- fetching messages
- refreshing aliases
- fetching folders
2025-11-26 18:03:44 +01:00
Raphaël BosiandGitHub fc4dbb80de [DASHBOARDS] Create display legend setting + animations (#16089)
## PR Description
- Create display legend setting
- Create pagination inside the legend
- Animate the legend on enter/exit
- Animate the transition between pages

## Video QA


https://github.com/user-attachments/assets/a68a4ea3-195f-4399-88f7-f83bc1a39cc4
2025-11-26 17:03:23 +00:00
GuillimandGitHub 7f441d741b Timelineactivites-views-seeder (#16103)
seeder for Timelineactivites views

Fixes https://github.com/twentyhq/core-team-issues/issues/1904


<img width="850" height="348" alt="CleanShot 2025-11-26 at 17 30 32"
src="https://github.com/user-attachments/assets/41a311c1-0b60-4201-885f-d0e8400dd6d5"
/>
2025-11-26 18:00:06 +01:00
Raphaël BosiandGitHub 60e69f92d9 [DASHBOARDS] Add pie chart empty state (#16100)
When no data is available, we display a gray circle instead of nothing.



https://github.com/user-attachments/assets/54db403b-739c-43fb-b422-8dcdfb6281fb
2025-11-26 17:23:52 +01:00
c82c4a4507 i18n - translations (#16101)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-26 17:21:44 +01:00
neo773andGitHub 4120c191f8 fix scheduling after folder actions are processed (#16097) 2025-11-26 17:09:06 +01:00
Raphaël BosiandGitHub 8dc182d659 Add New Widget page layout header information (#16098)
## Before

<img width="822" height="384" alt="CleanShot 2025-11-26 at 16 22 12@2x"
src="https://github.com/user-attachments/assets/014e2efc-c4e4-4140-b473-f09ac56855b5"
/>

## After

<img width="818" height="352" alt="CleanShot 2025-11-26 at 16 21 53@2x"
src="https://github.com/user-attachments/assets/5aa961a9-7d06-47b7-ad5d-6b5b9714a0d8"
/>
2025-11-26 16:38:36 +01:00
Raphaël BosiandGitHub c34f798a9c Reorder colors to have a proper gradient (#16096)
## Before

<img width="638" height="1712" alt="CleanShot 2025-11-26 at 15 28 47@2x"
src="https://github.com/user-attachments/assets/a8ebadf7-a642-46c1-bb96-067e8b451059"
/>


## After

<img width="638" height="1712" alt="CleanShot 2025-11-26 at 15 26 15@2x"
src="https://github.com/user-attachments/assets/d276240c-4b34-4ea3-954d-2a20a94ddf60"
/>
2025-11-26 14:40:45 +00:00
nitinandGitHub 6fcb05d9b3 part 3 of on click bar to filters: add sort plus some normalizations (#16075) 2025-11-26 19:48:48 +05:30
Baptiste DevessierandGitHub dc2c2c413c [Workflows] Fix filtering on relative date (#16087)
https://github.com/user-attachments/assets/4079d59e-0550-401f-a29b-b235edd8ed48

Closes https://github.com/twentyhq/twenty/issues/16054
2025-11-26 14:45:05 +01:00
Paul RastoinandGitHub 996ccd8353 Non composite and non morph or relation field update fix (#16091) 2025-11-26 11:54:04 +00:00
Paul RastoinandGitHub 74eab77539 Refactor upgrade devx to allow configuring workspaces status to pass over (#16066)
# Introduction
We need to be able to create custom workspace application on all
workspaces, even pending and ongoing etc
Right now the upgrade devx only allows and expect active or suspended
workspace to be passed to runOnWorkspace.

## WorkspacesMigrationRunner
Created an intermediate class `WorkspacesMigrationRunner` that expect an
array `WorkspaceStatus` to be fetched for the current command to be run
on
The `ActiveOrSuspendedCommandRunner` statically passes both `SUSPENDED`
and `ACTIVE`, whereas the create workspace custom application passed all
the enum values

## DataSource
Workspace that are not fully init don't have a `workspace_schema` so
they don't have `dataSource`
Made a not very elegant check to see if current workspace we're about to
create dataSource on has one historically
Which means that dataSource is now optional, it had only one impact on
an existing command and the desired devx will become consuming existing
services that do not expect dataSource ( or at least yet )
2025-11-26 12:53:33 +01:00
nitinandGitHub 0d34651d5e pie chart data labels, slice gap and initial animate presence on widget card header (#16084)
closes:
https://discord.com/channels/1130383047699738754/1442899090047373463
https://discord.com/channels/1130383047699738754/1438537119248285758

pie chart labels:


https://github.com/user-attachments/assets/d8f8e164-745f-4601-bee7-11a655ccd9b6



fixed header animations:


https://github.com/user-attachments/assets/76587a6d-53c4-4a11-a546-b4c83754870a
2025-11-26 15:02:48 +05:30
4d0c469157 Fix message import scheduled (#16071)
Co-authored-by: neo773 <neo773@protonmail.com>
2025-11-26 08:54:53 +01:00
MarieandGitHub 6c1c78ea3d [fix] User have no firstName nor lastName (#16057)
Closes https://github.com/twentyhq/twenty/issues/15692, fixes
https://github.com/twentyhq/twenty/issues/14678

The issue was:
- When a user is signing up, they are asked for their first name and
last name with which we fulfill their workspaceMember entity for the
workspace they are signing up to (which is the one they are creating if
they are not joining an existing workspace). user.firstName and
user.lastName remain empty
- When we create a record, we are using user.firstName and user.lastName
to fulfill the text field "createdByName", which intends to save the
name of the creator at the moment of the creation. This field is then
use 1) when filtering on createdBy (as a trick to be able to filter by
this, since we don't have filters on nested fields, ie we dont have
filters on person.createdByWorkspaceMember) 2) to display the user
creator when a user has left a workspace - otherwise we rely on the
dynamic createdByWorkspaceMember.firstName and lastName
- So filtering on createdBy was not working as createdByName is empty.
We did not see that in dev mode because we have seeded users with names

The fix
- When we create a record, we use workspaceMember.firstName and
workspaceMember.lastName as we should.
- When an existing user joins a workspace, they are asked to give their
name again so that we set their workspaceMember name
- This will not fix the history of the records (they will still have
createdByName empty so the filter will not work properly), but a command
to fix it would be very long as it would iterate over all the records of
each active workspace

The long-term view is to get rid of user and to store the name in
userWorkspace
2025-11-25 17:23:43 +00:00
Charles BochetandGitHub b1c03b533f Fix upgrade command messaging (#16067) 2025-11-25 18:14:51 +01:00
neo773andGitHub f3416d435c move folder cron to message-list-fetch (#16062) 2025-11-25 18:06:38 +01:00
neo773andGitHub 1740a2217a Update channel sync service to immediately enqueue jobs (#16064) 2025-11-25 18:05:32 +01:00
Baptiste DevessierandGitHub 0bf2d13832 [Side Panel V2] Bring back old container (#16065)
## Before

<img width="1446" height="780" alt="image"
src="https://github.com/user-attachments/assets/fa25f22d-b979-4a8f-9989-004d07f862d7"
/>

## After

<img width="3456" height="2160" alt="CleanShot 2025-11-25 at 17 35
59@2x"
src="https://github.com/user-attachments/assets/a87880c4-3faa-47c3-9215-34afc36270a3"
/>
2025-11-25 18:04:56 +01:00
Baptiste DevessierandGitHub 21543b6803 Don't recompute output schema when moving trigger (#16061)
Position changes don't affect the trigger's output schema, so
recomputing it is unnecessary. For webhook triggers specifically, the
backend can't reconstruct the schema (it returns `{}`), which overwrites
the frontend-built schema from `expectedBody`. Passing `{
computeOutputSchema: false }` prevents this data loss while avoiding
wasteful computation.

## Demo


https://github.com/user-attachments/assets/116af221-0d09-4dda-ad40-3301fa610bcd

Closes https://github.com/twentyhq/twenty/issues/15982
2025-11-25 17:37:32 +01:00
EtienneandGitHub 71724de7dd Security - disable gql introspection for non-auth user (#16047)
closes https://github.com/twentyhq/private-issues/issues/351
closes https://github.com/twentyhq/private-issues/issues/350

Before, introspection query works without token. After, fails.

```

query IntrospectionQuery {
  __schema {
    queryType {
      name
    }
    mutationType {
      name
    }
    subscriptionType {
      name
    }
    types {
      ...FullType
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
      }
    }
  }
}

fragment FullType on __Type {
  kind
  name
  description
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}

fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
  }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}
```
2025-11-25 15:39:29 +01:00
Raphaël BosiandGitHub 42bba3de52 Fix chart limits for two-dimensional group by (#16056)
The limit wasn't working properly for two dimensional stacked charts.
This PR fixes this.
2025-11-25 15:31:25 +01:00
Charles BochetandGitHub 8455ecc3e8 Add import scheduled status to messaging sync (#16058)
We have introduced to new syncStage statuses:
`messageChannel.MESSAGES_IMPORT_SCHEDULED` and
`calendarChannel.CALENDAR_EVENTS_IMPORT_SCHEDULED`

We need to make sure all existing workspaces have it
2025-11-25 15:27:58 +01:00
825728b1c4 i18n - translations (#16059)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-25 15:20:59 +01:00
Raphaël BosiandGitHub 6d141c2439 [DASHBOARDS] Pie Chart (#16048)
## Description

- Connect Pie Chart to the backend
- Update from the old design to the new design
- Switch seamlessly from/to other types of chart from the Pie Chart by
converting the configuration

Note: There are a couple things to implement before the pie chart is
ready to go live:
- Add a new setting on Bar, Line and Pie chart to hide and display
legends (toggle)
- Add data labels next to each slice

## Video QA


https://github.com/user-attachments/assets/b1561e32-0434-43ad-8855-d617b209ce27
2025-11-25 14:30:16 +01:00
BOHEUSandGitHub 88fbe6c51d Updated by leftover nitpick (#16040)
Nitpicks from #15937
2025-11-25 14:28:37 +01:00
nitinandGitHub 3be3c4e965 part 2 of filter/sort drill down from charts (#16013)
in this PR, we will handle simple filter translations (ie, fields that
use the contains operand)
2025-11-25 18:56:55 +05:30
EtienneandGitHub 2028a8f9be Null equivalence - Fix (#16050)
@charlesBochet 
In workflow codebase, NULL (instead of empty object) is expected on
workflow version object step field, when a new workflow is created for
example.
(packages/twenty-front/src/modules/workflow/workflow-diagram/utils/generateWorkflowDiagram.ts
- 42)
This case is not isolated and it creates many issues.

We decided to format NULL value to equivalent (empty string for text
field, empty object for raw_json) but it seems it complicates the dev x.

To unlock @Devessier I prefer revert the logic, the time we discuss how
to solve this cases.
2025-11-25 14:07:32 +01:00
nitinandGitHub ab3d48383b dashboards fast follows: tabs border changed to outline and legends factorization (#16049)
closes
https://discord.com/channels/1130383047699738754/1440633019042889828
https://discord.com/channels/1130383047699738754/1442819106880356363
2025-11-25 18:08:09 +05:30
53509360ff i18n - docs translations (#16053)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-25 13:23:06 +01:00
26169a2136 i18n - translations (#16052)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-25 12:46:03 +01:00
Félix MalfaitandGitHub e7ebf51e50 Replace agent handoff system with planning-based router (#16003)
## Overview

This PR replaces the dynamic agent handoff system with a more
predictable planning-based router that decides upfront how to handle
multi-agent coordination.

## Major Changes

### 🔄 Architecture Shift: Handoffs → Planning

**Removed:**
- `AgentHandoffEntity` and handoff tracking system
- `AgentHandoffService` and `AgentHandoffExecutorService`
- Dynamic agent-to-agent transfers during execution
- Handoff tool generation and description templates

**Added:**
- `AiRouterService` with two strategies: `simple` (single agent) and
`planned` (multi-agent)
- `AgentPlanExecutorService` for executing multi-step plans
- Plan validation (cycle detection, dependency resolution)
- `UnifiedRouterResult` type with discriminated union

### 🤖 New Standard Agents

Added two new specialized agents:
- **Researcher Agent**: Web search, fact-finding, competitive
intelligence
- **Code Agent**: TypeScript function generation for serverless
workflows

### 🏗️ Router Refactoring (Latest)

Split router responsibilities into focused services:
- `AiRouterStrategyDeciderService`: Decides simple vs planned strategy
- `AiRouterPlanGeneratorService`: Generates and validates execution
plans
- `AiRouterService`: Coordinates between services (reduced from 426→275
lines)

### ⚙️ Configuration Improvements

- Added `outputStrategy` to agent definitions (`direct` vs `synthesize`)
- Removed hardcoded special cases for workflow-builder
- Added `plannerModel` field to workspace entity
- Increased `MAX_STEPS` from 10 to 25 for complex workflows

### 📝 Agent Prompt Refinements

Significantly simplified prompts for better clarity:
- Workflow Builder: 51→36 lines
- Helper: 49→28 lines
- Data Manipulator: Enhanced with sorting guidance

### 🔍 Enhanced Debugging

- Plan reasoning and step count in data message parts
- Router debug info with token usage tracking
- Better logging throughout execution pipeline

## Benefits

1. **Simpler Mental Model**: Router decides upfront vs dynamic transfers
2. **Better Predictability**: Users see the plan before execution
3. **Cleaner Architecture**: SRP with focused services
4. **Configuration Over Code**: Agent behavior via config, not hardcoded
logic
5. **Plan Validation**: Catches invalid dependencies and cycles

## Migration Notes

- Database migration removes `agentHandoff` table
- Adds `plannerModel` column to workspace table
- No API breaking changes (agent endpoints unchanged)

## Testing

- Integration tests updated to remove handoff dependencies
- Agent tool test utilities simplified
- Plan validation covered by new logic

## Next Steps (Future PRs)

- Parallel execution of independent plan steps
- Dynamic re-planning based on results
- Plan caching for common routing patterns
- Error recovery strategies in plan executor
2025-11-25 12:10:14 +01:00
Abdullah.andGitHub 3c0ae49a23 Clicking outside inline fields on record page saves the value. (#16042)
Closes #15957

The core problem: `handleChange` calls `setDraftValue`, but when blur
fires, `handleClickOutside` runs in the same event turn and uses
the `draftValue` captured in its closure from the last render. React
hasn’t re-rendered yet, so that captured `draftValue` is stale. Recoil
atom writes are synchronous, but the render that would update the
closure happens on the next turn.

I considered deferring `handleClickOutside` to the next tick
(setTimeout/Promise), but that’s a timing hack: it makes focus/blur
ordering unpredictable (inline cells, tables, other listeners), risks
double triggers, and can fire after unmount. Another option was to
duplicate the `handleChange` logic inside `handleClickOutside`
(screenshot), but that defeats having draft state in one place.

<p align="center">
<img width="496" height="332" alt="const nextSecondaryLinks =
updatedLinks slice (1);"
src="https://github.com/user-attachments/assets/638e2bcf-871b-4b53-9124-c8489c5db530"
/>
</p>

The clean solution is to read the current draft from a Recoil snapshot
at call time inside `handleClickOutside`. Snapshot reads pull the latest
atom value (including synchronous `setDraftValue` that just ran) even
before a re-render occurs, so they’re not subject to the stale closure.
That way, blur uses the up-to-date draft without timing hacks or
duplicated logic.

MultiItemFieldInput is used in four places. Each of them contains the
updated code.
2025-11-25 11:37:37 +01:00
3e584c3d5f i18n - docs translations (#16044)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-25 11:21:42 +01:00
a47b7dfed0 i18n - translations (#16041)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-25 10:36:15 +01:00
MarieandGitHub 46d1ea6505 [groupBy] groupBy relation fields (#15951)
Example query
Here person has 
- a N - 1 relationship with company
- a N - 1 morph relationship with pet or company

<img width="862" height="374" alt="image"
src="https://github.com/user-attachments/assets/59bc9b82-c943-43de-ad82-d3393b76904b"
/>
<img width="415" height="629" alt="image"
src="https://github.com/user-attachments/assets/9a3176bc-99cd-4983-8611-68ca3a2cf527"
/>

truncated response
<img width="299" height="447" alt="image"
src="https://github.com/user-attachments/assets/45af0322-9e66-4eae-8353-6c0dda487bbe"
/>

We don't allow grouping by relations of relations.

Left to do
- rest api
- tests on permissions
2025-11-25 09:03:16 +00:00
neo773andGitHub 316aec3c40 fix: prevent NUMERIC field type creation via API (#16038)
Block users from creating NUMERIC, POSITION, and TS_VECTOR fields via
the API as these are system-only types. Users should use NUMBER instead
of NUMERIC.

/closes #16023
2025-11-25 09:51:48 +01:00
7109abc311 fix: Invisible content after closing the settings on mobile (#15971)
## Description

- This PR address https://github.com/twentyhq/twenty/issues/15958
- updated settings and main with condition to navigate to
defaultHomePagePath for main page
- updated search with context before opening search hence it resolve the
issue of search showing blank on settings page


## Before


https://github.com/user-attachments/assets/26eb50a0-fb59-4f70-9647-b8150dfdfa40




## After



https://github.com/user-attachments/assets/436fd869-fc0f-4921-98b9-d5eafa67a07f

---------

Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-11-24 19:51:04 +01:00
WeikoandGitHub 04562b11fb Migrate metadata cache (#16030)
## Context
Deprecating legacy ObjectMetadata from cache in favor of flat entities.
Introducing utils to build byName/byNameSingular/byNamePlural in
isolated cases

## Next
- I had to introduce a util to build from flat to legacy
objectMetadataMaps, we should instead use flat maps directly when needed
(datasource, schema generation, etc)
- Deprecate metadata version in the cache
- Use the new cache strategy for flat entities with permissions and
feature flags and inject in the global datasource context
2025-11-24 19:50:47 +01:00
Raphaël BosiandGitHub 26e2fe349f Fix page layout widget deletion (#16035)
With the new side panel, we are able to delete a widget with the side
panel still open. This caused the app to crash because we threw when the
widget id wasn't defined.

This PR fixes this by closing the side panel in the delete action and by
returning null instead of throwing.

## Before



https://github.com/user-attachments/assets/092bfe62-82dc-4d83-9967-1cc753ecf55e



## After


https://github.com/user-attachments/assets/8bed6cc5-961b-4112-8cf5-e587865d14da
2025-11-24 19:50:10 +01:00
Charles BochetandGitHub b2472b30c4 Add logs to debug user being disconnected randomly (#16037)
As per title, just adding logs to troubleshoot:
https://github.com/twentyhq/twenty/issues/13103
2025-11-24 19:49:02 +01:00
30b6907c44 i18n - docs translations (#16036)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-24 19:22:22 +01:00
EtienneandGitHub 208c0857ee common api - null equivalence (#15926)
closes https://github.com/twentyhq/core-team-issues/issues/1629

To do before requesting review : 
- filter update

Migration to come in an other PR


Strat : 
1/  Null transformation

- [x] Transform NULL equivalent value to NULL in field validation in
common api - pre-query - with feature flag
- [ ] Same logic in ORM (Not done, complex to handle feature flag here)
- [x] Transform NULL value to equivalent in data formatting in ORM -
post-query

2/ Migration (in other PR) for fieldMetadata not nullable with default
defaultValue (empty string, ...)

- [ ] Remove NOT NULL db constraint
- [ ] Update record value to NULL
- [ ] Update field metadata : isNullable:true
- [ ] Update uniqueIndex whereClause (also for standard uniqueIndex) 
- [ ] Activate feature flag

3/ Update metadata creation

- [x] No more default default value
- [x] Update standard field nullability
- [x] Remove index default whereClause for standard field

4/ Update filter

- [x] When filtering on NULL or empty string, be sure all records are
returned (the one with NULL + the one with "")

5/ Test

- [ ] Strat. to do
2025-11-24 18:57:47 +01:00
1968 changed files with 77811 additions and 40447 deletions
+2 -1
View File
@@ -12,6 +12,7 @@ This directory contains Twenty's development guidelines and best practices in th
### Core Guidelines
- **architecture.mdc** - Project overview, technology stack, and infrastructure setup (Always Applied)
- **nx-rules.mdc** - Nx workspace guidelines and best practices (Auto-attached to Nx files)
- **server-migrations.mdc** - Backend migration and TypeORM guidelines for `twenty-server` (Auto-attached to server entities and migration files)
### Code Quality
- **typescript-guidelines.mdc** - TypeScript best practices and conventions (Auto-attached to .ts/.tsx files)
@@ -40,7 +41,7 @@ You can manually reference any rule using the `@ruleName` syntax:
- `@testing-guidelines` - Get testing recommendations
### Rule Types Used
- **Always Applied** - Loaded in every context (architecture.mdc, README.mdc)
- **Always Applied** - Loaded in every context (architecture.mdc, README.mdc)
- **Auto Attached** - Loaded when matching file patterns are referenced
- **Agent Requested** - Available for AI to include when relevant
- **Manual** - Only included when explicitly mentioned
+5
View File
@@ -89,6 +89,8 @@ Use the AI codebase search to find:
### 1. Setup Git Branch
**IMPORTANT**: Always start from an up-to-date main branch to avoid merge conflicts and ensure the changelog is based on the latest code.
```bash
cd /Users/thomascolasdesfrancs/code/twenty
git checkout main
@@ -98,6 +100,8 @@ git checkout -b {VERSION}
Replace `{VERSION}` with the actual version number (e.g., `1.9.0`)
⚠️ **Do this first** before making any file changes. This ensures your branch is based on the latest main.
### 2. Create File Structure
**Create changelog file:**
@@ -174,6 +178,7 @@ Description of the third feature.
- Focus on user benefits, not technical implementation
- Use active voice
- Start with what the user can now do
- **NEVER mention the brand name "Twenty"** in changelog text - use "your workspace", "the platform", or similar neutral references instead
**Reference Previous Changelogs:**
- Check `packages/twenty-website/src/content/releases/` for examples
+29
View File
@@ -0,0 +1,29 @@
---
description: Guidelines for generating and managing TypeORM migrations in twenty-server
globs: [
"packages/twenty-server/src/**/*.entity.ts",
"packages/twenty-server/src/database/typeorm/**/*.ts"
]
alwaysApply: false
---
## Server Migrations (twenty-server)
- **When changing an entity, always generate a migration**
- If you modify a `*.entity.ts` file in `packages/twenty-server/src`, you **must** generate a corresponding TypeORM migration instead of manually editing the database schema.
- Use the Nx + TypeORM command from the project root:
```bash
npx nx run twenty-server:typeorm migration:generate src/database/typeorm/core/migrations/common/[name] -d src/database/typeorm/core/core.datasource.ts
```
- Replace `[name]` with a descriptive, kebab-case migration name that reflects the change (for example, `add-agent-turn-evaluation`).
- **Prefer generated migrations over manual edits**
- Let TypeORM infer schema changes from the updated entities; only adjust the generated migration file manually if absolutely necessary (for example, for data backfills or complex constraints).
- Keep schema changes (DDL) in these generated migrations and avoid mixing in heavy data migrations unless there is a strong reason and clear comments.
- **Keep migrations consistent and reversible**
- Ensure the generated migration includes both `up` and `down` logic that correctly applies and reverts the entity change when possible.
- Do not delete or rewrite existing, committed migrations unless you are explicitly working on a pre-release branch where history rewrites are allowed by team conventions.
+1 -1
View File
@@ -63,4 +63,4 @@ git push origin your-branch-name
## Reporting Issues
If you face any issues or have suggestions, please feel free to (create an issue on Twenty's GitHub repository)[https://github.com/twentyhq/twenty/issues/new]. Please provide as much detail as possible.
If you face any issues or have suggestions, please feel free to [create an issue on Twenty's GitHub repository](https://github.com/twentyhq/twenty/issues/new). Please provide as much detail as possible.
+55
View File
@@ -0,0 +1,55 @@
name: CI Create App
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/create-twenty-app/**
create-app-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
strategy:
matrix:
task: [lint, typecheck, test, build]
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Run ${{ matrix.task }} task
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:create-app
tasks: ${{ matrix.task }}
ci-create-app-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, create-app-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
@@ -1,4 +1,4 @@
name: CI CLI
name: CI SDK
on:
push:
@@ -19,9 +19,8 @@ jobs:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/twenty-cli/**
packages/twenty-server/**
cli-test:
packages/twenty-sdk/**
sdk-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
@@ -43,12 +42,12 @@ jobs:
- name: Run ${{ matrix.task }} task
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:cli
tag: scope:sdk
tasks: ${{ matrix.task }}
cli-e2e-test:
sdk-e2e-test:
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
needs: [changed-files-check, cli-test]
needs: [changed-files-check, sdk-test]
if: needs.changed-files-check.outputs.any_changed == 'true'
services:
postgres:
@@ -90,13 +89,13 @@ jobs:
- name: Server / Create Test DB
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
- name: CLI / Run E2E Tests
run: npx nx test:e2e twenty-cli
ci-cli-status-check:
- name: SDK / Run E2E Tests
run: npx nx test:e2e twenty-sdk
ci-sdk-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, cli-test, cli-e2e-test]
needs: [changed-files-check, sdk-test, sdk-e2e-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
@@ -1,4 +1,8 @@
name: 'Test Docker Compose'
permissions:
contents: read
on:
pull_request:
+3 -1
View File
@@ -124,7 +124,9 @@ jobs:
exit 0
fi
git commit -m "chore: sync docs artifacts"
git push origin HEAD:${{ github.head_ref }}
git push origin "HEAD:$HEAD_REF"
env:
HEAD_REF: ${{ github.head_ref }}
- name: Check for changes and commit
if: github.event_name != 'pull_request'
+2 -7
View File
@@ -9,8 +9,6 @@
"@linaria/core": "^6.2.0",
"@linaria/react": "^6.2.1",
"@radix-ui/colors": "^3.0.0",
"@sentry/profiling-node": "^9.26.0",
"@sentry/react": "^9.26.0",
"@sniptt/guards": "^0.2.0",
"@tabler/icons-react": "^3.31.0",
"@wyw-in-js/vite": "^0.7.0",
@@ -189,11 +187,7 @@
"ts-node": "10.9.1",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.17.0",
"vite": "^7.0.0",
"vite-plugin-checker": "^0.10.2",
"vite-plugin-cjs-interop": "^2.2.0",
"vite-plugin-dts": "3.8.1",
"vite-plugin-svgr": "^4.2.0"
"vite": "^7.0.0"
},
"engines": {
"node": "^24.5.0",
@@ -233,6 +227,7 @@
"packages/twenty-sdk",
"packages/twenty-apps",
"packages/twenty-cli",
"packages/create-twenty-app",
"tools/eslint-rules"
]
}
+91
View File
@@ -0,0 +1,91 @@
<div align="center">
<a href="https://twenty.com">
<picture>
<img alt="Twenty logo" src="https://raw.githubusercontent.com/twentyhq/twenty/2f25922f4cd5bd61e1427c57c4f8ea224e1d552c/packages/twenty-website/public/images/core/logo.svg" height="128">
</picture>
</a>
<h1>Create Twenty App</h1>
<a href="https://www.npmjs.com/package/create-twenty-app"><img alt="NPM version" src="https://img.shields.io/npm/v/create-twenty-app.svg?style=for-the-badge&labelColor=000000"></a>
<a href="https://github.com/twentyhq/twenty/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/npm/l/next.svg?style=for-the-badge&labelColor=000000"></a>
<a href="https://discord.gg/cx5n4Jzs57"><img alt="Join the community on Discord" src="https://img.shields.io/badge/Join%20the%20community-blueviolet.svg?style=for-the-badge&logo=Twenty&labelColor=000000&logoWidth=20"></a>
</div>
Create Twenty App is the official scaffolding CLI for building apps on top of [Twenty CRM](https://twenty.com). It sets up a readytorun project that works seamlessly with the [twenty-sdk](https://www.npmjs.com/package/twenty-sdk).
- Zeroconfig project bootstrap
- Preconfigured scripts for auth, generate, dev sync, oneoff sync, uninstall
- Strong TypeScript support and typed client generation
## Prerequisites
- Node.js 24+ (recommended) and Yarn 4
- A Twenty workspace and an API key (create one at https://app.twenty.com/settings/api-webhooks)
## Quick start
```bash
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
# Authenticate using your API key (you'll be prompted)
yarn auth
# Add a new entity to your application (guided)
yarn create-entity
# Generate a typed Twenty client and workspace entity types
yarn generate
# Start dev mode: automatically syncs local changes to your workspace
yarn dev
# Or run a onetime sync
yarn sync
# Uninstall the application from the current workspace
yarn uninstall
```
## What gets scaffolded
- A minimal app structure ready for Twenty
- TypeScript configuration
- Prewired scripts that wrap the `twenty` CLI from twenty-sdk
- Example placeholders to help you add entities, actions, and sync logic
## Next steps
- Explore the generated project and add your first entity with `yarn create-entity`.
- Keep your types uptodate using `yarn generate`.
- Use `yarn dev` while you iterate to see changes instantly in your workspace.
## Publish your application
Applications are currently stored in `twenty/packages/twenty-apps`.
You can share your application with all Twenty users:
```bash
# pull the Twenty project
git clone https://github.com/twentyhq/twenty.git
cd twenty
# create a new branch
git checkout -b feature/my-awesome-app
```
- Copy your app folder into `twenty/packages/twenty-apps`.
- Commit your changes and open a pull request on https://github.com/twentyhq/twenty
```bash
git commit -m "Add new application"
git push
```
Our team reviews contributions for quality, security, and reusability before merging.
## Troubleshooting
- Auth prompts not appearing: run `yarn auth` again and verify the API key permissions.
- Types not generated: ensure `yarn generate` runs without errors, then restart `yarn dev`.
## Contributing
- See our [GitHub](https://github.com/twentyhq/twenty)
- Join our [Discord](https://discord.gg/cx5n4Jzs57)
+54
View File
@@ -0,0 +1,54 @@
{
"name": "create-twenty-app",
"version": "0.1.0",
"description": "Command-line interface to create Twenty application",
"main": "dist/cli.cjs",
"bin": "dist/cli.cjs",
"files": [
"dist/**/*"
],
"scripts": {
"build": "npx rimraf dist && npx vite build"
},
"keywords": [
"twenty",
"cli",
"crm",
"application",
"development"
],
"exports": {
".": {
"types": "./dist/cli.d.ts",
"import": "./dist/cli.mjs",
"require": "./dist/cli.cjs"
}
},
"license": "AGPL-3.0",
"dependencies": {
"@genql/cli": "^3.0.3",
"chalk": "^5.3.0",
"commander": "^12.0.0",
"fs-extra": "^11.2.0",
"inquirer": "^10.0.0",
"lodash.camelcase": "^4.3.0",
"lodash.kebabcase": "^4.1.1",
"lodash.startcase": "^4.4.0",
"uuid": "^13.0.0"
},
"devDependencies": {
"@types/fs-extra": "^11.0.0",
"@types/inquirer": "^9.0.0",
"@types/lodash.camelcase": "^4.3.7",
"@types/lodash.kebabcase": "^4.1.7",
"@types/lodash.startcase": "^4",
"@types/node": "^20.0.0",
"vite": "^7.0.0",
"vite-plugin-dts": "^4.5.4",
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
"node": "^24.5.0",
"yarn": "^4.0.2"
}
}
+56
View File
@@ -0,0 +1,56 @@
{
"name": "create-twenty-app",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"tags": ["scope:create-app"],
"targets": {
"build": {
"dependsOn": ["^build"],
"outputs": ["{projectRoot}/dist"]
},
"dev": {
"executor": "nx:run-commands",
"dependsOn": ["build"],
"options": {
"cwd": "packages/create-twenty-app",
"command": "tsx src/cli.ts"
}
},
"start": {
"executor": "nx:run-commands",
"dependsOn": ["build"],
"options": {
"cwd": "packages/create-twenty-app",
"command": "node dist/cli.cjs"
}
},
"typecheck": {},
"lint": {
"options": {
"lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
"maxWarnings": 0
},
"configurations": {
"ci": {
"lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
"maxWarnings": 0
},
"fix": {}
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "{projectRoot}/jest.config.mjs"
},
"configurations": {
"ci": {
"ci": true,
"coverage": true,
"watchAll": false
}
}
}
}
}
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env node
import chalk from 'chalk';
import { Command, CommanderError } from 'commander';
import { CreateAppCommand } from './create-app.command';
import packageJson from '../package.json';
const program = new Command(packageJson.name)
.description('CLI tool to initialize a new Twenty application')
.version(
packageJson.version,
'-v, --version',
'Output the current version of create-twenty-app.',
)
.argument('[directory]')
.helpOption('-h, --help', 'Display this help message.')
.action(async (directory?: string) => {
if (directory && !/^[a-z0-9-]+$/.test(directory)) {
console.error(
chalk.red(
`Invalid directory "${directory}". Must contain only lowercase letters, numbers, and hyphens`,
),
);
process.exit(1);
}
await new CreateAppCommand().execute(directory);
});
program.exitOverride();
try {
program.parse();
} catch (error) {
if (error instanceof CommanderError) {
process.exit(error.exitCode);
}
if (error instanceof Error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
}
@@ -0,0 +1 @@
24.5.0
@@ -0,0 +1,35 @@
This is a [Twenty](https://twenty.com) application project bootstrapped with [`create-twenty-app`](https://www.npmjs.com/package/create-twenty-app).
## Getting Started
First, authenticate to your workspace:
```bash
yarn auth
```
Then, run the development server:
```bash
yarn dev
```
Open your Twenty instance and go to `/settings/applications` section to see the result.
You can start adding twenty entities by running
```bash
yarn create-entity
```
The application auto-updates as you edit the file.
## Learn More
To learn more about Twenty applications, take a look at the following resources:
- [twenty-sdk](https://www.npmjs.com/package/twenty-sdk) - learn about `twenty-sdk` tool.
- [Twenty doc](https://docs.twenty.com/) - Twenty's documentation.
- Join our [Discord](https://discord.gg/cx5n4Jzs57)
You can check out [the Twenty GitHub repository](https://github.com/twentyhq/twenty) - your feedback and contributions are welcome!
@@ -0,0 +1,137 @@
import js from '@eslint/js';
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import typescriptParser from '@typescript-eslint/parser';
import importPlugin from 'eslint-plugin-import';
import preferArrowPlugin from 'eslint-plugin-prefer-arrow';
import prettierPlugin from 'eslint-plugin-prettier';
import unusedImportsPlugin from 'eslint-plugin-unused-imports';
export default [
// Base JS rules
js.configs.recommended,
// Global ignores
{
ignores: ['**/node_modules/**', '**/dist/**', '**/coverage/**'],
},
// Base config for TS/JS files
{
files: ['**/*.{js,jsx,ts,tsx}'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: {
prettier: prettierPlugin,
import: importPlugin,
'prefer-arrow': preferArrowPlugin,
'unused-imports': unusedImportsPlugin,
},
rules: {
// General rules (aligned with main project)
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': [
'warn',
{ allow: ['group', 'groupCollapsed', 'groupEnd'] },
],
'no-control-regex': 0,
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-undef': 'off',
'no-unused-vars': 'off',
// Import rules
'import/no-relative-packages': 'error',
'import/no-useless-path-segments': 'error',
'import/no-duplicates': ['error', { considerQueryString: true }],
// Prefer arrow functions
'prefer-arrow/prefer-arrow-functions': [
'error',
{
disallowPrototype: true,
singleReturnOnly: false,
classPropertiesAllowed: false,
},
],
// Unused imports
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
// Prettier (formatting as lint errors if you want)
'prettier/prettier': 'error',
},
},
// TypeScript-specific configuration
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
plugins: {
'@typescript-eslint': typescriptEslint,
},
rules: {
// Turn off base rule and use TS-aware versions
'no-redeclare': 'off',
'@typescript-eslint/no-redeclare': 'error',
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
fixStyle: 'inline-type-imports',
},
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unused-vars': 'off',
},
},
// Test files (Jest)
{
files: ['**/*.spec.@(ts|tsx|js|jsx)', '**/*.test.@(ts|tsx|js|jsx)'],
languageOptions: {
globals: {
jest: true,
describe: true,
it: true,
expect: true,
beforeEach: true,
afterEach: true,
beforeAll: true,
afterAll: true,
},
},
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
];
@@ -11,7 +11,7 @@
"experimentalDecorators": true,
"importHelpers": true,
"allowUnreachableCode": false,
"strictNullChecks": true,
"strict": true,
"alwaysStrict": true,
"noImplicitAny": true,
"strictBindCallApply": false,
@@ -22,6 +22,5 @@
"skipDefaultLibCheck": true,
"resolveJsonModule": true,
},
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
}
@@ -2,11 +2,15 @@ import chalk from 'chalk';
import * as fs from 'fs-extra';
import inquirer from 'inquirer';
import * as path from 'path';
import { copyBaseApplicationProject } from '../utils/app-template';
import { copyBaseApplicationProject } from './utils/app-template';
import kebabCase from 'lodash.kebabcase';
import { convertToLabel } from '../utils/convert-to-label';
import { convertToLabel } from './utils/convert-to-label';
import { tryGitInit } from './utils/try-git-init';
import { install } from './utils/install';
export class AppInitCommand {
const CURRENT_EXECUTION_DIRECTORY = process.env.INIT_CWD || process.cwd();
export class CreateAppCommand {
async execute(directory?: string): Promise<void> {
try {
const { appName, appDisplayName, appDirectory, appDescription } =
@@ -25,6 +29,10 @@ export class AppInitCommand {
appDirectory,
});
await install(appDirectory);
await tryGitInit(appDirectory);
this.logSuccess(appDirectory);
} catch (error) {
console.error(
@@ -78,8 +86,8 @@ export class AppInitCommand {
const appDescription = description.trim();
const appDirectory = directory
? path.join(process.cwd(), kebabCase(directory))
: path.join(process.cwd(), kebabCase(appName));
? path.join(CURRENT_EXECUTION_DIRECTORY, directory)
: path.join(CURRENT_EXECUTION_DIRECTORY, kebabCase(appName));
return { appName, appDisplayName, appDirectory, appDescription };
}
@@ -111,10 +119,10 @@ export class AppInitCommand {
}
private logSuccess(appDirectory: string): void {
console.log(chalk.green('✅ Application created successfully!'));
console.log(chalk.green('✅ Application created!'));
console.log('');
console.log(chalk.blue('Next steps:'));
console.log(` cd ${appDirectory}`);
console.log(' twenty app dev');
console.log(`cd ${appDirectory.split('/').reverse()[0] ?? ''}`);
console.log('yarn auth');
}
}
@@ -0,0 +1,141 @@
import * as fs from 'fs-extra';
import { join } from 'path';
import { v4 } from 'uuid';
export const copyBaseApplicationProject = async ({
appName,
appDisplayName,
appDescription,
appDirectory,
}: {
appName: string;
appDisplayName: string;
appDescription: string;
appDirectory: string;
}) => {
await fs.copy(join(__dirname, './constants/base-application'), appDirectory);
await createPackageJson({ appName, appDirectory });
await createGitignore(appDirectory);
await createYarnLock(appDirectory);
await createApplicationConfig({
displayName: appDisplayName,
description: appDescription,
appDirectory,
});
};
const createYarnLock = async (appDirectory: string) => {
const yarnLockContent = `# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
`;
await fs.writeFile(join(appDirectory, 'yarn.lock'), yarnLockContent);
};
const createGitignore = async (appDirectory: string) => {
const gitignoreContent = `# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn
# codegen
generated
# testing
/coverage
# dev
/dist/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# typescript
*.tsbuildinfo
`;
await fs.writeFile(join(appDirectory, '.gitignore'), gitignoreContent);
};
const createApplicationConfig = async ({
displayName,
description,
appDirectory,
}: {
displayName: string;
description?: string;
appDirectory: string;
}) => {
const content = `import { type ApplicationConfig } from 'twenty-sdk';
const config: ApplicationConfig = {
universalIdentifier: '${v4()}',
displayName: '${displayName}',
description: '${description ?? ''}',
};
export default config;
`;
await fs.writeFile(join(appDirectory, 'application.config.ts'), content);
};
const createPackageJson = async ({
appName,
appDirectory,
}: {
appName: string;
appDirectory: string;
}) => {
const packageJson = {
name: appName,
version: '0.1.0',
license: 'MIT',
engines: {
node: '^24.5.0',
npm: 'please-use-yarn',
yarn: '>=4.0.2',
},
packageManager: 'yarn@4.9.2',
scripts: {
'create-entity': 'twenty app add',
dev: 'twenty app dev',
generate: 'twenty app generate',
sync: 'twenty app sync',
uninstall: 'twenty app uninstall',
auth: 'twenty auth login',
},
dependencies: {
'twenty-sdk': '0.1.2',
},
devDependencies: {
'@types/node': '^24.7.2',
typescript: '^5.9.3',
},
};
await fs.writeFile(
join(appDirectory, 'package.json'),
JSON.stringify(packageJson, null, 2),
'utf8',
);
};
@@ -0,0 +1,13 @@
import chalk from 'chalk';
import { promisify } from 'util';
import { exec } from 'child_process';
const execPromise = promisify(exec);
export const install = async (root: string) => {
try {
await execPromise('yarn', { cwd: root });
} catch (error: any) {
console.error(chalk.red('yarn install failed:'), error.stdout);
}
};
@@ -0,0 +1,70 @@
import * as fs from 'fs-extra';
import { join } from 'path';
import { promisify } from 'util';
import { exec } from 'child_process';
const execPromise = promisify(exec);
const isInGitRepository = async (root: string): Promise<boolean> => {
try {
await execPromise('git rev-parse --is-inside-work-tree', { cwd: root });
return true;
} catch {
// Empty catch block
}
return false;
};
const isInMercurialRepository = async (root: string): Promise<boolean> => {
try {
await execPromise('hg --cwd . root', { cwd: root });
return true;
} catch {
// Empty catch block
}
return false;
};
const isDefaultBranchSet = async (root: string): Promise<boolean> => {
try {
await execPromise('git config init.defaultBranch', { cwd: root });
return true;
} catch {
// Empty catch block
}
return false;
};
export const tryGitInit = async (root: string): Promise<boolean> => {
try {
await execPromise('git --version', { cwd: root });
if (
(await isInGitRepository(root)) ||
(await isInMercurialRepository(root))
) {
return false;
}
await execPromise('git init', { cwd: root });
try {
if (!(await isDefaultBranchSet(root))) {
await execPromise('git checkout -b main', { cwd: root });
}
await execPromise('git add -A', { cwd: root });
await execPromise(
'git commit -m "Initial commit from Create Twenty App"',
{
cwd: root,
},
);
return true;
} catch {
fs.rm(join(root, '.git'), { recursive: true, force: true });
return false;
}
} catch {
return false;
}
};
+26
View File
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strictNullChecks": true,
"alwaysStrict": true,
"noImplicitAny": true,
"strictBindCallApply": false,
"noEmit": true,
"paths": {
"@/*": ["./src/*"]
}
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../../tsconfig.base.json"
}
@@ -1,21 +1,23 @@
{
"extends": "../../tsconfig.base.json",
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"module": "commonjs",
"target": "ES2022",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"declaration": false,
"sourceMap": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts", "**/*.e2e-spec.ts", "**/__tests__/**"]
"exclude": [
"node_modules",
"dist",
"**/*.test.ts",
"**/*.spec.ts",
"**/__tests__/**"
]
}
@@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["jest", "node"]
},
"include": [
"**/__mocks__/**/*",
"vite.config.ts",
"jest.config.mjs",
"src/**/*.d.ts",
"src/**/*.spec.ts",
"src/**/*.spec.tsx",
"src/**/*.test.ts",
"src/**/*.test.tsx"
]
}
+96
View File
@@ -0,0 +1,96 @@
import fs from 'fs-extra';
import path from 'path';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import tsconfigPaths from 'vite-tsconfig-paths';
import packageJson from './package.json';
const moduleEntries = Object.keys((packageJson as any).exports || {})
.filter(
(key) => key !== './style.css' && key !== '.' && !key.startsWith('./src/'),
)
.map((module) => `src/${module.replace(/^\.\//, '')}/index.ts`);
const entries = ['src/cli.ts', ...moduleEntries];
const entryFileNames = (chunk: any, extension: 'cjs' | 'mjs') => {
if (!chunk.isEntry) {
throw new Error(
`Should never occurs, encountered a non entry chunk ${chunk.facadeModuleId}`,
);
}
const splitFaceModuleId = chunk.facadeModuleId?.split('/');
if (splitFaceModuleId === undefined) {
throw new Error(
`Should never occurs splitFaceModuleId is undefined ${chunk.facadeModuleId}`,
);
}
const moduleDirectory = splitFaceModuleId[splitFaceModuleId?.length - 2];
if (moduleDirectory === 'src') {
return `${chunk.name}.${extension}`;
}
return `${moduleDirectory}.${extension}`;
};
const copyAssetPlugin = (targets: { src: string; dest: string }[]) => {
return {
name: 'copy-assets',
closeBundle: async () => {
for (const target of targets) {
await fs.copy(
path.resolve(__dirname, target.src),
path.resolve(__dirname, target.dest),
);
}
},
};
};
export default defineConfig(() => {
const tsConfigPath = path.resolve(__dirname, './tsconfig.lib.json');
return {
root: __dirname,
cacheDir: '../../node_modules/.vite/packages/create-twenty-app',
plugins: [
tsconfigPaths({
root: __dirname,
}),
dts({ entryRoot: './src', tsconfigPath: tsConfigPath }),
copyAssetPlugin([
{
src: 'src/constants/base-application',
dest: 'dist/constants/base-application',
},
]),
],
build: {
outDir: 'dist',
lib: { entry: entries, name: 'create-twenty-app' },
rollupOptions: {
external: [
...Object.keys((packageJson as any).dependencies || {}),
'path',
'fs',
'child_process',
],
output: [
{
format: 'es',
entryFileNames: (chunk) => entryFileNames(chunk, 'mjs'),
},
{
format: 'cjs',
interop: 'auto',
esModule: true,
exports: 'named',
entryFileNames: (chunk) => entryFileNames(chunk, 'cjs'),
},
],
},
},
logLevel: 'warn',
};
});
@@ -2056,8 +2056,8 @@ __metadata:
linkType: hard
"glob@npm:^10.2.2":
version: 10.4.5
resolution: "glob@npm:10.4.5"
version: 10.5.0
resolution: "glob@npm:10.5.0"
dependencies:
foreground-child: "npm:^3.1.0"
jackspeak: "npm:^3.1.2"
@@ -2067,7 +2067,7 @@ __metadata:
path-scurry: "npm:^1.11.1"
bin:
glob: dist/esm/bin.mjs
checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e
checksum: 10c0/100705eddbde6323e7b35e1d1ac28bcb58322095bd8e63a7d0bef1a2cdafe0d0f7922a981b2b48369a4f8c1b077be5c171804534c3509dfe950dde15fbe6d828
languageName: node
linkType: hard
@@ -239,6 +239,15 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^24.7.2":
version: 24.10.1
resolution: "@types/node@npm:24.10.1"
dependencies:
undici-types: "npm:~7.16.0"
checksum: 10c0/d6bca7a78f550fbb376f236f92b405d676003a8a09a1b411f55920ef34286ee3ee51f566203920e835478784df52662b5b2af89159d9d319352e9ea21801c002
languageName: node
linkType: hard
"abbrev@npm:^3.0.0":
version: 3.0.1
resolution: "abbrev@npm:3.0.1"
@@ -572,8 +581,8 @@ __metadata:
linkType: hard
"glob@npm:^10.2.2":
version: 10.4.5
resolution: "glob@npm:10.4.5"
version: 10.5.0
resolution: "glob@npm:10.5.0"
dependencies:
foreground-child: "npm:^3.1.0"
jackspeak: "npm:^3.1.2"
@@ -583,7 +592,7 @@ __metadata:
path-scurry: "npm:^1.11.1"
bin:
glob: dist/esm/bin.mjs
checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e
checksum: 10c0/100705eddbde6323e7b35e1d1ac28bcb58322095bd8e63a7d0bef1a2cdafe0d0f7922a981b2b48369a4f8c1b077be5c171804534c3509dfe950dde15fbe6d828
languageName: node
linkType: hard
@@ -907,8 +916,10 @@ __metadata:
version: 0.0.0-use.local
resolution: "rollup-engine@workspace:."
dependencies:
"@types/node": "npm:^24.7.2"
dotenv: "npm:^16.4.5"
tsx: "npm:^4.20.6"
twenty-sdk: "npm:0.0.3"
languageName: unknown
linkType: soft
@@ -1067,6 +1078,20 @@ __metadata:
languageName: node
linkType: hard
"twenty-sdk@npm:0.0.3":
version: 0.0.3
resolution: "twenty-sdk@npm:0.0.3"
checksum: 10c0/0a3c85c27edb22fb50f7eb0da4f9770e85729fce05e9e0118ad0cdfc36e42425c93340a6cd1c276daf30aeeaa612db0cd905831c0a8287a31bff3da5be9b0562
languageName: node
linkType: hard
"undici-types@npm:~7.16.0":
version: 7.16.0
resolution: "undici-types@npm:7.16.0"
checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a
languageName: node
linkType: hard
"unique-filename@npm:^4.0.0":
version: 4.0.0
resolution: "unique-filename@npm:4.0.0"
@@ -50,7 +50,7 @@ const returnWorkspaceMemberObjectId = async (): Promise<string> => {
).id;
};
const createUpdatedByField = async (
const createUpdatedByFieldMetadata = async (
sourceObjectId: string,
workspaceMemberObjectId: string,
objectName: string,
@@ -124,7 +124,7 @@ const createUpdatedByField = async (
}
};
const updateUpdatedByField = async (
const updateUpdatedByFieldValue = async (
objectName: string,
workspaceMemberId: string,
recordId: string,
@@ -184,7 +184,7 @@ export const main = async (params: {
const workspaceMemberObjectId: string =
await returnWorkspaceMemberObjectId();
const isFieldCreated: boolean | undefined = await createUpdatedByField(
const isFieldCreated: boolean | undefined = await createUpdatedByFieldMetadata(
objectMetadata.id,
workspaceMemberObjectId,
objectMetadata.namePlural,
@@ -198,7 +198,7 @@ export const main = async (params: {
}
}
const isObjectUpdated: boolean | undefined = await updateUpdatedByField(
const isObjectUpdated: boolean | undefined = await updateUpdatedByFieldValue(
objectMetadata.namePlural,
workspaceMemberId,
recordId,
+8 -5
View File
@@ -1,13 +1,16 @@
# Why Twenty CLI?
# Deprecated: twenty-cli
A command-line interface to easily scaffold, develop, and publish applications that extend Twenty CRM
## Installation
This package is deprecated. Please install and use twenty-sdk instead:
```bash
npm install -g twenty-cli
npm uninstall twenty-cli
npm install -g twenty-sdk
```
The command name remains the same: twenty.
A command-line interface to easily scaffold, develop, and publish applications that extend Twenty CRM (now provided by twenty-sdk).
## Requirements
- yarn >= 4.9.2
- an `apiKey`. Go to `https://twenty.com/settings/api-webhooks` to generate one
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env node
const message = `\nTwenty CLI (twenty-cli) is deprecated.\n\nPlease install and use the new package instead:\n npm install -g twenty-sdk\n\nThe command name remains the same: \"twenty\".\nMore info: https://www.npmjs.com/package/twenty-sdk\n`;
console.error(message);
process.exitCode = 1;
+4 -58
View File
@@ -1,64 +1,10 @@
{
"name": "twenty-cli",
"version": "0.2.4",
"description": "Command-line interface for Twenty application development",
"main": "dist/cli.js",
"bin": {
"twenty": "dist/cli.js"
},
"files": [
"dist/**/*",
"!dist/**/*.e2e-spec.*",
"!dist/**/__tests__/**"
],
"version": "0.3.0",
"description": "[DEPRECATED] Use twenty-sdk instead: https://www.npmjs.com/package/twenty-sdk",
"scripts": {
"build": "echo 'use npx nx build'",
"dev": "tsx src/cli.ts",
"start": "node dist/cli.js"
"start": "echo 'deprecated'"
},
"keywords": [
"twenty",
"cli",
"crm",
"application",
"development"
],
"license": "AGPL-3.0",
"dependencies": {
"@genql/cli": "^3.0.3",
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1",
"axios": "^1.6.0",
"chalk": "^5.3.0",
"chokidar": "^4.0.0",
"commander": "^12.0.0",
"dotenv": "^16.4.0",
"fs-extra": "^11.2.0",
"graphql": "^16.8.1",
"inquirer": "^10.0.0",
"jsonc-parser": "^3.2.0",
"lodash.camelcase": "^4.3.0",
"lodash.capitalize": "^4.2.1",
"lodash.kebabcase": "^4.1.1",
"lodash.startcase": "^4.4.0",
"typescript": "^5.9.2",
"uuid": "^13.0.0"
},
"devDependencies": {
"@types/fs-extra": "^11.0.0",
"@types/inquirer": "^9.0.0",
"@types/jest": "^29.5.0",
"@types/lodash.camelcase": "^4.3.7",
"@types/lodash.capitalize": "^4",
"@types/lodash.kebabcase": "^4.1.7",
"@types/lodash.startcase": "^4",
"@types/node": "^20.0.0",
"jest": "^29.5.0",
"tsx": "^4.7.0",
"wait-on": "^7.2.0"
},
"engines": {
"node": "^24.5.0",
"yarn": "^4.0.2"
}
"license": "AGPL-3.0"
}
-94
View File
@@ -1,94 +0,0 @@
{
"name": "twenty-cli",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"tags": ["scope:cli"],
"targets": {
"before-build": {
"executor": "nx:run-commands",
"cache": true,
"options": {
"cwd": "packages/twenty-cli",
"commands": ["rimraf dist", "tsc --project tsconfig.lib.json"]
},
"dependsOn": ["^build", "typecheck"]
},
"build": {
"executor": "nx:run-commands",
"cache": true,
"options": {
"cwd": "packages/twenty-cli",
"commands": [
"cp -R src/constants/base-application-project dist/constants"
]
},
"dependsOn": ["before-build"]
},
"dev": {
"executor": "nx:run-commands",
"dependsOn": ["build"],
"options": {
"cwd": "packages/twenty-cli",
"command": "tsx src/cli.ts"
}
},
"start": {
"executor": "nx:run-commands",
"dependsOn": ["build"],
"options": {
"cwd": "packages/twenty-cli",
"command": "node dist/cli.js"
}
},
"typecheck": {},
"lint": {
"options": {
"lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
"maxWarnings": 0
},
"configurations": {
"ci": {
"lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
"maxWarnings": 0
},
"fix": {}
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "{projectRoot}/jest.config.mjs"
},
"configurations": {
"ci": {
"ci": true,
"coverage": true,
"watchAll": false
}
}
},
"test:e2e": {
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"cwd": "packages/twenty-cli",
"commands": [
"npx wait-on http://localhost:3000/healthz --timeout 600000 --interval 1000 --log && NODE_ENV=test npx jest --config ./jest.e2e.config.ts"
]
},
"parallel": false,
"dependsOn": [
"build",
{
"target": "database:reset",
"projects": "twenty-server"
},
{
"target": "start:ci-if-needed",
"projects": "twenty-server"
}
]
}
}
}
@@ -1,26 +0,0 @@
# Set environment values for your application here.
# Use the format: KEY=value
#
# These variables are automatically loaded when running your serverless functions.
# You can access them directly in your code using:
# const myValue = process.env.KEY;
#
# To make these variables available to your application, add them in application.config.ts file
#
# const config: ApplicationConfig = {
# ...
# applicationVariables: {
# KEY: {
# universalIdentifier: 'dedc53eb-9c12-4fe2-ba86-4a2add19d305',
# description: 'Description',
# isSecret: true,
# },
# },
# };
#
# Those environment variables will be provided to your serverless
# functions at runtime.
#
# Example:
# API_TOKEN=your-api-token
# TIMEOUT_MS=3000
@@ -1,5 +0,0 @@
# Duplicated with ./gitignore because npm publish does not include .gitignore
# https://github.com/npm/npm/issues/3763
.yarn/install-state.gz
.env
@@ -1,15 +0,0 @@
# {title}
{description}
## Requirements
- twenty-cli `npm install -g twenty-cli`
- an `apiKey`. Go to `https://twenty.com/settings/api-webhooks` to generate one
## Install to your Twenty workspace
```bash
twenty auth login
twenty app sync
```
@@ -1,2 +0,0 @@
.yarn/install-state.gz
.env
@@ -1,17 +0,0 @@
{
"name": "my-application",
"version": "0.0.1",
"license": "MIT",
"engines": {
"node": "^24.5.0",
"npm": "please-use-yarn",
"yarn": ">=4.0.2"
},
"packageManager": "yarn@4.9.2",
"dependencies": {
"twenty-sdk": "0.0.6"
},
"devDependencies": {
"@types/node": "^24.7.2"
}
}
@@ -1,38 +0,0 @@
# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!
__metadata:
version: 8
cacheKey: 10c0
"@types/node@npm:^24.7.2":
version: 24.9.1
resolution: "@types/node@npm:24.9.1"
dependencies:
undici-types: "npm:~7.16.0"
checksum: 10c0/c52f8168080ef9a7c3dc23d8ac6061fab5371aad89231a0f6f4c075869bc3de7e89b075b1f3e3171d9e5143d0dda1807c3dab8e32eac6d68f02e7480e7e78576
languageName: node
linkType: hard
"root-workspace-0b6124@workspace:.":
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
"@types/node": "npm:^24.7.2"
twenty-sdk: "npm:^0.0.2"
languageName: unknown
linkType: soft
"twenty-sdk@npm:^0.0.2":
version: 0.0.2
resolution: "twenty-sdk@npm:0.0.2"
checksum: 10c0/99e6fe86059d847b548c1f03e0f0c59a4d540caf1d28dd4500f1f5f0094196985ded955801274de9e72ff03e3d1f41e9a509b4c2c5a02ffc8a027277b1e35d8e
languageName: node
linkType: hard
"undici-types@npm:~7.16.0":
version: 7.16.0
resolution: "undici-types@npm:7.16.0"
checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a
languageName: node
linkType: hard
@@ -1,8 +0,0 @@
import { join } from 'path';
const BASE_PATH = join(__dirname, '../constants');
export const BASE_APPLICATION_PROJECT_PATH = join(
BASE_PATH,
'base-application-project',
);
@@ -1,107 +0,0 @@
import * as fs from 'fs-extra';
import { BASE_APPLICATION_PROJECT_PATH } from '../constants/constants-path';
import { writeJsoncFile } from '../utils/jsonc-parser';
import { join } from 'path';
import path from 'path';
import { v4 } from 'uuid';
export const copyBaseApplicationProject = async ({
appName,
appDisplayName,
appDescription,
appDirectory,
}: {
appName: string;
appDisplayName: string;
appDescription: string;
appDirectory: string;
}) => {
await fs.copy(BASE_APPLICATION_PROJECT_PATH, appDirectory);
await fs.rename(
join(appDirectory, 'gitignore'),
join(appDirectory, '.gitignore'),
);
await fs.copy(join(appDirectory, '.env.example'), join(appDirectory, '.env'));
await createBasePackageJson({
appName,
appDirectory,
});
await createApplicationConfig({
displayName: appDisplayName,
description: appDescription,
appDirectory,
});
await createReadmeContent({
displayName: appDisplayName,
appDescription,
appDirectory,
});
};
const createApplicationConfig = async ({
displayName,
description,
appDirectory,
}: {
displayName: string;
description?: string;
appDirectory: string;
}) => {
const content = `import { type ApplicationConfig } from 'twenty-sdk/application';
const config: ApplicationConfig = {
universalIdentifier: '${v4()}',
displayName: '${displayName}',
description: '${description ?? ''}',
};
export default config;
`;
await fs.writeFile(path.join(appDirectory, 'application.config.ts'), content);
};
const createBasePackageJson = async ({
appName,
appDirectory,
}: {
appName: string;
appDirectory: string;
}) => {
const base = JSON.parse(await readBaseApplicationProjectFile('package.json'));
base['universalIdentifier'] = v4();
base['name'] = appName;
await writeJsoncFile(join(appDirectory, 'package.json'), base);
};
const createReadmeContent = async ({
displayName,
appDescription,
appDirectory,
}: {
displayName: string;
appDescription: string;
appDirectory: string;
}) => {
let readmeContent = await readBaseApplicationProjectFile('README.md');
readmeContent = readmeContent.replace(/\{title}/g, displayName);
readmeContent = readmeContent.replace(/\{description}/g, appDescription);
await fs.writeFile(path.join(appDirectory, 'README.md'), readmeContent);
};
const readBaseApplicationProjectFile = async (fileName: string) => {
return await fs.readFile(
join(BASE_APPLICATION_PROJECT_PATH, fileName),
'utf-8',
);
};
-8
View File
@@ -1,8 +0,0 @@
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"composite": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts", "**/*.e2e-spec.ts", "**/__tests__/**"]
}
-14
View File
@@ -1,14 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["jest", "node"]
},
"include": [
"src/**/*",
"src/**/__tests__/**/*.spec.ts"
],
"exclude": [
"node_modules",
"dist",
]
}
@@ -39,6 +39,12 @@ Deploy Twenty on Railway with the community maintained template below.
[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty on Sealos
Deploy Twenty on Sealos with the community maintained template below.
[![Deploy on Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Others
Please feel free to Open a PR to add more Cloud Provider options.
@@ -39,6 +39,12 @@ crwdns60692:0crwdne60692:0
crwdns60694:0https://railway.com/button.svgcrwdnd60694:0https://railway.com/deploy/nAL3hAcrwdne60694:0
### crwdns64878:0crwdne64878:0
crwdns64880:0crwdne64880:0
crwdns64882:0https://sealos.io/Deploy-on-Sealos.svgcrwdnd64882:0https://sealos.io/products/app-store/twentycrwdne64882:0
## crwdns60696:0crwdne60696:0
crwdns60698:0crwdne60698:0
@@ -39,6 +39,12 @@ Stel Twenty op Railway in met die gemeenskap-onderhoudene sjabloon hieronder.
[![Stel op Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Ander
Stel Twenty op Sealos in met die deur die gemeenskap onderhoue sjabloon hieronder.
[![Stel op Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Ander
Voel vry om 'n PR te open om meer Wolkverskaffer opsies by te voeg.
@@ -57,7 +57,7 @@ sectionInfo: أتمتة العمليات والاندماج مع الأدوات
**المشكلة**: الوصول إلى حد 100 سير عمل متزامن لكل مساحة عمل.
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>لا يمكنك تشغيل أكثر من 100 سير عمل بالتوازي في أي وقت لكل مساحة عمل.</Warning></Warning>
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>لا يمكنك تشغيل أكثر من 100 سير عمل بالتوازي في أي وقت لكل مساحة عمل.</Warning></Warning>
**حلول**:
@@ -39,6 +39,12 @@ Nasazení Twenty na Railway s komunitně udržovanou šablonou níže.
[![Nasadit na Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Ostatní
Nasazení Twenty na Sealos s komunitně udržovanou šablonou níže.
[![Nasadit na Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Ostatní
Neváhejte otevřít PR pro přidání dalších možností poskytovatele cloudových služeb.
@@ -39,6 +39,12 @@ Implementer Twenty på Railway med den fællesskabsvedligeholdte skabelon nedenf
[![Implementer på Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty på Sealos
Implementer Twenty på Sealos med den fællesskabsvedligeholdte skabelon nedenfor.
[![Implementer på Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Andre
Du er velkommen til at åbne en PR for at tilføje flere Cloud Provider-muligheder.
@@ -39,6 +39,12 @@ image: /images/user-guide/notes/notes_header.png
[![Ανάπτυξη στο Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty στο Sealos
Αναπτύξτε το Twenty στο Sealos με το υποστηριζόμενο από την κοινότητα πρότυπο παρακάτω.
[![Ανάπτυξη στο Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Άλλες επιλογές
Παρακαλώ μη διστάσετε να ανοίξετε ένα PR για να προσθέσετε περισσότερες επιλογές Παρόχου Cloud.
@@ -18,7 +18,7 @@ Absolutamente. Puedes crear un nuevo espacio de trabajo haciendo clic en el men
<Accordion title="I accidentally created multiple workspaces but only need one. What should I do?"><Accordion title="How do I change my workspace appearance and regional settings?">Ve a `Configuración → Experiencia` para personalizar:
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>No elimines tu cuenta (accesible en Configuración → Configuración de perfil): tu cuenta se comparte entre los diferentes espacios de trabajo.</Warning></Warning>
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>No elimines tu cuenta (accesible en Configuración → Configuración de perfil): tu cuenta se comparte entre los diferentes espacios de trabajo.</Warning></Warning>
</Accordion>
<Accordion title="How can I disable my workspace?"><Accordion title="How can I disable my workspace?"><Accordion title="How can I disable my workspace?"><Accordion title="How can I disable my workspace?"><Accordion title="How can I disable my workspace?">Si solo deseas desactivar tu espacio de trabajo (no eliminarlo), ve a `Configuración → Facturación` y haz clic en `Cancelar plan`.</Accordion></Accordion>
@@ -57,7 +57,7 @@ Los formularios están diseñados actualmente solo para disparadores manuales. P
**Problema**: Se alcanza el límite de 100 flujos de trabajo concurrentes por espacio de trabajo.
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>No puedes ejecutar más de 100 flujos de trabajo en paralelo en cualquier momento por espacio de trabajo.</Warning></Warning>
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>No puedes ejecutar más de 100 flujos de trabajo en paralelo en cualquier momento por espacio de trabajo.</Warning></Warning>
**Soluciones**:
@@ -39,6 +39,12 @@ Déployez Twenty sur Railway avec le modèle maintenu par la communauté ci-dess
[![Déployer sur Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty sur Sealos
Déployez Twenty sur Sealos avec le modèle maintenu par la communauté ci-dessous.
[![Déployer sur Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Autres
N'hésitez pas à ouvrir une PR pour ajouter d'autres options de fournisseur cloud.
@@ -25,7 +25,7 @@ Vous pouvez **voir, modifier, supprimer des enregistrements** à partir de là a
- Utilisez la **barre de recherche** (appuyez sur `/` pour y accéder instantanément)
- Ouvrir la section **Paramètres**
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>Veuillez noter que notre documentation API est accessible sous la section Paramètres et non dans le guide de l'utilisateur.</Warning></Warning>
<Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning><Warning>Veuillez noter que notre documentation API est accessible sous la section Paramètres et non dans le guide de l'utilisateur.</Warning></Warning>
- </Warning>
Ayez un accès direct à vos **vues favorites**. Les favoris sont uniques pour chaque utilisateur.
@@ -39,6 +39,12 @@ image: /images/user-guide/notes/notes_header.png
[![פרסו על Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty על Sealos
פרסו את Twenty ב-Sealos עם התבנית המנוהלת על ידי הקהילה למטה.
[![פרסו על Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## אחרים
אל תהססו לפתוח PR כדי להוסיף עוד אפשרויות ספקי ענן.
@@ -39,6 +39,12 @@ Telepítse a Twenty-t a Railwayre az alábbi közösségi karbantartású sablon
[![Telepítés a Railwayre](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty a Sealoson
Nyugodtan nyisson PR-t további felhőszolgáltatók hozzáadásához.
[![Telepítés a Sealosra](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Egyéb
Nyugodtan nyisson PR-t további felhőszolgáltatók hozzáadásához.
@@ -23,6 +23,14 @@ Figma は、デザイナーと開発者の間のコミュニケーションの
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
このガイドは、Figma を使って共同作業する方法を説明します。
## アクセス
@@ -84,6 +92,28 @@ Figma プラットフォームの学習に関するより包括的な詳細と
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
これは推奨拡張機能の一部です。
## コラボレーション
@@ -41,6 +41,12 @@ Coolifyを使用してサーバーにTwentyをデプロイします。 (Coolify
[![Railwayにデプロイする](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Sealos上のTwenty
以下のコミュニティがメンテナンスしているテンプレートを使用して、SealosにTwentyをデプロイします。
[![Sealosにデプロイする](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## その他
もっと多くのクラウドプロバイダーオプションを追加するために、PRを自由に作成してください。
@@ -158,7 +158,7 @@ SSLHTTPS)は、特定のブラウザ機能が正しく動作するために
2. **.env ファイルを更新**
.env`ファイルを開き、`SERVER_URL\\\\\\\\\\\\\\`を更新します:
.env`ファイルを開き、`SERVER_URL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`を更新します:
```ini
SERVER_URL=http(s)://your-domain-or-ip:your-port
@@ -27,10 +27,10 @@ Twentyは、日常をサポートする最適なデータモデルを形成す
例:Stripeではオブジェクト`サブスクリプション`が、Airbnbではオブジェクト`旅行`が、スタートアップアクセラレーターではオブジェクト`バッチ`が必要でしょう。
**2. バリエーションにはフィールドを使い、新しいオブジェクトは使わないでください。**
既存のオブジェクトの特性に過ぎないもの(例:会社の「業種」や機会の「ステータス」)はフィールドにします。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。
既存のオブジェクトの特性に過ぎないもの(例:会社の「業種」や機会の「ステータス」)はフィールドにします。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。 カテゴリ、ラベル、属性にはフィールドが最適です。
**3. 単独で存在する場合には新しいオブジェクトを作成してください。**
概念が独自のライフサイクル、プロパティ、または関係を持つ場合、それは通常オブジェクトに値します。 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば:
概念が独自のライフサイクル、プロパティ、または関係を持つ場合、それは通常オブジェクトに値します。 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば: 例えば:
- **プロジェクト**:独自の期限、所有者、タスクを持つもの
- **サブスクリプション**:会社、製品、請求書を結ぶもの
@@ -50,7 +50,7 @@ CRMには基本的な2つの種類のレコードがあります:
## オブジェクト
オブジェクトは、CRMにおける特定のエンティティを表すデータ構造です(例:人々、会社、機会)。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。
オブジェクトは、CRMにおける特定のエンティティを表すデータ構造です(例:人々、会社、機会)。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。 オブジェクトは標準(ビルトイン)またはカスタム(あなたによって作成)することができます。
## 商談
@@ -39,6 +39,12 @@ Implementeer Twenty op Railway met de hieronder vermelde, door de gemeenschap on
[![Implementeer op Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty op Sealos
Implementeer Twenty op Sealos met de hieronder vermelde, door de gemeenschap onderhouden sjabloon.
[![Implementeer op Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Andere
Voel je vrij om een PR in te dienen om meer Cloud Provider-opties toe te voegen.
@@ -39,6 +39,12 @@ Implante Twenty no Railway com o template mantido pela comunidade abaixo.
[![Implantar no Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Twenty no Sealos
Implante Twenty no Sealos com o template mantido pela comunidade abaixo.
[![Implantar no Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Outros
Sinta-se à vontade para abrir um PR para adicionar mais opções de Provedor de Nuvem.
@@ -39,6 +39,12 @@ Triển khai Twenty trên Railway với mẫu do cộng đồng duy trì dưới
[![Triển khai trên Railway](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Khác
Hãy tự do mở một PR để thêm nhiều tùy chọn Nhà cung cấp Đám mây hơn.
[![Triển khai trên Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## Khác
Hãy tự do mở một PR để thêm nhiều tùy chọn Nhà cung cấp Đám mây hơn.
@@ -17,7 +17,7 @@ image: /images/user-guide/notes/notes_header.png
### Coolify
使用 Coolify 部署 Twenty 到伺服器。 (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出)
使用 Coolify 部署 Twenty 到伺服器。 (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出) (官方 Coolify 映像即將推出)
[Coolify 文件](https://coolify.io/docs/get-started/introduction)
@@ -39,6 +39,12 @@ image: /images/user-guide/notes/notes_header.png
[![在 Railway 上部署](https://railway.com/button.svg)](https://railway.com/deploy/nAL3hA)
### Sealos 上的 Twenty
使用下面社群維護的範本在 Sealos 部署 Twenty。
[![在 Sealos 上部署](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/twenty)
## 其他
歡迎自由提交 PR 以增加更多的雲供應商選項。
@@ -45,8 +45,9 @@ sectionInfo: 配置您的Twenty工作空间设置和偏好
刪除您的帳號將永久移除您對所有工作空間的訪問。
刪除您的帳號將永久移除您對所有工作空間的訪問。 此操作無法撤銷,您將失去所有工作空間權限,如您只想退出特定的團隊,應考慮退出個別的工作空間。 刪除您的帳號將永久移除您對所有工作空間的訪問。
刪除您的帳號將永久移除您對所有工作空間的訪問。 此操作無法撤銷,您將失去所有工作空間權限,如您只想退出特定的團隊,應考慮退出個別的工作空間。
</Warning> 刪除您的帳號將永久移除您對所有工作空間的訪問。
</Warning> 刪除您的帳號將永久移除您對所有工作空間的訪問。
刪除您的帳號將永久移除您對所有工作空間的訪問。 此操作無法撤銷,您將失去所有工作空間權限,如您只想退出特定的團隊,應考慮退出個別的工作空間。
</Warning>
要删除您的帐户:
+2 -1
View File
@@ -24,7 +24,8 @@
"@tiptap/core": "^3.4.2",
"@types/react": "^19",
"@types/react-dom": "^19",
"react-email": "4.0.6"
"react-email": "4.0.6",
"vite-plugin-dts": "3.8.1"
},
"exports": {
".": {
+3
View File
@@ -55,6 +55,7 @@
"@react-email/components": "^0.5.3",
"@react-pdf/renderer": "^4.1.6",
"@scalar/api-reference-react": "^0.4.36",
"@sentry/react": "^10.27.0",
"@tiptap/core": "^3.4.2",
"@tiptap/extension-bold": "^3.4.2",
"@tiptap/extension-document": "^3.4.2",
@@ -146,6 +147,8 @@
"optionator": "^0.9.1",
"playwright": "^1.56.1",
"rollup-plugin-visualizer": "^5.14.0",
"vite-plugin-checker": "^0.10.2",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^4.2.1"
}
}
File diff suppressed because one or more lines are too long
+76 -79
View File
@@ -53,6 +53,7 @@ export type Agent = {
applicationId?: Maybe<Scalars['UUID']>;
createdAt: Scalars['DateTime'];
description?: Maybe<Scalars['String']>;
evaluationInputs: Array<Scalars['String']>;
icon?: Maybe<Scalars['String']>;
id: Scalars['UUID'];
isCustom: Scalars['Boolean'];
@@ -67,17 +68,32 @@ export type Agent = {
updatedAt: Scalars['DateTime'];
};
export type AgentChatMessage = {
__typename?: 'AgentChatMessage';
export type AgentChatThread = {
__typename?: 'AgentChatThread';
createdAt: Scalars['DateTime'];
id: Scalars['UUID'];
parts: Array<AgentChatMessagePart>;
role: Scalars['String'];
threadId: Scalars['UUID'];
title?: Maybe<Scalars['String']>;
updatedAt: Scalars['DateTime'];
};
export type AgentChatMessagePart = {
__typename?: 'AgentChatMessagePart';
export type AgentIdInput = {
/** The id of the agent. */
id: Scalars['UUID'];
};
export type AgentMessage = {
__typename?: 'AgentMessage';
agentId?: Maybe<Scalars['UUID']>;
createdAt: Scalars['DateTime'];
id: Scalars['UUID'];
parts: Array<AgentMessagePart>;
role: Scalars['String'];
threadId: Scalars['UUID'];
turnId: Scalars['UUID'];
};
export type AgentMessagePart = {
__typename?: 'AgentMessagePart';
createdAt: Scalars['DateTime'];
errorDetails?: Maybe<Scalars['JSON']>;
errorMessage?: Maybe<Scalars['String']>;
@@ -105,24 +121,23 @@ export type AgentChatMessagePart = {
type: Scalars['String'];
};
export type AgentChatThread = {
__typename?: 'AgentChatThread';
export type AgentTurn = {
__typename?: 'AgentTurn';
agentId?: Maybe<Scalars['UUID']>;
createdAt: Scalars['DateTime'];
evaluations: Array<AgentTurnEvaluation>;
id: Scalars['UUID'];
messages: Array<AgentMessage>;
threadId: Scalars['UUID'];
};
export type AgentTurnEvaluation = {
__typename?: 'AgentTurnEvaluation';
comment?: Maybe<Scalars['String']>;
createdAt: Scalars['DateTime'];
id: Scalars['UUID'];
title?: Maybe<Scalars['String']>;
updatedAt: Scalars['DateTime'];
};
export type AgentHandoff = {
__typename?: 'AgentHandoff';
description?: Maybe<Scalars['String']>;
id: Scalars['UUID'];
toAgent: Agent;
};
export type AgentIdInput = {
/** The id of the agent. */
id: Scalars['UUID'];
score: Scalars['Int'];
turnId: Scalars['UUID'];
};
export type AggregateChartConfiguration = {
@@ -136,6 +151,8 @@ export type AggregateChartConfiguration = {
format?: Maybe<Scalars['String']>;
graphType: GraphType;
label?: Maybe<Scalars['String']>;
prefix?: Maybe<Scalars['String']>;
suffix?: Maybe<Scalars['String']>;
timezone?: Maybe<Scalars['String']>;
};
@@ -328,10 +345,12 @@ export type BarChartConfiguration = {
color?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
displayDataLabel?: Maybe<Scalars['Boolean']>;
displayLegend?: Maybe<Scalars['Boolean']>;
filter?: Maybe<Scalars['JSON']>;
firstDayOfTheWeek?: Maybe<Scalars['Int']>;
graphType: GraphType;
groupMode?: Maybe<BarChartGroupMode>;
isCumulative?: Maybe<Scalars['Boolean']>;
omitNullValues?: Maybe<Scalars['Boolean']>;
primaryAxisDateGranularity?: Maybe<ObjectRecordGroupByDateGranularity>;
primaryAxisGroupByFieldMetadataId: Scalars['UUID'];
@@ -670,6 +689,7 @@ export type CoreView = {
kanbanAggregateOperation?: Maybe<AggregateOperations>;
kanbanAggregateOperationFieldMetadataId?: Maybe<Scalars['UUID']>;
key?: Maybe<ViewKey>;
mainGroupByFieldMetadataId?: Maybe<Scalars['UUID']>;
name: Scalars['String'];
objectMetadataId: Scalars['UUID'];
openRecordIn: ViewOpenRecordIn;
@@ -755,14 +775,9 @@ export type CoreViewSort = {
workspaceId: Scalars['UUID'];
};
export type CreateAgentHandoffInput = {
description?: InputMaybe<Scalars['String']>;
fromAgentId: Scalars['UUID'];
toAgentId: Scalars['UUID'];
};
export type CreateAgentInput = {
description?: InputMaybe<Scalars['String']>;
evaluationInputs?: InputMaybe<Array<Scalars['String']>>;
icon?: InputMaybe<Scalars['String']>;
label: Scalars['String'];
modelConfiguration?: InputMaybe<Scalars['JSON']>;
@@ -949,6 +964,7 @@ export type CreateViewInput = {
kanbanAggregateOperation?: InputMaybe<AggregateOperations>;
kanbanAggregateOperationFieldMetadataId?: InputMaybe<Scalars['UUID']>;
key?: InputMaybe<ViewKey>;
mainGroupByFieldMetadataId?: InputMaybe<Scalars['UUID']>;
name: Scalars['String'];
objectMetadataId: Scalars['UUID'];
openRecordIn?: InputMaybe<ViewOpenRecordIn>;
@@ -1257,15 +1273,13 @@ export enum FeatureFlagKey {
IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED = 'IS_GLOBAL_WORKSPACE_DATASOURCE_ENABLED',
IS_IMAP_SMTP_CALDAV_ENABLED = 'IS_IMAP_SMTP_CALDAV_ENABLED',
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
IS_MESSAGE_FOLDER_CONTROL_ENABLED = 'IS_MESSAGE_FOLDER_CONTROL_ENABLED',
IS_PAGE_LAYOUT_ENABLED = 'IS_PAGE_LAYOUT_ENABLED',
IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
IS_RECORD_PAGE_LAYOUT_ENABLED = 'IS_RECORD_PAGE_LAYOUT_ENABLED',
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED',
IS_WORKFLOW_RUN_STOPPAGE_ENABLED = 'IS_WORKFLOW_RUN_STOPPAGE_ENABLED',
IS_WORKSPACE_MIGRATION_V2_ENABLED = 'IS_WORKSPACE_MIGRATION_V2_ENABLED'
IS_WORKFLOW_RUN_STOPPAGE_ENABLED = 'IS_WORKFLOW_RUN_STOPPAGE_ENABLED'
}
export type Field = {
@@ -1659,9 +1673,11 @@ export type LineChartConfiguration = {
color?: Maybe<Scalars['String']>;
description?: Maybe<Scalars['String']>;
displayDataLabel?: Maybe<Scalars['Boolean']>;
displayLegend?: Maybe<Scalars['Boolean']>;
filter?: Maybe<Scalars['JSON']>;
firstDayOfTheWeek?: Maybe<Scalars['Int']>;
graphType: GraphType;
isCumulative?: Maybe<Scalars['Boolean']>;
isStacked?: Maybe<Scalars['Boolean']>;
omitNullValues?: Maybe<Scalars['Boolean']>;
primaryAxisDateGranularity?: Maybe<ObjectRecordGroupByDateGranularity>;
@@ -1729,10 +1745,8 @@ export type Mutation = {
checkPublicDomainValidRecords?: Maybe<DomainValidRecords>;
checkoutSession: BillingSessionOutput;
computeStepOutputSchema: Scalars['JSON'];
createAgentHandoff: Scalars['Boolean'];
createApiKey: ApiKey;
createApprovedAccessDomain: ApprovedAccessDomain;
createChatThread: AgentChatThread;
createCoreView: CoreView;
createCoreViewField: CoreViewField;
createCoreViewFilter: CoreViewFilter;
@@ -1826,7 +1840,6 @@ export type Mutation = {
initiateOTPProvisioning: InitiateTwoFactorAuthenticationProvisioningOutput;
initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioningOutput;
publishServerlessFunction: ServerlessFunction;
removeAgentHandoff: Scalars['Boolean'];
removeRoleFromAgent: Scalars['Boolean'];
renewToken: AuthTokens;
resendEmailVerificationToken: ResendEmailVerificationTokenOutput;
@@ -1890,6 +1903,7 @@ export type Mutation = {
uploadImage: SignedFile;
uploadProfilePicture: SignedFile;
uploadWorkspaceLogo: SignedFile;
uploadWorkspaceMemberProfilePicture: SignedFile;
upsertFieldPermissions: Array<FieldPermission>;
upsertObjectPermissions: Array<ObjectPermission>;
upsertPermissionFlags: Array<PermissionFlag>;
@@ -1949,11 +1963,6 @@ export type MutationComputeStepOutputSchemaArgs = {
};
export type MutationCreateAgentHandoffArgs = {
input: CreateAgentHandoffInput;
};
export type MutationCreateApiKeyArgs = {
input: CreateApiKeyInput;
};
@@ -2409,11 +2418,6 @@ export type MutationPublishServerlessFunctionArgs = {
};
export type MutationRemoveAgentHandoffArgs = {
input: RemoveAgentHandoffInput;
};
export type MutationRemoveRoleFromAgentArgs = {
agentId: Scalars['UUID'];
};
@@ -2746,6 +2750,11 @@ export type MutationUploadWorkspaceLogoArgs = {
};
export type MutationUploadWorkspaceMemberProfilePictureArgs = {
file: Scalars['Upload'];
};
export type MutationUpsertFieldPermissionsArgs = {
upsertFieldPermissionsInput: UpsertFieldPermissionsInput;
};
@@ -2915,7 +2924,7 @@ export type ObjectRecordFilterInput = {
updatedAt?: InputMaybe<DateTimeFilter>;
};
/** Date granularity options (e.g. DAY, MONTH, QUARTER, YEAR, DAY_OF_THE_WEEK, MONTH_OF_THE_YEAR, QUARTER_OF_THE_YEAR) */
/** Date granularity options (e.g. DAY, MONTH, QUARTER, YEAR, WEEK, DAY_OF_THE_WEEK, MONTH_OF_THE_YEAR, QUARTER_OF_THE_YEAR) */
export enum ObjectRecordGroupByDateGranularity {
DAY = 'DAY',
DAY_OF_THE_WEEK = 'DAY_OF_THE_WEEK',
@@ -2924,6 +2933,7 @@ export enum ObjectRecordGroupByDateGranularity {
NONE = 'NONE',
QUARTER = 'QUARTER',
QUARTER_OF_THE_YEAR = 'QUARTER_OF_THE_YEAR',
WEEK = 'WEEK',
YEAR = 'YEAR'
}
@@ -3041,6 +3051,7 @@ export enum PermissionFlagType {
DATA_MODEL = 'DATA_MODEL',
DOWNLOAD_FILE = 'DOWNLOAD_FILE',
EXPORT_CSV = 'EXPORT_CSV',
HTTP_REQUEST_TOOL = 'HTTP_REQUEST_TOOL',
IMPERSONATE = 'IMPERSONATE',
IMPORT_CSV = 'IMPORT_CSV',
LAYOUTS = 'LAYOUTS',
@@ -3064,12 +3075,14 @@ export type PieChartConfiguration = {
dateGranularity?: Maybe<ObjectRecordGroupByDateGranularity>;
description?: Maybe<Scalars['String']>;
displayDataLabel?: Maybe<Scalars['Boolean']>;
displayLegend?: Maybe<Scalars['Boolean']>;
filter?: Maybe<Scalars['JSON']>;
firstDayOfTheWeek?: Maybe<Scalars['Int']>;
graphType: GraphType;
groupByFieldMetadataId: Scalars['UUID'];
groupBySubFieldName?: Maybe<Scalars['String']>;
orderBy?: Maybe<GraphOrderBy>;
showCenterMetric?: Maybe<Scalars['Boolean']>;
timezone?: Maybe<Scalars['String']>;
};
@@ -3131,17 +3144,12 @@ export type Query = {
apiKey?: Maybe<ApiKey>;
apiKeys: Array<ApiKey>;
billingPortalSession: BillingSessionOutput;
chatMessages: Array<AgentChatMessage>;
chatThread: AgentChatThread;
chatThreads: Array<AgentChatThread>;
checkUserExists: CheckUserExistOutput;
checkWorkspaceInviteHashIsValid: WorkspaceInviteHashValidOutput;
currentUser: User;
currentWorkspace: Workspace;
field: Field;
fields: FieldConnection;
findAgentHandoffTargets: Array<Agent>;
findAgentHandoffs: Array<AgentHandoff>;
findManyAgents: Array<Agent>;
findManyApplications: Array<Application>;
findManyCronTriggers: Array<CronTrigger>;
@@ -3222,16 +3230,6 @@ export type QueryBillingPortalSessionArgs = {
};
export type QueryChatMessagesArgs = {
threadId: Scalars['UUID'];
};
export type QueryChatThreadArgs = {
id: Scalars['UUID'];
};
export type QueryCheckUserExistsArgs = {
captchaToken?: InputMaybe<Scalars['String']>;
email: Scalars['String'];
@@ -3243,16 +3241,6 @@ export type QueryCheckWorkspaceInviteHashIsValidArgs = {
};
export type QueryFindAgentHandoffTargetsArgs = {
input: AgentIdInput;
};
export type QueryFindAgentHandoffsArgs = {
input: AgentIdInput;
};
export type QueryFindOneAgentArgs = {
input: AgentIdInput;
};
@@ -3602,11 +3590,6 @@ export enum RemoteTableStatus {
SYNCED = 'SYNCED'
}
export type RemoveAgentHandoffInput = {
fromAgentId: Scalars['UUID'];
toAgentId: Scalars['UUID'];
};
export type ResendEmailVerificationTokenOutput = {
__typename?: 'ResendEmailVerificationTokenOutput';
success: Scalars['Boolean'];
@@ -4032,6 +4015,7 @@ export type UuidFilterComparison = {
export type UpdateAgentInput = {
description?: InputMaybe<Scalars['String']>;
evaluationInputs?: InputMaybe<Array<Scalars['String']>>;
icon?: InputMaybe<Scalars['String']>;
id: Scalars['UUID'];
label?: InputMaybe<Scalars['String']>;
@@ -4083,6 +4067,7 @@ export type UpdateFieldInput = {
isUIReadOnly?: InputMaybe<Scalars['Boolean']>;
isUnique?: InputMaybe<Scalars['Boolean']>;
label?: InputMaybe<Scalars['String']>;
morphRelationsUpdatePayload?: InputMaybe<Array<Scalars['JSON']>>;
name?: InputMaybe<Scalars['String']>;
options?: InputMaybe<Scalars['JSON']>;
settings?: InputMaybe<Scalars['JSON']>;
@@ -4274,6 +4259,7 @@ export type UpdateViewInput = {
isCompact?: InputMaybe<Scalars['Boolean']>;
kanbanAggregateOperation?: InputMaybe<AggregateOperations>;
kanbanAggregateOperationFieldMetadataId?: InputMaybe<Scalars['UUID']>;
mainGroupByFieldMetadataId?: InputMaybe<Scalars['UUID']>;
name?: InputMaybe<Scalars['String']>;
openRecordIn?: InputMaybe<ViewOpenRecordIn>;
position?: InputMaybe<Scalars['Float']>;
@@ -4323,6 +4309,7 @@ export type UpdateWorkspaceInput = {
defaultRoleId?: InputMaybe<Scalars['UUID']>;
displayName?: InputMaybe<Scalars['String']>;
editableProfileFields?: InputMaybe<Array<Scalars['String']>>;
fastModel?: InputMaybe<Scalars['String']>;
inviteHash?: InputMaybe<Scalars['String']>;
isGoogleAuthBypassEnabled?: InputMaybe<Scalars['Boolean']>;
isGoogleAuthEnabled?: InputMaybe<Scalars['Boolean']>;
@@ -4333,7 +4320,7 @@ export type UpdateWorkspaceInput = {
isPublicInviteLinkEnabled?: InputMaybe<Scalars['Boolean']>;
isTwoFactorAuthenticationEnforced?: InputMaybe<Scalars['Boolean']>;
logo?: InputMaybe<Scalars['String']>;
routerModel?: InputMaybe<Scalars['String']>;
smartModel?: InputMaybe<Scalars['String']>;
subdomain?: InputMaybe<Scalars['String']>;
trashRetentionDays?: InputMaybe<Scalars['Float']>;
};
@@ -4660,6 +4647,7 @@ export type Workspace = {
deletedAt?: Maybe<Scalars['DateTime']>;
displayName?: Maybe<Scalars['String']>;
editableProfileFields?: Maybe<Array<Scalars['String']>>;
fastModel: Scalars['String'];
featureFlags?: Maybe<Array<FeatureFlagDto>>;
hasValidEnterpriseKey: Scalars['Boolean'];
id: Scalars['UUID'];
@@ -4676,6 +4664,7 @@ export type Workspace = {
logo?: Maybe<Scalars['String']>;
metadataVersion: Scalars['Float'];
routerModel: Scalars['String'];
smartModel: Scalars['String'];
subdomain: Scalars['String'];
trashRetentionDays: Scalars['Float'];
updatedAt: Scalars['DateTime'];
@@ -4803,7 +4792,7 @@ export type SearchQueryVariables = Exact<{
export type SearchQuery = { __typename?: 'Query', search: { __typename?: 'SearchResultConnection', edges: Array<{ __typename?: 'SearchResultEdge', cursor: string, node: { __typename?: 'SearchRecord', recordId: any, objectNameSingular: string, label: string, imageUrl?: string | null, tsRankCD: number, tsRank: number } }>, pageInfo: { __typename?: 'SearchResultPageInfo', hasNextPage: boolean, endCursor?: string | null } } };
export type PageLayoutWidgetFragmentFragment = { __typename?: 'PageLayoutWidget', id: any, title: string, type: WidgetType, objectMetadataId?: any | null, createdAt: string, updatedAt: string, deletedAt?: string | null, pageLayoutTabId: any, gridPosition: { __typename?: 'GridPosition', column: number, columnSpan: number, row: number, rowSpan: number }, configuration?: { __typename?: 'AggregateChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, label?: string | null, displayDataLabel?: boolean | null, format?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'BarChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, groupMode?: BarChartGroupMode | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'GaugeChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, displayDataLabel?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'IframeConfiguration', url?: string | null } | { __typename?: 'LineChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, isStacked?: boolean | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'PieChartConfiguration', graphType: GraphType, groupByFieldMetadataId: any, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, groupBySubFieldName?: string | null, dateGranularity?: ObjectRecordGroupByDateGranularity | null, orderBy?: GraphOrderBy | null, displayDataLabel?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | null };
export type PageLayoutWidgetFragmentFragment = { __typename?: 'PageLayoutWidget', id: any, title: string, type: WidgetType, objectMetadataId?: any | null, createdAt: string, updatedAt: string, deletedAt?: string | null, pageLayoutTabId: any, gridPosition: { __typename?: 'GridPosition', column: number, columnSpan: number, row: number, rowSpan: number }, configuration?: { __typename?: 'AggregateChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, label?: string | null, displayDataLabel?: boolean | null, format?: string | null, description?: string | null, filter?: any | null, prefix?: string | null, suffix?: string | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'BarChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, displayLegend?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, groupMode?: BarChartGroupMode | null, isCumulative?: boolean | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'GaugeChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, displayDataLabel?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'IframeConfiguration', url?: string | null } | { __typename?: 'LineChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, displayLegend?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, isStacked?: boolean | null, isCumulative?: boolean | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'PieChartConfiguration', graphType: GraphType, groupByFieldMetadataId: any, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, groupBySubFieldName?: string | null, dateGranularity?: ObjectRecordGroupByDateGranularity | null, orderBy?: GraphOrderBy | null, displayDataLabel?: boolean | null, showCenterMetric?: boolean | null, displayLegend?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | null };
export type UpdatePageLayoutWithTabsAndWidgetsMutationVariables = Exact<{
id: Scalars['String'];
@@ -4811,7 +4800,7 @@ export type UpdatePageLayoutWithTabsAndWidgetsMutationVariables = Exact<{
}>;
export type UpdatePageLayoutWithTabsAndWidgetsMutation = { __typename?: 'Mutation', updatePageLayoutWithTabsAndWidgets: { __typename?: 'PageLayout', id: any, name: string, type: PageLayoutType, objectMetadataId?: any | null, createdAt: string, updatedAt: string, deletedAt?: string | null, tabs?: Array<{ __typename?: 'PageLayoutTab', id: any, title: string, position: number, pageLayoutId: any, createdAt: string, updatedAt: string, widgets?: Array<{ __typename?: 'PageLayoutWidget', id: any, title: string, type: WidgetType, objectMetadataId?: any | null, createdAt: string, updatedAt: string, deletedAt?: string | null, pageLayoutTabId: any, gridPosition: { __typename?: 'GridPosition', column: number, columnSpan: number, row: number, rowSpan: number }, configuration?: { __typename?: 'AggregateChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, label?: string | null, displayDataLabel?: boolean | null, format?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'BarChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, groupMode?: BarChartGroupMode | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'GaugeChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, displayDataLabel?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'IframeConfiguration', url?: string | null } | { __typename?: 'LineChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, isStacked?: boolean | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'PieChartConfiguration', graphType: GraphType, groupByFieldMetadataId: any, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, groupBySubFieldName?: string | null, dateGranularity?: ObjectRecordGroupByDateGranularity | null, orderBy?: GraphOrderBy | null, displayDataLabel?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | null }> | null }> | null } };
export type UpdatePageLayoutWithTabsAndWidgetsMutation = { __typename?: 'Mutation', updatePageLayoutWithTabsAndWidgets: { __typename?: 'PageLayout', id: any, name: string, type: PageLayoutType, objectMetadataId?: any | null, createdAt: string, updatedAt: string, deletedAt?: string | null, tabs?: Array<{ __typename?: 'PageLayoutTab', id: any, title: string, position: number, pageLayoutId: any, createdAt: string, updatedAt: string, widgets?: Array<{ __typename?: 'PageLayoutWidget', id: any, title: string, type: WidgetType, objectMetadataId?: any | null, createdAt: string, updatedAt: string, deletedAt?: string | null, pageLayoutTabId: any, gridPosition: { __typename?: 'GridPosition', column: number, columnSpan: number, row: number, rowSpan: number }, configuration?: { __typename?: 'AggregateChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, label?: string | null, displayDataLabel?: boolean | null, format?: string | null, description?: string | null, filter?: any | null, prefix?: string | null, suffix?: string | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'BarChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, displayLegend?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, groupMode?: BarChartGroupMode | null, isCumulative?: boolean | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'GaugeChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, displayDataLabel?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'IframeConfiguration', url?: string | null } | { __typename?: 'LineChartConfiguration', graphType: GraphType, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, primaryAxisGroupByFieldMetadataId: any, primaryAxisGroupBySubFieldName?: string | null, primaryAxisDateGranularity?: ObjectRecordGroupByDateGranularity | null, primaryAxisOrderBy?: GraphOrderBy | null, secondaryAxisGroupByFieldMetadataId?: any | null, secondaryAxisGroupBySubFieldName?: string | null, secondaryAxisGroupByDateGranularity?: ObjectRecordGroupByDateGranularity | null, secondaryAxisOrderBy?: GraphOrderBy | null, omitNullValues?: boolean | null, axisNameDisplay?: AxisNameDisplay | null, displayDataLabel?: boolean | null, displayLegend?: boolean | null, rangeMin?: number | null, rangeMax?: number | null, color?: string | null, description?: string | null, filter?: any | null, isStacked?: boolean | null, isCumulative?: boolean | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | { __typename?: 'PieChartConfiguration', graphType: GraphType, groupByFieldMetadataId: any, aggregateFieldMetadataId: any, aggregateOperation: AggregateOperations, groupBySubFieldName?: string | null, dateGranularity?: ObjectRecordGroupByDateGranularity | null, orderBy?: GraphOrderBy | null, displayDataLabel?: boolean | null, showCenterMetric?: boolean | null, displayLegend?: boolean | null, color?: string | null, description?: string | null, filter?: any | null, timezone?: string | null, firstDayOfTheWeek?: number | null } | null }> | null }> | null } };
export type OnDbEventSubscriptionVariables = Exact<{
input: OnDbEventInput;
@@ -5137,12 +5126,14 @@ export const PageLayoutWidgetFragmentFragmentDoc = gql`
omitNullValues
axisNameDisplay
displayDataLabel
displayLegend
rangeMin
rangeMax
color
description
filter
groupMode
isCumulative
timezone
firstDayOfTheWeek
}
@@ -5161,12 +5152,14 @@ export const PageLayoutWidgetFragmentFragmentDoc = gql`
omitNullValues
axisNameDisplay
displayDataLabel
displayLegend
rangeMin
rangeMax
color
description
filter
isStacked
isCumulative
timezone
firstDayOfTheWeek
}
@@ -5179,6 +5172,8 @@ export const PageLayoutWidgetFragmentFragmentDoc = gql`
dateGranularity
orderBy
displayDataLabel
showCenterMetric
displayLegend
color
description
filter
@@ -5194,6 +5189,8 @@ export const PageLayoutWidgetFragmentFragmentDoc = gql`
format
description
filter
prefix
suffix
timezone
firstDayOfTheWeek
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
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

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