feat: batch updating (#16384)

#16383 

## Scope & Context
**Context**:
Added a **Bulk Update** feature to allow users to modify multiple
records simultaneously. This addresses the need for efficient data
management when dealing with large datasets.

**Scope**:
Enabling a "Bulk Update" flow that can be triggered for a filtered list
of records (e.g., current view). The feature guides the user through
selecting fields to modify, inputting new values, and executing the
update with real-time progress feedback.

## Current behavior
Currently, users must open and update records one by one.
To change the "Status" of 10 different opportunities, the user has to
navigate to each record detail page or use the inline cell editor 10
separate times. This is repetitive and time-consuming.

## Expected behavior
Users can trigger "Update Records" from the command menu or action bar.
1. **Choose Fields**: A step where users select which properties they
want to modify (e.g., check "Status" and "Assignee").
2. **Input Values**: Users provide the new values for the selected
fields.
3. **Execution**: Upon confirmation, the system updates all matching
records in the background.
4. **Feedback**: A progress indicator shows the number of processed
records, and a toast notification confirms completion.

*Key interactions:*
- Users can clear a field's value (set to null) by selecting the field
but leaving the input empty.
- The operation supports cancelling midway.


https://github.com/user-attachments/assets/c87366a3-246e-4615-9941-0bf63d70df86

## Technical inputs
**Core Functionality**:
- **Incremental Batch Processing**: Updates are performed in small
batches (using `useIncrementalUpdateManyRecords` to handle large
datasets without timing out or freezing the UI.
- **Global Feedback**: Integrated with the Snackbar system to notify
users of success or errors across the application.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces localization keys and generated messages to support the new
bulk update workflow.
> 
> - New strings for command menu selection info: `{totalCount} selected`
> - Footer actions for bulk update: `Apply`, `Cancel` in
`UpdateMultipleRecordsFooter`
> - Toasts in `UpdateMultipleRecordsContainer`: `Successfully updated
{count} records`, `Failed to update records. Please try again.`
> - Action labels: `Update`, `Update records` in
`DefaultRecordActionsConfig` and command menu hook
> - Adds/updates entries across multiple locale `.po` files and
regenerates `af-ZA` messages
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b1dce4c599b85fa2947ca63b265fc750e80d9bb6. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Samuel Arbibe <samuelarbibe@Samuels-MacBook-Pro.local>
Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
Samuel Arbibe
2025-12-31 17:02:27 +02:00
committed by GitHub
parent 145790840d
commit 888a50c3be
94 changed files with 2259 additions and 75 deletions
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalender"
msgid "{totalCost} credits"
msgstr "{totalCost} krediete"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Toepassings"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Kan nie skandeer nie? Kopieer die"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Kanselleer"
@@ -5276,6 +5287,11 @@ msgstr "Kon nie funksievlag opdateer nie. {errorMessage}"
msgid "Failed to update price."
msgstr "Kon nie prys opdateer nie."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Sukses"
msgid "Successfully merged {recordCount} records"
msgstr "Suksesvol saamgevoeg {recordCount} rekords"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "opdateer"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Opdateer"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. التقويم"
msgid "{totalCost} credits"
msgstr "{totalCost, plural, zero {لا اعتمادات} one {اعتماد واحد} two {اعتمادان} few {# اعتمادات} many {# اعتمادًا} other {# اعتماد}}"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "تطبيقات"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "هل لا يمكنك المسح؟ انسخ الـ"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "إلغاء"
@@ -5276,6 +5287,11 @@ msgstr "فشل في تحديث علم الميزة. {errorMessage}"
msgid "Failed to update price."
msgstr "فشل في تحديث السعر."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "نجاح"
msgid "Successfully merged {recordCount} records"
msgstr "تم دمج {recordCount} من السجلات بنجاح"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "تحديث"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "تحديث"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Calendari"
msgid "{totalCost} credits"
msgstr "{totalCost} crèdits"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Aplicacions"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "No pots escanejar? Copia la"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Cancel·la"
@@ -5276,6 +5287,11 @@ msgstr "No s'ha pogut actualitzar el feature flag. {errorMessage}"
msgid "Failed to update price."
msgstr "Ha fallat l'actualització del preu."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Èxit"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {s'ha fusionat un registre} other {s'han fusionat {recordCount} registres}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "actualitza"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Actualitza"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalendář"
msgid "{totalCost} credits"
msgstr "{totalCost} kreditů"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Aplikace"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Nemůžete skenovat? Zkopírujte"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Storno"
@@ -5276,6 +5287,11 @@ msgstr "Nepodařilo se aktualizovat příznak funkce. {errorMessage}"
msgid "Failed to update price."
msgstr "Nepodařilo se aktualizovat cenu."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Úspěch"
msgid "Successfully merged {recordCount} records"
msgstr "Úspěšně sloučeno {recordCount} záznamů"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "aktualizovat"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Aktualizovat"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalender"
msgid "{totalCost} credits"
msgstr "{totalCost} kreditter"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Applikationer"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Kan ikke scanne? Kopier"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Annuller"
@@ -5276,6 +5287,11 @@ msgstr "Kunne ikke opdatere funktionsflag. {errorMessage}"
msgid "Failed to update price."
msgstr "Kunne ikke opdatere pris."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Succes"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {En post blev succesfuldt flettet} other {# poster blev succesfuldt flettet}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11874,9 +11895,16 @@ msgstr "opdater"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Opdater"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalender"
msgid "{totalCost} credits"
msgstr "{totalCost} Credits"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Anwendungen"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Kann nicht gescannt werden? Kopieren Sie das"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Abbrechen"
@@ -5276,6 +5287,11 @@ msgstr "Feature-Flag konnte nicht aktualisiert werden. {errorMessage}"
msgid "Failed to update price."
msgstr "Fehler beim Aktualisieren des Preises."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Erfolg"
msgid "Successfully merged {recordCount} records"
msgstr "Erfolgreich {recordCount, plural, one {einen Datensatz} other {# Datensätze}} zusammengeführt"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "aktualisieren"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Aktualisieren"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Ημερολόγιο"
msgid "{totalCost} credits"
msgstr "{totalCost} πιστώσεις"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Εφαρμογές"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Δεν μπορείτε να σαρώσετε; Αντιγράψτε το
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Ακύρωση"
@@ -5276,6 +5287,11 @@ msgstr "Αποτυχία ενημέρωσης σημαίας δυνατότητ
msgid "Failed to update price."
msgstr "Αποτυχία ενημέρωσης τιμής."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10831,6 +10847,11 @@ msgstr "Επιτυχία"
msgid "Successfully merged {recordCount} records"
msgstr "Επιτυχής συγχώνευση {recordCount} εγγραφών"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11876,9 +11897,16 @@ msgstr "ενημέρωση"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Ενημέρωση"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
+28
View File
@@ -389,6 +389,11 @@ msgstr "{stepNumber}. Calendar"
msgid "{totalCost} credits"
msgstr "{totalCost} credits"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr "{totalCount} selected"
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1591,6 +1596,11 @@ msgstr "Application successfully uninstalled."
msgid "Applications"
msgstr "Applications"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr "Apply"
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2157,6 +2167,7 @@ msgstr "Can't scan? Copy the"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Cancel"
@@ -5271,6 +5282,11 @@ msgstr "Failed to update feature flag. {errorMessage}"
msgid "Failed to update price."
msgstr "Failed to update price."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr "Failed to update records. Please try again."
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10824,6 +10840,11 @@ msgstr "Success"
msgid "Successfully merged {recordCount} records"
msgstr "Successfully merged {recordCount} records"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr "Successfully updated {count} records"
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11869,9 +11890,16 @@ msgstr "update"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Update"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr "Update records"
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Calendario"
msgid "{totalCost} credits"
msgstr "{totalCost} créditos"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Aplicaciones"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "¿No puedes escanear? Copia el"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Cancelar"
@@ -5276,6 +5287,11 @@ msgstr "No se pudo actualizar el feature flag. {errorMessage}"
msgid "Failed to update price."
msgstr "Error al actualizar el precio."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Éxito"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {Se ha fusionado con éxito {recordCount} registro} other {Se han fusionado con éxito {recordCount} registros}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11874,9 +11895,16 @@ msgstr "actualizar"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Actualizar"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalenteri"
msgid "{totalCost} credits"
msgstr "{totalCost} hyvitystä"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Sovellukset"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Et voi skannata? Kopioi"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Peruuta"
@@ -5276,6 +5287,11 @@ msgstr "Ominaisuuslipun päivitys epäonnistui. {errorMessage}"
msgid "Failed to update price."
msgstr "Hinnan päivittäminen epäonnistui."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Onnistui"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {Onnistuneesti yhdistetty {recordCount} tietue} other {Onnistuneesti yhdistetty {recordCount} tietuetta}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "päivitä"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Päivitä"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Calendrier"
msgid "{totalCost} credits"
msgstr "{totalCost} crédits"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Applications"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Impossible de scanner ? Copiez le"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Annuler"
@@ -5276,6 +5287,11 @@ msgstr "Échec de la mise à jour du feature flag. {errorMessage}"
msgid "Failed to update price."
msgstr "Échec de la mise à jour du prix."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Succès"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {Fusion réussie de {recordCount} enregistrement} other {Fusion réussie de {recordCount} enregistrements}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11874,9 +11895,16 @@ msgstr "mettre à jour"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Mettre à jour"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. לוח שנה"
msgid "{totalCost} credits"
msgstr "{totalCost} קרדיטים"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "יישומים"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "לא ניתן לסרוק? העתק את"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "בטל"
@@ -5276,6 +5287,11 @@ msgstr "עדכון דגל התכונה נכשל. {errorMessage}"
msgid "Failed to update price."
msgstr "העדכון של המחיר נכשל."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "הצלחה"
msgid "Successfully merged {recordCount} records"
msgstr "נמזגו בהצלחה {recordCount} רשומות"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "עדכן"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "עדכן"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Naptár"
msgid "{totalCost} credits"
msgstr "{totalCost} kredit"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Alkalmazások"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Nem tud beolvasni? Másolja a"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Mégse"
@@ -5276,6 +5287,11 @@ msgstr "A funkciójelző frissítése nem sikerült. {errorMessage}"
msgid "Failed to update price."
msgstr "Az ár frissítése sikertelen."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Siker"
msgid "Successfully merged {recordCount} records"
msgstr "Sikeresen összevont {recordCount} rekordot"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "frissítés"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Frissítés"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Calendario"
msgid "{totalCost} credits"
msgstr "{totalCost} crediti"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Applicazioni"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Non puoi scansionare? Copia il"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Annulla"
@@ -5276,6 +5287,11 @@ msgstr "Impossibile aggiornare il feature flag. {errorMessage}"
msgid "Failed to update price."
msgstr "Impossibile aggiornare il prezzo."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Successo"
msgid "Successfully merged {recordCount} records"
msgstr "Unione completata di {recordCount} record"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11874,9 +11895,16 @@ msgstr "aggiorna"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Aggiorna"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. カレンダー"
msgid "{totalCost} credits"
msgstr "{totalCost} クレジット"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "アプリケーション"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "スキャンできませんか? コピーしてください"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "キャンセル"
@@ -5276,6 +5287,11 @@ msgstr "機能フラグの更新に失敗しました。{errorMessage}"
msgid "Failed to update price."
msgstr "価格の更新に失敗しました。"
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "成功"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount} 件のレコードが正常にマージされました"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "更新"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "更新"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. 캘린더"
msgid "{totalCost} credits"
msgstr "{totalCost} 크레딧"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "응용 프로그램"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "스캔이 불가능합니까?"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "취소"
@@ -5276,6 +5287,11 @@ msgstr "기능 플래그 업데이트 실패. {errorMessage}"
msgid "Failed to update price."
msgstr "가격 업데이트 실패."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "성공"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount}개의 레코드가 성공적으로 병합되었습니다"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "업데이트"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "업데이트"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalender"
msgid "{totalCost} credits"
msgstr "{totalCost} credits"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Applicaties"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Kan je niet scannen? Kopieer de"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Annuleren"
@@ -5276,6 +5287,11 @@ msgstr "Het bijwerken van de featureflag is mislukt. {errorMessage}"
msgid "Failed to update price."
msgstr "Fout bij het bijwerken van de prijs."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Succes"
msgid "Successfully merged {recordCount} records"
msgstr "Succesvol {recordCount} records samengevoegd"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11874,9 +11895,16 @@ msgstr "bijwerken"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Bijwerken"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalender"
msgid "{totalCost} credits"
msgstr "{totalCost} kreditter"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Applikasjoner"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Kan ikke skanne? Kopier "
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Avbryt"
@@ -5276,6 +5287,11 @@ msgstr "Kunne ikke oppdatere funksjonsflagg. {errorMessage}"
msgid "Failed to update price."
msgstr "Kunne ikke oppdatere pris."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Vellykket"
msgid "Successfully merged {recordCount} records"
msgstr "Vellykket sammenslått {recordCount} oppføringer"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "oppdater"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Oppdater"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalendarz"
msgid "{totalCost} credits"
msgstr "{totalCost, plural, one {# kredyt} few {# kredyty} many {# kredytów} other {# kredytów}}"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Aplikacje"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Nie można zeskanować? Skopiuj"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Anuluj"
@@ -5276,6 +5287,11 @@ msgstr "Nie udało się zaktualizować flagi funkcji. {errorMessage}"
msgid "Failed to update price."
msgstr "Nie udało się zaktualizować ceny."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Sukces"
msgid "Successfully merged {recordCount} records"
msgstr "Pomyślnie scalono {recordCount} rekordów"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "zaktualizuj"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Zaktualizuj"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -389,6 +389,11 @@ msgstr ""
msgid "{totalCost} credits"
msgstr ""
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1591,6 +1596,11 @@ msgstr ""
msgid "Applications"
msgstr ""
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2157,6 +2167,7 @@ msgstr ""
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr ""
@@ -5271,6 +5282,11 @@ msgstr ""
msgid "Failed to update price."
msgstr ""
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10824,6 +10840,11 @@ msgstr ""
msgid "Successfully merged {recordCount} records"
msgstr ""
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11867,9 +11888,16 @@ msgstr ""
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr ""
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Calendário"
msgid "{totalCost} credits"
msgstr "{totalCost} créditos"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr "Aplicação desinstalada com sucesso."
msgid "Applications"
msgstr "Aplicações"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Não consegue escanear? Copie o"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Cancelar"
@@ -5276,6 +5287,11 @@ msgstr "Falha ao atualizar a feature flag. {errorMessage}"
msgid "Failed to update price."
msgstr "Falha ao atualizar preço."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Sucesso"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {Mesclou com sucesso {recordCount} registro} other {Mesclou com sucesso {recordCount} registros}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "atualizar"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Atualizar"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Calendário"
msgid "{totalCost} credits"
msgstr "{totalCost} créditos"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Aplicações"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Não consegue escanear? Copie o"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Cancelar"
@@ -5276,6 +5287,11 @@ msgstr "Falha ao atualizar a feature flag. {errorMessage}"
msgid "Failed to update price."
msgstr "Falha ao atualizar o preço."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Sucesso"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {Registo mesclado com sucesso} other {Registos mesclados com sucesso}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "atualizar"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Atualizar"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Calendar"
msgid "{totalCost} credits"
msgstr "{totalCost} credite"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Aplicații"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Nu poți scana? Copiază"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Anulare"
@@ -5276,6 +5287,11 @@ msgstr "Nu s-a reușit actualizarea feature flag-ului. {errorMessage}"
msgid "Failed to update price."
msgstr "Eroare la actualizarea prețului."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Succes"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {Îmbinată cu succes {recordCount} înregistrare} few {Îmbinate cu succes {recordCount} înregistrări} other {Îmbinate cu succes {recordCount} de înregistrări}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "actualizează"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Actualizează"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
Binary file not shown.
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Календар"
msgid "{totalCost} credits"
msgstr "{totalCost} кредита"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Апликације"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Не можете да скенирате? Копирајте"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Откажи"
@@ -5276,6 +5287,11 @@ msgstr "Није успело ажурирање заставице функци
msgid "Failed to update price."
msgstr "Није успело ажурирање цене."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Успех"
msgid "Successfully merged {recordCount} records"
msgstr "Успешно спојено {recordCount} записа"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "ажурирај"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Ажурирати"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Kalender"
msgid "{totalCost} credits"
msgstr "{totalCost} krediter"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Applikationer"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Kan inte skanna? Kopiera "
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Avbryt"
@@ -5276,6 +5287,11 @@ msgstr "Det gick inte att uppdatera funktionsflagga. {errorMessage}"
msgid "Failed to update price."
msgstr "Misslyckades med att uppdatera pris."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10833,6 +10849,11 @@ msgstr "Lyckades"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount, plural, one {Framgångsrikt sammanfogad {recordCount} post} other {Framgångsrikt sammanfogade {recordCount} poster}}"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11886,9 +11907,16 @@ msgstr "uppdatera"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Uppdatera"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Takvim"
msgid "{totalCost} credits"
msgstr "{totalCost} kredi"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Uygulamalar"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Tarayamaz mısınız? Kopyalayın."
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "İptal"
@@ -5276,6 +5287,11 @@ msgstr "Özellik bayrağı güncellenemedi. {errorMessage}"
msgid "Failed to update price."
msgstr "Fiyat güncellenemedi."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Başarılı"
msgid "Successfully merged {recordCount} records"
msgstr "{recordCount} kayıt başarıyla birleştirildi"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "güncelle"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Güncelle"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Календар"
msgid "{totalCost} credits"
msgstr "{totalCost} кредитів"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Застосування"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Не можете сканувати? Скопіюйте"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Скасувати"
@@ -5276,6 +5287,11 @@ msgstr "Не вдалося оновити прапорець функції. {e
msgid "Failed to update price."
msgstr "Не вдалося оновити ціну."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Успіх"
msgid "Successfully merged {recordCount} records"
msgstr ""
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11874,9 +11895,16 @@ msgstr "оновити"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Оновити"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. Lịch"
msgid "{totalCost} credits"
msgstr "{totalCost} tín dụng"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "Ứng dụng"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "Không thể quét? Sao chép"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "Hủy bỏ"
@@ -5276,6 +5287,11 @@ msgstr "Không thể cập nhật cờ tính năng. {errorMessage}"
msgid "Failed to update price."
msgstr "Cập nhật giá thất bại."
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "Thành công"
msgid "Successfully merged {recordCount} records"
msgstr "Đã ghép thành công {recordCount} hồ sơ"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "cập nhật"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "Cập nhật"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. 日历"
msgid "{totalCost} credits"
msgstr "{totalCost} 积分"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "应用程序"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "无法扫描?复制"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "取消"
@@ -5276,6 +5287,11 @@ msgstr "更新功能开关失败。{errorMessage}"
msgid "Failed to update price."
msgstr "更新价格失败。"
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "成功"
msgid "Successfully merged {recordCount} records"
msgstr "成功合并 {recordCount} 条记录"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "更新"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "更新"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -394,6 +394,11 @@ msgstr "{stepNumber}. 日曆"
msgid "{totalCost} credits"
msgstr "{totalCost} 積分"
#. js-lingui-id: p38XKy
#: src/modules/command-menu/components/CommandMenuMultipleRecordsInfo.tsx
msgid "{totalCount} selected"
msgstr ""
#. js-lingui-id: ITVweg
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownDefaultView.tsx
#: src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownCustomView.tsx
@@ -1596,6 +1601,11 @@ msgstr ""
msgid "Applications"
msgstr "應用程序"
#. js-lingui-id: DB8zMK
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
msgid "Apply"
msgstr ""
#. js-lingui-id: UDlRcx
#: src/modules/settings/security/components/approvedAccessDomains/SettingsSecurityApprovedAccessDomainValidationEffect.tsx
msgid "Approved access domain validated"
@@ -2162,6 +2172,7 @@ msgstr "無法掃描? 複製"
#: src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx
#: src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx
#: src/modules/settings/components/SaveAndCancelButtons/CancelButton.tsx
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx
#: src/modules/action-menu/actions/record-actions/constants/DashboardActionsConfig.tsx
msgid "Cancel"
msgstr "取消"
@@ -5276,6 +5287,11 @@ msgstr "更新功能旗標失敗。{errorMessage}"
msgid "Failed to update price."
msgstr "更新價格失敗。"
#. js-lingui-id: J7vly7
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Failed to update records. Please try again."
msgstr ""
#. js-lingui-id: QGaQRo
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Failed to update role"
@@ -10829,6 +10845,11 @@ msgstr "成功"
msgid "Successfully merged {recordCount} records"
msgstr "成功合併了 {recordCount} 條記錄"
#. js-lingui-id: zsDoFr
#: src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx
msgid "Successfully updated {count} records"
msgstr ""
#. js-lingui-id: QJz8/3
#: src/modules/command-menu/pages/page-layout/constants/settings/ChartConfigurationSettingLabels.ts
msgid "Suffix"
@@ -11872,9 +11893,16 @@ msgstr "更新"
#: src/modules/settings/integrations/components/SettingsIntegrationRemoteTableSchemaUpdate.tsx
#: src/modules/information-banner/components/billing/InformationBannerFailPaymentInfo.tsx
#: src/modules/information-banner/components/billing/InformationBannerBillingSubscriptionPaused.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update"
msgstr "更新"
#. js-lingui-id: 0KAL3W
#: src/modules/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu.tsx
#: src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
msgid "Update records"
msgstr ""
#. js-lingui-id: 5bRMKt
#: src/modules/settings/members/components/MemberPermissionsTab.tsx
msgid "Update role"
@@ -4,6 +4,7 @@ import { DestroyMultipleRecordsAction } from '@/action-menu/actions/record-actio
import { ExportMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/components/ExportMultipleRecordsAction';
import { MergeMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/components/MergeMultipleRecordsAction';
import { RestoreMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/components/RestoreMultipleRecordsAction';
import { UpdateMultipleRecordsAction } from '@/action-menu/actions/record-actions/multiple-records/components/UpdateMultipleRecordsAction';
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
import { CreateNewIndexRecordNoSelectionRecordAction } from '@/action-menu/actions/record-actions/no-selection/components/CreateNewIndexRecordNoSelectionRecordAction';
import { CreateNewViewNoSelectionRecord } from '@/action-menu/actions/record-actions/no-selection/components/CreateNewViewNoSelectionRecord';
@@ -32,14 +33,13 @@ import { msg } from '@lingui/core/macro';
import { isNonEmptyString } from '@sniptt/guards';
import { MUTATION_MAX_MERGE_RECORDS } from 'twenty-shared/constants';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import {
IconArrowMerge,
IconBuildingSkyscraper,
IconCheckbox,
IconChevronDown,
IconChevronUp,
IconEdit,
IconEyeOff,
IconFileExport,
IconFileImport,
@@ -57,6 +57,8 @@ import {
IconTrashX,
IconUser,
} from 'twenty-ui/display';
import { isDefined } from 'twenty-shared/utils';
import { PermissionFlagType } from '~/generated-metadata/graphql';
export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
@@ -359,13 +361,28 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
component: <ExportSingleRecordAction />,
requiredPermissionFlag: PermissionFlagType.EXPORT_CSV,
},
[MultipleRecordsActionKeys.UPDATE]: {
type: ActionType.Standard,
scope: ActionScope.RecordSelection,
key: MultipleRecordsActionKeys.UPDATE,
label: msg`Update records`,
shortLabel: msg`Update`,
position: 14,
Icon: IconEdit,
accent: 'default',
isPinned: true,
shouldBeRegistered: ({ objectPermissions, isRemote }) =>
objectPermissions.canUpdateObjectRecords && !isRemote,
availableOn: [ActionViewType.INDEX_PAGE_BULK_SELECTION],
component: <UpdateMultipleRecordsAction />,
},
[MultipleRecordsActionKeys.MERGE]: {
type: ActionType.Standard,
scope: ActionScope.RecordSelection,
key: MultipleRecordsActionKeys.MERGE,
label: msg`Merge records`,
shortLabel: msg`Merge`,
position: 14,
position: 15,
Icon: IconArrowMerge,
accent: 'default',
isPinned: false,
@@ -388,7 +405,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: MultipleRecordsActionKeys.EXPORT,
label: msg`Export records`,
shortLabel: msg`Export`,
position: 15,
position: 16,
Icon: IconFileExport,
accent: 'default',
isPinned: false,
@@ -403,7 +420,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.IMPORT_RECORDS,
label: msg`Import records`,
shortLabel: msg`Import`,
position: 16,
position: 17,
Icon: IconFileImport,
accent: 'default',
isPinned: false,
@@ -419,7 +436,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.EXPORT_VIEW,
label: msg`Export view`,
shortLabel: msg`Export`,
position: 17,
position: 18,
Icon: IconFileExport,
accent: 'default',
isPinned: false,
@@ -434,7 +451,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
label: msg`See deleted records`,
shortLabel: msg`Deleted records`,
position: 18,
position: 19,
Icon: IconRotate2,
accent: 'default',
isPinned: false,
@@ -449,7 +466,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.CREATE_NEW_VIEW,
label: msg`Create View`,
shortLabel: msg`Create View`,
position: 19,
position: 20,
Icon: IconLayout,
accent: 'default',
isPinned: false,
@@ -464,7 +481,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.HIDE_DELETED_RECORDS,
label: msg`Hide deleted records`,
shortLabel: msg`Hide deleted`,
position: 20,
position: 21,
Icon: IconEyeOff,
accent: 'default',
isPinned: false,
@@ -479,7 +496,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_WORKFLOWS,
label: msg`Go to Workflows`,
shortLabel: msg`See Workflows`,
position: 21,
position: 22,
Icon: IconSettingsAutomation,
accent: 'default',
isPinned: false,
@@ -512,7 +529,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_PEOPLE,
label: msg`Go to People`,
shortLabel: msg`People`,
position: 22,
position: 23,
Icon: IconUser,
isPinned: false,
availableOn: [
@@ -544,7 +561,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_COMPANIES,
label: msg`Go to Companies`,
shortLabel: msg`Companies`,
position: 23,
position: 24,
Icon: IconBuildingSkyscraper,
isPinned: false,
availableOn: [
@@ -576,7 +593,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_DASHBOARDS,
label: msg`Go to Dashboards`,
shortLabel: msg`Dashboards`,
position: 24,
position: 25,
Icon: IconLayoutDashboard,
isPinned: false,
availableOn: [
@@ -607,7 +624,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_OPPORTUNITIES,
label: msg`Go to Opportunities`,
shortLabel: msg`Opportunities`,
position: 25,
position: 26,
Icon: IconTargetArrow,
isPinned: false,
availableOn: [
@@ -640,7 +657,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_SETTINGS,
label: msg`Go to Settings`,
shortLabel: msg`Settings`,
position: 26,
position: 27,
Icon: IconSettings,
isPinned: false,
availableOn: [
@@ -666,7 +683,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_TASKS,
label: msg`Go to Tasks`,
shortLabel: msg`Tasks`,
position: 27,
position: 28,
Icon: IconCheckbox,
isPinned: false,
availableOn: [
@@ -698,7 +715,7 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
key: NoSelectionRecordActionKeys.GO_TO_NOTES,
label: msg`Go to Notes`,
shortLabel: msg`Notes`,
position: 28,
position: 29,
Icon: IconCheckbox,
isPinned: false,
availableOn: [
@@ -0,0 +1,21 @@
import { ActionDisplay } from '@/action-menu/actions/display/components/ActionDisplay';
import { useOpenUpdateMultipleRecordsPageInCommandMenu } from '@/command-menu/hooks/useOpenUpdateMultipleRecordsPageInCommandMenu';
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
export const UpdateMultipleRecordsAction = () => {
const contextStoreInstanceId = useAvailableComponentInstanceIdOrThrow(
ContextStoreComponentInstanceContext,
);
const { openUpdateMultipleRecordsPageInCommandMenu } =
useOpenUpdateMultipleRecordsPageInCommandMenu({
contextStoreInstanceId,
});
const handleClick = () => {
openUpdateMultipleRecordsPageInCommandMenu();
};
return <ActionDisplay onClick={handleClick} />;
};
@@ -1,4 +1,5 @@
export enum MultipleRecordsActionKeys {
UPDATE = 'update-multiple-records',
DELETE = 'delete-multiple-records',
EXPORT = 'export-multiple-records',
MERGE = 'merge-multiple-records',
@@ -0,0 +1,34 @@
import { DEFAULT_RECORD_ACTIONS_CONFIG } from '@/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig';
import { MultipleRecordsActionKeys } from '@/action-menu/actions/record-actions/multiple-records/types/MultipleRecordsActionKeys';
import { getActionLabel } from '@/action-menu/utils/getActionLabel';
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
import { useFindManyRecordsSelectedInContextStore } from '@/context-store/hooks/useFindManyRecordsSelectedInContextStore';
import { useTheme } from '@emotion/react';
import { t } from '@lingui/core/macro';
type CommandMenuMultipleRecordsInfoProps = {
commandMenuPageInstanceId: string;
};
export const CommandMenuMultipleRecordsInfo = ({
commandMenuPageInstanceId,
}: CommandMenuMultipleRecordsInfoProps) => {
const theme = useTheme();
const { totalCount } = useFindManyRecordsSelectedInContextStore({
instanceId: commandMenuPageInstanceId,
limit: 1,
});
const { Icon, label } =
DEFAULT_RECORD_ACTIONS_CONFIG[MultipleRecordsActionKeys.UPDATE];
return (
<CommandMenuPageInfoLayout
icon={<Icon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />}
iconColor={theme.font.color.tertiary}
title={getActionLabel(label)}
label={t`${totalCount} selected`}
/>
);
};
@@ -1,3 +1,4 @@
import { CommandMenuMultipleRecordsInfo } from '@/command-menu/components/CommandMenuMultipleRecordsInfo';
import { CommandMenuPageLayoutInfo } from '@/command-menu/components/CommandMenuPageLayoutInfo';
import { CommandMenuRecordInfo } from '@/command-menu/components/CommandMenuRecordInfo';
import { CommandMenuWorkflowStepInfo } from '@/command-menu/components/CommandMenuWorkflowStepInfo';
@@ -61,6 +62,17 @@ export const CommandMenuPageInfo = ({ pageChip }: CommandMenuPageInfoProps) => {
return <CommandMenuPageLayoutInfo />;
}
const isMultipleRecordsPage =
pageChip.page?.page === CommandMenuPages.UpdateRecords;
if (isMultipleRecordsPage && isDefined(pageChip.page?.pageId)) {
return (
<CommandMenuMultipleRecordsInfo
commandMenuPageInstanceId={pageChip.page.pageId}
/>
);
}
return (
<StyledPageTitle>
<OverflowingTextWithTooltip text={pageChip.text ?? ''} />
@@ -29,6 +29,7 @@ export const StyledPageInfoTextContainer = styled.div`
export const StyledPageInfoTitleContainer = styled.div`
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
padding-inline: ${({ theme }) => theme.spacing(1)};
min-width: 0;
max-width: 150px;
`;
@@ -10,6 +10,7 @@ import { CommandMenuPageLayoutTabSettings } from '@/command-menu/pages/page-layo
import { CommandMenuPageLayoutWidgetTypeSelect } from '@/command-menu/pages/page-layout/components/CommandMenuPageLayoutWidgetTypeSelect';
import { CommandMenuMergeRecordPage } from '@/command-menu/pages/record-page/components/CommandMenuMergeRecordPage';
import { CommandMenuRecordPage } from '@/command-menu/pages/record-page/components/CommandMenuRecordPage';
import { CommandMenuUpdateMultipleRecords } from '@/command-menu/pages/record-page/components/CommandMenuUpdateMultipleRecords';
import { CommandMenuEditRichTextPage } from '@/command-menu/pages/rich-text-page/components/CommandMenuEditRichTextPage';
import { CommandMenuSearchRecordsPage } from '@/command-menu/pages/search/components/CommandMenuSearchRecordsPage';
import { CommandMenuWorkflowCreateStep } from '@/command-menu/pages/workflow/step/create/components/CommandMenuWorkflowCreateStep';
@@ -27,6 +28,7 @@ export const COMMAND_MENU_PAGES_CONFIG = new Map<
[CommandMenuPages.Root, <CommandMenu />],
[CommandMenuPages.ViewRecord, <CommandMenuRecordPage />],
[CommandMenuPages.MergeRecords, <CommandMenuMergeRecordPage />],
[CommandMenuPages.UpdateRecords, <CommandMenuUpdateMultipleRecords />],
[CommandMenuPages.ViewEmailThread, <CommandMenuMessageThreadPage />],
[CommandMenuPages.ViewCalendarEvent, <CommandMenuCalendarEventPage />],
[CommandMenuPages.EditRichText, <CommandMenuEditRichTextPage />],
@@ -0,0 +1,6 @@
describe('useOpenUpdateMultipleRecordsPageInCommandMenu', () => {
it('should work', () => {
// const { result } = renderHook(() => useOpenUpdateMultipleRecordsPageInCommandMenu({ contextStoreInstanceId: 'test' }));
expect(true).toBe(true);
});
});
@@ -0,0 +1,31 @@
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
import { CommandMenuPages } from '@/command-menu/types/CommandMenuPages';
import { msg, t } from '@lingui/core/macro';
import { useRecoilCallback } from 'recoil';
import { IconBoxMultiple } from 'twenty-ui/display';
type UseOpenUpdateMultipleRecordsPageInCommandMenuProps = {
contextStoreInstanceId: string;
};
export const useOpenUpdateMultipleRecordsPageInCommandMenu = ({
contextStoreInstanceId,
}: UseOpenUpdateMultipleRecordsPageInCommandMenuProps) => {
const { navigateCommandMenu } = useNavigateCommandMenu();
const openUpdateMultipleRecordsPageInCommandMenu = useRecoilCallback(() => {
return async () => {
navigateCommandMenu({
page: CommandMenuPages.UpdateRecords,
pageTitle: t(msg`Update records`),
pageIcon: IconBoxMultiple,
pageId: contextStoreInstanceId,
});
};
}, [navigateCommandMenu, contextStoreInstanceId]);
return {
openUpdateMultipleRecordsPageInCommandMenu,
};
};
@@ -0,0 +1,42 @@
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { UpdateMultipleRecordsContainer } from '@/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useComponentInstanceStateContext } from '@/ui/utilities/state/component-state/hooks/useComponentInstanceStateContext';
import styled from '@emotion/styled';
const StyledRightDrawerRecord = styled.div<{
isMobile: boolean;
}>`
height: ${({ theme, isMobile }) => {
const mobileOffset = isMobile ? theme.spacing(16) : '0px';
return `calc(100% - ${mobileOffset})`;
}};
`;
export const CommandMenuUpdateMultipleRecords = () => {
const isMobile = useIsMobile();
const commandMenuPageInstanceId = useComponentInstanceStateContext(
CommandMenuPageComponentInstanceContext,
)?.instanceId;
if (!commandMenuPageInstanceId) {
throw new Error('Command menu page instance id is not defined');
}
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow(
commandMenuPageInstanceId,
);
return (
<StyledRightDrawerRecord isMobile={isMobile}>
<UpdateMultipleRecordsContainer
objectNameSingular={objectMetadataItem.nameSingular}
contextStoreInstanceId={commandMenuPageInstanceId}
/>
</StyledRightDrawerRecord>
);
};
@@ -2,6 +2,7 @@ export enum CommandMenuPages {
Root = 'root',
ViewRecord = 'view-record',
MergeRecords = 'merge-records',
UpdateRecords = 'update-records',
ViewEmailThread = 'view-email-thread',
ViewCalendarEvent = 'view-calendar-event',
EditRichText = 'edit-rich-text',
@@ -0,0 +1,195 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useIncrementalFetchAndMutateRecords } from '@/object-record/hooks/useIncrementalFetchAndMutateRecords';
import { useLazyFindManyRecords } from '@/object-record/hooks/useLazyFindManyRecords';
import { renderHook } from '@testing-library/react';
jest.mock('@/object-metadata/hooks/useObjectMetadataItem');
jest.mock('@/object-record/hooks/useLazyFindManyRecords');
const mockUseObjectMetadataItem = jest.mocked(useObjectMetadataItem);
const mockUseLazyFindManyRecords = jest.mocked(useLazyFindManyRecords);
describe('useIncrementalFetchAndMutateRecords', () => {
const mockFindManyRecordsLazy = jest.fn();
const mockFetchMoreRecordsLazy = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
mockUseObjectMetadataItem.mockReturnValue({
objectMetadataItem: {
nameSingular: 'company',
namePlural: 'companies',
} as any,
});
mockUseLazyFindManyRecords.mockReturnValue({
findManyRecordsLazy: mockFindManyRecordsLazy,
fetchMoreRecordsLazy: mockFetchMoreRecordsLazy,
} as any);
});
it('should fetch and mutate records in batches', async () => {
mockFindManyRecordsLazy.mockResolvedValue({
data: {
companies: {
totalCount: 3,
edges: [{ node: { id: '1' } }, { node: { id: '2' } }],
pageInfo: {
hasNextPage: true,
endCursor: 'cursor-1',
},
},
},
});
mockFetchMoreRecordsLazy.mockResolvedValue({
data: {
edges: [{ node: { id: '3' } }],
pageInfo: {
hasNextPage: false,
endCursor: 'cursor-2',
},
},
});
const { result } = renderHook(() =>
useIncrementalFetchAndMutateRecords({
objectNameSingular: 'company',
limit: 2,
} as any),
);
const mutateBatchMock = jest.fn();
await result.current.incrementalFetchAndMutate(mutateBatchMock);
expect(mockFindManyRecordsLazy).toHaveBeenCalled();
expect(mutateBatchMock).toHaveBeenCalledTimes(2);
expect(mutateBatchMock).toHaveBeenNthCalledWith(1, {
recordIds: ['1', '2'],
totalFetchedCount: 2,
totalCount: 3,
abortSignal: expect.any(Object),
});
expect(mockFetchMoreRecordsLazy).toHaveBeenCalledWith(2);
expect(mutateBatchMock).toHaveBeenNthCalledWith(2, {
recordIds: ['3'],
totalFetchedCount: 3,
totalCount: 3,
abortSignal: expect.any(Object),
});
});
it('should update progress during processing', async () => {
mockFindManyRecordsLazy.mockResolvedValue({
data: {
companies: {
totalCount: 1,
edges: [{ node: { id: '1' } }],
pageInfo: { hasNextPage: false },
},
},
});
const { result } = renderHook(() =>
useIncrementalFetchAndMutateRecords({
objectNameSingular: 'company',
} as any),
);
expect(result.current.isProcessing).toBe(false);
await result.current.incrementalFetchAndMutate(jest.fn());
expect(result.current.isProcessing).toBe(false);
});
it('should do nothing if findManyRecordsLazy is undefined', async () => {
mockUseLazyFindManyRecords.mockReturnValue({
findManyRecordsLazy: undefined,
fetchMoreRecordsLazy: mockFetchMoreRecordsLazy,
} as any);
const { result } = renderHook(() =>
useIncrementalFetchAndMutateRecords({
objectNameSingular: 'company',
} as any),
);
await result.current.incrementalFetchAndMutate(jest.fn());
expect(mockFindManyRecordsLazy).not.toHaveBeenCalled();
});
it('should abort processing when cancel is called', async () => {
mockFindManyRecordsLazy.mockResolvedValue({
data: {
companies: {
totalCount: 10,
edges: [],
pageInfo: { hasNextPage: true, endCursor: 'c1' },
},
},
});
const { result } = renderHook(() =>
useIncrementalFetchAndMutateRecords({
objectNameSingular: 'company',
} as any),
);
const abortMock = jest.fn();
jest.spyOn(global, 'AbortController').mockImplementation(
() =>
({
signal: { aborted: true } as unknown as AbortSignal,
abort: abortMock,
}) as unknown as AbortController,
);
await result.current.incrementalFetchAndMutate(jest.fn());
expect(mockFetchMoreRecordsLazy).not.toHaveBeenCalled();
jest.restoreAllMocks();
});
it('should call abort on current controller when cancel is invoked', () => {
const { result } = renderHook(() =>
useIncrementalFetchAndMutateRecords({ objectNameSingular: 'c' } as any),
);
result.current.cancel();
});
it('should silently return when AbortError is thrown during fetch', async () => {
const error: any = new Error('Aborted');
error.name = 'AbortError';
mockFindManyRecordsLazy.mockRejectedValue(error);
const { result } = renderHook(() =>
useIncrementalFetchAndMutateRecords({
objectNameSingular: 'company',
} as any),
);
await expect(
result.current.incrementalFetchAndMutate(jest.fn()),
).resolves.toBeUndefined();
});
it('should rethrow non-AbortError errors', async () => {
mockFindManyRecordsLazy.mockRejectedValue(new Error('Network error'));
const { result } = renderHook(() =>
useIncrementalFetchAndMutateRecords({
objectNameSingular: 'company',
} as any),
);
await expect(
result.current.incrementalFetchAndMutate(jest.fn()),
).rejects.toThrow('Network error');
});
});
@@ -0,0 +1,153 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useIncrementalFetchAndMutateRecords } from '@/object-record/hooks/useIncrementalFetchAndMutateRecords';
import { useIncrementalUpdateManyRecords } from '@/object-record/hooks/useIncrementalUpdateManyRecords';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpdateManyRecords } from '@/object-record/hooks/useUpdateManyRecords';
import { renderHook } from '@testing-library/react';
jest.mock('@/object-metadata/hooks/useObjectMetadataItem');
jest.mock('@/object-record/hooks/useRegisterObjectOperation');
jest.mock('@/object-record/hooks/useUpdateManyRecords', () => ({
useUpdateManyRecords: jest.fn(),
}));
jest.mock('@/object-record/hooks/useRefetchAggregateQueries', () => ({
useRefetchAggregateQueries: () => ({
refetchAggregateQueries: jest.fn(),
}),
}));
jest.mock('@/object-record/hooks/useIncrementalFetchAndMutateRecords');
const mockUseObjectMetadataItem = jest.mocked(useObjectMetadataItem);
const mockUseRegisterObjectOperation = jest.mocked(useRegisterObjectOperation);
const mockUseUpdateManyRecords = jest.mocked(useUpdateManyRecords);
const mockUseIncrementalFetchAndMutateRecords = jest.mocked(
useIncrementalFetchAndMutateRecords,
);
describe('useIncrementalUpdateManyRecords', () => {
const mockUpdateManyRecords = jest.fn();
const mockRegisterObjectOperation = jest.fn();
const mockIncrementalFetchAndMutate = jest.fn();
const mockUpdateProgress = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
mockUseObjectMetadataItem.mockReturnValue({
objectMetadataItem: {
namePlural: 'companies',
} as any,
});
mockUseRegisterObjectOperation.mockReturnValue({
registerObjectOperation: mockRegisterObjectOperation,
});
mockUseUpdateManyRecords.mockReturnValue({
updateManyRecords: mockUpdateManyRecords,
});
mockUseIncrementalFetchAndMutateRecords.mockReturnValue({
incrementalFetchAndMutate: mockIncrementalFetchAndMutate,
progress: { displayType: 'number' },
isProcessing: false,
updateProgress: mockUpdateProgress,
cancel: jest.fn(),
});
});
it('should call incrementalFetchAndMutate and execute mutations via useUpdateManyRecords', async () => {
mockIncrementalFetchAndMutate.mockImplementation(async (callback) => {
// Simulate one batch
await callback({
recordIds: ['1', '2'],
totalCount: 2,
totalFetchedCount: 2,
abortSignal: new AbortController().signal,
});
});
const { result } = renderHook(() =>
useIncrementalUpdateManyRecords({
objectNameSingular: 'company',
} as any),
);
await result.current.incrementalUpdateManyRecords({ name: 'New Name' });
expect(mockIncrementalFetchAndMutate).toHaveBeenCalled();
expect(mockUpdateManyRecords).toHaveBeenCalledWith({
recordIdsToUpdate: ['1', '2'],
updateOneRecordInput: { name: 'New Name' },
delayInMsBetweenRequests: 50,
skipRegisterObjectOperation: true,
skipRefetchAggregateQueries: true,
abortSignal: expect.any(AbortSignal),
});
expect(mockUpdateProgress).toHaveBeenCalledWith(2, 2);
expect(mockRegisterObjectOperation).toHaveBeenCalledWith(
expect.anything(),
{
type: 'update-many',
result: {
updateInputs: [
{ id: '1', name: 'New Name' },
{ id: '2', name: 'New Name' },
],
},
},
);
});
it('should pass abortSignal to updateManyRecords', async () => {
const abortController = new AbortController();
mockIncrementalFetchAndMutate.mockImplementation(async (callback) => {
await callback({
recordIds: ['1'],
totalCount: 1,
totalFetchedCount: 1,
abortSignal: abortController.signal,
});
});
const { result } = renderHook(() =>
useIncrementalUpdateManyRecords({
objectNameSingular: 'company',
} as any),
);
await result.current.incrementalUpdateManyRecords({ name: 'New Name' });
expect(mockUpdateManyRecords).toHaveBeenCalledWith(
expect.objectContaining({
abortSignal: abortController.signal,
}),
);
});
it('should execute cleanup actions (refetch aggregates, register operation) even if processing fails', async () => {
mockIncrementalFetchAndMutate.mockRejectedValue(
new Error('Process failed'),
);
const { result } = renderHook(() =>
useIncrementalUpdateManyRecords({
objectNameSingular: 'company',
} as any),
);
await expect(
result.current.incrementalUpdateManyRecords({ name: 'New Name' }),
).rejects.toThrow('Process failed');
expect(mockRegisterObjectOperation).toHaveBeenCalledWith(
expect.anything(),
{
type: 'update-many',
result: {
updateInputs: [],
},
},
);
});
});
@@ -129,7 +129,10 @@ export const useIncrementalDeleteManyRecords = <T>({
],
);
const deleteManyRecordsBatch = async (recordIdsToDelete: string[]) => {
const deleteManyRecordsBatch = async (
recordIdsToDelete: string[],
abortSignal: AbortSignal,
) => {
const numberOfBatches = Math.ceil(
recordIdsToDelete.length / mutationPageSize,
);
@@ -168,6 +171,11 @@ export const useIncrementalDeleteManyRecords = <T>({
variables: {
filter: { id: { in: batchedIdsToDelete } },
},
context: {
fetchOptions: {
signal: abortSignal,
},
},
})
.catch((error: Error) => {
if (skipOptimisticEffect) {
@@ -215,13 +223,15 @@ export const useIncrementalDeleteManyRecords = <T>({
const incrementalDeleteManyRecords = async () => {
let totalDeletedCount = 0;
await incrementalFetchAndMutate(async ({ recordIds, totalCount }) => {
await deleteManyRecordsBatch(recordIds);
await incrementalFetchAndMutate(
async ({ recordIds, totalCount, abortSignal }) => {
await deleteManyRecordsBatch(recordIds, abortSignal);
totalDeletedCount += recordIds.length;
totalDeletedCount += recordIds.length;
updateProgress(totalDeletedCount, totalCount);
});
updateProgress(totalDeletedCount, totalCount);
},
);
await refetchAggregateQueries();
@@ -73,7 +73,10 @@ export const useIncrementalDestroyManyRecords = <T>({
recordGqlFields: { id: true },
});
const destroyManyRecordsBatch = async (recordIdsToDestroy: string[]) => {
const destroyManyRecordsBatch = async (
recordIdsToDestroy: string[],
abortSignal: AbortSignal,
) => {
const numberOfBatches = Math.ceil(
recordIdsToDestroy.length / mutationPageSize,
);
@@ -94,6 +97,11 @@ export const useIncrementalDestroyManyRecords = <T>({
variables: {
filter: { id: { in: batchedIdsToDestroy } },
},
context: {
fetchOptions: {
signal: abortSignal,
},
},
optimisticResponse: skipOptimisticEffect
? undefined
: {
@@ -145,13 +153,15 @@ export const useIncrementalDestroyManyRecords = <T>({
const incrementalDestroyManyRecords = async () => {
let totalDestroyedCount = 0;
await incrementalFetchAndMutate(async ({ recordIds, totalCount }) => {
await destroyManyRecordsBatch(recordIds);
await incrementalFetchAndMutate(
async ({ recordIds, totalCount, abortSignal }) => {
await destroyManyRecordsBatch(recordIds, abortSignal);
totalDestroyedCount += recordIds.length;
totalDestroyedCount += recordIds.length;
updateProgress(totalDestroyedCount, totalCount);
});
updateProgress(totalDestroyedCount, totalCount);
},
);
await refetchAggregateQueries();
@@ -15,6 +15,7 @@ type MutateRecordsBatchParams = {
recordIds: string[];
totalFetchedCount: number;
totalCount: number;
abortSignal: AbortSignal;
};
export const useIncrementalFetchAndMutateRecords = <T>({
@@ -29,6 +30,9 @@ export const useIncrementalFetchAndMutateRecords = <T>({
displayType: 'number',
});
const [abortController, setAbortController] =
useState<AbortController | null>(null);
const { fetchMoreRecordsLazy, findManyRecordsLazy } = useLazyFindManyRecords({
objectNameSingular,
filter,
@@ -50,6 +54,8 @@ export const useIncrementalFetchAndMutateRecords = <T>({
try {
setIsProcessing(true);
const controller = new AbortController();
setAbortController(controller);
const findManyRecordsDataResult = await findManyRecordsLazy();
@@ -73,6 +79,7 @@ export const useIncrementalFetchAndMutateRecords = <T>({
recordIds: firstPageRecordIds,
totalFetchedCount,
totalCount,
abortSignal: controller.signal,
});
}
@@ -81,7 +88,7 @@ export const useIncrementalFetchAndMutateRecords = <T>({
let lastCursor = firstQueryResult?.pageInfo.endCursor ?? null;
for (let pageIndex = 0; pageIndex < remainingPages; pageIndex++) {
if (lastCursor === null) {
if (lastCursor === null || controller.signal.aborted) {
break;
}
@@ -89,7 +96,7 @@ export const useIncrementalFetchAndMutateRecords = <T>({
break;
}
const rawResult = await fetchMoreRecordsLazy();
const rawResult = await fetchMoreRecordsLazy(limit);
const fetchMoreResult = rawResult?.data;
const currentPageRecordIds =
@@ -102,6 +109,7 @@ export const useIncrementalFetchAndMutateRecords = <T>({
recordIds: currentPageRecordIds,
totalFetchedCount,
totalCount,
abortSignal: controller.signal,
});
}
@@ -111,14 +119,25 @@ export const useIncrementalFetchAndMutateRecords = <T>({
lastCursor = fetchMoreResult?.pageInfo.endCursor ?? null;
}
} catch (error) {
if ((error as any).name === 'AbortError') {
return;
}
throw error;
} finally {
setIsProcessing(false);
setProgress({
displayType: 'number',
});
setAbortController(null);
}
};
const cancel = () => {
abortController?.abort();
};
const updateProgress = (
processedRecordCount: number,
totalRecordCount: number,
@@ -135,5 +154,6 @@ export const useIncrementalFetchAndMutateRecords = <T>({
isProcessing,
incrementalFetchAndMutate,
updateProgress,
cancel,
};
};
@@ -0,0 +1,101 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { DEFAULT_QUERY_PAGE_SIZE } from '@/object-record/constants/DefaultQueryPageSize';
import { type UseFindManyRecordsParams } from '@/object-record/hooks/useFetchMoreRecordsWithPagination';
import { useIncrementalFetchAndMutateRecords } from '@/object-record/hooks/useIncrementalFetchAndMutateRecords';
import { useRefetchAggregateQueries } from '@/object-record/hooks/useRefetchAggregateQueries';
import { useRegisterObjectOperation } from '@/object-record/hooks/useRegisterObjectOperation';
import { useUpdateManyRecords } from '@/object-record/hooks/useUpdateManyRecords';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
const DEFAULT_DELAY_BETWEEN_MUTATIONS_MS = 50;
type UseIncrementalUpdateManyRecordsParams<T> = Omit<
UseFindManyRecordsParams<T>,
'skip'
> & {
objectNameSingular: string;
pageSize?: number;
delayInMsBetweenMutations?: number;
};
export const useIncrementalUpdateManyRecords = <
T,
UpdatedObjectRecord extends ObjectRecord = ObjectRecord,
>({
objectNameSingular,
filter,
orderBy,
pageSize = DEFAULT_QUERY_PAGE_SIZE,
delayInMsBetweenMutations = DEFAULT_DELAY_BETWEEN_MUTATIONS_MS,
}: UseIncrementalUpdateManyRecordsParams<T>) => {
const { registerObjectOperation } = useRegisterObjectOperation();
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular,
});
const { updateManyRecords } = useUpdateManyRecords<UpdatedObjectRecord>({
objectNameSingular,
});
const { refetchAggregateQueries } = useRefetchAggregateQueries({
objectMetadataNamePlural: objectMetadataItem.namePlural,
});
const {
incrementalFetchAndMutate,
progress,
isProcessing,
updateProgress,
cancel,
} = useIncrementalFetchAndMutateRecords<T>({
objectNameSingular,
filter,
orderBy,
limit: pageSize,
recordGqlFields: { id: true },
});
const incrementalUpdateManyRecords = async (
fieldsToUpdate: Partial<UpdatedObjectRecord>,
) => {
let totalUpdatedCount = 0;
const allUpdatedRecordIds: string[] = [];
try {
await incrementalFetchAndMutate(
async ({ recordIds, totalCount, abortSignal }) => {
await updateManyRecords({
recordIdsToUpdate: recordIds,
updateOneRecordInput: fieldsToUpdate,
delayInMsBetweenRequests: delayInMsBetweenMutations,
skipRegisterObjectOperation: true,
skipRefetchAggregateQueries: true,
abortSignal,
});
totalUpdatedCount += recordIds.length;
allUpdatedRecordIds.push(...recordIds);
updateProgress(totalUpdatedCount, totalCount);
},
);
} finally {
await refetchAggregateQueries();
registerObjectOperation(objectMetadataItem, {
type: 'update-many',
result: {
updateInputs: allUpdatedRecordIds.map((id) => ({
id,
...fieldsToUpdate,
})),
},
});
}
return totalUpdatedCount;
};
return { incrementalUpdateManyRecords, progress, isProcessing, cancel };
};
@@ -33,6 +33,9 @@ export type UpdateManyRecordsProps<T extends ObjectRecord = ObjectRecord> = {
updateOneRecordInput: Partial<Omit<T, 'id'>>;
skipOptimisticEffect?: boolean;
delayInMsBetweenRequests?: number;
skipRegisterObjectOperation?: boolean;
skipRefetchAggregateQueries?: boolean;
abortSignal?: AbortSignal;
};
export const useUpdateManyRecords = <T extends ObjectRecord = ObjectRecord>({
@@ -83,6 +86,9 @@ export const useUpdateManyRecords = <T extends ObjectRecord = ObjectRecord>({
updateOneRecordInput,
delayInMsBetweenRequests,
skipOptimisticEffect = false,
skipRegisterObjectOperation = false,
skipRefetchAggregateQueries = false,
abortSignal,
}: UpdateManyRecordsProps<T>) => {
const numberOfBatches = Math.ceil(
recordIdsToUpdate.length / mutationPageSize,
@@ -177,6 +183,11 @@ export const useUpdateManyRecords = <T extends ObjectRecord = ObjectRecord>({
filter: { id: { in: batchedIdsToUpdate } },
data: sanitizedInput,
},
context: {
fetchOptions: {
signal: abortSignal,
},
},
})
.catch((error: Error) => {
if (skipOptimisticEffect) {
@@ -249,17 +260,21 @@ export const useUpdateManyRecords = <T extends ObjectRecord = ObjectRecord>({
}
}
await refetchAggregateQueries();
if (!skipRefetchAggregateQueries) {
await refetchAggregateQueries();
}
registerObjectOperation(objectMetadataItem, {
type: 'update-many',
result: {
updateInputs: recordIdsToUpdate.map((id) => ({
id,
...updateOneRecordInput,
})),
},
});
if (!skipRegisterObjectOperation) {
registerObjectOperation(objectMetadataItem, {
type: 'update-many',
result: {
updateInputs: recordIdsToUpdate.map((id) => ({
id,
...updateOneRecordInput,
})),
},
});
}
return updatedRecords;
};
@@ -69,9 +69,9 @@ export const RecordTableVirtualizedDataChangedEffect = () => {
}
if (lastObjectOperation.data.type === 'update-one') {
const updatedFieldNames =
Object.keys(lastObjectOperation?.data.result.updateInput ?? {}) ??
[];
const updateInput = lastObjectOperation.data.result.updateInput;
const updatedFieldNames = Object.keys(updateInput ?? {}) ?? [];
const updatedFieldMetadataItems = activeFieldMetadataItems.filter(
(fieldMetadataItemToFilter) =>
@@ -0,0 +1,109 @@
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
import { UpdateMultipleRecordsFooter } from '@/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter';
import { UpdateMultipleRecordsForm } from '@/object-record/record-update-multiple/components/UpdateMultipleRecordsForm';
import { useUpdateMultipleRecordsActions } from '@/object-record/record-update-multiple/hooks/useUpdateMultipleRecordsActions';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { ShowPageContainer } from '@/ui/layout/page/components/ShowPageContainer';
import { RightDrawerProvider } from '@/ui/layout/right-drawer/contexts/RightDrawerContext';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { useState } from 'react';
const StyledShowPageRightContainer = styled.div`
display: flex;
flex-direction: column;
justify-content: start;
width: 100%;
height: 100%;
overflow: auto;
`;
const StyledContentContainer = styled.div`
flex: 1;
overflow-y: auto;
background: ${({ theme }) => theme.background.primary};
padding-bottom: ${({ theme }) => theme.spacing(16)};
`;
export type UpdateMultipleRecordsState = Record<string, any>;
export const UpdateMultipleRecordsContainer = ({
objectNameSingular,
contextStoreInstanceId,
}: {
objectNameSingular: string;
contextStoreInstanceId: string;
}) => {
const { updateRecords, isUpdating, progress, cancel } =
useUpdateMultipleRecordsActions({
objectNameSingular,
contextStoreInstanceId,
});
const { t } = useLingui();
const { enqueueSuccessSnackBar, enqueueErrorSnackBar } = useSnackBar();
const { closeCommandMenu } = useCommandMenu();
const [fieldUpdates, setFieldUpdates] = useState<UpdateMultipleRecordsState>(
{},
);
const handleUpdate = async () => {
try {
const count = await updateRecords(fieldUpdates);
if (count !== undefined) {
enqueueSuccessSnackBar({
message: t`Successfully updated ${count} records`,
});
closeCommandMenu();
}
} catch (error) {
enqueueErrorSnackBar({
message:
error instanceof Error
? error.message
: t`Failed to update records. Please try again.`,
});
}
};
const handleCancel = () => {
cancel();
closeCommandMenu();
};
const hasChanges = Object.values(fieldUpdates).some(
(value) => value !== undefined,
);
const handleFieldChange = (fieldName: string, value: any) => {
setFieldUpdates((prevState) => ({
...prevState,
[fieldName]: value,
}));
};
return (
<RightDrawerProvider value={{ isInRightDrawer: true }}>
<ShowPageContainer>
<StyledShowPageRightContainer>
<StyledContentContainer>
<UpdateMultipleRecordsForm
disabled={isUpdating}
values={fieldUpdates}
onChange={handleFieldChange}
objectNameSingular={objectNameSingular}
/>
</StyledContentContainer>
<UpdateMultipleRecordsFooter
isUpdating={isUpdating}
progress={progress}
onUpdate={handleUpdate}
onCancel={handleCancel}
isUpdateDisabled={!hasChanges}
/>
</StyledShowPageRightContainer>
</ShowPageContainer>
</RightDrawerProvider>
);
};
@@ -0,0 +1,80 @@
import { computeProgressText } from '@/action-menu/utils/computeProgressText';
import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId';
import { type ObjectRecordQueryProgress } from '@/object-record/types/ObjectRecordQueryProgress';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { Key } from 'ts-key-enum';
import { IconBoxMultiple } from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
const StyledFooterContainer = styled.div`
align-items: flex-end;
background: ${({ theme }) => theme.background.primary};
border-top: 1px solid ${({ theme }) => theme.border.color.light};
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
justify-content: flex-end;
padding: ${({ theme }) => theme.spacing(2)};
`;
const StyledFooterActions = styled.div`
display: flex;
align-items: flex-end;
gap: ${({ theme }) => theme.spacing(2)};
`;
type UpdateMultipleRecordsFooterProps = {
isUpdating: boolean;
progress?: ObjectRecordQueryProgress;
onUpdate: () => void;
onCancel: () => void;
isUpdateDisabled?: boolean;
};
export const UpdateMultipleRecordsFooter = ({
isUpdating,
progress,
onUpdate,
onCancel,
isUpdateDisabled,
}: UpdateMultipleRecordsFooterProps) => {
const { t } = useLingui();
const progressText = computeProgressText(progress);
useHotkeysOnFocusedElement({
keys: [`${Key.Control}+${Key.Enter}`, `${Key.Meta}+${Key.Enter}`],
callback: () => {
if (!isUpdating && !isUpdateDisabled) {
onUpdate();
}
},
focusId: SIDE_PANEL_FOCUS_ID,
dependencies: [onUpdate, isUpdating, isUpdateDisabled],
});
return (
<StyledFooterContainer>
<StyledFooterActions>
<Button
title={t`Cancel`}
variant="secondary"
size="small"
onClick={onCancel}
/>
<Button
title={isUpdating ? t`Apply${progressText}` : t`Apply`}
variant="primary"
accent="blue"
size="small"
Icon={IconBoxMultiple}
isLoading={isUpdating && !progressText}
hotkeys={isUpdating ? undefined : ['⌘', '⏎']}
onClick={onUpdate}
disabled={isUpdating || isUpdateDisabled}
/>
</StyledFooterActions>
</StyledFooterContainer>
);
};
@@ -0,0 +1,83 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsFieldDefinition';
import { FormFieldInput } from '@/object-record/record-field/ui/components/FormFieldInput';
import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/isFieldRelation';
import { type UpdateMultipleRecordsState } from '@/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer';
import { isUpdateRecordValueEmpty } from '@/object-record/record-update-multiple/utils/isUpdateRecordValueEmpty';
import { shouldDisplayFormMultiEditField } from '@/object-record/record-update-multiple/utils/shouldDisplayFormMultiEditField';
import styled from '@emotion/styled';
import { FieldMetadataType } from 'twenty-shared/types';
import { Section } from 'twenty-ui/layout';
const StyledSection = styled(Section)`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(6)};
padding: ${({ theme }) => theme.spacing(4)} ${({ theme }) => theme.spacing(3)};
width: auto;
`;
export type UpdateMultipleRecordsFormProps = {
objectNameSingular: string;
disabled?: boolean;
values: UpdateMultipleRecordsState;
onChange: (fieldName: string, value: any) => void;
};
export const UpdateMultipleRecordsForm = ({
objectNameSingular,
disabled = false,
values,
onChange,
}: UpdateMultipleRecordsFormProps) => {
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular,
});
const editableFields = objectMetadataItem.fields
.filter(shouldDisplayFormMultiEditField)
.sort((fieldA, fieldB) => fieldA.name.localeCompare(fieldB.name));
const fieldsWithDefinitions = editableFields.map((fieldMetadataItem) => ({
fieldMetadataItem,
fieldDefinition: formatFieldMetadataItemAsFieldDefinition({
field: fieldMetadataItem,
objectMetadataItem,
showLabel: true,
labelWidth: 90,
}),
}));
return (
<StyledSection>
{fieldsWithDefinitions.map(({ fieldMetadataItem, fieldDefinition }) => {
const fieldName = fieldDefinition.metadata.fieldName;
const isRelation = isFieldRelation(fieldDefinition);
const fieldNameOrRelationIdName =
isRelation && fieldMetadataItem.type === FieldMetadataType.RELATION
? (fieldMetadataItem.settings?.joinColumnName as string)
: fieldName;
const value = values[fieldNameOrRelationIdName];
const handleValueChange = (newValue: any) => {
if (isUpdateRecordValueEmpty(newValue)) {
onChange(fieldNameOrRelationIdName, undefined);
} else {
onChange(fieldNameOrRelationIdName, newValue);
}
};
return (
<FormFieldInput
key={fieldDefinition.metadata.fieldName}
readonly={disabled}
field={fieldDefinition}
defaultValue={value}
onChange={handleValueChange}
/>
);
})}
</StyledSection>
);
};
@@ -0,0 +1,109 @@
import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
import { ApolloCoreClientContext } from '@/object-metadata/contexts/ApolloCoreClientContext';
import { UpdateMultipleRecordsContainer } from '@/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer';
import { ApolloClient, InMemoryCache } from '@apollo/client';
import { MockLink } from '@apollo/client/testing';
import { type Meta, type StoryObj } from '@storybook/react';
import { expect, userEvent, within } from '@storybook/test';
import gql from 'graphql-tag';
import { ContextStoreDecorator } from '~/testing/decorators/ContextStoreDecorator';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { RootDecorator } from '~/testing/decorators/RootDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
const UPDATE_MANY_COMPANIES_MUTATION = gql`
mutation UpdateManyCompanies(
$filter: CompanyFilterInput!
$data: CompanyUpdateInput!
) {
updateManyCompanies(filter: $filter, data: $data) {
id
}
}
`;
const mocks = [
{
request: {
query: UPDATE_MANY_COMPANIES_MUTATION,
variables: {
filter: { id: { in: ['1'] } }, // Assuming filter setup
data: { name: 'New Name' },
},
},
result: {
data: {
updateManyCompanies: [{ id: '1', __typename: 'Company' }],
},
},
},
];
const mockLink = new MockLink(mocks);
const mockApolloCoreClient = new ApolloClient({
link: mockLink,
cache: new InMemoryCache({ addTypename: false }),
});
const meta: Meta<typeof UpdateMultipleRecordsContainer> = {
title:
'Modules/ObjectRecord/RecordUpdateMultiple/Components/UpdateMultipleRecordsContainer',
component: UpdateMultipleRecordsContainer,
decorators: [
(Story) => (
<ApolloCoreClientContext.Provider value={mockApolloCoreClient}>
<ActionMenuContext.Provider
value={{
actions: [],
actionMenuType: 'index-page-action-menu-dropdown',
displayType: 'dropdownItem',
isInRightDrawer: true,
}}
>
<Story />
</ActionMenuContext.Provider>
</ApolloCoreClientContext.Provider>
),
ContextStoreDecorator,
ObjectMetadataItemsDecorator,
SnackBarDecorator,
I18nFrontDecorator,
RootDecorator,
],
args: {
objectNameSingular: 'company',
contextStoreInstanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
},
parameters: {
contextStore: {
componentInstanceId: MAIN_CONTEXT_STORE_INSTANCE_ID,
},
},
};
export default meta;
type Story = StoryObj<typeof UpdateMultipleRecordsContainer>;
export const Default: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const nameLabel = await canvas.findByText('Name', {}, { timeout: 10000 });
const nameInput = within(nameLabel.parentElement!).getByRole('textbox');
await userEvent.type(nameInput, 'New Name');
const applyButton = await canvas.findByRole('button', { name: /Apply/i });
expect(applyButton).toBeEnabled();
await userEvent.click(applyButton);
const cancelButton = await canvas.findByRole('button', { name: /Cancel/i });
expect(cancelButton).toBeEnabled();
await userEvent.click(cancelButton);
},
};
@@ -0,0 +1,85 @@
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
import { useIncrementalUpdateManyRecords } from '@/object-record/hooks/useIncrementalUpdateManyRecords';
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { renderHook } from '@testing-library/react';
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { useUpdateMultipleRecordsActions } from '@/object-record/record-update-multiple/hooks/useUpdateMultipleRecordsActions';
jest.mock('@/context-store/utils/computeContextStoreFilters');
jest.mock('@/object-record/hooks/useIncrementalUpdateManyRecords');
jest.mock('@/object-record/record-filter/hooks/useFilterValueDependencies');
jest.mock('@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow');
jest.mock('@/ui/utilities/state/component-state/hooks/useRecoilComponentValue');
const mockComputeContextStoreFilters = jest.mocked(computeContextStoreFilters);
const mockUseIncrementalUpdateManyRecords = jest.mocked(
useIncrementalUpdateManyRecords,
);
const mockUseFilterValueDependencies = jest.mocked(useFilterValueDependencies);
const mockUseContextStoreObjectMetadataItemOrThrow = jest.mocked(
useContextStoreObjectMetadataItemOrThrow,
);
const mockUseRecoilComponentValue = jest.mocked(useRecoilComponentValue);
describe('useUpdateMultipleRecordsActions', () => {
const mockIncrementalUpdateManyRecords = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
mockIncrementalUpdateManyRecords.mockResolvedValue(5);
mockUseIncrementalUpdateManyRecords.mockReturnValue({
incrementalUpdateManyRecords: mockIncrementalUpdateManyRecords,
isProcessing: false,
progress: { processedRecordCount: 5 },
cancel: jest.fn(),
} as any);
mockUseContextStoreObjectMetadataItemOrThrow.mockReturnValue({
objectMetadataItem: { id: 'obj-meta-id' },
} as any);
mockUseFilterValueDependencies.mockReturnValue({
filterValueDependencies: {},
} as any);
mockUseRecoilComponentValue.mockReturnValue({});
mockComputeContextStoreFilters.mockReturnValue('mock-filter' as any);
});
it('should call incrementalUpdateManyRecords and return the count', async () => {
const { result } = renderHook(() =>
useUpdateMultipleRecordsActions({
objectNameSingular: 'company',
contextStoreInstanceId: 'test-id',
}),
);
const count = await result.current.updateRecords({ name: 'New Name' });
expect(mockIncrementalUpdateManyRecords).toHaveBeenCalledWith({
name: 'New Name',
});
expect(count).toBe(5);
});
it('should throw error when update fails', async () => {
mockIncrementalUpdateManyRecords.mockRejectedValue(
new Error('Update failed'),
);
const { result } = renderHook(() =>
useUpdateMultipleRecordsActions({
objectNameSingular: 'company',
contextStoreInstanceId: 'test-id',
}),
);
await expect(
result.current.updateRecords({ name: 'New Name' }),
).rejects.toThrow('Update failed');
});
});
@@ -0,0 +1,76 @@
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { contextStoreAnyFieldFilterValueComponentState } from '@/context-store/states/contextStoreAnyFieldFilterValueComponentState';
import { contextStoreFilterGroupsComponentState } from '@/context-store/states/contextStoreFilterGroupsComponentState';
import { contextStoreFiltersComponentState } from '@/context-store/states/contextStoreFiltersComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { computeContextStoreFilters } from '@/context-store/utils/computeContextStoreFilters';
import { useIncrementalUpdateManyRecords } from '@/object-record/hooks/useIncrementalUpdateManyRecords';
import { useFilterValueDependencies } from '@/object-record/record-filter/hooks/useFilterValueDependencies';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
type UseUpdateMultipleRecordsActionsProps = {
objectNameSingular: string;
contextStoreInstanceId: string;
};
export const useUpdateMultipleRecordsActions = ({
objectNameSingular,
contextStoreInstanceId,
}: UseUpdateMultipleRecordsActionsProps) => {
const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow(
contextStoreInstanceId,
);
const contextStoreTargetedRecordsRule = useRecoilComponentValue(
contextStoreTargetedRecordsRuleComponentState,
contextStoreInstanceId,
);
const contextStoreFilters = useRecoilComponentValue(
contextStoreFiltersComponentState,
contextStoreInstanceId,
);
const contextStoreFilterGroups = useRecoilComponentValue(
contextStoreFilterGroupsComponentState,
contextStoreInstanceId,
);
const contextStoreAnyFieldFilterValue = useRecoilComponentValue(
contextStoreAnyFieldFilterValueComponentState,
contextStoreInstanceId,
);
const { filterValueDependencies } = useFilterValueDependencies();
const graphqlFilter = computeContextStoreFilters({
contextStoreTargetedRecordsRule,
contextStoreFilters,
contextStoreFilterGroups,
objectMetadataItem,
filterValueDependencies,
contextStoreAnyFieldFilterValue,
});
const {
incrementalUpdateManyRecords,
isProcessing: isUpdating,
progress,
cancel,
} = useIncrementalUpdateManyRecords({
objectNameSingular,
filter: graphqlFilter,
});
const updateRecords = async (fieldsToUpdate: Record<string, any>) => {
const count = await incrementalUpdateManyRecords(fieldsToUpdate);
return count;
};
return {
updateRecords,
isUpdating,
progress,
cancel,
};
};
@@ -0,0 +1,32 @@
import { isUpdateRecordValueEmpty } from '@/object-record/record-update-multiple/utils/isUpdateRecordValueEmpty';
describe('isUpdateRecordValueEmpty', () => {
it('should return true for null or undefined', () => {
expect(isUpdateRecordValueEmpty(null)).toBe(true);
expect(isUpdateRecordValueEmpty(undefined)).toBe(true);
});
it('should return true for empty string', () => {
expect(isUpdateRecordValueEmpty('')).toBe(true);
});
it('should return true for empty array', () => {
expect(isUpdateRecordValueEmpty([])).toBe(true);
});
it('should return false for non-empty array', () => {
expect(isUpdateRecordValueEmpty([1])).toBe(false);
});
it('should return true for object with all empty values', () => {
expect(isUpdateRecordValueEmpty({ a: null, b: '' })).toBe(true);
});
it('should return false for object with non-empty values', () => {
expect(isUpdateRecordValueEmpty({ a: 1 })).toBe(false);
});
it('should return false for Date object', () => {
expect(isUpdateRecordValueEmpty(new Date())).toBe(false);
});
});
@@ -0,0 +1,46 @@
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { shouldDisplayFormMultiEditField } from '@/object-record/record-update-multiple/utils/shouldDisplayFormMultiEditField';
import { FieldMetadataType } from 'twenty-shared/types';
const createMockFieldMetadataItem = (
overrides: Partial<FieldMetadataItem> = {},
): FieldMetadataItem =>
({
id: 'test-field-id',
name: 'testField',
label: 'Test Field',
type: FieldMetadataType.TEXT,
isActive: true,
isSystem: false,
isUIReadOnly: false,
isUnique: false,
isNullable: true,
...overrides,
}) as FieldMetadataItem;
describe('shouldDisplayFormMultiEditField', () => {
it('should return true for a regular text field', () => {
const field = createMockFieldMetadataItem({
type: FieldMetadataType.TEXT,
});
expect(shouldDisplayFormMultiEditField(field)).toBe(true);
});
it('should return false for unique fields', () => {
const field = createMockFieldMetadataItem({
type: FieldMetadataType.TEXT,
isUnique: true,
});
expect(shouldDisplayFormMultiEditField(field)).toBe(false);
});
it('should return false for inactive fields', () => {
const field = createMockFieldMetadataItem({
isActive: false,
});
expect(shouldDisplayFormMultiEditField(field)).toBe(false);
});
});
@@ -0,0 +1,21 @@
export const isUpdateRecordValueEmpty = (value: any): boolean => {
if (value == null || value === '') {
return true;
}
if (Array.isArray(value)) {
return value.length === 0;
}
if (value instanceof Date) {
return false;
}
if (typeof value === 'object') {
return Object.values(value).every(
(val) => val === null || val === undefined || val === '',
);
}
return false;
};
@@ -0,0 +1,18 @@
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { shouldDisplayFormField } from '@/workflow/workflow-steps/workflow-actions/utils/shouldDisplayFormField';
export const shouldDisplayFormMultiEditField = (
fieldMetadataItem: FieldMetadataItem,
) => {
if (
!shouldDisplayFormField({ fieldMetadataItem, actionType: 'UPDATE_RECORD' })
) {
return false;
}
if (fieldMetadataItem.isUnique === true) {
return false;
}
return true;
};
@@ -0,0 +1,9 @@
import { getUpdateManyRecordsMutationResponseField } from '@/object-record/utils/getUpdateManyRecordsMutationResponseField';
describe('getUpdateManyRecordsMutationResponseField', () => {
it('should work', () => {
expect(getUpdateManyRecordsMutationResponseField('companies')).toBe(
'updateCompanies',
);
});
});
@@ -35,6 +35,7 @@ export {
IconBookmark,
IconBookmarkPlus,
IconBox,
IconBoxMultiple,
IconBrackets,
IconBracketsAngle,
IconBracketsContain,
@@ -153,6 +154,7 @@ export {
IconDoorEnter,
IconDotsVertical,
IconDownload,
IconEdit,
IconEditCircle,
IconExclamationCircle,
IconExternalLink,
+2
View File
@@ -101,6 +101,7 @@ export {
IconBookmark,
IconBookmarkPlus,
IconBox,
IconBoxMultiple,
IconBrackets,
IconBracketsAngle,
IconBracketsContain,
@@ -219,6 +220,7 @@ export {
IconDoorEnter,
IconDotsVertical,
IconDownload,
IconEdit,
IconEditCircle,
IconExclamationCircle,
IconExternalLink,