mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
enable/disable collection/folder run buttons based on the filtered requests (#5131)
This commit is contained in:
@@ -4,7 +4,7 @@ import { get, cloneDeep, find } from 'lodash';
|
||||
import { updateCollectionTagsList, updateRunnerTagsDetails } from 'providers/ReduxStore/slices/collections';
|
||||
import TagList from 'components/TagList';
|
||||
|
||||
const RunnerTags = ({ collectionUid }) => {
|
||||
const RunnerTags = ({ collectionUid, className = '' }) => {
|
||||
const dispatch = useDispatch();
|
||||
const collections = useSelector((state) => state.collections.collections);
|
||||
const collection = cloneDeep(find(collections, (c) => c.uid === collectionUid));
|
||||
@@ -87,7 +87,7 @@ const RunnerTags = ({ collectionUid }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mt-6 flex flex-col">
|
||||
<div className={`mt-6 flex flex-col ${className}`}>
|
||||
<div className="flex gap-2">
|
||||
<label className="block font-medium">Filter requests with tags</label>
|
||||
<input
|
||||
|
||||
@@ -10,6 +10,7 @@ import ResponsePane from './ResponsePane';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { areItemsLoading } from 'utils/collections';
|
||||
import RunnerTags from './RunnerTags/index';
|
||||
import { getRequestItemsForCollectionRun } from 'utils/collections/index';
|
||||
|
||||
const getDisplayName = (fullPath, pathname, name = '') => {
|
||||
let relativePath = path.relative(fullPath, pathname);
|
||||
@@ -73,6 +74,10 @@ export default function RunnerResults({ collection }) {
|
||||
// have tags been added for the collection run
|
||||
const areTagsAdded = tags.include.length > 0 || tags.exclude.length > 0;
|
||||
|
||||
const requestItemsForCollectionRun = getRequestItemsForCollectionRun({ recursive: true, tags, items: collection.items });
|
||||
const totalRequestItemsCountForCollectionRun = requestItemsForCollectionRun.length;
|
||||
const shouldDisableCollectionRun = totalRequestItemsCountForCollectionRun <= 0;
|
||||
|
||||
const items = cloneDeep(get(collection, 'runnerResult.items', []))
|
||||
.map((item) => {
|
||||
const info = findItemInCollection(collectionCopy, item.uid);
|
||||
@@ -161,9 +166,9 @@ export default function RunnerResults({ collection }) {
|
||||
</div>
|
||||
|
||||
{/* Tags for the collection run */}
|
||||
<RunnerTags collectionUid={collection.uid} />
|
||||
<RunnerTags collectionUid={collection.uid} className='mb-6' />
|
||||
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary mt-6" onClick={runCollection}>
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary mt-6" disabled={shouldDisableCollectionRun} onClick={runCollection}>
|
||||
Run Collection
|
||||
</button>
|
||||
|
||||
@@ -346,7 +351,7 @@ export default function RunnerResults({ collection }) {
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary mt-6" onClick={runAgain}>
|
||||
Run Again
|
||||
</button>
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary mt-6 ml-3" onClick={runCollection}>
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary mt-6 ml-3" disabled={shouldDisableCollectionRun} onClick={runCollection}>
|
||||
Run Collection
|
||||
</button>
|
||||
<button className="btn btn-sm btn-close mt-6 ml-3" onClick={resetRunner}>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { flattenItems } from 'utils/collections';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { areItemsLoading } from 'utils/collections';
|
||||
import RunnerTags from 'components/RunnerResults/RunnerTags/index';
|
||||
import { getRequestItemsForCollectionRun } from 'utils/collections/index';
|
||||
|
||||
const RunCollectionItem = ({ collectionUid, item, onClose }) => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -48,70 +49,65 @@ const RunCollectionItem = ({ collectionUid, item, onClose }) => {
|
||||
onClose();
|
||||
}
|
||||
|
||||
const getRequestsCount = (items) => {
|
||||
const requestTypes = ['http-request', 'graphql-request']
|
||||
return items.filter(req => requestTypes.includes(req.type)).length;
|
||||
}
|
||||
|
||||
const runLength = item ? getRequestsCount(item.items) : get(collection, 'items.length', 0);
|
||||
const flattenedItems = flattenItems(item ? item.items : collection.items);
|
||||
const recursiveRunLength = getRequestsCount(flattenedItems);
|
||||
|
||||
const isFolderLoading = areItemsLoading(item);
|
||||
|
||||
const requestItemsForRecursiveFolderRun = getRequestItemsForCollectionRun({ recursive: true, tags, items: item ? item.items : collection.items });
|
||||
const totalRequestItemsCountForRecursiveFolderRun = requestItemsForRecursiveFolderRun.length;
|
||||
const shouldDisableRecursiveFolderRun = totalRequestItemsCountForRecursiveFolderRun <= 0;
|
||||
|
||||
const requestItemsForFolderRun = getRequestItemsForCollectionRun({ recursive: false, tags, items: item ? item.items : collection.items });
|
||||
const totalRequestItemsCountForFolderRun = requestItemsForFolderRun.length;
|
||||
const shouldDisableFolderRun = totalRequestItemsCountForFolderRun <= 0;
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<Modal size="md" title="Collection Runner" hideFooter={true} handleCancel={onClose}>
|
||||
{!runLength && !recursiveRunLength ? (
|
||||
<div className="mb-8">No request found in this folder.</div>
|
||||
) : (
|
||||
<div>
|
||||
<div className="mb-1">
|
||||
<span className="font-medium">Run</span>
|
||||
<span className="ml-1 text-xs">({runLength} requests)</span>
|
||||
</div>
|
||||
<div className="mb-8">This will only run the requests in this folder.</div>
|
||||
<div className="mb-1">
|
||||
<span className="font-medium">Recursive Run</span>
|
||||
<span className="ml-1 text-xs">({recursiveRunLength} requests)</span>
|
||||
</div>
|
||||
<div className={isFolderLoading ? "mb-2" : "mb-8"}>This will run all the requests in this folder and all its subfolders.</div>
|
||||
{isFolderLoading ? <div className='mb-8 warning'>Requests in this folder are still loading.</div> : null}
|
||||
{isCollectionRunInProgress ? <div className='mb-6 warning'>A Collection Run is already in progress.</div> : null}
|
||||
<div>
|
||||
<div className="mb-1">
|
||||
<span className="font-medium">Run</span>
|
||||
<span className="ml-1 text-xs">({totalRequestItemsCountForFolderRun} requests)</span>
|
||||
</div>
|
||||
<div className="mb-8">This will only run the requests in this folder.</div>
|
||||
<div className="mb-1">
|
||||
<span className="font-medium">Recursive Run</span>
|
||||
<span className="ml-1 text-xs">({totalRequestItemsCountForRecursiveFolderRun} requests)</span>
|
||||
</div>
|
||||
<div className={isFolderLoading ? "mb-2" : "mb-8"}>This will run all the requests in this folder and all its subfolders.</div>
|
||||
{isFolderLoading ? <div className='mb-8 warning'>Requests in this folder are still loading.</div> : null}
|
||||
{isCollectionRunInProgress ? <div className='mb-6 warning'>A Collection Run is already in progress.</div> : null}
|
||||
|
||||
{/* Tags for the collection run */}
|
||||
<RunnerTags collectionUid={collection.uid} />
|
||||
{/* Tags for the collection run */}
|
||||
<RunnerTags collectionUid={collection.uid} className='mb-6' />
|
||||
|
||||
<div className="flex justify-end bruno-modal-footer">
|
||||
<span className="mr-3">
|
||||
<button type="button" onClick={onClose} className="btn btn-md btn-close">
|
||||
Cancel
|
||||
</button>
|
||||
</span>
|
||||
{
|
||||
isCollectionRunInProgress ?
|
||||
<div className="flex justify-end bruno-modal-footer">
|
||||
<span className="mr-3">
|
||||
<button type="button" onClick={onClose} className="btn btn-md btn-close">
|
||||
Cancel
|
||||
</button>
|
||||
</span>
|
||||
{
|
||||
isCollectionRunInProgress ?
|
||||
<span>
|
||||
<button type="submit" className="submit btn btn-md btn-secondary mr-3" onClick={handleViewRunner}>
|
||||
View Run
|
||||
</button>
|
||||
</span>
|
||||
:
|
||||
<>
|
||||
<span>
|
||||
<button type="submit" className="submit btn btn-md btn-secondary mr-3" onClick={handleViewRunner}>
|
||||
View Run
|
||||
<button type="submit" disabled={shouldDisableRecursiveFolderRun} className="submit btn btn-md btn-secondary mr-3" onClick={() => onSubmit(true)}>
|
||||
Recursive Run
|
||||
</button>
|
||||
</span>
|
||||
:
|
||||
<>
|
||||
<span>
|
||||
<button type="submit" disabled={!recursiveRunLength} className="submit btn btn-md btn-secondary mr-3" onClick={() => onSubmit(true)}>
|
||||
Recursive Run
|
||||
</button>
|
||||
</span>
|
||||
<span>
|
||||
<button type="submit" disabled={!runLength} className="submit btn btn-md btn-secondary" onClick={() => onSubmit(false)}>
|
||||
Run
|
||||
</button>
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
<span>
|
||||
<button type="submit" disabled={shouldDisableFolderRun} className="submit btn btn-md btn-secondary" onClick={() => onSubmit(false)}>
|
||||
Run
|
||||
</button>
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
</StyledWrapper>
|
||||
);
|
||||
|
||||
@@ -41,7 +41,7 @@ const TagList = ({ tagsHintList = [], handleAddTag, tags, handleRemoveTag, onSav
|
||||
<SingleLineEditor
|
||||
className="border border-gray-500/50 px-2"
|
||||
value={text}
|
||||
placeholder="Enter tag name (e.g., smoke, regression etc)"
|
||||
placeholder="e.g., smoke, regression etc"
|
||||
autocomplete={tagsHintList}
|
||||
showHintsOnClick={true}
|
||||
showHintsFor={[]}
|
||||
|
||||
@@ -2,6 +2,7 @@ import {cloneDeep, isEqual, sortBy, filter, map, isString, findIndex, find, each
|
||||
import { uuid } from 'utils/common';
|
||||
import { sortByNameThenSequence } from 'utils/common/index';
|
||||
import path from 'utils/common/path';
|
||||
import { isRequestTagsIncluded } from '@usebruno/common';
|
||||
|
||||
const replaceTabsWithSpaces = (str, numSpaces = 2) => {
|
||||
if (!str || !str.length || !isString(str)) {
|
||||
@@ -1125,3 +1126,31 @@ export const getUniqueTagsFromItems = (items = []) => {
|
||||
getTags(items);
|
||||
return Array.from(allTags).sort();
|
||||
};
|
||||
|
||||
|
||||
export const getRequestItemsForCollectionRun = ({ recursive, items = [], tags }) => {
|
||||
let requestItems = [];
|
||||
|
||||
if (recursive) {
|
||||
requestItems = flattenItems(items);
|
||||
} else {
|
||||
each(items, (item) => {
|
||||
if (item.request) {
|
||||
requestItems.push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const requestTypes = ['http-request', 'graphql-request'];
|
||||
requestItems = requestItems.filter(request => requestTypes.includes(request.type));
|
||||
|
||||
if (tags && tags.include && tags.exclude) {
|
||||
const includeTags = tags.include ? tags.include : [];
|
||||
const excludeTags = tags.exclude ? tags.exclude : [];
|
||||
requestItems = requestItems.filter(({ tags = [] }) => {
|
||||
return isRequestTagsIncluded(tags, includeTags, excludeTags);
|
||||
});
|
||||
}
|
||||
|
||||
return requestItems;
|
||||
};
|
||||
Reference in New Issue
Block a user