enable/disable collection/folder run buttons based on the filtered requests (#5131)

This commit is contained in:
lohit
2025-07-17 14:21:00 +05:30
committed by GitHub
parent 36e3554d5f
commit d5cb051f19
5 changed files with 89 additions and 59 deletions

View File

@@ -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

View File

@@ -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}>

View File

@@ -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>
);

View File

@@ -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={[]}

View File

@@ -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;
};