diff --git a/packages/bruno-app/src/components/Sidebar/ImportSettings/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/StyledWrapper.js
similarity index 100%
rename from packages/bruno-app/src/components/Sidebar/ImportSettings/StyledWrapper.js
rename to packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/StyledWrapper.js
diff --git a/packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/index.js b/packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/index.js
index 243a51f56..ffd543bf6 100644
--- a/packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/index.js
+++ b/packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/index.js
@@ -1,15 +1,94 @@
-import React, { useRef, useEffect, useState } from 'react';
+import React, { useRef, useEffect, useState, forwardRef } from 'react';
import { useDispatch } from 'react-redux';
import { useFormik } from 'formik';
import * as Yup from 'yup';
+import { IconCaretDown } from '@tabler/icons';
import { browseDirectory } from 'providers/ReduxStore/slices/collections/actions';
+import { postmanToBruno } from 'utils/importers/postman-collection';
+import { convertInsomniaToBruno } from 'utils/importers/insomnia-collection';
+import { convertOpenapiToBruno } from 'utils/importers/openapi-collection';
+import { processBrunoCollection } from 'utils/importers/bruno-collection';
+import { wsdlToBruno } from '@usebruno/converters';
+import { toastError } from 'utils/common/error';
import Modal from 'components/Modal';
import Help from 'components/Help';
+import Dropdown from 'components/Dropdown';
+import StyledWrapper from './StyledWrapper';
+// Extract collection name from raw data
+const getCollectionName = (format, rawData) => {
+ if (!rawData) return 'Collection';
-const ImportCollectionLocation = ({ onClose, handleSubmit, collectionName }) => {
+ switch (format) {
+ case 'openapi':
+ return rawData.info?.title || 'OpenAPI Collection';
+ case 'postman':
+ return rawData.info?.name || rawData.collection?.info?.name || 'Postman Collection';
+ case 'insomnia':
+ // For Insomnia v4 format, name is in the workspace resource
+ if (rawData.resources && Array.isArray(rawData.resources)) {
+ const workspace = rawData.resources.find((r) => r._type === 'workspace');
+ if (workspace?.name) {
+ return workspace.name;
+ }
+ }
+ // Fallback to root name property
+ return rawData.name || 'Insomnia Collection';
+ case 'bruno':
+ return rawData.name || 'Bruno Collection';
+ case 'wsdl':
+ return 'WSDL Collection';
+ default:
+ return 'Collection';
+ }
+};
+
+// Convert raw data to Bruno collection format
+const convertCollection = async (format, rawData, groupingType) => {
+ try {
+ let collection;
+
+ switch (format) {
+ case 'openapi':
+ collection = convertOpenapiToBruno(rawData, { groupBy: groupingType });
+ break;
+ case 'wsdl':
+ collection = await wsdlToBruno(rawData);
+ break;
+ case 'postman':
+ collection = await postmanToBruno(rawData);
+ break;
+ case 'insomnia':
+ collection = convertInsomniaToBruno(rawData);
+ break;
+ case 'bruno':
+ collection = await processBrunoCollection(rawData);
+ break;
+ default:
+ throw new Error('Unknown collection format');
+ }
+
+ return collection;
+ } catch (err) {
+ console.error('Conversion error:', err);
+ toastError(err, 'Failed to convert collection');
+ throw err;
+ }
+};
+
+const groupingOptions = [
+ { value: 'tags', label: 'Tags', description: 'Group requests by OpenAPI tags', testId: 'grouping-option-tags' },
+ { value: 'path', label: 'Paths', description: 'Group requests by URL path structure', testId: 'grouping-option-path' }
+];
+
+const ImportCollectionLocation = ({ onClose, handleSubmit, rawData, format }) => {
const inputRef = useRef();
const dispatch = useDispatch();
+ const [groupingType, setGroupingType] = useState('tags');
+ const dropdownTippyRef = useRef();
+ const isOpenApi = format === 'openapi';
+
+ const collectionName = getCollectionName(format, rawData);
const formik = useFormik({
enableReinitialize: true,
@@ -22,10 +101,27 @@ const ImportCollectionLocation = ({ onClose, handleSubmit, collectionName }) =>
.max(500, 'must be 500 characters or less')
.required('Location is required')
}),
- onSubmit: (values) => {
- handleSubmit(values.collectionLocation);
+ onSubmit: async (values) => {
+ const convertedCollection = await convertCollection(format, rawData, groupingType);
+ handleSubmit(convertedCollection, values.collectionLocation);
}
});
+
+ const onDropdownCreate = (ref) => {
+ dropdownTippyRef.current = ref;
+ };
+
+ const GroupingDropdownIcon = forwardRef((props, ref) => {
+ const selectedOption = groupingOptions.find((option) => option.value === groupingType);
+ return (
+
+
+
{selectedOption.label}
+
+
+
+ );
+ });
const browse = () => {
dispatch(browseDirectory())
.then((dirPath) => {
@@ -48,53 +144,89 @@ const ImportCollectionLocation = ({ onClose, handleSubmit, collectionName }) =>
const onSubmit = () => formik.handleSubmit();
return (
-
-