diff --git a/.github/workflows/run-indinvidual-tests.yml b/.github/workflows/run-indinvidual-tests.yml index 1b5f7fec6f..429064c32b 100644 --- a/.github/workflows/run-indinvidual-tests.yml +++ b/.github/workflows/run-indinvidual-tests.yml @@ -108,7 +108,7 @@ jobs: - name: Get yarn cache directory path id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" + run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - uses: actions/cache@v4 id: yarn-cache diff --git a/frappe/automation/doctype/assignment_rule/assignment_rule.json b/frappe/automation/doctype/assignment_rule/assignment_rule.json index b370274cf6..66f8b8d291 100644 --- a/frappe/automation/doctype/assignment_rule/assignment_rule.json +++ b/frappe/automation/doctype/assignment_rule/assignment_rule.json @@ -67,7 +67,7 @@ "label": "Assignment Rules" }, { - "description": "Simple Python Expression, Example: status == 'Open' and type == 'Bug'", + "description": "Simple Python Expression, Example: status == 'Open' and issue_type == 'Bug'", "fieldname": "assign_condition", "fieldtype": "Code", "in_list_view": 1, @@ -80,7 +80,7 @@ "fieldtype": "Column Break" }, { - "description": "Simple Python Expression, Example: Status in (\"Closed\", \"Cancelled\")", + "description": "Simple Python Expression, Example: status in (\"Closed\", \"Cancelled\")", "fieldname": "unassign_condition", "fieldtype": "Code", "label": "Unassign Condition", @@ -119,7 +119,7 @@ "fieldtype": "Section Break" }, { - "description": "Simple Python Expression, Example: Status in (\"Invalid\")", + "description": "Simple Python Expression, Example: status == \"Invalid\"", "fieldname": "close_condition", "fieldtype": "Code", "label": "Close Condition", @@ -152,9 +152,10 @@ "mandatory_depends_on": "eval: doc.rule == 'Based on Field'" } ], + "grid_page_length": 50, "index_web_pages_for_search": 1, "links": [], - "modified": "2024-03-23 16:01:27.590910", + "modified": "2025-08-25 17:09:11.644603", "modified_by": "Administrator", "module": "Automation", "name": "Assignment Rule", @@ -174,8 +175,9 @@ "write": 1 } ], + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/frappe/core/doctype/doctype/doctype.json b/frappe/core/doctype/doctype/doctype.json index 6a035986b3..95f85fd9e8 100644 --- a/frappe/core/doctype/doctype/doctype.json +++ b/frappe/core/doctype/doctype/doctype.json @@ -702,7 +702,7 @@ "label": "Protect Attached Files" }, { - "default": "0", + "default": "20", "depends_on": "istable", "fieldname": "rows_threshold_for_grid_search", "fieldtype": "Int", @@ -792,7 +792,7 @@ "link_fieldname": "document_type" } ], - "modified": "2025-07-19 12:23:16.296416", + "modified": "2025-09-23 06:48:13.555017", "modified_by": "Administrator", "module": "Core", "name": "DocType", diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index b49ae51036..6fed582df7 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -141,7 +141,6 @@ class File(Document): self.validate_file_url() self.validate_file_on_disk() self.file_size = frappe.form_dict.file_size or self.file_size - self.check_content() def validate_attachment_references(self): if not self.attached_to_doctype: diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index 987ec66dde..13f4ee83f5 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -30,6 +30,7 @@ "apply_strict_user_permissions", "column_break_21", "allow_older_web_view_links", + "show_external_link_warning", "security_tab", "security", "session_expiry", @@ -744,12 +745,19 @@ "fieldtype": "Int", "label": "Max signups allowed per hour", "non_negative": 1 + }, + { + "default": "Never", + "fieldname": "show_external_link_warning", + "fieldtype": "Select", + "label": "Show External Link Warning", + "options": "Never\nAsk\nAlways" } ], "icon": "fa fa-cog", "issingle": 1, "links": [], - "modified": "2025-09-03 10:52:38.096662", + "modified": "2025-09-24 16:04:02.016562", "modified_by": "Administrator", "module": "Core", "name": "System Settings", diff --git a/frappe/core/doctype/system_settings/system_settings.py b/frappe/core/doctype/system_settings/system_settings.py index 5e0e57f096..b78395ce5e 100644 --- a/frappe/core/doctype/system_settings/system_settings.py +++ b/frappe/core/doctype/system_settings/system_settings.py @@ -97,6 +97,7 @@ class SystemSettings(Document): session_expiry: DF.Data | None setup_complete: DF.Check show_absolute_datetime_in_timeline: DF.Check + show_external_link_warning: DF.Literal["Never", "Ask", "Always"] store_attached_pdf_document: DF.Check strip_exif_metadata_from_uploaded_images: DF.Check time_format: DF.Literal["HH:mm:ss", "HH:mm"] diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json index 03ac4d1761..4eb0593966 100644 --- a/frappe/custom/doctype/customize_form/customize_form.json +++ b/frappe/custom/doctype/customize_form/customize_form.json @@ -13,6 +13,7 @@ "label", "search_fields", "grid_page_length", + "rows_threshold_for_grid_search", "link_filters", "column_break_5", "istable", @@ -422,6 +423,13 @@ "fieldname": "recipient_account_field", "fieldtype": "Data", "label": "Recipient Account Field" + }, + { + "depends_on": "istable", + "fieldname": "rows_threshold_for_grid_search", + "fieldtype": "Int", + "label": "Rows Threshold for Grid Search", + "non_negative": 1 } ], "hide_toolbar": 1, @@ -430,7 +438,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2025-07-19 12:23:41.564203", + "modified": "2025-09-23 07:13:52.631903", "modified_by": "Administrator", "module": "Custom", "name": "Customize Form", diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 584882a754..f5061f3f52 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -75,6 +75,7 @@ class CustomizeForm(Document): queue_in_background: DF.Check quick_entry: DF.Check recipient_account_field: DF.Data | None + rows_threshold_for_grid_search: DF.Int search_fields: DF.Data | None sender_field: DF.Data | None sender_name_field: DF.Data | None @@ -748,6 +749,7 @@ doctype_properties = { "force_re_route_to_default_view": "Check", "translated_doctype": "Check", "grid_page_length": "Int", + "rows_threshold_for_grid_search": "Int", } docfield_properties = { diff --git a/frappe/locale/fa.po b/frappe/locale/fa.po index 5adda8ab94..e5a799f43b 100644 --- a/frappe/locale/fa.po +++ b/frappe/locale/fa.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: frappe\n" "Report-Msgid-Bugs-To: developers@frappe.io\n" "POT-Creation-Date: 2025-09-21 09:33+0000\n" -"PO-Revision-Date: 2025-09-22 20:24\n" +"PO-Revision-Date: 2025-09-24 20:35\n" "Last-Translator: developers@frappe.io\n" "Language-Team: Persian\n" "MIME-Version: 1.0\n" @@ -3533,7 +3533,7 @@ msgstr "ساخت" #. Description of a Card Break in the Build Workspace #: frappe/core/workspace/build/build.json msgid "Build your own reports, print formats, and dashboards. Create personalized workspaces for easier navigation" -msgstr "" +msgstr "گزارش‌ها، قالب‌های چاپ و داشبوردهای خودتان را بسازید. برای پیمایش آسان‌تر، فضاهای کاری شخصی‌سازی‌شده ایجاد کنید" #: frappe/workflow/doctype/workflow/workflow_list.js:18 msgid "Build {0}" @@ -4061,7 +4061,7 @@ msgstr "محتویات فایل یک پوشه را نمی‌توان دریاف #: frappe/printing/page/print/print.js:884 msgid "Cannot have multiple printers mapped to a single print format." -msgstr "نمی‌توان چندین چاپگر را به یک قالب چاپی نگاشت کرد." +msgstr "نمی‌توان چندین چاپگر را به یک قالب چاپ واحد نگاشت کرد." #: frappe/public/js/frappe/form/grid.js:1133 msgid "Cannot import table with more than 5000 rows." diff --git a/frappe/locale/nb.po b/frappe/locale/nb.po index eb26d49a46..0f30e40e50 100644 --- a/frappe/locale/nb.po +++ b/frappe/locale/nb.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: frappe\n" "Report-Msgid-Bugs-To: developers@frappe.io\n" "POT-Creation-Date: 2025-09-21 09:33+0000\n" -"PO-Revision-Date: 2025-09-22 20:25\n" +"PO-Revision-Date: 2025-09-24 20:35\n" "Last-Translator: developers@frappe.io\n" "Language-Team: Norwegian Bokmal\n" "MIME-Version: 1.0\n" @@ -4608,7 +4608,7 @@ msgstr "Velg autentiseringsmetode som skal brukes av alle brukere" #: frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py:39 #: frappe/website/doctype/contact_us_settings/contact_us_settings.json msgid "City" -msgstr "By" +msgstr "Poststed" #. Label of the city (Data) field in DocType 'Address' #: frappe/contacts/doctype/address/address.json @@ -8838,7 +8838,7 @@ msgstr "Utsending av e-post er slått av." #. Description of the 'Send Email Alert' (Check) field in DocType 'Workflow' #: frappe/workflow/doctype/workflow/workflow.json msgid "Emails will be sent with next possible workflow actions" -msgstr "E-postmeldinger vil bli sendt med neste mulige handlinger i arbeidsflyten" +msgstr "Det vil bli sendt e-post med informasjon om neste mulige arbeidsflythandlinger" #: frappe/website/doctype/web_form/web_form.js:34 msgid "Embed code copied" @@ -16392,7 +16392,7 @@ msgstr "Navneregel" #. Settings' #: frappe/core/doctype/document_naming_settings/document_naming_settings.json msgid "Naming Series" -msgstr "Navneserie" +msgstr "Nummerserie" #: frappe/model/naming.py:268 msgid "Naming Series mandatory" @@ -24814,7 +24814,7 @@ msgstr "Egenskaper for tilstand" #: frappe/contacts/doctype/address/address.json #: frappe/website/doctype/contact_us_settings/contact_us_settings.json msgid "State/Province" -msgstr "Stat/provins" +msgstr "Delstat/provins" #. Label of the document_states_section (Tab Break) field in DocType 'DocType' #. Label of the states (Table) field in DocType 'Customize Form' @@ -29094,12 +29094,12 @@ msgstr "Meta-tagg for nettstedet" #: frappe/website/doctype/website_route_meta/website_route_meta.json #: frappe/website/workspace/website/website.json msgid "Website Route Meta" -msgstr "" +msgstr "Sti-metadata for nettsted" #. Name of a DocType #: frappe/website/doctype/website_route_redirect/website_route_redirect.json msgid "Website Route Redirect" -msgstr "" +msgstr "Sti-viderekobling for nettsted" #. Name of a DocType #. Label of a Link in the Website Workspace @@ -29133,24 +29133,24 @@ msgstr "Innstillinger for nettsted" #: frappe/website/doctype/website_sidebar/website_sidebar.json #: frappe/website/workspace/website/website.json msgid "Website Sidebar" -msgstr "" +msgstr "Nettstedets sidefelt" #. Name of a DocType #: frappe/website/doctype/website_sidebar_item/website_sidebar_item.json msgid "Website Sidebar Item" -msgstr "" +msgstr "Element i nettstedets sidefelt" #. Name of a DocType #. Label of a Link in the Website Workspace #: frappe/website/doctype/website_slideshow/website_slideshow.json #: frappe/website/workspace/website/website.json msgid "Website Slideshow" -msgstr "" +msgstr "Lysbildefremvisning på nettstedet" #. Name of a DocType #: frappe/website/doctype/website_slideshow_item/website_slideshow_item.json msgid "Website Slideshow Item" -msgstr "" +msgstr "Element i lysbildefremvisning på nettstedet" #. Label of the website_theme (Link) field in DocType 'Website Settings' #. Name of a DocType @@ -29164,18 +29164,18 @@ msgstr "Nettstedstema" #. Name of a DocType #: frappe/website/doctype/website_theme_ignore_app/website_theme_ignore_app.json msgid "Website Theme Ignore App" -msgstr "" +msgstr "Ignorer app for nettstedstema" #. Label of the website_theme_image (Image) field in DocType 'Website Settings' #: frappe/website/doctype/website_settings/website_settings.json msgid "Website Theme Image" -msgstr "" +msgstr "Bilde­ for nettstedstema" #. Label of the website_theme_image_link (Code) field in DocType 'Website #. Settings' #: frappe/website/doctype/website_settings/website_settings.json msgid "Website Theme image link" -msgstr "" +msgstr "Bilde­lenke for nettstedstema" #. Option for the 'SocketIO Transport Mode' (Select) field in DocType 'System #. Health Report' @@ -29201,7 +29201,7 @@ msgstr "Onsdag" #: frappe/public/js/frappe/views/calendar/calendar.js:276 msgid "Week" -msgstr "" +msgstr "Uke" #. Option for the 'Frequency' (Select) field in DocType 'Auto Email Report' #: frappe/email/doctype/auto_email_report/auto_email_report.json @@ -29239,7 +29239,7 @@ msgstr "Ukeslang" #: frappe/desk/page/setup_wizard/setup_wizard.js:384 msgid "Welcome" -msgstr "" +msgstr "Velkommen" #. Label of the welcome_email_template (Link) field in DocType 'System #. Settings' @@ -29247,12 +29247,12 @@ msgstr "" #: frappe/core/doctype/system_settings/system_settings.json #: frappe/email/doctype/email_group/email_group.json msgid "Welcome Email Template" -msgstr "" +msgstr "Mal for velkomst-e-post" #. Label of the welcome_url (Data) field in DocType 'Email Group' #: frappe/email/doctype/email_group/email_group.json msgid "Welcome URL" -msgstr "" +msgstr "Velkomst-URL" #. Name of a Workspace #: frappe/core/workspace/welcome_workspace/welcome_workspace.json @@ -29261,11 +29261,11 @@ msgstr "Velkomst og introduksjon" #: frappe/core/doctype/user/user.py:416 msgid "Welcome email sent" -msgstr "" +msgstr "Velkomst-e-post sendt" #: frappe/core/doctype/user/user.py:477 msgid "Welcome to {0}" -msgstr "" +msgstr "Velkommen til {0}" #: frappe/public/js/frappe/ui/notifications/notifications.js:62 msgid "What's New" @@ -29332,7 +29332,7 @@ msgstr "Vil legge til «%» før og etter spørringen" #: frappe/desk/page/setup_wizard/setup_wizard.js:485 msgid "Will be your login ID" -msgstr "" +msgstr "Vil være din innloggings-ID" #: frappe/printing/page/print_format_builder/print_format_builder.js:424 msgid "Will only be shown if section headings are enabled" @@ -29342,7 +29342,7 @@ msgstr "Vil bare vises hvis seksjonsoverskrifter er aktivert" #. in DocType 'System Settings' #: frappe/core/doctype/system_settings/system_settings.json msgid "Will run scheduled jobs only once a day for inactive sites. Set it to 0 to avoid automatically disabling the scheduler." -msgstr "" +msgstr "Kjører planlagte jobber bare én gang om dagen for inaktive nettsteder. Sett den til 0 for å unngå automatisk deaktivering av planleggeren." #: frappe/public/js/frappe/form/print_utils.js:45 msgid "With Letter head" @@ -29357,7 +29357,7 @@ msgstr "Info om bakgrunnsprosesser" #. Label of the worker_name (Data) field in DocType 'RQ Worker' #: frappe/core/doctype/rq_worker/rq_worker.json msgid "Worker Name" -msgstr "" +msgstr "Prosessnavn" #. Option for the 'Comment Type' (Select) field in DocType 'Comment' #. Group in DocType's connections @@ -29373,30 +29373,30 @@ msgstr "Arbeidsflyt" #: frappe/workflow/doctype/workflow_action/workflow_action.json #: frappe/workflow/doctype/workflow_action/workflow_action.py:444 msgid "Workflow Action" -msgstr "" +msgstr "Arbeidsflythandling" #. Name of a DocType #. Description of a DocType #: frappe/workflow/doctype/workflow_action_master/workflow_action_master.json msgid "Workflow Action Master" -msgstr "" +msgstr "Mal for arbeidsflythandling" #. Label of the workflow_action_name (Data) field in DocType 'Workflow Action #. Master' #: frappe/workflow/doctype/workflow_action_master/workflow_action_master.json msgid "Workflow Action Name" -msgstr "" +msgstr "Navn på arbeidsflythandling" #. Name of a DocType #: frappe/workflow/doctype/workflow_action_permitted_role/workflow_action_permitted_role.json msgid "Workflow Action Permitted Role" -msgstr "" +msgstr "Tillatt rolle for arbeidsflythandling" #. Description of the 'Is Optional State' (Check) field in DocType 'Workflow #. Document State' #: frappe/workflow/doctype/workflow_document_state/workflow_document_state.json msgid "Workflow Action is not created for optional states" -msgstr "Arbeidsflythandlingen er ikke opprettet for valgfrie tilstander" +msgstr "Det opprettes ikke arbeidsflythandling for valgfrie tilstander" #: frappe/public/js/workflow_builder/store.js:129 #: frappe/workflow/doctype/workflow/workflow.js:25 @@ -29420,7 +29420,7 @@ msgstr "Med Arbeidsflytbygger kan du lage arbeidsflyter visuelt. Du kan dra og s #. Label of the workflow_data (JSON) field in DocType 'Workflow' #: frappe/workflow/doctype/workflow/workflow.json msgid "Workflow Data" -msgstr "" +msgstr "Arbeidsflytdata" #: frappe/public/js/workflow_builder/components/Properties.vue:44 msgid "Workflow Details" @@ -29429,40 +29429,40 @@ msgstr "Arbeidsflytdetaljer" #. Name of a DocType #: frappe/workflow/doctype/workflow_document_state/workflow_document_state.json msgid "Workflow Document State" -msgstr "" +msgstr "Tilstand for arbeidsflytdokument" #. Label of the workflow_name (Data) field in DocType 'Workflow' #: frappe/workflow/doctype/workflow/workflow.json msgid "Workflow Name" -msgstr "" +msgstr "Navn på arbeidsflyt" #. Label of the workflow_state (Data) field in DocType 'Workflow Action' #. Name of a DocType #: frappe/workflow/doctype/workflow_action/workflow_action.json #: frappe/workflow/doctype/workflow_state/workflow_state.json msgid "Workflow State" -msgstr "" +msgstr "Arbeidsflyttilstand" #. Label of the workflow_state_field (Data) field in DocType 'Workflow' #: frappe/workflow/doctype/workflow/workflow.json msgid "Workflow State Field" -msgstr "" +msgstr "Felt for arbeidsflyttilstand" #: frappe/model/workflow.py:64 msgid "Workflow State not set" -msgstr "" +msgstr "Arbeidsflyttilstand ikke angitt" #: frappe/model/workflow.py:260 frappe/model/workflow.py:268 msgid "Workflow State transition not allowed from {0} to {1}" -msgstr "" +msgstr "Overgang mellom arbeidsflyttilstander er ikke tillatt fra {0} til {1}" #: frappe/workflow/doctype/workflow/workflow.js:140 msgid "Workflow States Don't Exist" -msgstr "" +msgstr "Arbeidsflyttilstander finnes ikke" #: frappe/model/workflow.py:384 msgid "Workflow Status" -msgstr "" +msgstr "Arbeidsflyttilstand" #. Option for the 'Script Type' (Select) field in DocType 'Server Script' #: frappe/core/doctype/server_script/server_script.json @@ -29472,26 +29472,26 @@ msgstr "Oppgaver i arbeidsflyt" #. Name of a DocType #: frappe/workflow/doctype/workflow_transition/workflow_transition.json msgid "Workflow Transition" -msgstr "" +msgstr "Arbeidsflytovergang" #. Name of a DocType #: frappe/workflow/doctype/workflow_transition_task/workflow_transition_task.json msgid "Workflow Transition Task" -msgstr "" +msgstr "Oppgave ved arbeidsflytovergang" #. Name of a DocType #: frappe/workflow/doctype/workflow_transition_tasks/workflow_transition_tasks.json msgid "Workflow Transition Tasks" -msgstr "" +msgstr "Oppgaver ved arbeidsflytovergang" #. Description of a DocType #: frappe/workflow/doctype/workflow_state/workflow_state.json msgid "Workflow state represents the current state of a document." -msgstr "" +msgstr "Arbeidsflyttilstand representerer den nåværende tilstanden til et dokument." #: frappe/public/js/workflow_builder/store.js:83 msgid "Workflow updated successfully" -msgstr "Arbeidsflyten ble vellykket oppdatert" +msgstr "Arbeidsflyten ble oppdatert" #. Label of the workspace_section (Section Break) field in DocType 'User' #. Label of a Link in the Build Workspace @@ -29577,15 +29577,15 @@ msgstr "Arbeidsområder" #: frappe/public/js/frappe/form/footer/form_timeline.js:757 msgid "Would you like to publish this comment? This means it will become visible to website/portal users." -msgstr "" +msgstr "Ønsker du å publisere denne kommentaren? Dette betyr at den blir synlig for brukere av nettstedet/portalen." #: frappe/public/js/frappe/form/footer/form_timeline.js:761 msgid "Would you like to unpublish this comment? This means it will no longer be visible to website/portal users." -msgstr "" +msgstr "Ønsker du å avpublisere denne kommentaren? Dette betyr at den ikke lenger vil være synlig for brukere av nettstedet/portalen." #: frappe/desk/page/setup_wizard/setup_wizard.py:41 msgid "Wrapping up" -msgstr "" +msgstr "Oppsummerer" #. Label of the write (Check) field in DocType 'Custom DocPerm' #. Label of the write (Check) field in DocType 'DocPerm' @@ -29604,7 +29604,7 @@ msgstr "" #: frappe/public/js/frappe/views/reports/report_view.js:495 msgid "X Axis Field" -msgstr "" +msgstr "Felt i X-akse" #. Label of the x_field (Select) field in DocType 'Dashboard Chart' #: frappe/desk/doctype/dashboard_chart/dashboard_chart.json @@ -29623,7 +29623,7 @@ msgstr "Y-akse" #: frappe/public/js/frappe/views/reports/report_view.js:502 msgid "Y Axis Fields" -msgstr "" +msgstr "Felt for Y-akse" #. Label of the y_field (Select) field in DocType 'Dashboard Chart Field' #: frappe/desk/doctype/dashboard_chart_field/dashboard_chart_field.json @@ -29711,27 +29711,27 @@ msgstr "I går" #: frappe/public/js/frappe/utils/user.js:33 msgctxt "Name of the current user. For example: You edited this 5 hours ago." msgid "You" -msgstr "" +msgstr "Du" #: frappe/public/js/frappe/form/footer/form_timeline.js:463 msgid "You Liked" -msgstr "" +msgstr "Du likte" #: frappe/public/js/frappe/form/footer/version_timeline_content_builder.js:266 msgid "You added 1 row to {0}" -msgstr "" +msgstr "Du la til 1 rad til {0}" #: frappe/public/js/frappe/form/footer/version_timeline_content_builder.js:244 msgid "You added {0} rows to {1}" -msgstr "" +msgstr "Du la til {0} rader til {1}" #: frappe/public/js/frappe/dom.js:438 msgid "You are connected to internet." -msgstr "" +msgstr "Du er koblet til Internett." #: frappe/public/js/frappe/ui/toolbar/navbar.html:20 msgid "You are impersonating as another user." -msgstr "" +msgstr "Du utgir deg for å være en annen bruker." #: frappe/integrations/frappe_providers/frappecloud_billing.py:28 msgid "You are not allowed to access this resource" @@ -29739,27 +29739,27 @@ msgstr "Du har ikke tilgang til denne ressursen" #: frappe/permissions.py:431 msgid "You are not allowed to access this {0} record because it is linked to {1} '{2}' in field {3}" -msgstr "" +msgstr "Du har ikke tilgang til denne {0} oppføringen fordi den er lenket til {1} '{2}' i felt {3}" #: frappe/permissions.py:420 msgid "You are not allowed to access this {0} record because it is linked to {1} '{2}' in row {3}, field {4}" -msgstr "" +msgstr "Du har ikke tilgang til denne {0} -posten fordi den er knyttet til {1} '{2}' i rad {3}, felt {4}" #: frappe/public/js/frappe/views/kanban/kanban_board.bundle.js:68 msgid "You are not allowed to create columns" -msgstr "" +msgstr "Du har ikke rettigheter til å opprette kolonner" #: frappe/core/doctype/report/report.py:97 msgid "You are not allowed to delete Standard Report" -msgstr "" +msgstr "Du har ikke rettigheter til å slette standardrapporten" #: frappe/website/doctype/website_theme/website_theme.py:73 msgid "You are not allowed to delete a standard Website Theme" -msgstr "" +msgstr "Du har ikke rettigheter til å slette et standard nettstedstema" #: frappe/core/doctype/report/report.py:391 msgid "You are not allowed to edit the report." -msgstr "" +msgstr "Du har ikke rettigheter til å redigere rapporten." #: frappe/core/doctype/data_import/exporter.py:121 #: frappe/core/doctype/data_import/exporter.py:125 @@ -29770,39 +29770,39 @@ msgstr "Du har ikke rettigheter til å eksportere {} dokumenttype (DocType)" #: frappe/public/js/frappe/views/treeview.js:448 msgid "You are not allowed to print this report" -msgstr "Du har ikke tillatelse til å skrive ut denne rapporten" +msgstr "Du har ikke rettigheter til å skrive ut denne rapporten" #: frappe/public/js/frappe/views/communication.js:787 msgid "You are not allowed to send emails related to this document" -msgstr "" +msgstr "Du har ikke rettigheter til å sende e-poster om dette dokumentet" #: frappe/website/doctype/web_form/web_form.py:605 msgid "You are not allowed to update this Web Form Document" -msgstr "" +msgstr "Du har ikke rettigheter til å oppdatere dette nettskjemadokumentet" #: frappe/public/js/frappe/request.js:37 msgid "You are not connected to Internet. Retry after sometime." -msgstr "" +msgstr "Du er ikke koblet til Internett. Prøv på nytt etter en stund." #: frappe/public/js/frappe/web_form/webform_script.js:22 msgid "You are not permitted to access this page without login." -msgstr "" +msgstr "Du har ikke tilgang til denne siden uten å være logget inn." #: frappe/www/app.py:27 msgid "You are not permitted to access this page." -msgstr "" +msgstr "Ditt rettighetsnivå hindrer visning av denne siden." #: frappe/__init__.py:465 msgid "You are not permitted to access this resource. Login to access" -msgstr "" +msgstr "Du må være innlogget for å få tilgang til denne ressursen." #: frappe/public/js/frappe/form/sidebar/document_follow.js:131 msgid "You are now following this document. You will receive daily updates via email. You can change this in User Settings." -msgstr "" +msgstr "Du følger nå dette dokumentet. Du vil motta daglige oppdateringer via e-post. Du kan endre dette i brukerinnstillingene." #: frappe/core/doctype/installed_applications/installed_applications.py:117 msgid "You are only allowed to update order, do not remove or add apps." -msgstr "" +msgstr "Du kan bare endre rekkefølgen på appene, ikke legge til eller fjerne dem." #: frappe/email/doctype/email_account/email_account.js:284 msgid "You are selecting Sync Option as ALL, It will resync all read as well as unread message from server. This may also cause the duplication of Communication (emails)." @@ -29811,7 +29811,7 @@ msgstr "Du velger Synkroniseringsalternativet ALLE. Dette vil synkronisere alle #: frappe/public/js/frappe/form/footer/form_timeline.js:414 msgctxt "Form timeline" msgid "You attached {0}" -msgstr "" +msgstr "Du la ved {0}" #: frappe/printing/page/print_format_builder/print_format_builder.js:749 msgid "You can add dynamic properties from the document by using Jinja templating." @@ -29831,11 +29831,11 @@ msgstr "Du kan også kopiere og lime inn dette" #: frappe/templates/emails/delete_data_confirmation.html:11 msgid "You can also copy-paste this {0} to your browser" -msgstr "" +msgstr "Du kan også kopiere og lime inn denne {0} i nettleseren din" #: frappe/templates/emails/user_invitation_expired.html:8 msgid "You can ask your team to resend the invitation if you'd still like to join." -msgstr "" +msgstr "Du kan be teamet ditt om å sende invitasjonen på nytt hvis du fortsatt ønsker å bli med." #: frappe/core/page/permission_manager/permission_manager_help.html:17 msgid "You can change Submitted documents by cancelling them and then, amending them." @@ -29851,19 +29851,19 @@ msgstr "Du kan fortsette med onboarding-prosessen etter å ha utforsket denne si #: frappe/model/delete_doc.py:137 msgid "You can disable this {0} instead of deleting it." -msgstr "" +msgstr "Du kan deaktivere denne {0} i stedet for å slette den." #: frappe/core/doctype/file/file.py:758 msgid "You can increase the limit from System Settings." -msgstr "" +msgstr "Du kan øke grensen fra systeminnstillingene." #: frappe/utils/synchronization.py:48 msgid "You can manually remove the lock if you think it's safe: {}" -msgstr "" +msgstr "Du kan manuelt fjerne låsen hvis du tror det er trygt: {}" #: frappe/public/js/frappe/form/controls/markdown_editor.js:75 msgid "You can only insert images in Markdown fields" -msgstr "" +msgstr "Du kan bare sette inn bilder i felter som støtter Markdown" #: frappe/public/js/frappe/list/bulk_operations.js:42 msgid "You can only print upto {0} documents at a time" @@ -29889,7 +29889,7 @@ msgstr "Du kan velge ett av følgende," #. 'System Settings' #: frappe/core/doctype/system_settings/system_settings.json msgid "You can set a high value here if multiple users will be logging in from the same network." -msgstr "" +msgstr "Du kan angi en høy verdi her hvis flere brukere skal logge seg på fra samme nettverk." #: frappe/desk/query_report.py:382 msgid "You can try changing the filters of your report." @@ -30858,7 +30858,7 @@ msgstr "" #: frappe/public/js/frappe/widgets/number_card_widget.js:309 msgid "since last week" -msgstr "" +msgstr "siden forrige uke" #: frappe/public/js/frappe/widgets/number_card_widget.js:311 msgid "since last year" @@ -31410,7 +31410,7 @@ msgstr "" #: frappe/model/workflow.py:245 msgid "{0} is not a valid Workflow State. Please update your Workflow and try again." -msgstr "" +msgstr "{0} er ikke en gyldig arbeidsflyttilstand. Oppdater arbeidsflyten din og prøv på nytt." #: frappe/permissions.py:809 msgid "{0} is not a valid parent DocType for {1}" @@ -31704,7 +31704,7 @@ msgstr "" #: frappe/public/js/frappe/utils/pretty_date.js:64 msgid "{0} weeks ago" -msgstr "" +msgstr "{0} uker siden" #: frappe/public/js/frappe/utils/pretty_date.js:39 msgid "{0} y" diff --git a/frappe/locale/sr.po b/frappe/locale/sr.po index bbbb059968..53ee9fb11a 100644 --- a/frappe/locale/sr.po +++ b/frappe/locale/sr.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: frappe\n" "Report-Msgid-Bugs-To: developers@frappe.io\n" "POT-Creation-Date: 2025-09-21 09:33+0000\n" -"PO-Revision-Date: 2025-09-21 19:57\n" +"PO-Revision-Date: 2025-09-24 20:35\n" "Last-Translator: developers@frappe.io\n" "Language-Team: Serbian (Cyrillic)\n" "MIME-Version: 1.0\n" @@ -19602,7 +19602,7 @@ msgstr "Прецизност" #: frappe/core/doctype/doctype/doctype.py:1670 msgid "Precision ({0}) for {1} cannot be greater than its length ({2})." -msgstr "" +msgstr "Прецизност ({0}) за {1} не може бити већа од његове дужине ({2})." #: frappe/core/doctype/doctype/doctype.py:1401 msgid "Precision should be between 1 and 6" @@ -23652,7 +23652,7 @@ msgstr "Поставите нестандардну прецизност за п #. Description of the 'Precision' (Select) field in DocType 'DocField' #: frappe/core/doctype/docfield/docfield.json msgid "Set non-standard precision for a Float, Currency or Percent field" -msgstr "" +msgstr "Подесите нестандардну прецизност за поља врсте децимални број, валута или проценат" #. Label of the set_only_once (Check) field in DocType 'DocField' #: frappe/core/doctype/docfield/docfield.json @@ -26110,7 +26110,7 @@ msgstr "Број пројекта добијен путем Google Cloud кон #: frappe/desk/utils.py:106 msgid "The report you requested has been generated.

Click here to download:
{0}

This link will expire in {1} hours." -msgstr "" +msgstr "Извештај који сте затражили је генерисан.

Кликните овде за преузимање:
{0}

Овај линк истиче за {1} сата." #: frappe/core/doctype/user/user.py:1000 msgid "The reset password link has been expired" @@ -26335,7 +26335,7 @@ msgstr "Ово се не може опозвати" #: frappe/desk/doctype/number_card/number_card.js:480 msgctxt "Number Card" msgid "This card is visible only to Administrator and System Managers by default. Set a DocType to share with users who have read access." -msgstr "" +msgstr "Ова картица је подразумевано видљива само администратору и систем менаџерима. Подесите DocType да је делите са корисницима који имају право читања." #. Description of the 'Is Public' (Check) field in DocType 'Number Card' #: frappe/desk/doctype/number_card/number_card.json @@ -30284,7 +30284,7 @@ msgstr "Ваш упит је примљен. Одговорићемо Вам у #: frappe/desk/query_report.py:342 frappe/desk/reportview.py:396 msgid "Your report is being generated in the background. You will receive an email on {0} with a download link once it is ready." -msgstr "" +msgstr "Ваш извештај се генерише у позадини. Добићете имејл на {0} са линком за преузимање када буде спреман." #: frappe/app.py:374 msgid "Your session has expired, please login again to continue." diff --git a/frappe/locale/sr_CS.po b/frappe/locale/sr_CS.po index 4d57d2a98c..ebdcb82ce4 100644 --- a/frappe/locale/sr_CS.po +++ b/frappe/locale/sr_CS.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: frappe\n" "Report-Msgid-Bugs-To: developers@frappe.io\n" "POT-Creation-Date: 2025-09-21 09:33+0000\n" -"PO-Revision-Date: 2025-09-21 19:58\n" +"PO-Revision-Date: 2025-09-24 20:35\n" "Last-Translator: developers@frappe.io\n" "Language-Team: Serbian (Latin)\n" "MIME-Version: 1.0\n" @@ -19603,7 +19603,7 @@ msgstr "Preciznost" #: frappe/core/doctype/doctype/doctype.py:1670 msgid "Precision ({0}) for {1} cannot be greater than its length ({2})." -msgstr "" +msgstr "Preciznost ({0}) za {1} ne može biti veća od njegove dužine ({2})." #: frappe/core/doctype/doctype/doctype.py:1401 msgid "Precision should be between 1 and 6" @@ -23653,7 +23653,7 @@ msgstr "Postavite nestandardnu preciznost za polje sa decimalnim brojem ili valu #. Description of the 'Precision' (Select) field in DocType 'DocField' #: frappe/core/doctype/docfield/docfield.json msgid "Set non-standard precision for a Float, Currency or Percent field" -msgstr "" +msgstr "Podesite nestandardnu preciznost za polja vrste decimalni broj, valuta ili procenat" #. Label of the set_only_once (Check) field in DocType 'DocField' #: frappe/core/doctype/docfield/docfield.json @@ -26111,7 +26111,7 @@ msgstr "Broj projekta dobijen putem Google Cloud konzole, u odeljku
Click here to download:
{0}

This link will expire in {1} hours." -msgstr "" +msgstr "Izveštaj koji ste zatražili je generisan.

Kliknite ovde za preuzimanje:
{0}

Ovaj link ističe za {1} sata." #: frappe/core/doctype/user/user.py:1000 msgid "The reset password link has been expired" @@ -26336,7 +26336,7 @@ msgstr "Ovo se ne može opozvati" #: frappe/desk/doctype/number_card/number_card.js:480 msgctxt "Number Card" msgid "This card is visible only to Administrator and System Managers by default. Set a DocType to share with users who have read access." -msgstr "" +msgstr "Ova kartica je podrazumevano vidljiva samo administratoru i sistem menadžerima. Podesite DocType da je delite sa korisnicima koji imaju pravo čitanja." #. Description of the 'Is Public' (Check) field in DocType 'Number Card' #: frappe/desk/doctype/number_card/number_card.json @@ -30284,7 +30284,7 @@ msgstr "Vaš upit je primljen. Odgovorićemo Vam uskoro, ukoliko imate dodatne i #: frappe/desk/query_report.py:342 frappe/desk/reportview.py:396 msgid "Your report is being generated in the background. You will receive an email on {0} with a download link once it is ready." -msgstr "" +msgstr "Vaš izveštaj se generiše u pozadini. Dobićete imejl na {0} sa linkom za preuzimanje kada bude spreman." #: frappe/app.py:374 msgid "Your session has expired, please login again to continue." diff --git a/frappe/public/js/frappe/form/grid_row.js b/frappe/public/js/frappe/form/grid_row.js index 10b18171e7..5934c3be0e 100644 --- a/frappe/public/js/frappe/form/grid_row.js +++ b/frappe/public/js/frappe/form/grid_row.js @@ -8,11 +8,12 @@ export default class GridRow { this.set_docfields(); this.columns = {}; this.columns_list = []; - this.depandant_fields = { + this.dependent_fields = { mandatory: [], read_only: [], }; this.row_check_html = ''; + this.default_rows_threshold_for_grid_search = 20; this.make(); } make() { @@ -160,7 +161,7 @@ export default class GridRow { this.grid.add_new_row(idx, null, show, copy_doc); } move() { - // promopt the user where they want to move this row + // prompt the user where they want to move this row var me = this; frappe.prompt( { @@ -802,7 +803,7 @@ export default class GridRow { this.evaluate_depends_on_value(df.mandatory_depends_on) ) { df.reqd = 1; - this.depandant_fields["mandatory"].push(df); + this.dependent_fields["mandatory"].push(df); } if ( @@ -811,16 +812,16 @@ export default class GridRow { this.evaluate_depends_on_value(df.read_only_depends_on) ) { df.read_only = 1; - this.depandant_fields["read_only"].push(df); + this.dependent_fields["read_only"].push(df); } } - refresh_depedency() { - this.depandant_fields["read_only"].forEach((df) => { + refresh_dependency() { + this.dependent_fields["read_only"].forEach((df) => { df.read_only = 0; this.set_dependant_property(df); }); - this.depandant_fields["mandatory"].forEach((df) => { + this.dependent_fields["mandatory"].forEach((df) => { df.reqd = 0; this.set_dependant_property(df); }); @@ -871,7 +872,7 @@ export default class GridRow { let show_length = this.grid?.meta?.rows_threshold_for_grid_search > 0 ? this.grid.meta.rows_threshold_for_grid_search - : 20; + : this.default_rows_threshold_for_grid_search; this.show_search = this.show_search && (this.grid?.data?.length >= show_length || this.grid.filter_applied); @@ -1016,7 +1017,7 @@ export default class GridRow { } } - // Delay date_picker widget to prevent temparary layout shift (UX). + // Delay date_picker widget to prevent temporary layout shift (UX). function handle_date_picker() { let date_time_picker = document.querySelectorAll(".datepicker.active")[0]; @@ -1184,7 +1185,7 @@ export default class GridRow { // df.onchange is common for all rows in grid let field_on_change_function = df.onchange; field.df.change = (e) => { - this.refresh_depedency(); + this.refresh_dependency(); // trigger onchange with current grid row field as "this" field_on_change_function && field_on_change_function.apply(field, [e]); me.refresh_field(field.df.fieldname); diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index 8c6effa2fc..01d983d493 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -28,6 +28,11 @@ $("body").on("click", "a", function (e) { const href = target_element.getAttribute("href"); const is_on_same_host = target_element.hostname === window.location.hostname; + if (frappe.router.show_external_link_warning_if_needed(target_element)) { + e.preventDefault(); + return; // warning shown + } + if (target_element.getAttribute("target") === "_blank") { return; } @@ -570,6 +575,105 @@ frappe.router = { slug(name) { return name.toLowerCase().replace(/ /g, "-"); }, + + show_external_link_warning_if_needed(/** @type {HTMLAnchorElement} */ aElement) { + try { + if (!aElement?.href) { + return false; // not a true link + } + + // Get the external link handling type + /** @type {'Always' | 'Ask' | 'Never' | null} */ + const showWarningWhen = frappe.boot.show_external_link_warning || "Never"; + if (showWarningWhen == "Never") { + return false; // the feature is disabled + } + + // Check that the origin is external (does not prevent self-clickjacking on GET endpoints) + const url = new URL(aElement.href); + const hostname = url.hostname; + if (hostname === window.location.hostname) { + return false; // self-linking is allowed + } + + // Check if the origin was ignored by the user + const localStorageKey = `skip-external-link-warning:${hostname}`; + if (showWarningWhen == "Ask" && localStorage.getItem(localStorageKey)) { + return false; // user chose to skip warning forever + } + + // Check if the link if inside the confirmation popup + const incominSkipToken = aElement.getAttribute("data-skip-link-warning"); + if (incominSkipToken && sessionStorage.getItem(incominSkipToken) == "1") { + return false; // anchor is the confirmation itself + } + + // Finally, show the warning + const dialog = new frappe.ui.Dialog({ + title: __("Warning"), + primary_action: null, + fields: [ + { + fieldname: "warning_html", + fieldtype: "HTML", + }, + { + fieldname: "confirm_checkbox", + fieldtype: "Check", + label: __("Do not warn me again about {0}", [ + frappe.utils.escape_html(hostname).bold(), + ]), + default: 0, + hidden: showWarningWhen == "Always", + change() { + if (dialog.get_value("confirm_checkbox")) { + localStorage.setItem(localStorageKey, "1"); + } else { + localStorage.removeItem(localStorageKey); + } + }, + }, + ], + }); + + const warningElement = dialog.fields_dict.warning_html.$wrapper.get(0); + + const introElement = document.createElement("p"); + introElement.textContent = __( + "You are about to open an external link. To confirm, click the link again." + ); + warningElement.appendChild(introElement); + + const boxElement = document.createElement("div"); + boxElement.classList.add("border", "rounded-lg", "p-3", "mt-6", "mb-6", "text-center"); + warningElement.appendChild(boxElement); + + const hintElement = document.createElement("p"); + hintElement.classList.add("text-sm", "mb-1"); + hintElement.textContent = __("You will be redirected to:"); + boxElement.appendChild(hintElement); + + const confirmElement = document.createElement("a"); + confirmElement.classList.add("text-sm", "font-mono"); + confirmElement.style.wordBreak = "break-all"; + confirmElement.textContent = aElement.href; + confirmElement.href = aElement.href; + confirmElement.target = aElement.target; + confirmElement.addEventListener("click", () => dialog.hide(), { capture: true }); + + // Add a token to skip the warning when clicking inside the confirmation dialog + const skipToken = frappe.utils.get_random(16); + confirmElement.setAttribute("data-skip-link-warning", skipToken); + sessionStorage.setItem(skipToken, "1"); + boxElement.appendChild(confirmElement); + + dialog.show(); + return true; // prevent default handling + } catch (e) { + console.error(e); + } + return false; + }, }; // global functions for backward compatibility diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index 6692135bb6..266d5e8a6b 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -720,9 +720,13 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { } return new Promise((resolve) => { + const js_filters = (frappe.query_reports[this.report_name]?.filters || []).filter( + (filter) => filter.fieldtype === "Link" && filters[filter.fieldname] !== "" + ); + this.last_ajax = frappe.call({ method: "frappe.desk.query_report.run", - type: "GET", + type: "POST", args: { report_name: this.report_name, filters: filters, @@ -730,7 +734,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { is_tree: this.report_settings.tree, parent_field: this.report_settings.parent_field, are_default_filters: are_default_filters, - js_filters: frappe.query_reports[this.report_name]?.filters, + js_filters: js_filters, }, callback: resolve, always: () => this.page.btn_secondary.prop("disabled", false), diff --git a/frappe/sessions.py b/frappe/sessions.py index 5e9fdb43b9..701e140ae5 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -181,6 +181,7 @@ def get(): bootinfo["user"]["impersonated_by"] = frappe.session.data.get("impersonated_by") bootinfo["navbar_settings"] = frappe.client_cache.get_doc("Navbar Settings") bootinfo.has_app_updates = has_app_update_notifications() + bootinfo.show_external_link_warning = frappe.get_system_settings("show_external_link_warning") return bootinfo