Feature (Size/M) : BRU-3560 Remove Beta badge from openAPI sync (#8250)

* BRU-3560 Remove Beta badge from openAPI sync

* BRU-3560 Comments fixed

* BRU-3560 Comments resolved

* BRU-3560 Comments resolved

* BRU-3560 Comments resolved

---------

Co-authored-by: bruno-sachin <bruno-sachin@brunos-MacBook-Air.local>
This commit is contained in:
sachin-bruno
2026-06-17 19:24:26 +05:30
committed by GitHub
parent 7b94e069e9
commit fab18d9e3e
9 changed files with 36 additions and 55 deletions

View File

@@ -128,17 +128,6 @@ const ConnectSpecForm = ({ sourceUrl, setSourceUrl, isLoading, error, setError,
</div>
))}
</div>
<p className="beta-feedback-inline">
OpenAPI Sync is in Beta we'd love to hear your feedback and suggestions.{' '}
<button
type="button"
className="beta-feedback-link"
onClick={() => window?.ipcRenderer?.openExternal('https://github.com/usebruno/bruno/discussions/7401')}
>
Share feedback
</button>
</p>
</div>
);
};

View File

@@ -131,16 +131,6 @@ const OpenAPISyncTab = ({ collection }) => {
error={error}
onOpenSettings={() => setShowSettingsModal(true)}
/>
<p className="beta-feedback-inline">
OpenAPI Sync is in Beta we'd love to hear your feedback and suggestions.{' '}
<button
type="button"
className="beta-feedback-link"
onClick={() => window?.ipcRenderer?.openExternal('https://github.com/usebruno/bruno/discussions/7401')}
>
Share feedback
</button>
</p>
</div>
)}

View File

@@ -6,20 +6,38 @@ import StyledWrapper from './StyledWrapper';
import * as Yup from 'yup';
import debounce from 'lodash/debounce';
import toast from 'react-hot-toast';
import { IconFlask } from '@tabler/icons';
import get from 'lodash/get';
import { BETA_FEATURES as BETA_FEATURE_IDS } from 'utils/beta-features';
// Commented out while there are no active beta features. Re-enable this import when
// adding a beta feature its keys are then referenced as BETA_FEATURE_IDS.MY_FEATURE in the BETA_FEATURES array.
// import { BETA_FEATURES as BETA_FEATURE_IDS } from 'utils/beta-features';
/**
* UI metadata for beta features rendered in Preferences.
* IDs must match keys from utils/beta-features.js BETA_FEATURES.
* UI metadata for the Beta Features section in Preferences — one entry per toggle.
* The whole tab is data-driven from this array: the form fields, validation schema,
* initial values and the rendered checkboxes are all generated from it.
*
* Each entry has the shape { id, label, description }:
* - id (required) the feature key. MUST be a value from BETA_FEATURES in
* utils/beta-features.js (imported here as BETA_FEATURE_IDS). It is
* used as the preference key (preferences.beta[id]), the form field
* name and the checkbox id, so it must be stable and unique.
* - label (required) short name shown next to the checkbox.
* - description (required) one-line explanation shown under the label.
*
* To add a beta feature:
* 1. Add its key to BETA_FEATURES in utils/beta-features.js (e.g. MY_FEATURE: 'my-feature').
* 2. Add an entry to the array below using BETA_FEATURE_IDS.MY_FEATURE.
* 3. Gate the feature in code with useBetaFeature(BETA_FEATURES.MY_FEATURE).
*
* When the array is empty, the Beta tab shows "No beta features are currently available",
* so a feature can be hidden by simply removing or commenting out its entry.
*/
const BETA_FEATURES = [
{
id: BETA_FEATURE_IDS.OPENAPI_SYNC,
label: 'OpenAPI Sync',
description: 'Synchronize your Bruno collection with an OpenAPI specification. Detect drift, review changes, and sync with a single click.'
}
// {
// id: BETA_FEATURE_IDS.OPENAPI_SYNC,
// label: 'OpenAPI Sync',
// description: 'Synchronize your Bruno collection with an OpenAPI specification. Detect drift, review changes, and sync with a single click.'
// }
];
const Beta = ({ close }) => {

View File

@@ -37,8 +37,6 @@ import { normalizePath } from 'utils/common/path';
import classNames from 'classnames';
import StyledWrapper from './StyledWrapper';
import { useTheme } from 'providers/Theme';
import { useBetaFeature, BETA_FEATURES } from 'utils/beta-features';
import StatusBadge from 'ui/StatusBadge/index';
const CollectionHeader = ({ collection, isScratchCollection }) => {
const dispatch = useDispatch();
@@ -50,7 +48,6 @@ const CollectionHeader = ({ collection, isScratchCollection }) => {
// Get the current active workspace
const currentWorkspace = workspaces.find((w) => w.uid === activeWorkspaceUid);
const gitRootPath = collection?.git?.gitRootPath;
const isOpenAPISyncEnabled = useBetaFeature(BETA_FEATURES.OPENAPI_SYNC);
// Workspace rename state
const [isRenamingWorkspace, setIsRenamingWorkspace] = useState(false);
@@ -235,8 +232,8 @@ const CollectionHeader = ({ collection, isScratchCollection }) => {
const overflowMenuItems = [
{ id: 'variables', label: 'Variables', leftSection: IconEye, onClick: viewVariables },
{ id: 'file-mode', label: collection.fileMode ? 'Switch to Code Mode' : 'Switch to File Mode', leftSection: collection.fileMode ? IconFileOff : IconFileCode, onClick: handleFileModeClick },
...(isOpenAPISyncEnabled && !hasOpenApiSyncConfigured
? [{ id: 'openapi-sync', label: 'OpenAPI', leftSection: OpenAPISyncIcon, rightSection: <StatusBadge status="info" size="xs">Beta</StatusBadge>, onClick: viewOpenApiSync }]
...(!hasOpenApiSyncConfigured
? [{ id: 'openapi-sync', label: 'OpenAPI', leftSection: OpenAPISyncIcon, onClick: viewOpenApiSync }]
: []),
{ id: 'collection-settings', label: 'Collection Settings', leftSection: IconSettings, onClick: viewCollectionSettings }
];
@@ -588,7 +585,7 @@ const CollectionHeader = ({ collection, isScratchCollection }) => {
{!isScratchCollection && (
<div className="flex flex-grow gap-1.5 items-center justify-end">
{/* OpenAPI Sync - standalone only when configured and beta enabled */}
{isOpenAPISyncEnabled && hasOpenApiSyncConfigured && (
{hasOpenApiSyncConfigured && (
<ToolHint
text={hasOpenApiError ? 'OpenAPI Error' : hasOpenApiUpdates ? 'OpenAPI Updates Available' : 'OpenAPI'}
toolhintId="OpenApiSyncToolhintId"

View File

@@ -2,7 +2,6 @@ import React from 'react';
import GradientCloseButton from './GradientCloseButton';
import { IconVariable, IconSettings, IconRun, IconFolder, IconDatabase, IconWorld, IconHome, IconFileCode } from '@tabler/icons';
import OpenAPISyncIcon from 'components/Icons/OpenAPISync';
import StatusBadge from 'ui/StatusBadge/index';
const SpecialTab = ({ handleCloseClick, type, tabName, handleDoubleClick, hasDraft }) => {
const getTabInfo = (type, tabName) => {
@@ -92,7 +91,6 @@ const SpecialTab = ({ handleCloseClick, type, tabName, handleDoubleClick, hasDra
<>
<OpenAPISyncIcon size={14} className="special-tab-icon flex-shrink-0" />
<span className="ml-1 tab-name mr-1">OpenAPI</span>
<StatusBadge status="info" size="xs">Beta</StatusBadge>
</>
);
}

View File

@@ -52,8 +52,6 @@ import { getRevealInFolderLabel } from 'utils/common/platform';
import { openDevtoolsAndSwitchToTerminal } from 'utils/terminal';
import ActionIcon from 'ui/ActionIcon';
import MenuDropdown from 'ui/MenuDropdown';
import StatusBadge from 'ui/StatusBadge';
import { useBetaFeature, BETA_FEATURES } from 'utils/beta-features';
import { useSidebarAccordion } from 'components/Sidebar/SidebarAccordionContext';
import { createEmptyStateMenuItems } from 'utils/collections/emptyStateRequest';
import useKeybinding from 'hooks/useKeybinding';
@@ -63,7 +61,6 @@ import useKeybinding from 'hooks/useKeybinding';
const EMPTY_STATE_DELAY_MS = 300;
const Collection = ({ collection, searchText }) => {
const isOpenAPISyncEnabled = useBetaFeature(BETA_FEATURES.OPENAPI_SYNC);
const { dropdownContainerRef } = useSidebarAccordion();
const [showNewFolderModal, setShowNewFolderModal] = useState(false);
const [showNewRequestModal, setShowNewRequestModal] = useState(false);
@@ -375,13 +372,12 @@ const Collection = ({ collection, searchText }) => {
setShowCloneCollectionModalOpen(true);
}
},
...(isOpenAPISyncEnabled ? [{
{
id: 'sync-openapi',
leftSection: OpenAPISyncIcon,
label: 'OpenAPI',
rightSection: <StatusBadge status="info" size="xs">Beta</StatusBadge>,
onClick: openOpenAPISyncTab
}] : []),
},
...(hasCopiedItems
? [
{

View File

@@ -14,7 +14,6 @@ import { processOpenCollection } from 'utils/importers/opencollection';
import { wsdlToBruno } from '@usebruno/converters';
import { toastError } from 'utils/common/error';
import { addLog } from 'providers/ReduxStore/slices/logs';
import { useBetaFeature, BETA_FEATURES } from 'utils/beta-features';
import Portal from 'components/Portal';
import Modal from 'components/Modal';
import Help from 'components/Help';
@@ -111,8 +110,7 @@ const ImportCollectionLocation = ({ onClose, handleSubmit, rawData, format, sour
const [groupingType, setGroupingType] = useState('tags');
const [collectionFormat, setCollectionFormat] = useState(DEFAULT_COLLECTION_FORMAT);
const [showFileFormat, setShowFileFormat] = useState(false);
const isOpenAPISyncEnabled = useBetaFeature(BETA_FEATURES.OPENAPI_SYNC);
const [enableCheckForSpecUpdates, setEnableCheckForSpecUpdates] = useState(isOpenAPISyncEnabled);
const [enableCheckForSpecUpdates, setEnableCheckForSpecUpdates] = useState(false);
const dropdownTippyRef = useRef();
const optionsDropdownTippyRef = useRef();
const isOpenApi = format === 'openapi';
@@ -120,7 +118,7 @@ const ImportCollectionLocation = ({ onClose, handleSubmit, rawData, format, sour
const isOpenApiFromUrl = isOpenApi && !!sourceUrl && !filePath;
const isOpenApiFromFile = isOpenApi && !!filePath && !sourceUrl;
const isSwagger2 = isOpenApi && rawData?.swagger && String(rawData.swagger).startsWith('2');
const showCheckForSpecUpdatesOption = isOpenAPISyncEnabled && (isOpenApiFromUrl || isOpenApiFromFile);
const showCheckForSpecUpdatesOption = isOpenApiFromUrl || isOpenApiFromFile;
const { workspaces, activeWorkspaceUid } = useSelector((state) => state.workspaces);
const preferences = useSelector((state) => state.app.preferences);
@@ -391,7 +389,6 @@ const ImportCollectionLocation = ({ onClose, handleSubmit, rawData, format, sour
</div>
</div>
)}
{showCheckForSpecUpdatesOption && (
<div className={`mt-4 ${isSwagger2 ? 'opacity-50 pointer-events-none' : ''}`}>
<label className={`flex items-center gap-2 ${isSwagger2 ? '' : 'cursor-pointer'}`}>

View File

@@ -2,16 +2,13 @@ import { useEffect, useMemo, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { checkActiveWorkspaceCollectionsForUpdates } from 'providers/ReduxStore/slices/openapi-sync';
import { normalizePath } from 'utils/common/path';
import { useBetaFeature, BETA_FEATURES } from 'utils/beta-features';
const POLL_INTERVAL = 5 * 60 * 1000; // 5 minutes
const useOpenAPISyncPolling = () => {
const dispatch = useDispatch();
const isOpenAPISyncEnabled = useBetaFeature(BETA_FEATURES.OPENAPI_SYNC);
// Global toggle for pausing all OpenAPI sync polling
const pollingEnabled = useSelector((state) => state.openapiSync?.pollingEnabled ?? true) && isOpenAPISyncEnabled;
const pollingEnabled = useSelector((state) => state.openapiSync?.pollingEnabled ?? true);
const collections = useSelector((state) => state.collections?.collections || []);
const { workspaces, activeWorkspaceUid } = useSelector((state) => state.workspaces);
const activeWorkspace = workspaces.find((w) => w.uid === activeWorkspaceUid);

View File

@@ -5,8 +5,7 @@ import { useSelector } from 'react-redux';
* Contains all available beta feature keys
*/
export const BETA_FEATURES = Object.freeze({
NODE_VM: 'nodevm',
OPENAPI_SYNC: 'openapi-sync'
NODE_VM: 'nodevm'
});
/**