From efad149afcb1cf13dec22b33e82367df81f78242 Mon Sep 17 00:00:00 2001 From: "Siddharth Gelera (reaper)" Date: Fri, 14 Nov 2025 16:57:29 +0530 Subject: [PATCH] HTTP stream enhancements (#6077) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add stop request button in api url bar * docs: add farsi translation * fix: handle escaped forward slashes by fast-json-format library upgrade * refactor: change ui to use one from Websockets * chore: cleanup * fix: lint issues * Replace IconPlayerStop with IconSquareRoundedX * update json request and response formatting logic * chore: format changes * chore: remove un-needed diffs * chore: sanitize * bugfix(#5939): curl import fails for custom content-types * chore: remove un-needed diffs * chore: enhance response handling for streaming * fix: disable requestid check for tests and assertions to be updated after streaming result * chore: housekeeping * fix: streamline loading and cancel request icon logic * chore: formatting * fix: multiple co-pilot changes * fix: handle in folders * feat: add WaitGroup utility for managing concurrent tasks * refactor: remove WaitGroup utility and clean up network IPC logic * refactor: remove unused setTimeout import and clean up post script execution * refactor: clean up post-response script execution logic * undiff * re-align * refactor: streamline post-response script execution - Cleaned up formatting and improved readability of the post-response script execution logic. - Consolidated parameters in function calls for consistency. * fix: keep original dataBuffer for saving response --------- Co-authored-by: adarshajit Co-authored-by: sajadoncode Co-authored-by: lohit-bruno Co-authored-by: Bijin A B Co-authored-by: Pragadesh-45 Co-authored-by: Anoop M D Co-authored-by: Anoop M D Co-authored-by: Dawid Góra --- contributing.md | 6 + docs/contributing/contributing_fa.md | 92 ++++++++ docs/publishing/publishing_fa.md | 8 + docs/readme/readme_fa.md | 143 +++++++++++++ package-lock.json | 9 +- packages/bruno-app/package.json | 3 +- .../RequestPane/GraphQLVariables/index.js | 5 +- .../components/RequestPane/GrpcBody/index.js | 5 +- .../components/RequestPane/QueryUrl/index.js | 29 ++- .../src/components/RequestTabPanel/index.js | 15 +- .../ResponsePane/ResponseBookmark/index.js | 26 ++- .../ResponsePane/ResponseStopWatch/index.js | 8 +- .../WsResponsePane/WSMessagesList/index.js | 2 +- .../src/components/ResponsePane/index.js | 39 ++-- .../ReduxStore/slices/collections/index.js | 127 ++++++----- packages/bruno-app/src/utils/common/index.js | 7 +- .../bruno-app/src/utils/common/index.spec.js | 8 +- .../bruno-app/src/utils/curl/content-type.js | 29 +++ .../bruno-app/src/utils/curl/curl-to-json.js | 3 +- .../src/utils/curl/curl-to-json.spec.js | 33 +++ packages/bruno-app/src/utils/curl/index.js | 15 +- packages/bruno-app/src/utils/network/index.js | 63 +++--- .../bruno-electron/src/ipc/network/index.js | 200 ++++++++++-------- publishing.md | 1 + readme.md | 2 + .../fixtures/collection/request.bru | 3 +- .../json-response-formatting.spec.ts | 3 + 27 files changed, 643 insertions(+), 241 deletions(-) create mode 100644 docs/contributing/contributing_fa.md create mode 100644 docs/publishing/publishing_fa.md create mode 100644 docs/readme/readme_fa.md create mode 100644 packages/bruno-app/src/utils/curl/content-type.js diff --git a/contributing.md b/contributing.md index 0c6a7d4a6..6206d59f5 100644 --- a/contributing.md +++ b/contributing.md @@ -16,6 +16,7 @@ | [日本語](docs/contributing/contributing_ja.md) | [हिंदी](docs/contributing/contributing_hi.md) | [Dutch](docs/contributing/contributing_nl.md) +| [فارسی](docs/contributing/contributing_fa.md) ## Let's make Bruno better, together!! @@ -74,6 +75,7 @@ npm run build:bruno-filestore # bundle js sandbox libraries npm run sandbox:bundle-libraries --workspace=packages/bruno-js ``` + ##### Option 2 ```bash @@ -94,18 +96,22 @@ npm run dev:electron ``` ##### Option 2 + ```bash # run electron and react app concurrently npm run dev ``` #### Customize Electron `userData` path + If `ELECTRON_USER_DATA_PATH` env-variable is present and its development mode, then `userData` path is modified accordingly. e.g. + ```sh ELECTRON_USER_DATA_PATH=$(realpath ~/Desktop/bruno-test) npm run dev:electron ``` + This will create a `bruno-test` folder on your Desktop and use it as the `userData` path. ### Troubleshooting diff --git a/docs/contributing/contributing_fa.md b/docs/contributing/contributing_fa.md new file mode 100644 index 000000000..5316a48a9 --- /dev/null +++ b/docs/contributing/contributing_fa.md @@ -0,0 +1,92 @@ +[English](../../contributing.md) + +## با هم، Bruno را بهتر می‌کنیم! + +خوشحالم که قصد دارید Bruno را بهبود ببخشید. در ادامه قوانین و راهنماها برای راه‌اندازی Bruno روی سیستم شما آورده شده است. + +### فناوری‌های استفاده‌شده + +به فارسی برونو Bruno با استفاده از Next.js و React ساخته شده است. همچنین از Electron برای بسته‌بندی نسخه دسکتاپ (که امکان مجموعه‌های محلی را فراهم می‌کند) استفاده می‌کنیم. + +کتابخانه‌هایی که استفاده می‌کنیم: + +- CSS - Tailwind استایل +- Codemirror - ویرایشگر کد +- Redux - مدیریت وضعیت +- Tabler Icons - آیکون‌ها +- formik - فرم‌ها +- Yup اعتبارسنجی اسکیمـا +- axios - کلاینت درخواست +- chokidar - پایش‌گر سیستم فایل + +### پیش‌نیازها + +شما به [نود v20.x یا اخرین نسخه پایدار](https://nodejs.org/en/) و npm 8.x نیاز دارید. در این پروژه از فضای کاری npm (npm workspaces) استفاده می‌کنیم. + +### شروع به کدنویسی + +برای راه‌اندازی محیط توسعه محلی به فایل [مستندات توسعه](docs/development_fa.md) مراجعه کنید: + +### ارسال Pull Request + +1 - لطفاً Pull Requestها (PR) را کوتاه و متمرکز نگه دارید و تنها یک هدف مشخص را دنبال کنند.
+2 - لطفاً از فرمت نام‌گذاری شاخه‌ها استفاده کنید: + +- feature/[name]: این شاخه باید شامل یک قابلیت مشخص باشد. + - feature/dark-mode : مثال +- bugfix/[name]: این شاخه باید تنها شامل رفع یک باگ مشخص باشد. + - bugfix/bug-1 : مثال + +## توسعه + +به فارسی برونو یا Bruno به‌صورت یک اپلیکیشن «سنگین» توسعه داده می‌شود. برای اجرا باید ابتدا Next.js را در یک پنجره ترمینال اجرا کنید و سپس اپلیکیشن Electron را در پنجره ترمینال دیگری راه‌اندازی نمایید. + +### نیازمندی توسعه + +- NodeJS v18 + +### اجرای محلی + +```bash +# از ورژن NodeJS 18 استفاده کنید +nvm use + +# نصب وابستگی‌ها +npm i --legacy-peer-deps + +# ساخت مستندات GraphQL +npm run build:graphql-docs + +# ساخت bruno-query +npm run build:bruno-query + +# اجرای اپ Next (ترمینال 1) +npm run dev:web + +# اجرای اپ Electron (ترمینال 2) +npm run dev:electron +``` + +### عیب‌یابی + +ممکن است هنگام اجرای `npm install` خطای `Unsupported platform` ببینید. برای رفع این مشکل، پوشه `node_modules` و فایل `package-lock.json` را حذف کرده و سپس دوباره `npm install` را اجرا کنید. این کار معمولاً همه پکیج‌های لازم را نصب می‌کند. + +```shell +# حذف پوشه node_modules در زیردایرکتوری‌ها +find ./ -type d -name "node_modules" -print0 | while read -d $'\0' dir; do + rm -rf "$dir" +done + +# حذف فایل package-lock.json در زیردایرکتوری‌ها +find . -type f -name "package-lock.json" -delete +``` + +### تست‌ها + +```bash +# اجرای تست‌های schema مربوط به bruno +npm test --workspace=packages/bruno-schema + +# اجرای تست‌ها در همه فضاهای کاری (در صورت وجود) +npm test --workspaces --if-present +``` diff --git a/docs/publishing/publishing_fa.md b/docs/publishing/publishing_fa.md new file mode 100644 index 000000000..6d24240c8 --- /dev/null +++ b/docs/publishing/publishing_fa.md @@ -0,0 +1,8 @@ +[English](../../publishing.md) + +### انتشار Bruno در یک پکیج منیجر جدید + +اگرچه کد ما متن‌باز است و همه می‌توانند از آن استفاده کنند، لطفاً قبل از انتشار Bruno در مدیر بسته‌های جدید با ما تماس بگیرید. به عنوان سازنده Bruno، علامت تجاری `Bruno` را برای این پروژه دارم و مایلم توزیع آن را مدیریت کنم. اگر دوست دارید Bruno را در یک مدیر بسته جدید ببینید، لطفاً یک issue در گیت‌هاب ثبت کنید. + +اگرچه بیشتر قابلیت‌های ما رایگان و متن‌باز هستند (شامل REST و GraphQL Apis)، +ما تلاش می‌کنیم بین اصول متن‌باز و توسعه پایدار تعادل مناسبی برقرار کنیم - https://github.com/usebruno/bruno/discussions/269 diff --git a/docs/readme/readme_fa.md b/docs/readme/readme_fa.md new file mode 100644 index 000000000..3e495d426 --- /dev/null +++ b/docs/readme/readme_fa.md @@ -0,0 +1,143 @@ +
+ + +### برونو یا Bruno - محیط توسعه متن باز برای تست و توسعه API ها + +[![GitHub version](https://badge.fury.io/gh/usebruno%2Fbruno.svg)](https://badge.fury.io/gh/usebruno%bruno) +[![CI](https://github.com/usebruno/bruno/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/usebruno/bruno/actions/workflows/tests.yml) +[![Commit Activity](https://img.shields.io/github/commit-activity/m/usebruno/bruno)](https://github.com/usebruno/bruno/pulse) +[![X](https://img.shields.io/twitter/follow/use_bruno?style=social&logo=x)](https://twitter.com/use_bruno) +[![Website](https://img.shields.io/badge/Website-Visit-blue)](https://www.usebruno.com) +[![Download](https://img.shields.io/badge/Download-Latest-brightgreen)](https://www.usebruno.com/downloads) + +[English](../../readme.md) +| [Українська](./readme_ua.md) +| [Русский](./readme_ru.md) +| [Türkçe](./readme_tr.md) +| [Deutsch](./readme_de.md) +| [Français](./readme_fr.md) +| [Português (BR)](./readme_pt_br.md) +| [한국어](./readme_kr.md) +| [বাংলা](./readme_bn.md) +| [Español](./readme_es.md) +| **فارسی** +| [Română](./readme_ro.md) +| [Polski](./readme_pl.md) +| [简体中文](./readme_cn.md) +| [正體中文](./readme_zhtw.md) +| [العربية](./readme_ar.md) +| [日本語](./readme_ja.md) +| [ქართული](./readme_ka.md) + +برونو یک کلاینت API جدید و نوآورانه است که هدفش تغییر وضعیت فعلی ابزارهایی مانند Postman و سایر ابزارهای مشابه است. + +برونو مجموعه‌های شما را مستقیماً در یک پوشه روی فایل‌سیستم شما ذخیره می‌کند. ما از یک زبان نشانه‌گذاری ساده به نام Bru برای ذخیره اطلاعات درخواست‌های API استفاده می‌کنیم. + +شما می‌توانید برای همکاری روی مجموعه‌های API خود، از Git یا هر سیستم کنترل نسخه دلخواهتان استفاده کنید. + +برونو فقط به صورت آفلاین کار می‌کند. هیچ برنامه‌ای برای اضافه کردن همگام‌سازی ابری به برونو در آینده وجود ندارد. ما به حریم خصوصی داده‌های شما اهمیت می‌دهیم و معتقدیم که باید روی دستگاه خودتان باقی بمانند. می‌توانید چشم‌انداز بلندمدت ما را مطالعه کنید. [اینجا (به انگلیسی)](https://github.com/usebruno/bruno/discussions/269) + +📢 جدیدترین ارائه ما را در کنفرانس India FOSS 3.0 تماشا کنید. +[اینجا](https://www.youtube.com/watch?v=7bSMFpbcPiY) + +![bruno](/assets/images/landing-2.png)

+ +### نصب + +برونو به صورت یک فایل باینری برای دانلود در دسترس است. [بر روی وبسایت ما](https://www.usebruno.com/downloads) برای مک لینکوس و ویندوز. + +همچنین می‌توانید برونو را از طریق مدیر بسته‌هایی مانند Homebrew، Chocolatey، Snap و Apt نصب کنید. + +```sh +# بر روی مک از طریق brew +brew install bruno + +# بر روی ویندوز از طریق Chocolatey +choco install bruno + +# بر روی لینوکس از طریق Snap +snap install bruno + +# بر روی لینوکس از طریق Apt +sudo mkdir -p /etc/apt/keyrings +sudo apt update && sudo apt install gpg curl +curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x9FA6017ECABE0266" \ + | gpg --dearmor \ + | sudo tee /etc/apt/keyrings/bruno.gpg > /dev/null +sudo chmod 644 /etc/apt/keyrings/bruno.gpg +echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/bruno.gpg] http://debian.usebruno.com/ bruno stable" \ + | sudo tee /etc/apt/sources.list.d/bruno.list +sudo apt update && sudo apt install bruno +``` + +### روی پلتفرم‌های مختلف کار می‌کند 🖥️ + +![bruno](/assets/images/run-anywhere.png)

+ +### همکاری از طریق گیت 👩‍💻🧑‍💻 + +یا هر سیستم کنترل نسخه‌ای که ترجیح می‌دهید + +![bruno](/assets/images/version-control.png)

+ +### لینک‌های مهم 📌 + +- [آخرین نسخه پایدار ما](https://github.com/usebruno/bruno/discussions/269) +- [نقشه راه](https://github.com/usebruno/bruno/discussions/384) +- [مستندات](https://docs.usebruno.com) +- [وبسایت](https://www.usebruno.com) +- [اشتراک ها](https://www.usebruno.com/pricing) +- [دانلود](https://www.usebruno.com/downloads) + +### ویدیوها 🎥 + +- [تجربه ها](https://github.com/usebruno/bruno/discussions/343) +- [مرکز دانش](https://github.com/usebruno/bruno/discussions/386) +- [اسکریپ مانیا](https://github.com/usebruno/bruno/discussions/385) + +### حمایت ❤️ + +جوون! اگر این پروژه را دوست دارید، روی دکمه ⭐ کلیک کنید! + +### تجربه‌های به اشتراک گذاشته‌شده 📣 + +اگر برونو به شما یا تیمتان کمک کرده است، لطفاً فراموش نکنید تجربه‌های خود را به اشتراک بگذارید. [تجربه‌های خود را در بحث گیت‌هاب ما به اشتراک بگذارید](https://github.com/usebruno/bruno/discussions/343). + +### انتشار برونو در یک پکیچ منیجر جدید + +لطفا چک بکنید [اینجارو](../../publishing.md) برای اطلاعات بیشتر. + +### مشارکت 👩‍💻🧑‍💻 + +خوشحالم که می‌خواهید برونو را بهتر کنید. لطفا [راهنمای مشارکت را بررسی کنید](../contributing/contributing_fa.md). + +حتی اگر نمی‌توانید از طریق کدنویسی مشارکت کنید، در گزارش باگ‌ها و درخواست قابلیت‌های جدید که به حل نیازهای شما کمک می‌کند تردید نکنید. + +### نویسنده ها + + + +### در ارتباط باشید 🌐 + +[𝕏 (تویتر)](https://twitter.com/use_bruno)
+[وبسایت](https://www.usebruno.com)
+[دیسکورد](https://discord.com/invite/KgcZUncpjq)
+[لینکدین](https://www.linkedin.com/company/usebruno) + +### برند + +**نام** + +به فارسی برونو - `Bruno` یک علامت تجاری ثبت‌شده متعلق به [Anoop M D](https://www.helloanoop.com/) + +**لوگو** + +لوگو توسط [OpenMoji](https://openmoji.org/library/emoji-1F436/) ساخته شده است. مجوز: CC [BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) + +### مجوز 📄 + +[MIT](../../license.md) diff --git a/package-lock.json b/package-lock.json index 746bccd2a..b54d8eb5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14235,9 +14235,9 @@ } }, "node_modules/fast-json-format": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/fast-json-format/-/fast-json-format-0.3.0.tgz", - "integrity": "sha512-B95psGYXJ5XItmxLR6JFcQRQafDyfy8ecHiV/jWCJF9oCIA9/o+wt89cGW61D04xf07yCpIaevvCQbgeJ9w8lQ==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/fast-json-format/-/fast-json-format-0.4.0.tgz", + "integrity": "sha512-HEomBtr2fYaVX3iaRdcVLU7Qd3SQhCYvXlMMM9RNaihfIaj5bIC7ADqw/bAPSg/uyX6FIBPq69ioXq0B4Cb6eA==", "license": "MIT" }, "node_modules/fast-json-stable-stringify": { @@ -26874,7 +26874,7 @@ "dompurify": "^3.2.4", "escape-html": "^1.0.3", "fast-fuzzy": "^1.12.0", - "fast-json-format": "~0.3.0", + "fast-json-format": "~0.4.0", "file": "^0.2.2", "file-dialog": "^0.0.8", "file-saver": "^2.0.5", @@ -26883,6 +26883,7 @@ "graphiql": "3.7.1", "graphql": "^16.6.0", "graphql-request": "^3.7.0", + "hexy": "^0.3.5", "httpsnippet": "^3.0.9", "i18next": "24.1.2", "idb": "^7.0.0", diff --git a/packages/bruno-app/package.json b/packages/bruno-app/package.json index 09b5f2741..1959a15dc 100644 --- a/packages/bruno-app/package.json +++ b/packages/bruno-app/package.json @@ -28,7 +28,7 @@ "dompurify": "^3.2.4", "escape-html": "^1.0.3", "fast-fuzzy": "^1.12.0", - "fast-json-format": "~0.3.0", + "fast-json-format": "~0.4.0", "file": "^0.2.2", "file-dialog": "^0.0.8", "file-saver": "^2.0.5", @@ -37,6 +37,7 @@ "graphiql": "3.7.1", "graphql": "^16.6.0", "graphql-request": "^3.7.0", + "hexy": "^0.3.5", "httpsnippet": "^3.0.9", "i18next": "24.1.2", "idb": "^7.0.0", diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js index 0a7fd98c9..6ab530ebd 100644 --- a/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js +++ b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js @@ -6,9 +6,9 @@ import { updateRequestGraphqlVariables } from 'providers/ReduxStore/slices/colle import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions'; import { useTheme } from 'providers/Theme'; import StyledWrapper from './StyledWrapper'; -import { format, applyEdits } from 'jsonc-parser'; import { IconWand } from '@tabler/icons'; import toast from 'react-hot-toast'; +import { prettifyJsonString } from 'utils/common/index'; const GraphQLVariables = ({ variables, item, collection }) => { const dispatch = useDispatch(); @@ -19,8 +19,7 @@ const GraphQLVariables = ({ variables, item, collection }) => { const onPrettify = () => { if (!variables) return; try { - const edits = format(variables, undefined, { tabSize: 2, insertSpaces: true }); - const prettyVariables = applyEdits(variables, edits); + const prettyVariables = prettifyJsonString(variables); dispatch( updateRequestGraphqlVariables({ variables: prettyVariables, diff --git a/packages/bruno-app/src/components/RequestPane/GrpcBody/index.js b/packages/bruno-app/src/components/RequestPane/GrpcBody/index.js index e17bdb074..0e1eb8d0b 100644 --- a/packages/bruno-app/src/components/RequestPane/GrpcBody/index.js +++ b/packages/bruno-app/src/components/RequestPane/GrpcBody/index.js @@ -12,9 +12,9 @@ import StyledWrapper from './StyledWrapper'; import { IconSend, IconRefresh, IconWand, IconPlus, IconTrash, IconChevronDown, IconChevronUp } from '@tabler/icons'; import ToolHint from 'components/ToolHint/index'; import { toastError } from 'utils/common/error'; -import { format, applyEdits } from 'jsonc-parser'; import toast from 'react-hot-toast' import { getAbsoluteFilePath } from 'utils/common/path'; +import { prettifyJsonString } from 'utils/common/index'; const SingleGrpcMessage = ({ message, item, collection, index, methodType, isCollapsed, onToggleCollapse, handleRun, canClientSendMultipleMessages }) => { const dispatch = useDispatch(); @@ -130,8 +130,7 @@ const SingleGrpcMessage = ({ message, item, collection, index, methodType, isCol const onPrettify = () => { try { - const edits = format(content, undefined, { tabSize: 2, insertSpaces: true }); - const prettyBodyJson = applyEdits(content, edits); + const prettyBodyJson = prettifyJsonString(content); const currentMessages = [...(body.grpc || [])]; currentMessages[index] = { diff --git a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js index 2c0fb3dd1..afaef13f3 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js +++ b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js @@ -2,10 +2,10 @@ import React, { useState, useEffect, useRef, useMemo } from 'react'; import get from 'lodash/get'; import { useDispatch } from 'react-redux'; import { requestUrlChanged, updateRequestMethod } from 'providers/ReduxStore/slices/collections'; -import { saveRequest } from 'providers/ReduxStore/slices/collections/actions'; +import { cancelRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions'; import HttpMethodSelector from './HttpMethodSelector'; import { useTheme } from 'providers/Theme'; -import { IconDeviceFloppy, IconArrowRight, IconCode, IconX } from '@tabler/icons'; +import { IconDeviceFloppy, IconArrowRight, IconCode, IconSquareRoundedX } from '@tabler/icons'; import SingleLineEditor from 'components/SingleLineEditor'; import { isMacOS } from 'utils/common/platform'; import { hasRequestChanges } from 'utils/collections'; @@ -22,6 +22,7 @@ const QueryUrl = ({ item, collection, handleRun }) => { const saveShortcut = isMac ? 'Cmd + S' : 'Ctrl + S'; const editorRef = useRef(null); const isGrpc = item.type === 'grpc-request'; + const isLoading = ['queued', 'sending'].includes(item.requestState); const [methodSelectorWidth, setMethodSelectorWidth] = useState(90); const [generateCodeItemModalOpen, setGenerateCodeItemModalOpen] = useState(false); @@ -80,6 +81,10 @@ const QueryUrl = ({ item, collection, handleRun }) => { } }; + const handleCancelRequest = () => { + dispatch(cancelRequest(item.cancelTokenUid, item, collection)); + }; + return (
@@ -87,7 +92,7 @@ const QueryUrl = ({ item, collection, handleRun }) => {
gRPC
- + ) : ( )} @@ -149,11 +154,23 @@ const QueryUrl = ({ item, collection, handleRun }) => { Save ({saveShortcut})
+ { - item.response?.hasStreamRunning ? ( - + isLoading || item.response?.stream?.running ? ( + ) : ( - + ) } diff --git a/packages/bruno-app/src/components/RequestTabPanel/index.js b/packages/bruno-app/src/components/RequestTabPanel/index.js index a347c1d0a..f8d3aba83 100644 --- a/packages/bruno-app/src/components/RequestTabPanel/index.js +++ b/packages/bruno-app/src/components/RequestTabPanel/index.js @@ -74,7 +74,8 @@ const RequestTabPanel = () => { const screenWidth = useSelector((state) => state.app.screenWidth); let asideWidth = useSelector((state) => state.app.leftSidebarWidth); const [leftPaneWidth, setLeftPaneWidth] = useState( - focusedTab && focusedTab.requestPaneWidth ? focusedTab.requestPaneWidth : (screenWidth - asideWidth) / 2.2); // 2.2 is intentional to make both panes appear to be of equal width + focusedTab && focusedTab.requestPaneWidth ? focusedTab.requestPaneWidth : (screenWidth - asideWidth) / 2.2 + ); // 2.2 is intentional to make both panes appear to be of equal width const [topPaneHeight, setTopPaneHeight] = useState(focusedTab?.requestPaneHeight || MIN_TOP_PANE_HEIGHT); const [dragging, setDragging] = useState(false); const dragOffset = useRef({ x: 0, y: 0 }); @@ -140,10 +141,12 @@ const RequestTabPanel = () => { setDragging(false); if (!isVerticalLayout) { const mainRect = mainSectionRef.current.getBoundingClientRect(); - dispatch(updateRequestPaneTabWidth({ - uid: activeTabUid, - requestPaneWidth: e.clientX - mainRect.left - })); + dispatch( + updateRequestPaneTabWidth({ + uid: activeTabUid, + requestPaneWidth: e.clientX - mainRect.left + }) + ); } } }; @@ -260,7 +263,7 @@ const RequestTabPanel = () => { return; } - if (item.response?.hasStreamRunning) { + if (item.response?.stream?.running) { dispatch(cancelRequest(item.cancelTokenUid, item, collection)).catch((err) => toast.custom((t) => toast.dismiss(t.id)} />, { duration: 5000 diff --git a/packages/bruno-app/src/components/ResponsePane/ResponseBookmark/index.js b/packages/bruno-app/src/components/ResponsePane/ResponseBookmark/index.js index b00440c3a..9efe51f2e 100644 --- a/packages/bruno-app/src/components/ResponsePane/ResponseBookmark/index.js +++ b/packages/bruno-app/src/components/ResponsePane/ResponseBookmark/index.js @@ -12,12 +12,25 @@ import { getInitialExampleName } from 'utils/collections/index'; import classnames from 'classnames'; import StyledWrapper from './StyledWrapper'; +const getTitleText = ({ isResponseTooLarge, isStreamingResponse }) => { + if (isStreamingResponse) { + return 'Response Examples aren\'t supported in streaming responses yet.'; + } + + if (isResponseTooLarge) { + return 'Response size exceeds 5MB limit. Cannot save as example.'; + } + + return 'Save current response as example'; +}; + const ResponseBookmark = ({ item, collection, responseSize }) => { const dispatch = useDispatch(); const [showSaveResponseExampleModal, setShowSaveResponseExampleModal] = useState(false); const response = item.response || {}; const isResponseTooLarge = responseSize >= 5 * 1024 * 1024; // 5 MB + const isStreamingResponse = response.stream; // Only show for HTTP requests if (item.type !== 'http-request') { @@ -96,19 +109,22 @@ const ResponseBookmark = ({ item, collection, responseSize }) => { toast.success(`Example "${name}" created successfully`); }; + const disabledMessage = getTitleText({ + isResponseTooLarge, + isStreamingResponse + }); + return ( <>