diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/contributor/command-menu-items/contributor-stats.command-menu-item.ts b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/command-menu-items/contributor-stats.command-menu-item.ts new file mode 100644 index 0000000000..ebc49ffdc2 --- /dev/null +++ b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/command-menu-items/contributor-stats.command-menu-item.ts @@ -0,0 +1,11 @@ +import { defineCommandMenuItem, objectMetadataItem } from 'twenty-sdk/define'; + +export default defineCommandMenuItem({ + universalIdentifier: '7d3f2b9e-5c0a-4e8b-ad6e-2f9c3b4d5e6a', + frontComponentUniversalIdentifier: '6c2f1a8d-4b9e-4f7a-9c5d-1e8b2a3d4c5f', + label: 'Contributor Stats', + icon: 'IconChartBar', + isPinned: false, + conditionalAvailabilityExpression: + objectMetadataItem.nameSingular === 'contributor', +}); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/contributor/command-menu-items/fetch-contributors.command-menu-item.ts b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/command-menu-items/fetch-contributors.command-menu-item.ts new file mode 100644 index 0000000000..72d5a7a30a --- /dev/null +++ b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/command-menu-items/fetch-contributors.command-menu-item.ts @@ -0,0 +1,11 @@ +import { defineCommandMenuItem, objectMetadataItem } from 'twenty-sdk/define'; + +export default defineCommandMenuItem({ + universalIdentifier: '4640992f-c2c9-4bba-b5df-9c8f05dc9e80', + frontComponentUniversalIdentifier: '08f40f82-24ed-4f3e-8c99-695151e90e38', + label: 'Fetch Contributors', + icon: 'IconUsers', + isPinned: false, + conditionalAvailabilityExpression: + objectMetadataItem.nameSingular === 'contributor', +}); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/contributor-stats.front-component.tsx b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/contributor-stats.front-component.tsx index 91cf928460..e2aee6d49d 100644 --- a/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/contributor-stats.front-component.tsx +++ b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/contributor-stats.front-component.tsx @@ -1,10 +1,6 @@ import { useEffect, useMemo, useState } from 'react'; import { defineFrontComponent } from 'twenty-sdk/define'; -import { - enqueueSnackbar, - objectMetadataItem, - useRecordId, -} from 'twenty-sdk/front-component'; +import { enqueueSnackbar, useRecordId } from 'twenty-sdk/front-component'; import { THEME } from 'src/modules/github/contributor/components/theme'; import { callAppRoute } from 'src/modules/shared/call-app-route'; @@ -682,12 +678,4 @@ export default defineFrontComponent({ description: 'Displays time-bucketed charts of PRs authored (merged only), merged and reviewed by a contributor over the last week, month, 3 months or year.', component: ContributorStats, - command: { - universalIdentifier: '7d3f2b9e-5c0a-4e8b-ad6e-2f9c3b4d5e6a', - label: 'Contributor Stats', - icon: 'IconChartBar', - isPinned: false, - conditionalAvailabilityExpression: - objectMetadataItem.nameSingular === 'contributor', - }, }); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/fetch-contributors.front-component.tsx b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/fetch-contributors.front-component.tsx index 6f7bd34cdf..a3d70ae079 100644 --- a/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/fetch-contributors.front-component.tsx +++ b/packages/twenty-apps/community/github-connector/src/modules/github/contributor/front-components/fetch-contributors.front-component.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from 'react'; import { defineFrontComponent } from 'twenty-sdk/define'; import { enqueueSnackbar, - objectMetadataItem, unmountFrontComponent, updateProgress, } from 'twenty-sdk/front-component'; @@ -95,12 +94,4 @@ export default defineFrontComponent({ 'Fetches contributors from every configured GitHub repo (GITHUB_REPOS) and upserts them as Contributor records.', isHeadless: true, component: FetchContributors, - command: { - universalIdentifier: '4640992f-c2c9-4bba-b5df-9c8f05dc9e80', - label: 'Fetch Contributors', - icon: 'IconUsers', - isPinned: false, - conditionalAvailabilityExpression: - objectMetadataItem.nameSingular === 'contributor', - }, }); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/issue/command-menu-items/fetch-issues.command-menu-item.ts b/packages/twenty-apps/community/github-connector/src/modules/github/issue/command-menu-items/fetch-issues.command-menu-item.ts new file mode 100644 index 0000000000..2eb31aa011 --- /dev/null +++ b/packages/twenty-apps/community/github-connector/src/modules/github/issue/command-menu-items/fetch-issues.command-menu-item.ts @@ -0,0 +1,11 @@ +import { defineCommandMenuItem, objectMetadataItem } from 'twenty-sdk/define'; + +export default defineCommandMenuItem({ + universalIdentifier: 'c34f56aa-ff65-43a4-9db2-774945dbcc53', + frontComponentUniversalIdentifier: '9430e4fc-9ecb-428d-9bde-2babeb1f452f', + label: 'Fetch Issues', + icon: 'IconBug', + isPinned: false, + conditionalAvailabilityExpression: + objectMetadataItem.nameSingular === 'issue', +}); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/issue/front-components/fetch-issues.front-component.tsx b/packages/twenty-apps/community/github-connector/src/modules/github/issue/front-components/fetch-issues.front-component.tsx index 303b035ee9..afab8218fe 100644 --- a/packages/twenty-apps/community/github-connector/src/modules/github/issue/front-components/fetch-issues.front-component.tsx +++ b/packages/twenty-apps/community/github-connector/src/modules/github/issue/front-components/fetch-issues.front-component.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from 'react'; import { defineFrontComponent } from 'twenty-sdk/define'; import { enqueueSnackbar, - objectMetadataItem, unmountFrontComponent, updateProgress, } from 'twenty-sdk/front-component'; @@ -98,12 +97,4 @@ export default defineFrontComponent({ description: 'Fetches issues from GitHub repos', isHeadless: true, component: FetchIssues, - command: { - universalIdentifier: 'c34f56aa-ff65-43a4-9db2-774945dbcc53', - label: 'Fetch Issues', - icon: 'IconBug', - isPinned: false, - conditionalAvailabilityExpression: - objectMetadataItem.nameSingular === 'issue', - }, }); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/project-item/command-menu-items/fetch-project-items.command-menu-item.ts b/packages/twenty-apps/community/github-connector/src/modules/github/project-item/command-menu-items/fetch-project-items.command-menu-item.ts new file mode 100644 index 0000000000..52fbaedbb6 --- /dev/null +++ b/packages/twenty-apps/community/github-connector/src/modules/github/project-item/command-menu-items/fetch-project-items.command-menu-item.ts @@ -0,0 +1,11 @@ +import { defineCommandMenuItem, objectMetadataItem } from 'twenty-sdk/define'; + +export default defineCommandMenuItem({ + universalIdentifier: '719cfe1c-d570-4c8c-89e6-88671c6ba1ea', + frontComponentUniversalIdentifier: '7c397b0c-8b19-4fac-924a-8f6aa1dece78', + label: 'Fetch Project Items', + icon: 'IconLayoutKanban', + isPinned: false, + conditionalAvailabilityExpression: + objectMetadataItem.nameSingular === 'projectItem', +}); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/project-item/front-components/fetch-project-items.front-component.tsx b/packages/twenty-apps/community/github-connector/src/modules/github/project-item/front-components/fetch-project-items.front-component.tsx index 407607747d..bf5b7a64cc 100644 --- a/packages/twenty-apps/community/github-connector/src/modules/github/project-item/front-components/fetch-project-items.front-component.tsx +++ b/packages/twenty-apps/community/github-connector/src/modules/github/project-item/front-components/fetch-project-items.front-component.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from 'react'; import { defineFrontComponent } from 'twenty-sdk/define'; import { enqueueSnackbar, - objectMetadataItem, unmountFrontComponent, updateProgress, } from 'twenty-sdk/front-component'; @@ -97,12 +96,4 @@ export default defineFrontComponent({ description: 'Fetches project items from GitHub Projects V2', isHeadless: true, component: FetchProjectItems, - command: { - universalIdentifier: '719cfe1c-d570-4c8c-89e6-88671c6ba1ea', - label: 'Fetch Project Items', - icon: 'IconLayoutKanban', - isPinned: false, - conditionalAvailabilityExpression: - objectMetadataItem.nameSingular === 'projectItem', - }, }); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/pull-request/command-menu-items/fetch-prs.command-menu-item.ts b/packages/twenty-apps/community/github-connector/src/modules/github/pull-request/command-menu-items/fetch-prs.command-menu-item.ts new file mode 100644 index 0000000000..06d7110b72 --- /dev/null +++ b/packages/twenty-apps/community/github-connector/src/modules/github/pull-request/command-menu-items/fetch-prs.command-menu-item.ts @@ -0,0 +1,11 @@ +import { defineCommandMenuItem, objectMetadataItem } from 'twenty-sdk/define'; + +export default defineCommandMenuItem({ + universalIdentifier: '0b24e6d6-da0c-4c0e-8d88-5bfd7f3cd75a', + frontComponentUniversalIdentifier: '5e2ba8df-1db5-4964-94d3-44cccfd791a0', + label: 'Fetch Pull Requests', + icon: 'IconGitPullRequest', + isPinned: false, + conditionalAvailabilityExpression: + objectMetadataItem.nameSingular === 'pullRequest', +}); diff --git a/packages/twenty-apps/community/github-connector/src/modules/github/pull-request/front-components/fetch-prs.front-component.tsx b/packages/twenty-apps/community/github-connector/src/modules/github/pull-request/front-components/fetch-prs.front-component.tsx index 055cd9ac3c..d19ec28d72 100644 --- a/packages/twenty-apps/community/github-connector/src/modules/github/pull-request/front-components/fetch-prs.front-component.tsx +++ b/packages/twenty-apps/community/github-connector/src/modules/github/pull-request/front-components/fetch-prs.front-component.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from 'react'; import { defineFrontComponent } from 'twenty-sdk/define'; import { enqueueSnackbar, - objectMetadataItem, unmountFrontComponent, updateProgress, } from 'twenty-sdk/front-component'; @@ -101,12 +100,4 @@ export default defineFrontComponent({ description: 'Fetches pull requests and reviews from GitHub repos', isHeadless: true, component: FetchPrs, - command: { - universalIdentifier: '0b24e6d6-da0c-4c0e-8d88-5bfd7f3cd75a', - label: 'Fetch Pull Requests', - icon: 'IconGitPullRequest', - isPinned: false, - conditionalAvailabilityExpression: - objectMetadataItem.nameSingular === 'pullRequest', - }, }); diff --git a/packages/twenty-docs/developers/extend/apps/layout/command-menu-items.mdx b/packages/twenty-docs/developers/extend/apps/layout/command-menu-items.mdx index 35078122d6..7df707f70c 100644 --- a/packages/twenty-docs/developers/extend/apps/layout/command-menu-items.mdx +++ b/packages/twenty-docs/developers/extend/apps/layout/command-menu-items.mdx @@ -84,11 +84,11 @@ export default defineCommandMenuItem({ The `conditionalAvailabilityExpression` field lets you control when a command is visible based on the current page context. Import typed variables and operators from `twenty-sdk` to build expressions: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/developers/extend/apps/layout/front-components.mdx index 7c0fb95b84..36f876a3b7 100644 --- a/packages/twenty-docs/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/developers/extend/apps/layout/front-components.mdx @@ -423,8 +423,8 @@ export default defineFrontComponent({ Use `useSelectedRecordIds()` to handle multiple selected records. This is useful for bulk operations: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; diff --git a/packages/twenty-docs/l/ar/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/ar/developers/extend/apps/front-components.mdx index e2c06ac1f9..e9fdb645db 100644 --- a/packages/twenty-docs/l/ar/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/ar/developers/extend/apps/front-components.mdx @@ -306,14 +306,14 @@ export default defineFrontComponent({ يتيح لك الحقل `conditionalAvailabilityExpression` التحكّم في وقت ظهور الأمر بناءً على سياق الصفحة الحالي. استورد متغيّرات ومشغّلات مضبوطة الأنواع من `twenty-sdk` لبناء التعابير: ```tsx -import { defineFrontComponent } from 'twenty-sdk/define'; import { + defineFrontComponent, pageType, numberOfSelectedRecords, objectPermissions, everyEquals, isDefined, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineFrontComponent({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/cs/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/cs/developers/extend/apps/front-components.mdx index cd4c852b70..e98773a276 100644 --- a/packages/twenty-docs/l/cs/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/cs/developers/extend/apps/front-components.mdx @@ -306,14 +306,14 @@ Přidání pole `command` do `defineFrontComponent` zaregistruje komponentu v p Pole `conditionalAvailabilityExpression` vám umožní řídit viditelnost příkazu na základě aktuálního kontextu stránky. Pro sestavení výrazů importujte typované proměnné a operátory z `twenty-sdk`: ```tsx -import { defineFrontComponent } from 'twenty-sdk/define'; import { + defineFrontComponent, pageType, numberOfSelectedRecords, objectPermissions, everyEquals, isDefined, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineFrontComponent({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/de/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/de/developers/extend/apps/front-components.mdx index b34f1a87a5..891b547a9c 100644 --- a/packages/twenty-docs/l/de/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/de/developers/extend/apps/front-components.mdx @@ -298,8 +298,8 @@ export default defineFrontComponent({ Verwenden Sie `useSelectedRecordIds()`, um mehrere ausgewählte Datensätze zu verwalten. Dies ist nützlich für Stapelvorgänge: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; @@ -383,11 +383,11 @@ export default defineCommandMenuItem({ Mit dem Feld `conditionalAvailabilityExpression` können Sie basierend auf dem aktuellen Seitenkontext steuern, wann ein Befehl sichtbar ist. Importieren Sie typisierte Variablen und Operatoren aus `twenty-sdk`, um Ausdrücke zu erstellen: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/de/developers/extend/apps/layout/command-menu-items.mdx b/packages/twenty-docs/l/de/developers/extend/apps/layout/command-menu-items.mdx index bf17bd9714..2a06af5020 100644 --- a/packages/twenty-docs/l/de/developers/extend/apps/layout/command-menu-items.mdx +++ b/packages/twenty-docs/l/de/developers/extend/apps/layout/command-menu-items.mdx @@ -84,11 +84,11 @@ export default defineCommandMenuItem({ Mit dem Feld `conditionalAvailabilityExpression` können Sie basierend auf dem aktuellen Seitenkontext steuern, wann ein Befehl sichtbar ist. Importieren Sie typisierte Variablen und Operatoren aus `twenty-sdk`, um Ausdrücke zu erstellen: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx index a2c836f607..fa53ea7e44 100644 --- a/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/de/developers/extend/apps/layout/front-components.mdx @@ -423,8 +423,8 @@ export default defineFrontComponent({ Verwenden Sie `useSelectedRecordIds()`, um mehrere ausgewählte Datensätze zu verwalten. Dies ist nützlich für Stapelvorgänge: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; diff --git a/packages/twenty-docs/l/it/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/it/developers/extend/apps/front-components.mdx index e1bb9eaafc..ace72b9528 100644 --- a/packages/twenty-docs/l/it/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/it/developers/extend/apps/front-components.mdx @@ -306,14 +306,14 @@ Aggiungere un campo `command` a `defineFrontComponent` registra il componente ne Il campo `conditionalAvailabilityExpression` consente di controllare quando un comando è visibile in base al contesto della pagina corrente. Importa variabili tipizzate e operatori da `twenty-sdk` per costruire espressioni: ```tsx -import { defineFrontComponent } from 'twenty-sdk/define'; import { + defineFrontComponent, pageType, numberOfSelectedRecords, objectPermissions, everyEquals, isDefined, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineFrontComponent({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/pt/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/pt/developers/extend/apps/front-components.mdx index bd51d48990..595aba0280 100644 --- a/packages/twenty-docs/l/pt/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/pt/developers/extend/apps/front-components.mdx @@ -298,8 +298,8 @@ export default defineFrontComponent({ Use `useSelectedRecordIds()` para lidar com vários registros selecionados. Isso é útil para operações em lote: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; @@ -383,11 +383,11 @@ export default defineCommandMenuItem({ O campo `conditionalAvailabilityExpression` permite controlar quando um comando é visível com base no contexto da página atual. Importe variáveis tipadas e operadores de `twenty-sdk` para construir expressões: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/pt/developers/extend/apps/layout/command-menu-items.mdx b/packages/twenty-docs/l/pt/developers/extend/apps/layout/command-menu-items.mdx index 57952eabe8..41b36d8418 100644 --- a/packages/twenty-docs/l/pt/developers/extend/apps/layout/command-menu-items.mdx +++ b/packages/twenty-docs/l/pt/developers/extend/apps/layout/command-menu-items.mdx @@ -84,11 +84,11 @@ export default defineCommandMenuItem({ O campo `conditionalAvailabilityExpression` permite controlar quando um comando é visível com base no contexto da página atual. Importe variáveis tipadas e operadores de `twenty-sdk` para construir expressões: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx index 8935fdac0d..a649390984 100644 --- a/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/pt/developers/extend/apps/layout/front-components.mdx @@ -423,8 +423,8 @@ export default defineFrontComponent({ Use `useSelectedRecordIds()` para lidar com vários registros selecionados. Isso é útil para operações em lote: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; diff --git a/packages/twenty-docs/l/ro/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/ro/developers/extend/apps/front-components.mdx index 3427fd1216..4a4eccd01d 100644 --- a/packages/twenty-docs/l/ro/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/ro/developers/extend/apps/front-components.mdx @@ -298,8 +298,8 @@ export default defineFrontComponent({ Folosiți `useSelectedRecordIds()` pentru a gestiona mai multe înregistrări selectate. Acest lucru este util pentru operațiuni în masă: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; @@ -383,11 +383,11 @@ export default defineCommandMenuItem({ Câmpul `conditionalAvailabilityExpression` vă permite să controlați când este vizibilă o comandă în funcție de contextul paginii curente. Importați variabile tipizate și operatori din `twenty-sdk` pentru a construi expresii: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/ro/developers/extend/apps/layout/command-menu-items.mdx b/packages/twenty-docs/l/ro/developers/extend/apps/layout/command-menu-items.mdx index 85d6825fdb..c2d888dbfd 100644 --- a/packages/twenty-docs/l/ro/developers/extend/apps/layout/command-menu-items.mdx +++ b/packages/twenty-docs/l/ro/developers/extend/apps/layout/command-menu-items.mdx @@ -84,11 +84,11 @@ export default defineCommandMenuItem({ Câmpul `conditionalAvailabilityExpression` vă permite să controlați când este vizibilă o comandă în funcție de contextul paginii curente. Importați variabile tipizate și operatori din `twenty-sdk` pentru a construi expresii: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx index f5469ac79d..94673d0155 100644 --- a/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/ro/developers/extend/apps/layout/front-components.mdx @@ -423,8 +423,8 @@ export default defineFrontComponent({ Folosiți `useSelectedRecordIds()` pentru a gestiona mai multe înregistrări selectate. Acest lucru este util pentru operațiuni în masă: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; diff --git a/packages/twenty-docs/l/ru/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/ru/developers/extend/apps/front-components.mdx index 05acf3fae6..bf15835534 100644 --- a/packages/twenty-docs/l/ru/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/ru/developers/extend/apps/front-components.mdx @@ -298,8 +298,8 @@ export default defineFrontComponent({ Используйте `useSelectedRecordIds()` для обработки нескольких выбранных записей. Это полезно для массовых операций: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; @@ -383,11 +383,11 @@ export default defineCommandMenuItem({ Поле `conditionalAvailabilityExpression` позволяет управлять видимостью команды в зависимости от текущего контекста страницы. Импортируйте типизированные переменные и операторы из `twenty-sdk`, чтобы составлять выражения: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/ru/developers/extend/apps/layout/command-menu-items.mdx b/packages/twenty-docs/l/ru/developers/extend/apps/layout/command-menu-items.mdx index b3dbf6a053..f491bbc310 100644 --- a/packages/twenty-docs/l/ru/developers/extend/apps/layout/command-menu-items.mdx +++ b/packages/twenty-docs/l/ru/developers/extend/apps/layout/command-menu-items.mdx @@ -84,11 +84,11 @@ export default defineCommandMenuItem({ Поле `conditionalAvailabilityExpression` позволяет управлять видимостью команды в зависимости от текущего контекста страницы. Импортируйте типизированные переменные и операторы из `twenty-sdk`, чтобы составлять выражения: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx index a69c06abce..377f5b9a55 100644 --- a/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/ru/developers/extend/apps/layout/front-components.mdx @@ -423,8 +423,8 @@ export default defineFrontComponent({ Используйте `useSelectedRecordIds()` для обработки нескольких выбранных записей. Это полезно для массовых операций: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; diff --git a/packages/twenty-docs/l/tr/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/tr/developers/extend/apps/front-components.mdx index eb623422ea..7f09f963fa 100644 --- a/packages/twenty-docs/l/tr/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/tr/developers/extend/apps/front-components.mdx @@ -298,8 +298,8 @@ export default defineFrontComponent({ Birden çok seçili kaydı yönetmek için `useSelectedRecordIds()` kullanın. Bu, toplu işlemler için kullanışlıdır: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; @@ -383,11 +383,11 @@ export default defineCommandMenuItem({ `conditionalAvailabilityExpression` alanı, geçerli sayfa bağlamına göre bir komutun ne zaman görünür olacağını kontrol etmenizi sağlar. İfadeler oluşturmak için `twenty-sdk`'den türlendirilmiş değişkenleri ve operatörleri içe aktarın: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/tr/developers/extend/apps/layout/command-menu-items.mdx b/packages/twenty-docs/l/tr/developers/extend/apps/layout/command-menu-items.mdx index c90fc12365..dac2ba29d6 100644 --- a/packages/twenty-docs/l/tr/developers/extend/apps/layout/command-menu-items.mdx +++ b/packages/twenty-docs/l/tr/developers/extend/apps/layout/command-menu-items.mdx @@ -84,11 +84,11 @@ export default defineCommandMenuItem({ `conditionalAvailabilityExpression` alanı, geçerli sayfa bağlamına göre bir komutun ne zaman görünür olacağını kontrol etmenizi sağlar. İfadeler oluşturmak için `twenty-sdk`'den türlendirilmiş değişkenleri ve operatörleri içe aktarın: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx index d27aad1868..d61a881352 100644 --- a/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/tr/developers/extend/apps/layout/front-components.mdx @@ -423,8 +423,8 @@ export default defineFrontComponent({ Birden çok seçili kaydı yönetmek için `useSelectedRecordIds()` kullanın. Bu, toplu işlemler için kullanışlıdır: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; diff --git a/packages/twenty-docs/l/zh/developers/extend/apps/front-components.mdx b/packages/twenty-docs/l/zh/developers/extend/apps/front-components.mdx index 06f41c4464..b03034e7a4 100644 --- a/packages/twenty-docs/l/zh/developers/extend/apps/front-components.mdx +++ b/packages/twenty-docs/l/zh/developers/extend/apps/front-components.mdx @@ -298,8 +298,8 @@ export default defineFrontComponent({ 使用 `useSelectedRecordIds()` 来处理多个已选记录。 这对于批量操作很有用: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; @@ -383,11 +383,11 @@ export default defineCommandMenuItem({ 通过 `conditionalAvailabilityExpression` 字段,您可以基于当前页面上下文控制命令何时可见。 从 `twenty-sdk` 导入带类型的变量和运算符来构建表达式: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/zh/developers/extend/apps/layout/command-menu-items.mdx b/packages/twenty-docs/l/zh/developers/extend/apps/layout/command-menu-items.mdx index 51091a0bef..7b9817d292 100644 --- a/packages/twenty-docs/l/zh/developers/extend/apps/layout/command-menu-items.mdx +++ b/packages/twenty-docs/l/zh/developers/extend/apps/layout/command-menu-items.mdx @@ -84,11 +84,11 @@ export default defineCommandMenuItem({ 通过 `conditionalAvailabilityExpression` 字段,您可以基于当前页面上下文控制命令何时可见。 从 `twenty-sdk` 导入带类型的变量和运算符来构建表达式: ```ts src/command-menu-items/bulk-update.command-menu-item.ts -import { defineCommandMenuItem } from 'twenty-sdk/define'; import { + defineCommandMenuItem, objectPermissions, everyEquals, -} from 'twenty-sdk/front-component'; +} from 'twenty-sdk/define'; export default defineCommandMenuItem({ universalIdentifier: '...', diff --git a/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx b/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx index 6aed8e2c52..4da6c2392e 100644 --- a/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx +++ b/packages/twenty-docs/l/zh/developers/extend/apps/layout/front-components.mdx @@ -423,8 +423,8 @@ export default defineFrontComponent({ 使用 `useSelectedRecordIds()` 来处理多个已选记录。 这对于批量操作很有用: ```tsx src/front-components/bulk-export.tsx -import { defineFrontComponent } from 'twenty-sdk/define'; -import { useSelectedRecordIds, numberOfSelectedRecords } from 'twenty-sdk/front-component'; +import { defineFrontComponent, numberOfSelectedRecords } from 'twenty-sdk/define'; +import { useSelectedRecordIds } from 'twenty-sdk/front-component'; import { enqueueSnackbar, closeSidePanel } from 'twenty-sdk/front-component'; import { CoreApiClient } from 'twenty-sdk/clients'; diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/comparison-operator-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/comparison-operator-front-component.ts index 35e5ba14a3..8856adeb9c 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/comparison-operator-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/comparison-operator-front-component.ts @@ -1,5 +1,7 @@ -import { defineCommandMenuItem } from '@/sdk/define'; -import { numberOfSelectedRecords } from '@/sdk/front-component'; +import { + defineCommandMenuItem, + numberOfSelectedRecords, +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'comparison-operator-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/complex-soft-delete-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/complex-soft-delete-front-component.ts index bcf2c50004..e3c530f1f7 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/complex-soft-delete-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/complex-soft-delete-front-component.ts @@ -1,10 +1,10 @@ -import { defineCommandMenuItem } from '@/sdk/define'; import { + defineCommandMenuItem, none, numberOfSelectedRecords, objectPermissions, selectedRecords, -} from '@/sdk/front-component'; +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'complex-soft-delete-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/custom-function-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/custom-function-front-component.ts index 0060c469ef..942e306a73 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/custom-function-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/custom-function-front-component.ts @@ -1,5 +1,8 @@ -import { defineCommandMenuItem } from '@/sdk/define'; -import { someDefined, selectedRecords } from '@/sdk/front-component'; +import { + defineCommandMenuItem, + selectedRecords, + someDefined, +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'custom-function-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/feature-flag-gated-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/feature-flag-gated-front-component.ts index 6a3ee7cc9a..c49c072aa0 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/feature-flag-gated-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/feature-flag-gated-front-component.ts @@ -1,5 +1,8 @@ -import { defineCommandMenuItem } from '@/sdk/define'; -import { featureFlags, objectPermissions } from '@/sdk/front-component'; +import { + defineCommandMenuItem, + featureFlags, + objectPermissions, +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'feature-flag-gated-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/parenthesized-expression-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/parenthesized-expression-front-component.ts index 260455eb1c..1fb08c368b 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/parenthesized-expression-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/parenthesized-expression-front-component.ts @@ -1,9 +1,9 @@ -import { defineCommandMenuItem } from '@/sdk/define'; import { + defineCommandMenuItem, favoriteRecordIds, objectMetadataItem, pageType, -} from '@/sdk/front-component'; +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'parenthesized-expression-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/permissions-check-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/permissions-check-front-component.ts index 7dda72cc24..edccab2c00 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/permissions-check-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/permissions-check-front-component.ts @@ -1,5 +1,8 @@ -import { defineCommandMenuItem } from '@/sdk/define'; -import { isInSidePanel, objectPermissions } from '@/sdk/front-component'; +import { + defineCommandMenuItem, + isInSidePanel, + objectPermissions, +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'permissions-check-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/simple-boolean-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/simple-boolean-front-component.ts index aacf6e495e..41e055e0b3 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/simple-boolean-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/simple-boolean-front-component.ts @@ -1,5 +1,4 @@ -import { defineCommandMenuItem } from '@/sdk/define'; -import { pageType } from '@/sdk/front-component'; +import { defineCommandMenuItem, pageType } from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'simple-boolean-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/string-comparison-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/string-comparison-front-component.ts index 5152884e37..a2f9342afd 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/string-comparison-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/string-comparison-front-component.ts @@ -1,5 +1,9 @@ -import { defineCommandMenuItem } from '@/sdk/define'; -import { everyEquals, pageType, selectedRecords } from '@/sdk/front-component'; +import { + defineCommandMenuItem, + everyEquals, + pageType, + selectedRecords, +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'string-comparison-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/target-permissions-front-component.ts b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/target-permissions-front-component.ts index e7406c2586..762649f088 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/target-permissions-front-component.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/conditional-availability/__tests__/__mocks__/target-permissions-front-component.ts @@ -1,5 +1,8 @@ -import { defineCommandMenuItem } from '@/sdk/define'; -import { pageType, targetObjectWritePermissions } from '@/sdk/front-component'; +import { + defineCommandMenuItem, + pageType, + targetObjectWritePermissions, +} from '@/sdk/define'; export default defineCommandMenuItem({ universalIdentifier: 'target-permissions-cmd', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/plugins/__tests__/__snapshots__/stub-twenty-sdk-define.plugin.spec.ts.snap b/packages/twenty-sdk/src/cli/utilities/build/common/plugins/__tests__/__snapshots__/stub-twenty-sdk-define.plugin.spec.ts.snap index 305c5f1ee1..d96182e611 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/plugins/__tests__/__snapshots__/stub-twenty-sdk-define.plugin.spec.ts.snap +++ b/packages/twenty-sdk/src/cli/utilities/build/common/plugins/__tests__/__snapshots__/stub-twenty-sdk-define.plugin.spec.ts.snap @@ -27,7 +27,38 @@ exports[`stub-twenty-sdk-define plugin > matches the recorded export partition 1 "ViewSortDirection", "ViewType", "ViewVisibility", + "canAccessFullAdminPanel", + "canImpersonate", + "every", + "everyDefined", + "everyEquals", + "favoriteRecordIds", + "featureFlags", "generateDefaultFieldUniversalIdentifier", + "hasAnySoftDeleteFilterOnView", + "includes", + "includesEvery", + "isDashboardPageLayoutInEditMode", + "isDefined", + "isInSidePanel", + "isLayoutCustomizationModeEnabled", + "isNonEmptyString", + "isSelectAll", + "none", + "noneDefined", + "noneEquals", + "numberOfSelectedRecords", + "objectMetadataItem", + "objectMetadataLabel", + "objectPermissions", + "pageType", + "selectedRecords", + "some", + "someDefined", + "someEquals", + "someNonEmptyString", + "targetObjectReadPermissions", + "targetObjectWritePermissions", "validateFields", ], "factories": [ diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts index eea4d8e234..e52e971acb 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts @@ -9,6 +9,7 @@ import { extractManifestFromFile } from '@/cli/utilities/build/manifest/manifest import { addMissingFieldOptionIds } from '@/cli/utilities/build/manifest/utils/add-missing-field-option-ids'; import { fromRoleConfigToRoleManifest } from '@/cli/utilities/build/manifest/utils/from-role-config-to-role-manifest'; import { getDefaultFieldsInObjectFields } from '@/cli/utilities/build/manifest/utils/get-default-fields-in-object-fields'; +import { validateConditionalAvailabilityUsage } from '@/cli/utilities/build/manifest/utils/validate-conditional-availability-usage'; import { validateViewFilterOperands } from '@/cli/utilities/build/manifest/utils/validate-view-filter-operands'; import { type ApplicationConfig, type LogicFunctionConfig } from '@/sdk/define'; import { type CommandMenuItemConfig } from '@/sdk/define/command-menu-items/command-menu-item-config'; @@ -126,6 +127,10 @@ export const buildManifest = async ( const fileContent = await readFile(filePath, 'utf-8'); const relativePath = relative(appPath, filePath); + errors.push( + ...validateConditionalAvailabilityUsage(fileContent, relativePath), + ); + const targetFunctionName = extractDefineEntity(fileContent); if (!targetFunctionName) { diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/utils/__tests__/validate-conditional-availability-usage.spec.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/utils/__tests__/validate-conditional-availability-usage.spec.ts new file mode 100644 index 0000000000..56a89eac68 --- /dev/null +++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/utils/__tests__/validate-conditional-availability-usage.spec.ts @@ -0,0 +1,241 @@ +import { validateConditionalAvailabilityUsage } from '@/cli/utilities/build/manifest/utils/validate-conditional-availability-usage'; + +const validate = (source: string, filename = 'src/example.front-component.tsx') => + validateConditionalAvailabilityUsage(source, filename); + +describe('validateConditionalAvailabilityUsage', () => { + describe('valid usage', () => { + it('should allow a variable inside a bare conditionalAvailabilityExpression', () => { + const source = ` + import { defineCommandMenuItem } from 'twenty-sdk/define'; + import { objectMetadataItem } from 'twenty-sdk/define'; + + export default defineCommandMenuItem({ + universalIdentifier: 'x', + label: 'X', + frontComponentUniversalIdentifier: 'y', + conditionalAvailabilityExpression: + objectMetadataItem.nameSingular === 'pullRequest', + }); + `; + + expect(validate(source)).toEqual([]); + }); + + it('should allow a variable inside a nested command.conditionalAvailabilityExpression', () => { + const source = ` + import { defineFrontComponent } from 'twenty-sdk/define'; + import { objectMetadataItem } from 'twenty-sdk/define'; + + export default defineFrontComponent({ + universalIdentifier: 'x', + component: () => null, + command: { + universalIdentifier: 'z', + label: 'Z', + conditionalAvailabilityExpression: + objectMetadataItem.nameSingular === 'issue', + }, + }); + `; + + expect(validate(source)).toEqual([]); + }); + + it('should allow operators inside the expression', () => { + const source = ` + import { defineCommandMenuItem } from 'twenty-sdk/define'; + import { objectPermissions, everyEquals } from 'twenty-sdk/define'; + + export default defineCommandMenuItem({ + conditionalAvailabilityExpression: everyEquals( + objectPermissions, + 'canUpdateObjectRecords', + true, + ), + }); + `; + + expect(validate(source)).toEqual([]); + }); + + it('should not flag same-named helpers imported from twenty-shared/utils', () => { + const source = ` + import { isDefined } from 'twenty-shared/utils'; + + export const useThing = (value: unknown) => { + if (isDefined(value)) { + return value; + } + + return null; + }; + `; + + expect(validate(source, 'src/use-thing.ts')).toEqual([]); + }); + + it('should not flag Array.prototype.includes property access', () => { + const source = ` + import { includes } from 'twenty-sdk/define'; + import { defineCommandMenuItem } from 'twenty-sdk/define'; + + const items: string[] = []; + export const hasItem = items.includes('a'); + + export default defineCommandMenuItem({ + conditionalAvailabilityExpression: includes(items, 'a'), + }); + `; + + expect(validate(source, 'src/has-item.ts')).toEqual([]); + }); + + it('should trust files that define an expression (runtime placeholder is the backstop for in-file misuse)', () => { + const source = ` + import { defineCommandMenuItem } from 'twenty-sdk/define'; + import { numberOfSelectedRecords } from 'twenty-sdk/define'; + + export default defineCommandMenuItem({ + label: numberOfSelectedRecords, + conditionalAvailabilityExpression: numberOfSelectedRecords >= 2, + }); + `; + + expect(validate(source)).toEqual([]); + }); + + it('should trust an expression declared with a string-literal property key', () => { + const source = ` + import { defineCommandMenuItem } from 'twenty-sdk/define'; + import { objectMetadataItem } from 'twenty-sdk/define'; + + export default defineCommandMenuItem({ + 'conditionalAvailabilityExpression': + objectMetadataItem.nameSingular === 'pullRequest', + }); + `; + + expect(validate(source)).toEqual([]); + }); + + it('should not flag a type-only import declaration', () => { + const source = ` + import type { objectMetadataItem } from 'twenty-sdk/define'; + + export type Thing = typeof objectMetadataItem; + `; + + expect(validate(source, 'src/thing.ts')).toEqual([]); + }); + + it('should not flag an inline type-only import specifier', () => { + const source = ` + import { type objectMetadataItem } from 'twenty-sdk/define'; + + export type Thing = typeof objectMetadataItem; + `; + + expect(validate(source, 'src/thing.ts')).toEqual([]); + }); + }); + + describe('invalid usage', () => { + it('should flag a variable used in a component body', () => { + const source = ` + import { objectMetadataItem } from 'twenty-sdk/define'; + + export const Component = () => { + const name = objectMetadataItem.nameSingular; + return name; + }; + `; + + const errors = validate(source); + + expect(errors).toHaveLength(1); + expect(errors[0]).toContain('objectMetadataItem'); + expect(errors[0]).toContain('conditionalAvailabilityExpression'); + }); + + it('should flag a variable imported in a file with no expression', () => { + const source = ` + import { defineCommandMenuItem } from 'twenty-sdk/define'; + import { numberOfSelectedRecords } from 'twenty-sdk/define'; + + export default defineCommandMenuItem({ + label: numberOfSelectedRecords, + }); + `; + + const errors = validate(source); + + expect(errors).toHaveLength(1); + expect(errors[0]).toContain('numberOfSelectedRecords'); + }); + + it('should flag an operator called at runtime', () => { + const source = ` + import { isDefined } from 'twenty-sdk/define'; + + export const check = (value: unknown) => isDefined(value); + `; + + const errors = validate(source, 'src/check.ts'); + + expect(errors).toHaveLength(1); + expect(errors[0]).toContain('isDefined'); + }); + + it('should flag a variable imported from the twenty-sdk root entry', () => { + const source = ` + import { objectMetadataItem } from 'twenty-sdk'; + + export const label = objectMetadataItem.labelSingular; + `; + + expect(validate(source, 'src/label.ts')).toHaveLength(1); + }); + + it('should flag misuse when conditionalAvailabilityExpression appears only in a comment', () => { + const source = ` + import { objectMetadataItem } from 'twenty-sdk/define'; + + // TODO: move this into a conditionalAvailabilityExpression later + export const Component = () => objectMetadataItem.nameSingular; + `; + + const errors = validate(source); + + expect(errors).toHaveLength(1); + expect(errors[0]).toContain('objectMetadataItem'); + }); + + it('should flag misuse when conditionalAvailabilityExpression appears only in a string literal', () => { + const source = ` + import { objectMetadataItem } from 'twenty-sdk/define'; + + export const doc = 'conditionalAvailabilityExpression'; + export const Component = () => objectMetadataItem.nameSingular; + `; + + const errors = validate(source); + + expect(errors).toHaveLength(1); + expect(errors[0]).toContain('objectMetadataItem'); + }); + + it('should flag namespace-import runtime use with no expression', () => { + const source = ` + import * as sdk from 'twenty-sdk/define'; + + export const label = sdk.objectMetadataItem.labelSingular; + `; + + const errors = validate(source, 'src/label.ts'); + + expect(errors).toHaveLength(1); + expect(errors[0]).toContain('objectMetadataItem'); + }); + }); +}); diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/utils/validate-conditional-availability-usage.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/utils/validate-conditional-availability-usage.ts new file mode 100644 index 0000000000..b8182fb54b --- /dev/null +++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/utils/validate-conditional-availability-usage.ts @@ -0,0 +1,156 @@ +import { CONDITIONAL_AVAILABILITY_VARIABLE_NAMES } from '@/sdk/define/conditional-availability/conditional-availability-variable-names'; +import { isDefined } from 'twenty-shared/utils'; +import ts from 'typescript'; + +const CONDITIONAL_AVAILABILITY_EXPRESSION_PROPERTY = + 'conditionalAvailabilityExpression'; + +const EXPRESSION_VARIABLE_MODULE_SPECIFIERS = ['twenty-sdk/define', 'twenty-sdk']; + +const EXPRESSION_VARIABLE_NAMES = new Set( + CONDITIONAL_AVAILABILITY_VARIABLE_NAMES, +); + +type ImportedExpressionVariable = { + importedName: string; + node: ts.Node; +}; + +const collectImportedExpressionVariables = ( + sourceFile: ts.SourceFile, +): ImportedExpressionVariable[] => { + const imported: ImportedExpressionVariable[] = []; + + for (const statement of sourceFile.statements) { + if ( + !ts.isImportDeclaration(statement) || + !ts.isStringLiteral(statement.moduleSpecifier) || + !EXPRESSION_VARIABLE_MODULE_SPECIFIERS.includes( + statement.moduleSpecifier.text, + ) + ) { + continue; + } + + const importClause = statement.importClause; + + if ( + !isDefined(importClause) || + importClause.phaseModifier === ts.SyntaxKind.TypeKeyword + ) { + continue; + } + + const namedBindings = importClause.namedBindings; + + if (!isDefined(namedBindings)) { + continue; + } + + if (ts.isNamespaceImport(namedBindings)) { + const namespaceName = namedBindings.name.text; + + const collectNamespaceMemberUsages = (node: ts.Node): void => { + if ( + ts.isPropertyAccessExpression(node) && + ts.isIdentifier(node.expression) && + node.expression.text === namespaceName && + EXPRESSION_VARIABLE_NAMES.has(node.name.text) + ) { + imported.push({ importedName: node.name.text, node }); + } + + ts.forEachChild(node, collectNamespaceMemberUsages); + }; + + collectNamespaceMemberUsages(sourceFile); + continue; + } + + if (!ts.isNamedImports(namedBindings)) { + continue; + } + + for (const element of namedBindings.elements) { + if (element.isTypeOnly) { + continue; + } + + const importedName = (element.propertyName ?? element.name).text; + + if (EXPRESSION_VARIABLE_NAMES.has(importedName)) { + imported.push({ importedName, node: element }); + } + } + } + + return imported; +}; + +const hasConditionalAvailabilityExpressionProperty = ( + sourceFile: ts.SourceFile, +): boolean => { + let found = false; + + const findExpressionProperty = (node: ts.Node): void => { + if (found) { + return; + } + + if ( + (ts.isPropertyAssignment(node) || + ts.isShorthandPropertyAssignment(node)) && + (ts.isIdentifier(node.name) || ts.isStringLiteral(node.name)) && + node.name.text === CONDITIONAL_AVAILABILITY_EXPRESSION_PROPERTY + ) { + found = true; + return; + } + + ts.forEachChild(node, findExpressionProperty); + }; + + findExpressionProperty(sourceFile); + + return found; +}; + +export const validateConditionalAvailabilityUsage = ( + fileContent: string, + relativePath: string, +): string[] => { + if ( + !CONDITIONAL_AVAILABILITY_VARIABLE_NAMES.some((name) => + fileContent.includes(name), + ) + ) { + return []; + } + + const sourceFile = ts.createSourceFile( + relativePath, + fileContent, + ts.ScriptTarget.Latest, + true, + relativePath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS, + ); + + const importedExpressionVariables = + collectImportedExpressionVariables(sourceFile); + + if (importedExpressionVariables.length === 0) { + return []; + } + + if (hasConditionalAvailabilityExpressionProperty(sourceFile)) { + return []; + } + + return importedExpressionVariables.map(({ importedName, node }) => { + const { line, character } = sourceFile.getLineAndCharacterOfPosition( + node.getStart(sourceFile), + ); + + return `${relativePath}:${line + 1}:${character + 1} - "${importedName}" is a conditional-availability expression variable from twenty-sdk but this file has no ${CONDITIONAL_AVAILABILITY_EXPRESSION_PROPERTY}. These variables can only be used inside a command's ${CONDITIONAL_AVAILABILITY_EXPRESSION_PROPERTY}, not at runtime.`; + }); +}; diff --git a/packages/twenty-sdk/src/sdk/define/conditional-availability/__tests__/conditional-availability-variables.spec.ts b/packages/twenty-sdk/src/sdk/define/conditional-availability/__tests__/conditional-availability-variables.spec.ts new file mode 100644 index 0000000000..72c2e521d5 --- /dev/null +++ b/packages/twenty-sdk/src/sdk/define/conditional-availability/__tests__/conditional-availability-variables.spec.ts @@ -0,0 +1,56 @@ +import { CONDITIONAL_AVAILABILITY_VARIABLE_NAMES } from '@/sdk/define/conditional-availability/conditional-availability-variable-names'; +import * as conditionalAvailabilityVariables from '@/sdk/define/conditional-availability/conditional-availability-variables'; + +describe('conditional-availability-variables', () => { + it('should not throw when the module is imported', () => { + expect(conditionalAvailabilityVariables.objectMetadataItem).toBeDefined(); + }); + + it('should throw on property access of a context variable', () => { + expect( + () => + ( + conditionalAvailabilityVariables.objectMetadataItem as unknown as { + nameSingular: string; + } + ).nameSingular, + ).toThrow('conditionalAvailabilityExpression'); + }); + + it('should throw on primitive coercion of a context variable', () => { + expect(() => { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + void (conditionalAvailabilityVariables.numberOfSelectedRecords >= 2); + }).toThrow('conditionalAvailabilityExpression'); + }); + + it('should throw when an operator is called at runtime', () => { + expect(() => conditionalAvailabilityVariables.isDefined('value')).toThrow( + 'conditionalAvailabilityExpression', + ); + }); + + it('should mention the variable name in the error', () => { + expect(() => + conditionalAvailabilityVariables.everyEquals([], 'prop', true), + ).toThrow('everyEquals'); + }); + + it('should report its own export name in the runtime error for every variable', () => { + for (const [name, value] of Object.entries( + conditionalAvailabilityVariables, + )) { + expect(() => (value as unknown as () => void)()).toThrow(name); + } + }); + + // Drift guard: every exported variable must be listed in the shared constant + // so the build-time guard can never miss a newly added variable. + it('should keep CONDITIONAL_AVAILABILITY_VARIABLE_NAMES in sync with the exports', () => { + const exportedNames = Object.keys(conditionalAvailabilityVariables); + + expect(new Set(CONDITIONAL_AVAILABILITY_VARIABLE_NAMES)).toEqual( + new Set(exportedNames), + ); + }); +}); diff --git a/packages/twenty-sdk/src/sdk/define/conditional-availability/conditional-availability-variable-names.ts b/packages/twenty-sdk/src/sdk/define/conditional-availability/conditional-availability-variable-names.ts new file mode 100644 index 0000000000..f4cf61ab8c --- /dev/null +++ b/packages/twenty-sdk/src/sdk/define/conditional-availability/conditional-availability-variable-names.ts @@ -0,0 +1,33 @@ +export const CONDITIONAL_AVAILABILITY_VARIABLE_NAMES = [ + 'pageType', + 'isInSidePanel', + 'isDashboardPageLayoutInEditMode', + 'isLayoutCustomizationModeEnabled', + 'favoriteRecordIds', + 'isSelectAll', + 'hasAnySoftDeleteFilterOnView', + 'numberOfSelectedRecords', + 'objectPermissions', + 'selectedRecords', + 'featureFlags', + 'targetObjectReadPermissions', + 'targetObjectWritePermissions', + 'canImpersonate', + 'canAccessFullAdminPanel', + 'objectMetadataItem', + 'objectMetadataLabel', + 'isDefined', + 'isNonEmptyString', + 'includes', + 'every', + 'everyDefined', + 'everyEquals', + 'some', + 'someDefined', + 'someEquals', + 'none', + 'noneDefined', + 'noneEquals', + 'someNonEmptyString', + 'includesEvery', +] as const; diff --git a/packages/twenty-sdk/src/sdk/define/conditional-availability/conditional-availability-variables.ts b/packages/twenty-sdk/src/sdk/define/conditional-availability/conditional-availability-variables.ts new file mode 100644 index 0000000000..3a3b55c927 --- /dev/null +++ b/packages/twenty-sdk/src/sdk/define/conditional-availability/conditional-availability-variables.ts @@ -0,0 +1,167 @@ +import { type CommandMenuContextApi } from 'twenty-shared/types'; + +const isPromiseUnwrapProbe = (property: string | symbol): boolean => + property === 'then'; + +const isSymbolProbe = (property: string | symbol): boolean => + typeof property === 'symbol'; + +const createExpressionOnlyPlaceholder = (name: string): unknown => { + const fail = (): never => { + throw new Error( + `"${name}" from twenty-sdk can only be used inside a command's conditionalAvailabilityExpression, not at runtime.`, + ); + }; + + const handler: ProxyHandler<() => void> = { + get: (_target, property) => { + if (isPromiseUnwrapProbe(property) || isSymbolProbe(property)) { + return undefined; + } + + return fail(); + }, + apply: fail, + construct: fail, + has: fail, + }; + + return new Proxy(function expressionOnlyPlaceholder() {}, handler); +}; + +export const pageType = createExpressionOnlyPlaceholder( + 'pageType', +) as CommandMenuContextApi['pageType']; + +export const isInSidePanel = createExpressionOnlyPlaceholder( + 'isInSidePanel', +) as CommandMenuContextApi['isInSidePanel']; + +export const isDashboardPageLayoutInEditMode = createExpressionOnlyPlaceholder( + 'isDashboardPageLayoutInEditMode', +) as CommandMenuContextApi['isDashboardPageLayoutInEditMode']; + +export const isLayoutCustomizationModeEnabled = createExpressionOnlyPlaceholder( + 'isLayoutCustomizationModeEnabled', +) as CommandMenuContextApi['isLayoutCustomizationModeEnabled']; + +export const favoriteRecordIds = createExpressionOnlyPlaceholder( + 'favoriteRecordIds', +) as CommandMenuContextApi['favoriteRecordIds']; + +export const isSelectAll = createExpressionOnlyPlaceholder( + 'isSelectAll', +) as CommandMenuContextApi['isSelectAll']; + +export const hasAnySoftDeleteFilterOnView = createExpressionOnlyPlaceholder( + 'hasAnySoftDeleteFilterOnView', +) as CommandMenuContextApi['hasAnySoftDeleteFilterOnView']; + +export const numberOfSelectedRecords = createExpressionOnlyPlaceholder( + 'numberOfSelectedRecords', +) as CommandMenuContextApi['numberOfSelectedRecords']; + +export const objectPermissions = createExpressionOnlyPlaceholder( + 'objectPermissions', +) as CommandMenuContextApi['objectPermissions']; + +export const selectedRecords = createExpressionOnlyPlaceholder( + 'selectedRecords', +) as CommandMenuContextApi['selectedRecords']; + +export const featureFlags = createExpressionOnlyPlaceholder( + 'featureFlags', +) as CommandMenuContextApi['featureFlags']; + +export const targetObjectReadPermissions = createExpressionOnlyPlaceholder( + 'targetObjectReadPermissions', +) as CommandMenuContextApi['targetObjectReadPermissions']; + +export const targetObjectWritePermissions = createExpressionOnlyPlaceholder( + 'targetObjectWritePermissions', +) as CommandMenuContextApi['targetObjectWritePermissions']; + +export const canImpersonate = createExpressionOnlyPlaceholder( + 'canImpersonate', +) as CommandMenuContextApi['canImpersonate']; + +export const canAccessFullAdminPanel = createExpressionOnlyPlaceholder( + 'canAccessFullAdminPanel', +) as CommandMenuContextApi['canAccessFullAdminPanel']; + +export const objectMetadataItem = createExpressionOnlyPlaceholder( + 'objectMetadataItem', +) as CommandMenuContextApi['objectMetadataItem']; + +export const objectMetadataLabel = createExpressionOnlyPlaceholder( + 'objectMetadataLabel', +) as CommandMenuContextApi['objectMetadataLabel']; + +export const isDefined = createExpressionOnlyPlaceholder('isDefined') as ( + value: unknown, +) => boolean; + +export const isNonEmptyString = createExpressionOnlyPlaceholder( + 'isNonEmptyString', +) as (value: unknown) => boolean; + +export const includes = createExpressionOnlyPlaceholder('includes') as ( + array: unknown, + value: unknown, +) => boolean; + +export const every = createExpressionOnlyPlaceholder('every') as ( + array: unknown, + prop: string, +) => boolean; + +export const everyDefined = createExpressionOnlyPlaceholder('everyDefined') as ( + array: unknown, + prop: string, +) => boolean; + +export const everyEquals = createExpressionOnlyPlaceholder('everyEquals') as ( + array: unknown, + prop: string, + value: unknown, +) => boolean; + +export const some = createExpressionOnlyPlaceholder('some') as ( + array: unknown, + prop: string, +) => boolean; + +export const someDefined = createExpressionOnlyPlaceholder('someDefined') as ( + array: unknown, + prop: string, +) => boolean; + +export const someEquals = createExpressionOnlyPlaceholder('someEquals') as ( + array: unknown, + prop: string, + value: unknown, +) => boolean; + +export const none = createExpressionOnlyPlaceholder('none') as ( + array: unknown, + prop: string, +) => boolean; + +export const noneDefined = createExpressionOnlyPlaceholder('noneDefined') as ( + array: unknown, + prop: string, +) => boolean; + +export const noneEquals = createExpressionOnlyPlaceholder('noneEquals') as ( + array: unknown, + prop: string, + value: unknown, +) => boolean; + +export const someNonEmptyString = createExpressionOnlyPlaceholder( + 'someNonEmptyString', +) as (array: unknown, prop: string) => boolean; + +export const includesEvery = createExpressionOnlyPlaceholder( + 'includesEvery', +) as (array: unknown, prop: string, value: unknown) => boolean; diff --git a/packages/twenty-sdk/src/sdk/define/index.ts b/packages/twenty-sdk/src/sdk/define/index.ts index daec775ef0..7cfbc85079 100644 --- a/packages/twenty-sdk/src/sdk/define/index.ts +++ b/packages/twenty-sdk/src/sdk/define/index.ts @@ -31,6 +31,40 @@ export { defineCommandMenuItem } from '@/sdk/define/command-menu-items/define-co export type { CommandMenuItemConfig } from '@/sdk/define/command-menu-items/command-menu-item-config'; export type { CommandMenuItemManifest } from 'twenty-shared/application'; +export { + pageType, + isInSidePanel, + isDashboardPageLayoutInEditMode, + isLayoutCustomizationModeEnabled, + favoriteRecordIds, + isSelectAll, + hasAnySoftDeleteFilterOnView, + numberOfSelectedRecords, + objectPermissions, + selectedRecords, + featureFlags, + targetObjectReadPermissions, + targetObjectWritePermissions, + canImpersonate, + canAccessFullAdminPanel, + isDefined, + isNonEmptyString, + includes, + every, + everyDefined, + everyEquals, + some, + someDefined, + someEquals, + none, + noneDefined, + noneEquals, + someNonEmptyString, + includesEvery, + objectMetadataItem, + objectMetadataLabel, +} from '@/sdk/define/conditional-availability/conditional-availability-variables'; + export { defineFrontComponent } from '@/sdk/define/front-component/define-front-component'; export type { FrontComponentConfig, diff --git a/packages/twenty-sdk/src/sdk/front-component/conditional-availability/conditional-availability-variables.ts b/packages/twenty-sdk/src/sdk/front-component/conditional-availability/conditional-availability-variables.ts deleted file mode 100644 index d027735c19..0000000000 --- a/packages/twenty-sdk/src/sdk/front-component/conditional-availability/conditional-availability-variables.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { type CommandMenuContextApi } from 'twenty-shared/types'; - -export const pageType = null as unknown as CommandMenuContextApi['pageType']; -export const isInSidePanel = - null as unknown as CommandMenuContextApi['isInSidePanel']; -export const isDashboardPageLayoutInEditMode = - null as unknown as CommandMenuContextApi['isDashboardPageLayoutInEditMode']; -export const isLayoutCustomizationModeEnabled = - null as unknown as CommandMenuContextApi['isLayoutCustomizationModeEnabled']; -export const favoriteRecordIds = - null as unknown as CommandMenuContextApi['favoriteRecordIds']; -export const isSelectAll = - null as unknown as CommandMenuContextApi['isSelectAll']; -export const hasAnySoftDeleteFilterOnView = - null as unknown as CommandMenuContextApi['hasAnySoftDeleteFilterOnView']; -export const numberOfSelectedRecords = - null as unknown as CommandMenuContextApi['numberOfSelectedRecords']; -export const objectPermissions = - null as unknown as CommandMenuContextApi['objectPermissions']; -export const selectedRecords = - null as unknown as CommandMenuContextApi['selectedRecords']; -export const featureFlags = - null as unknown as CommandMenuContextApi['featureFlags']; -export const targetObjectReadPermissions = - null as unknown as CommandMenuContextApi['targetObjectReadPermissions']; -export const targetObjectWritePermissions = - null as unknown as CommandMenuContextApi['targetObjectWritePermissions']; -export const canImpersonate = - null as unknown as CommandMenuContextApi['canImpersonate']; -export const canAccessFullAdminPanel = - null as unknown as CommandMenuContextApi['canAccessFullAdminPanel']; - -export const objectMetadataItem = - null as unknown as CommandMenuContextApi['objectMetadataItem']; - -export const objectMetadataLabel = - null as unknown as CommandMenuContextApi['objectMetadataLabel']; - -export const isDefined = null as unknown as (value: unknown) => boolean; -export const isNonEmptyString = null as unknown as (value: unknown) => boolean; -export const includes = null as unknown as ( - array: unknown, - value: unknown, -) => boolean; -export const every = null as unknown as ( - array: unknown, - prop: string, -) => boolean; -export const everyDefined = null as unknown as ( - array: unknown, - prop: string, -) => boolean; -export const everyEquals = null as unknown as ( - array: unknown, - prop: string, - value: unknown, -) => boolean; -export const some = null as unknown as ( - array: unknown, - prop: string, -) => boolean; -export const someDefined = null as unknown as ( - array: unknown, - prop: string, -) => boolean; -export const someEquals = null as unknown as ( - array: unknown, - prop: string, - value: unknown, -) => boolean; -export const none = null as unknown as ( - array: unknown, - prop: string, -) => boolean; -export const noneDefined = null as unknown as ( - array: unknown, - prop: string, -) => boolean; -export const noneEquals = null as unknown as ( - array: unknown, - prop: string, - value: unknown, -) => boolean; -export const someNonEmptyString = null as unknown as ( - array: unknown, - prop: string, -) => boolean; -export const includesEvery = null as unknown as ( - array: unknown, - prop: string, - value: unknown, -) => boolean; diff --git a/packages/twenty-sdk/src/sdk/front-component/index.ts b/packages/twenty-sdk/src/sdk/front-component/index.ts index d0ea55aa59..750cfeea1e 100644 --- a/packages/twenty-sdk/src/sdk/front-component/index.ts +++ b/packages/twenty-sdk/src/sdk/front-component/index.ts @@ -1,35 +1,3 @@ -export { - pageType, - isInSidePanel, - isDashboardPageLayoutInEditMode, - isLayoutCustomizationModeEnabled, - favoriteRecordIds, - isSelectAll, - hasAnySoftDeleteFilterOnView, - numberOfSelectedRecords, - objectPermissions, - selectedRecords, - featureFlags, - targetObjectReadPermissions, - targetObjectWritePermissions, - canImpersonate, - canAccessFullAdminPanel, - isDefined, - isNonEmptyString, - includes, - every, - everyDefined, - everyEquals, - some, - someDefined, - someEquals, - none, - noneDefined, - noneEquals, - someNonEmptyString, - includesEvery, - objectMetadataItem, -} from './conditional-availability/conditional-availability-variables'; export { closeSidePanel } from './functions/closeSidePanel'; export { copyToClipboard } from './functions/copyToClipboard'; export { getApplicationVariable } from './functions/getApplicationVariable';