From bc58169ea9799dae3e8894a7042875ae86c50098 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Mon, 27 Nov 2023 21:03:48 +0530 Subject: [PATCH 01/10] moved filter by field on top of the page Signed-off-by: msivasubramaniaan --- src/webview/common/devfileListItem.tsx | 32 ++++++----- src/webview/common/devfileSearch.tsx | 54 +++++++++---------- .../devfile-registry/app/devfileRegistry.tsx | 2 +- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/webview/common/devfileListItem.tsx b/src/webview/common/devfileListItem.tsx index a9f4c5b7f..5f2261e72 100644 --- a/src/webview/common/devfileListItem.tsx +++ b/src/webview/common/devfileListItem.tsx @@ -70,7 +70,7 @@ function DevfileListContent(props: DevfileListItemProps) { {props.devfile.description} - : } - color={props.devfile.supportsDebug ? 'success' : 'error'} - /> - : } - color={props.devfile.supportsDeploy ? 'success' : 'error'} - /> + { + props.devfile.supportsDebug && } + color={'success'} + /> + } + { + props.devfile.supportsDeploy && } + color={'success'} + /> + } {(props.devfile.tags && props.devfile.tags.map((tag, i) => { if (i >= 4) { return; diff --git a/src/webview/common/devfileSearch.tsx b/src/webview/common/devfileSearch.tsx index 6a31e867a..5c2ba465d 100644 --- a/src/webview/common/devfileSearch.tsx +++ b/src/webview/common/devfileSearch.tsx @@ -654,15 +654,39 @@ export function DevfileSearch(props: DevfileSearchProps) { return ( <> - {props.titleText} + + {(devfileCapabilities.length > 0 || devfileTags.length > 0) && ( + + + Filter by + + + {devfileCapabilities.length > 0 && ( + <> + + + )} + {devfileTags.length > 0 && ( + + )} + + + )} + - + {devfileRegistries.length > 1 && ( <> Devfile Registries - + )} - {(devfileCapabilities.length > 0 || devfileTags.length > 0) && ( - <> - - Filter by - - - {devfileCapabilities.length > 0 && ( - <> - - - - )} - {devfileTags.length > 0 && ( - - )} - - - )} diff --git a/src/webview/devfile-registry/app/devfileRegistry.tsx b/src/webview/devfile-registry/app/devfileRegistry.tsx index eb90507d9..375f27507 100644 --- a/src/webview/devfile-registry/app/devfileRegistry.tsx +++ b/src/webview/devfile-registry/app/devfileRegistry.tsx @@ -36,7 +36,7 @@ export const DevfileRegistry = () => { return ( - + From 902fcfc99d74e31f7e9401c72fc22a904c502842 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Mon, 27 Nov 2023 21:09:57 +0530 Subject: [PATCH 02/10] removed unused import Signed-off-by: msivasubramaniaan --- src/webview/common/devfileListItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webview/common/devfileListItem.tsx b/src/webview/common/devfileListItem.tsx index 5f2261e72..3de1119e6 100644 --- a/src/webview/common/devfileListItem.tsx +++ b/src/webview/common/devfileListItem.tsx @@ -2,7 +2,7 @@ * Copyright (c) Red Hat, Inc. All rights reserved. * Licensed under the MIT License. See LICENSE file in the project root for license information. *-----------------------------------------------------------------------------------------------*/ -import { Check, Close } from '@mui/icons-material'; +import { Check } from '@mui/icons-material'; import { Box, Chip, Stack, Tooltip, Typography } from '@mui/material'; import * as React from 'react'; import { Devfile } from '../common/devfile'; From 9f2cf6c68fa707359d339e149eb4db8c4eb3a1b0 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Tue, 28 Nov 2023 00:11:45 +0530 Subject: [PATCH 03/10] changed filter by with checkbox Signed-off-by: msivasubramaniaan --- src/webview/common/devfileListItem.tsx | 32 +-- src/webview/common/devfileSearch.tsx | 202 ++++++++---------- .../devfile-registry/app/devfileRegistry.tsx | 2 +- 3 files changed, 114 insertions(+), 122 deletions(-) diff --git a/src/webview/common/devfileListItem.tsx b/src/webview/common/devfileListItem.tsx index a9f4c5b7f..00da3c9c8 100644 --- a/src/webview/common/devfileListItem.tsx +++ b/src/webview/common/devfileListItem.tsx @@ -2,7 +2,7 @@ * Copyright (c) Red Hat, Inc. All rights reserved. * Licensed under the MIT License. See LICENSE file in the project root for license information. *-----------------------------------------------------------------------------------------------*/ -import { Check, Close } from '@mui/icons-material'; +import { Check } from '@mui/icons-material'; import { Box, Chip, Stack, Tooltip, Typography } from '@mui/material'; import * as React from 'react'; import { Devfile } from '../common/devfile'; @@ -93,23 +93,27 @@ function DevfileListContent(props: DevfileListItemProps) { {props.devfile.description} - : } - color={props.devfile.supportsDebug ? 'success' : 'error'} - /> - : } - color={props.devfile.supportsDeploy ? 'success' : 'error'} - /> + { + props.devfile.supportsDebug && } + color={'success'} + /> + } + { + props.devfile.supportsDeploy && } + color={'success'} + /> + } {(props.devfile.tags && props.devfile.tags.map((tag, i) => { if (i >= 4) { return; diff --git a/src/webview/common/devfileSearch.tsx b/src/webview/common/devfileSearch.tsx index 6a31e867a..6db505930 100644 --- a/src/webview/common/devfileSearch.tsx +++ b/src/webview/common/devfileSearch.tsx @@ -6,7 +6,6 @@ import { Close, FileCopy, Launch, Search } from '@mui/icons-material'; import { Box, Button, - Chip, Checkbox, Divider, FormControl, @@ -162,81 +161,43 @@ function RegistriesPicker(props: { ); } -function RegistryCapabilitiesPicker(props: { - capabilityEnabled: { capabilityName: string; enabled: boolean }[]; - setCapabilityEnabled: React.Dispatch< - React.SetStateAction<{ capabilityName: string; enabled: boolean }[]> - >; -}) { - function onClick(clickedCapability: string, checked: boolean) { - const updatedList = [...props.capabilityEnabled] // - .filter((entry) => entry.capabilityName !== clickedCapability); - updatedList.push({ - capabilityName: clickedCapability, - enabled: checked, - }); - const filteredUpdatedList = updatedList - .sort((capA, capB) => { - return capA.capabilityName.localeCompare(capB.capabilityName) - }); - props.setCapabilityEnabled([...filteredUpdatedList]); - } - - return ( - - {props.capabilityEnabled.map((_cap) => { - return ( - {onClick(_cap.capabilityName, !_cap.enabled)}} - label={_cap.capabilityName} - key={_cap.capabilityName} - /> - ); - })} - - ); -} - -function RegistryTagsPicker(props: { - tagEnabled: { tagName: string; enabled: boolean }[]; +function TagsPicker(props: { + tagEnabled: { name: string; enabled: boolean }[]; setTagEnabled: React.Dispatch< - React.SetStateAction<{ tagName: string; enabled: boolean }[]> + React.SetStateAction<{ name: string; enabled: boolean }[]> >; }) { - function onClick(clickedTag: string, checked: boolean) { + function onCheckboxClick(clickedRegistry: string, checked: boolean) { const updatedList = [...props.tagEnabled] // - .filter((entry) => entry.tagName !== clickedTag); + .filter((entry) => entry.name !== clickedRegistry); updatedList.push({ - tagName: clickedTag, + name: clickedRegistry, enabled: checked, }); - const filteredUpdatedList = updatedList - .sort((tagA, tagB) => { - return tagA.tagName.localeCompare(tagB.tagName) - }); - props.setTagEnabled([...filteredUpdatedList]); + updatedList.sort((regA, regB) => regA.name.localeCompare(regB.name)); + props.setTagEnabled(updatedList); } return ( - - {props.tagEnabled.map((_tag) => { + + {props.tagEnabled.map((tag) => { return ( - {onClick(_tag.tagName, !_tag.enabled)}} - label={_tag.tagName} - key={_tag.tagName} + + onCheckboxClick(tag.name, checked) + } + /> + } + label={tag.name} + key={tag.name} /> ); })} - + ); } @@ -247,7 +208,6 @@ const SelectTemplateProject = React.forwardRef( setSelectedProject: (projectName: string) => void; closeModal: () => void; }, - ref, ) => { const [selectedTemplateProject, setSelectedTemplateProject] = React.useState(''); const [isInteracted, setInteracted] = React.useState(false); @@ -410,7 +370,7 @@ const SelectTemplateProject = React.forwardRef( > { + onMouseLeave={() => { setTimeout(() => setYamlCopied((_) => false), 200); }} arrow @@ -478,14 +438,18 @@ export type DevfileSearchProps = { * @returns */ function isToBeIncluded(devfile: Devfile, tagFilter: string[], debugSupportFilter: boolean, deploySupportFilter: boolean): boolean { + // eslint-disable-next-line no-console + console.log('dep',deploySupportFilter); + // eslint-disable-next-line no-console + console.log('deg',debugSupportFilter); const includesDebugSupport = debugSupportFilter === false || debugSupportFilter === devfile.supportsDebug; const includesDeploySupport = deploySupportFilter === false || deploySupportFilter === devfile.supportsDeploy; const includesTags = tagFilter.length === 0 || devfile.tags.filter((_devfileTag) => { return tagFilter.find((_selectedTags) => _devfileTag === _selectedTags) !== undefined; }).length > 0; - return includesDebugSupport && includesDeploySupport && includesTags; - } + return includesDebugSupport && includesDeploySupport && includesTags; +} export function DevfileSearch(props: DevfileSearchProps) { const ITEMS_PER_PAGE = 6; @@ -499,14 +463,16 @@ export function DevfileSearch(props: DevfileSearchProps) { >([]); const [devfileCapabilities, setDevfileCapabilities] = React.useState([]); const [capabilityEnabled, setCapabilityEnabled] = React.useState< - { capabilityName: string; enabled: boolean }[] + { name: string; enabled: boolean }[] >([]); const [devfileTags, setDevfileTags] = React.useState([]); const [tagEnabled, setTagEnabled] = React.useState< - { tagName: string; enabled: boolean }[] + { name: string; enabled: boolean }[] >([]); const [searchText, setSearchText] = React.useState(''); + const [showMore, setShowMore] = React.useState(false); + function respondToMessage(messageEvent: MessageEvent) { const message = messageEvent.data as Message; switch (message.action) { @@ -543,8 +509,8 @@ export function DevfileSearch(props: DevfileSearchProps) { const enabledArray = []; for (const capability of devfileCapabilities) { enabledArray.push({ - capabilityName: capability, - enabled: false, // All values set to false means that no filter is to be applied + name: capability, + enabled: false // All values set to false means that no filter is to be applied }); } setCapabilityEnabled((_) => enabledArray); @@ -554,8 +520,8 @@ export function DevfileSearch(props: DevfileSearchProps) { const enabledArray = []; for (const tag of devfileTags) { enabledArray.push({ - tagName: tag, - enabled: false, // All values set to false means that no filter is to be applied + name: tag, + enabled: false // All values set to false means that no filter is to be applied }); } setTagEnabled((_) => enabledArray); @@ -592,11 +558,11 @@ export function DevfileSearch(props: DevfileSearchProps) { return ; } - if(!devfileCapabilities) { + if (!devfileCapabilities) { return ; } - if(!devfileTags) { + if (!devfileTags) { return ; } @@ -605,18 +571,18 @@ export function DevfileSearch(props: DevfileSearchProps) { .map((entry) => entry.registryName); const debugSupport = capabilityEnabled // - .filter((_cap) => _cap.capabilityName === 'Debug Support') // + .filter((_cap) => _cap.name === 'Debug Support') // .filter((_cap) => _cap.enabled) // .length > 0; const deploySupport = capabilityEnabled // - .filter((_cap) => _cap.capabilityName === 'Deploy Support') // + .filter((_cap) => _cap.name === 'Deploy Support') // .filter((_cap) => _cap.enabled) // .length > 0; const activeTags = tagEnabled .filter((_tag) => _tag.enabled) // - .map((_tag) => _tag.tagName); + .map((_tag) => _tag.name); const devfiles: Devfile[] = devfileRegistries // .filter((devfileRegistry) => activeRegistries.includes(devfileRegistry.name)) // @@ -654,15 +620,61 @@ export function DevfileSearch(props: DevfileSearchProps) { return ( <> - {props.titleText} - + + {(devfileCapabilities.length > 0 || devfileTags.length > 0) && ( + <> + + + Filter by + + + {devfileCapabilities.length > 0 && ( + <> + + + + )} + + + {devfileTags.length > 0 && ( + <> + + + Tags + + + + + { + setShowMore((prev) => !prev); + }} + > + {!showMore ? 'Show more' : 'Show less'} + + + + + )} + + )} {devfileRegistries.length > 1 && ( <> - + Devfile Registries - + )} - {(devfileCapabilities.length > 0 || devfileTags.length > 0) && ( - <> - - Filter by - - - {devfileCapabilities.length > 0 && ( - <> - - - - )} - {devfileTags.length > 0 && ( - - )} - - - )} - + } width="100%" > diff --git a/src/webview/devfile-registry/app/devfileRegistry.tsx b/src/webview/devfile-registry/app/devfileRegistry.tsx index eb90507d9..375f27507 100644 --- a/src/webview/devfile-registry/app/devfileRegistry.tsx +++ b/src/webview/devfile-registry/app/devfileRegistry.tsx @@ -36,7 +36,7 @@ export const DevfileRegistry = () => { return ( - + From 6fe2dd0e713f155b2cb7268a5f6bbe99929039af Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Tue, 28 Nov 2023 00:16:37 +0530 Subject: [PATCH 04/10] revert the change Signed-off-by: msivasubramaniaan --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index f45bad7fd..24e7dd207 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ indent_style = space indent_size = 4 # We recommend you to keep these unchanged -end_of_line = crlf +end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true From 54bdc065e910efc7be0a9ad4d2a22a883d469a10 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Thu, 30 Nov 2023 17:31:29 +0530 Subject: [PATCH 05/10] added clear all and other UI improvements Signed-off-by: msivasubramaniaan --- src/webview/common/devfileListItem.tsx | 40 ++++- src/webview/common/devfileSearch.tsx | 160 +++++++++++------- .../pages/createComponent.tsx | 4 +- .../devfile-registry/app/devfileRegistry.tsx | 2 +- 4 files changed, 136 insertions(+), 70 deletions(-) diff --git a/src/webview/common/devfileListItem.tsx b/src/webview/common/devfileListItem.tsx index 00da3c9c8..789c00128 100644 --- a/src/webview/common/devfileListItem.tsx +++ b/src/webview/common/devfileListItem.tsx @@ -3,7 +3,7 @@ * Licensed under the MIT License. See LICENSE file in the project root for license information. *-----------------------------------------------------------------------------------------------*/ import { Check } from '@mui/icons-material'; -import { Box, Chip, Stack, Tooltip, Typography } from '@mui/material'; +import { Box, Chip, Link, Stack, Tooltip, Typography } from '@mui/material'; import * as React from 'react'; import { Devfile } from '../common/devfile'; import DevfileLogo from '../../../images/context/devfile.png'; @@ -12,6 +12,7 @@ import validator from 'validator' export type DevfileListItemProps = { devfile: Devfile; buttonCallback?: () => void; + showFullDescription?: boolean; }; function checkedDevfileLogoUrl(logoUrl?: string) { @@ -38,11 +39,12 @@ export function DevfileListItem(props: DevfileListItemProps) { ) : ( <> - + )} @@ -50,6 +52,7 @@ export function DevfileListItem(props: DevfileListItemProps) { } function DevfileListContent(props: DevfileListItemProps) { + const [showMore, setShowMore] = React.useState(false); // for the width setting: // one unit of padding is 8px with the default MUI theme, and we add a margin on both sides return ( @@ -70,7 +73,7 @@ function DevfileListContent(props: DevfileListItemProps) { )} - - {props.devfile.description} - + + + {props.devfile.description} + + { + props.showFullDescription && props.devfile.description.length > 102 && { + setShowMore((prev) => !prev); + }} + > + {!showMore ? 'More' : 'Less'} + + } + { props.devfile.supportsDebug && void; + perPageCount: number; + devfilesLength: number; }) { return ( @@ -98,18 +100,25 @@ function SearchBar(props: { ), }} value={props.searchText} - sx={{ flexGrow: '1', maxWidth: '450px' }} + sx={{ flexGrow: '1', maxWidth: '650px' }} onChange={(event) => { props.setSearchText(event.target.value.toLowerCase()); }} /> - { - props.setCurrentPage(value); - }} - /> + + { + props.setCurrentPage(value); + }} + /> + + Showing items {(props.currentPage - 1) * props.perPageCount + 1} -{' '} + {Math.min(props.currentPage * props.perPageCount, props.devfilesLength)} of{' '} + {props.devfilesLength} + + ); } @@ -161,6 +170,23 @@ function RegistriesPicker(props: { ); } +/** + * sort the tags based on selection and alphabet order. + * + * @param tag + * @returns number + */ +function ascTag(oldTag: { name: string; enabled: boolean }, newTag: { name: string; enabled: boolean }) { + const oldTagEnabled = oldTag.enabled; + const newTagEnabled = newTag.enabled; + if (oldTagEnabled && !newTagEnabled) { + return -1; + } else if (newTagEnabled && !oldTagEnabled) { + return 1; + } + return oldTag.name.localeCompare(newTag.name); +} + function TagsPicker(props: { tagEnabled: { name: string; enabled: boolean }[]; setTagEnabled: React.Dispatch< @@ -174,7 +200,7 @@ function TagsPicker(props: { name: clickedRegistry, enabled: checked, }); - updatedList.sort((regA, regB) => regA.name.localeCompare(regB.name)); + updatedList.sort(ascTag); props.setTagEnabled(updatedList); } @@ -266,7 +292,7 @@ const SelectTemplateProject = React.forwardRef( top: '50%', left: '50%', width: isWideEnough ? '900px' : 'calc(100vw - 48px)', - maxHeight: 'calc(100vh - 48px)', + maxHeight: '100vh', transform: 'translate(-50%, -50%)', padding: 2, }} @@ -278,7 +304,7 @@ const SelectTemplateProject = React.forwardRef( alignItems="flex-start" marginBottom={1} > - + @@ -438,10 +464,6 @@ export type DevfileSearchProps = { * @returns */ function isToBeIncluded(devfile: Devfile, tagFilter: string[], debugSupportFilter: boolean, deploySupportFilter: boolean): boolean { - // eslint-disable-next-line no-console - console.log('dep',deploySupportFilter); - // eslint-disable-next-line no-console - console.log('deg',debugSupportFilter); const includesDebugSupport = debugSupportFilter === false || debugSupportFilter === devfile.supportsDebug; const includesDeploySupport = deploySupportFilter === false || deploySupportFilter === devfile.supportsDeploy; const includesTags = tagFilter.length === 0 || devfile.tags.filter((_devfileTag) => { @@ -452,7 +474,7 @@ function isToBeIncluded(devfile: Devfile, tagFilter: string[], debugSupportFilte } export function DevfileSearch(props: DevfileSearchProps) { - const ITEMS_PER_PAGE = 6; + const ITEMS_PER_PAGE = 8; const QUARKUS_REGEX = /[Qq]uarkus/; const [selectedDevfile, setSelectedDevfile] = React.useState(); @@ -516,7 +538,7 @@ export function DevfileSearch(props: DevfileSearchProps) { setCapabilityEnabled((_) => enabledArray); }, [devfileCapabilities]); - React.useEffect(() => { + const clearDevfileAll = () => { const enabledArray = []; for (const tag of devfileTags) { enabledArray.push({ @@ -525,7 +547,9 @@ export function DevfileSearch(props: DevfileSearchProps) { }); } setTagEnabled((_) => enabledArray); - }, [devfileTags]); + } + + React.useEffect(() => clearDevfileAll(), [devfileTags]); React.useEffect(() => { props.setSelectedDevfile(selectedDevfile); @@ -619,13 +643,17 @@ export function DevfileSearch(props: DevfileSearchProps) { return ( <> - - - + + + {(devfileCapabilities.length > 0 || devfileTags.length > 0) && ( <> - + Filter by @@ -641,54 +669,72 @@ export function DevfileSearch(props: DevfileSearchProps) { {devfileTags.length > 0 && ( <> - - + Tags - - { - setShowMore((prev) => !prev); - }} - > - {!showMore ? 'Show more' : 'Show less'} - - - + + + { + setShowMore((prev) => !prev); + if (showMore) { + const myDiv = document.getElementById('tags'); + myDiv.scrollTop = 0; + } + }} + > + {!showMore ? 'Show more' : 'Show less'} + + + { + activeTags.length > 0 && + + { + clearDevfileAll() + }} + > + Clear {activeTags.length > 1 ? 'all' : ''} + + + } + )} )} {devfileRegistries.length > 1 && ( <> - + + Devfile Registries - - - + )} - - - - - - + + + + 0.0001 ? 1 : 0) } + perPageCount={ITEMS_PER_PAGE} + devfilesLength={devfiles.length} /> {/* 320px is the approximate combined height of the top bar and bottom bar in the devfile search view */} {/* 5em is the padding at the top of the page */} } width="100%" > @@ -725,11 +773,6 @@ export function DevfileSearch(props: DevfileSearchProps) { ); })} - - Showing items {(currentPage - 1) * ITEMS_PER_PAGE + 1} -{' '} - {Math.min(currentPage * ITEMS_PER_PAGE, devfiles.length)} of{' '} - {devfiles.length} - @@ -751,6 +794,7 @@ export function DevfileSearch(props: DevfileSearchProps) { setSelectedDevfile(undefined); }} open={!!selectedDevfile} + disableScrollLock > @@ -157,7 +157,7 @@ export default function CreateComponent() { maxWidth="lg" sx={{ height: '100%', - paddingTop: '5em', + paddingTop: '1em', paddingBottom: '16px', }} > diff --git a/src/webview/devfile-registry/app/devfileRegistry.tsx b/src/webview/devfile-registry/app/devfileRegistry.tsx index 375f27507..e87b332e1 100644 --- a/src/webview/devfile-registry/app/devfileRegistry.tsx +++ b/src/webview/devfile-registry/app/devfileRegistry.tsx @@ -36,7 +36,7 @@ export const DevfileRegistry = () => { return ( - + From 7b455c04482e3cf8e3e5ee11dfb34121d5269006 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Sun, 3 Dec 2023 00:59:21 +0530 Subject: [PATCH 06/10] improve UI based on Mohit comment in the PR Signed-off-by: msivasubramaniaan --- .../common-ext/createComponentHelpers.ts | 110 +++++++++++------- src/webview/common/devfileExplanation.tsx | 4 +- src/webview/common/devfileListItem.tsx | 103 ++++++++-------- src/webview/common/devfileSearch.tsx | 49 ++++---- src/webview/common/fromTemplateProject.tsx | 3 + src/webview/common/vscode-theme.ts | 4 +- .../pages/createComponent.tsx | 1 + .../devfile-registry/app/devfileRegistry.tsx | 2 +- 8 files changed, 152 insertions(+), 124 deletions(-) diff --git a/src/webview/common-ext/createComponentHelpers.ts b/src/webview/common-ext/createComponentHelpers.ts index e548433dc..208478048 100644 --- a/src/webview/common-ext/createComponentHelpers.ts +++ b/src/webview/common-ext/createComponentHelpers.ts @@ -26,7 +26,7 @@ export async function isValidProjectFolder( if (!folder) { // Folder cannot be Undefined return { status: ValidationStatus.error, - message: 'Please specify a valid folder path' + message: 'Please specify a valid folder path' }; } @@ -98,7 +98,7 @@ async function canRecursivelyCreateProjectFolder( const folderPath = path.parse(folder); const root = folderPath.root; - // Reconstruct the folder to avoid having `/` (or `\` on Windows) at the end + // Reconstruct the folder to avoid having `/` (or `\` on Windows) at the end let parentFolder: string = path.join(folderPath.dir, folderPath.base).toString(); let parentFolderExists = false; while (parentFolder !== root && !parentFolderExists) { @@ -134,18 +134,18 @@ async function canRecursivelyCreateProjectFolder( * @param isComponentBasedValidation component based validation or not * @returns the validation message if the component name is invalid, and undefined otherwise */ -export function validateName(name: string, isComponentBasedValidation=true): string { - let validationMessage = NameValidator.emptyName(`Please enter a ${isComponentBasedValidation? 'component' : ''} name.`, name); +export function validateName(name: string, isComponentBasedValidation = true): string { + let validationMessage = NameValidator.emptyName(`Please enter a ${isComponentBasedValidation ? 'component' : ''} name.`, name); if (!validationMessage) { validationMessage = NameValidator.validateMatches( - `Not a valid ${isComponentBasedValidation? 'component' : ''} name. + `Not a valid ${isComponentBasedValidation ? 'component' : ''} name. Please use lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character`, name, ); } if (!validationMessage) { validationMessage = NameValidator.lengthName( - `${isComponentBasedValidation? 'Component name' : 'Name'} should be between 2-63 characters`, + `${isComponentBasedValidation ? 'Component name' : 'Name'} should be between 2-63 characters`, name, 0, ); @@ -204,38 +204,40 @@ export function getDevfileRegistries(): DevfileRegistry[] { (devfileRegistry) => format(devfileRegistry.url) === format(component.registry.url), ); - devfileRegistry.devfiles.push({ - description: component.description, - registryName: devfileRegistry.name, - logoUrl: component.devfileData.devfile.metadata.icon, - name: component.displayName, - id: component.name, - starterProjects: component.devfileData.devfile.starterProjects, - tags: component.tags, - yaml: JSYAML.dump(component.devfileData.devfile), - supportsDebug: - Boolean( - component.devfileData.devfile.commands?.find( - (command) => command.exec?.group?.kind === 'debug', + if (!component?.tags.some((value) => value.toLowerCase().includes('deprecate'))) { + devfileRegistry.devfiles.push({ + description: component.description, + registryName: devfileRegistry.name, + logoUrl: component.devfileData.devfile.metadata.icon, + name: component.displayName, + id: component.name, + starterProjects: component.devfileData.devfile.starterProjects, + tags: component.tags, + yaml: JSYAML.dump(component.devfileData.devfile), + supportsDebug: + Boolean( + component.devfileData.devfile.commands?.find( + (command) => command.exec?.group?.kind === 'debug', + ), + ) || + Boolean( + component.devfileData.devfile.commands?.find( + (command) => command.composite?.group?.kind === 'debug', + ), ), - ) || - Boolean( - component.devfileData.devfile.commands?.find( - (command) => command.composite?.group?.kind === 'debug', + supportsDeploy: + Boolean( + component.devfileData.devfile.commands?.find( + (command) => command.exec?.group?.kind === 'deploy', + ), + ) || + Boolean( + component.devfileData.devfile.commands?.find( + (command) => command.composite?.group?.kind === 'deploy', + ), ), - ), - supportsDeploy: - Boolean( - component.devfileData.devfile.commands?.find( - (command) => command.exec?.group?.kind === 'deploy', - ), - ) || - Boolean( - component.devfileData.devfile.commands?.find( - (command) => command.composite?.group?.kind === 'deploy', - ), - ), - } as Devfile); + } as Devfile); + } } devfileRegistries.sort((a, b) => (a.name < b.name ? -1 : 1)); return devfileRegistries; @@ -251,7 +253,7 @@ export function getDevfileRegistries(): DevfileRegistry[] { * @returns a list of the devfile capabilities */ export function getDevfileCapabilities(): string[] { - return [ 'Debug Support', 'Deploy Support']; + return ['Debug Support', 'Deploy Support']; } /** @@ -259,17 +261,35 @@ export function getDevfileCapabilities(): string[] { * * @returns a list of the devfile tags */ -export function getDevfileTags(url?:string ): string[] { +export function getDevfileTags(url?: string): string[] { const devfileRegistries = getDevfileRegistries(); const devfileTags: string[] = [ - ...new Set( - devfileRegistries - .filter((devfileRegistry) => url ? devfileRegistry.url === url : true) - .flatMap((_devfileRegistry) => _devfileRegistry.devfiles) - .flatMap((_devfile) => _devfile.tags)) - ] + ...new Set( + devfileRegistries + .filter((devfileRegistry) => url ? devfileRegistry.url === url : true) + .flatMap((_devfileRegistry) => _devfileRegistry.devfiles).sort(devfileSort) + .flatMap((_devfile) => _devfile.tags)) + ] + return devfileTags.filter((devfileTag) => !devfileTag.toLowerCase().includes('deprecate')) .sort((a, b) => a.localeCompare(b)); +} + +function devfileSort(a: Devfile, b: Devfile): number { + const QUARKUS_REGEX = /[Qq]uarkus/; + const aQuarkus = QUARKUS_REGEX.test(a.name); + const bQuarkus = QUARKUS_REGEX.test(b.name); + if (aQuarkus && !bQuarkus) { + return -1; + } else if (bQuarkus && !aQuarkus) { + return 1; + } + + if (a.supportsDebug && !b.supportsDebug) { + return -1; + } else if (b.supportsDebug && !a.supportsDebug) { + return 1; + } - return devfileTags; + return a.name < b.name ? -1 : 1; } diff --git a/src/webview/common/devfileExplanation.tsx b/src/webview/common/devfileExplanation.tsx index d42415f76..589cfcaac 100644 --- a/src/webview/common/devfileExplanation.tsx +++ b/src/webview/common/devfileExplanation.tsx @@ -2,13 +2,13 @@ * Copyright (c) Red Hat, Inc. All rights reserved. * Licensed under the MIT License. See LICENSE file in the project root for license information. *-----------------------------------------------------------------------------------------------*/ -import { Alert, AlertTitle } from '@mui/material'; +import { Alert } from '@mui/material'; import * as React from 'react'; export function DevfileExplanation() { return ( - DevfileA YAML file that contains information on how to deploy + Devfile: A YAML file that contains information on how to deploy your component to OpenShift, based on the language or framework that the project uses. ); diff --git a/src/webview/common/devfileListItem.tsx b/src/webview/common/devfileListItem.tsx index 789c00128..759c8af8e 100644 --- a/src/webview/common/devfileListItem.tsx +++ b/src/webview/common/devfileListItem.tsx @@ -3,7 +3,7 @@ * Licensed under the MIT License. See LICENSE file in the project root for license information. *-----------------------------------------------------------------------------------------------*/ import { Check } from '@mui/icons-material'; -import { Box, Chip, Link, Stack, Tooltip, Typography } from '@mui/material'; +import { Box, Chip, Stack, Tooltip, Typography } from '@mui/material'; import * as React from 'react'; import { Devfile } from '../common/devfile'; import DevfileLogo from '../../../images/context/devfile.png'; @@ -52,101 +52,96 @@ export function DevfileListItem(props: DevfileListItemProps) { } function DevfileListContent(props: DevfileListItemProps) { - const [showMore, setShowMore] = React.useState(false); // for the width setting: // one unit of padding is 8px with the default MUI theme, and we add a margin on both sides return ( - + - + {props.devfile.name} {props.devfile.registryName && ( - + from {props.devfile.registryName} )} + + + { + props.devfile.supportsDebug && } + color={'success'} + /> + } + { + props.devfile.supportsDeploy && } + color={'success'} + /> + } + {(props.devfile.tags && props.devfile.tags.map((tag, i) => { + if (i >= 4) { + return; + } + return ; + }))} + {(props.devfile.tags && props.devfile.tags.length > 4 && ( + + + + ))} + {props.devfile.description} - { - props.showFullDescription && props.devfile.description.length > 102 && { - setShowMore((prev) => !prev); - }} - > - {!showMore ? 'More' : 'Less'} - - } - - - { - props.devfile.supportsDebug && } - color={'success'} - /> - } - { - props.devfile.supportsDeploy && } - color={'success'} - /> - } - {(props.devfile.tags && props.devfile.tags.map((tag, i) => { - if (i >= 4) { - return; - } - return ; - }))} - {(props.devfile.tags && props.devfile.tags.length > 4 && ( - - - - ))} diff --git a/src/webview/common/devfileSearch.tsx b/src/webview/common/devfileSearch.tsx index f203a9a8f..f66c005b2 100644 --- a/src/webview/common/devfileSearch.tsx +++ b/src/webview/common/devfileSearch.tsx @@ -23,6 +23,7 @@ import { Select, Stack, TextField, + Theme, Tooltip, Typography, useMediaQuery @@ -31,7 +32,7 @@ import { every } from 'lodash'; import * as React from 'react'; import CopyToClipboard from 'react-copy-to-clipboard'; import SyntaxHighlighter from 'react-syntax-highlighter'; -import { monokai } from 'react-syntax-highlighter/dist/esm/styles/hljs'; +import { monokai, qtcreatorLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'; import { Devfile, DevfileRegistry, TemplateProjectIdentifier } from '../common/devfile'; import { DevfileExplanation } from './devfileExplanation'; import { DevfileListItem } from './devfileListItem'; @@ -83,29 +84,31 @@ function SearchBar(props: { return ( - + + ), endAdornment: ( props.setSearchText('')}> - + ), + disableUnderline: true }} value={props.searchText} - sx={{ flexGrow: '1', maxWidth: '650px' }} + sx={{ flexGrow: '1', maxWidth: '650px', py: 0, background: 'rgba(127, 127, 127, 8%)' }} onChange={(event) => { props.setSearchText(event.target.value.toLowerCase()); }} /> - + void; closeModal: () => void; - }, + theme: Theme; + } ) => { const [selectedTemplateProject, setSelectedTemplateProject] = React.useState(''); const [isInteracted, setInteracted] = React.useState(false); @@ -306,7 +310,7 @@ const SelectTemplateProject = React.forwardRef( > - + @@ -409,7 +413,7 @@ const SelectTemplateProject = React.forwardRef( void; + + theme?: Theme; }; /** @@ -474,7 +480,7 @@ function isToBeIncluded(devfile: Devfile, tagFilter: string[], debugSupportFilte } export function DevfileSearch(props: DevfileSearchProps) { - const ITEMS_PER_PAGE = 8; + const ITEMS_PER_PAGE = 12; const QUARKUS_REGEX = /[Qq]uarkus/; const [selectedDevfile, setSelectedDevfile] = React.useState(); @@ -644,11 +650,10 @@ export function DevfileSearch(props: DevfileSearchProps) { return ( <> - - + {(devfileCapabilities.length > 0 || devfileTags.length > 0) && ( <> @@ -680,12 +685,13 @@ export function DevfileSearch(props: DevfileSearchProps) { tagEnabled={tagEnabled} setTagEnabled={setTagEnabled} /> - + { setShowMore((prev) => !prev); if (showMore) { @@ -694,7 +700,7 @@ export function DevfileSearch(props: DevfileSearchProps) { } }} > - {!showMore ? 'Show more' : 'Show less'} + Show {!showMore ? 'more' : 'less'} { @@ -734,7 +740,7 @@ export function DevfileSearch(props: DevfileSearchProps) { - + } - width="100%" + width={'100%'} > {devfiles .slice( @@ -811,6 +817,7 @@ export function DevfileSearch(props: DevfileSearchProps) { closeModal={() => { setSelectedDevfile((_) => undefined); }} + theme = {props.theme} /> diff --git a/src/webview/common/fromTemplateProject.tsx b/src/webview/common/fromTemplateProject.tsx index 1f7491e66..179c0680f 100644 --- a/src/webview/common/fromTemplateProject.tsx +++ b/src/webview/common/fromTemplateProject.tsx @@ -7,12 +7,14 @@ import 'react-dom'; import { Devfile, TemplateProjectIdentifier } from './devfile'; import { DevfileSearch } from './devfileSearch'; import { SetNameAndFolder } from './setNameAndFolder'; +import { Theme } from '@mui/material'; type CurrentPage = 'selectTemplateProject' | 'setNameAndFolder'; type FromTemplateProjectProps = { titleText: string goHome?: () => void; + theme: Theme; }; type Message = { @@ -77,6 +79,7 @@ export function FromTemplateProject(props: FromTemplateProjectProps) { setSelectedTemplateProject={setSelectedProjectAndAdvance} titleText={props.titleText} goBack={props.goHome} + theme={props.theme} /> ); case 'setNameAndFolder': diff --git a/src/webview/common/vscode-theme.ts b/src/webview/common/vscode-theme.ts index 8029cc022..e56470db3 100644 --- a/src/webview/common/vscode-theme.ts +++ b/src/webview/common/vscode-theme.ts @@ -153,6 +153,8 @@ export function createVSCodeTheme(paletteMode: PaletteMode): Theme { defaultProps: { style: { whiteSpace: 'nowrap', + backgroundColor: computedStyle.getPropertyValue('--vscode-button-background'), + color: computedStyle.getPropertyValue('--vscode-button-foreground'), }, }, }, @@ -164,7 +166,7 @@ export function createVSCodeTheme(paletteMode: PaletteMode): Theme { }, style: { backgroundColor: computedStyle.getPropertyValue( - '--vscode-tab-border', + '--vscode-editor-background', ), }, }, diff --git a/src/webview/create-component/pages/createComponent.tsx b/src/webview/create-component/pages/createComponent.tsx index 65752513d..937c4df46 100644 --- a/src/webview/create-component/pages/createComponent.tsx +++ b/src/webview/create-component/pages/createComponent.tsx @@ -144,6 +144,7 @@ export default function CreateComponent() { goHome={() => { setCurrentView((_) => 'home'); }} + theme={theme} /> ); default: diff --git a/src/webview/devfile-registry/app/devfileRegistry.tsx b/src/webview/devfile-registry/app/devfileRegistry.tsx index e87b332e1..d41c53cbc 100644 --- a/src/webview/devfile-registry/app/devfileRegistry.tsx +++ b/src/webview/devfile-registry/app/devfileRegistry.tsx @@ -37,7 +37,7 @@ export const DevfileRegistry = () => { return ( - + ); From e6ebad7d96ef9fe064d71778c3fbc8b205805f2c Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Sun, 3 Dec 2023 01:08:41 +0530 Subject: [PATCH 07/10] reduced alert padding top and bottom Signed-off-by: msivasubramaniaan --- src/webview/common/devfileExplanation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webview/common/devfileExplanation.tsx b/src/webview/common/devfileExplanation.tsx index 589cfcaac..ab1c221ac 100644 --- a/src/webview/common/devfileExplanation.tsx +++ b/src/webview/common/devfileExplanation.tsx @@ -7,7 +7,7 @@ import * as React from 'react'; export function DevfileExplanation() { return ( - + Devfile: A YAML file that contains information on how to deploy your component to OpenShift, based on the language or framework that the project uses. From b2ca6998844152579dc807cfeb140d601f41c75e Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Sun, 3 Dec 2023 01:30:58 +0530 Subject: [PATCH 08/10] fix ui test case Signed-off-by: msivasubramaniaan --- test/ui/suite/devfileRegistries.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ui/suite/devfileRegistries.ts b/test/ui/suite/devfileRegistries.ts index 14da6f64f..83b442387 100644 --- a/test/ui/suite/devfileRegistries.ts +++ b/test/ui/suite/devfileRegistries.ts @@ -126,7 +126,7 @@ export function testDevfileRegistries() { // initialize web view editor const webView = new RegistryWebViewEditor('Devfile Registry - DefaultDevfileRegistry'); await webView.initializeEditor(); - expect(await webView.getRegistryStackNames()).to.include.members(['Quarkus Java', 'Django', 'Go Runtime', 'Maven Java', 'Node.js Runtime', 'Open Liberty Gradle']); + expect(await webView.getRegistryStackNames()).to.include.members(['Quarkus Java', 'Django', 'Maven Java', 'Node.js Runtime', 'Open Liberty Gradle']); }); after(async function context() { From eedcd3a53e8bf61dfc9ff20745c196fedc52fed8 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Sun, 3 Dec 2023 01:37:46 +0530 Subject: [PATCH 09/10] update tag sorting Signed-off-by: msivasubramaniaan --- src/webview/common-ext/createComponentHelpers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/webview/common-ext/createComponentHelpers.ts b/src/webview/common-ext/createComponentHelpers.ts index 208478048..72ec1b279 100644 --- a/src/webview/common-ext/createComponentHelpers.ts +++ b/src/webview/common-ext/createComponentHelpers.ts @@ -271,8 +271,7 @@ export function getDevfileTags(url?: string): string[] { .flatMap((_devfileRegistry) => _devfileRegistry.devfiles).sort(devfileSort) .flatMap((_devfile) => _devfile.tags)) ] - return devfileTags.filter((devfileTag) => !devfileTag.toLowerCase().includes('deprecate')) - .sort((a, b) => a.localeCompare(b)); + return devfileTags.filter((devfileTag) => !devfileTag.toLowerCase().includes('deprecate')); } function devfileSort(a: Devfile, b: Devfile): number { From f8775c5748eea818004aeaa4230db6fdf0466ab1 Mon Sep 17 00:00:00 2001 From: msivasubramaniaan Date: Mon, 4 Dec 2023 21:32:17 +0530 Subject: [PATCH 10/10] fixed tag unselect issue and moved devfile selection on top Signed-off-by: msivasubramaniaan --- .../common-ext/createComponentHelpers.ts | 23 +-- src/webview/common/devfileSearch.tsx | 190 ++++++++++-------- 2 files changed, 113 insertions(+), 100 deletions(-) diff --git a/src/webview/common-ext/createComponentHelpers.ts b/src/webview/common-ext/createComponentHelpers.ts index 72ec1b279..2f2ae1603 100644 --- a/src/webview/common-ext/createComponentHelpers.ts +++ b/src/webview/common-ext/createComponentHelpers.ts @@ -253,7 +253,7 @@ export function getDevfileRegistries(): DevfileRegistry[] { * @returns a list of the devfile capabilities */ export function getDevfileCapabilities(): string[] { - return ['Debug Support', 'Deploy Support']; + return ['Debug', 'Deploy']; } /** @@ -268,27 +268,8 @@ export function getDevfileTags(url?: string): string[] { ...new Set( devfileRegistries .filter((devfileRegistry) => url ? devfileRegistry.url === url : true) - .flatMap((_devfileRegistry) => _devfileRegistry.devfiles).sort(devfileSort) + .flatMap((_devfileRegistry) => _devfileRegistry.devfiles) .flatMap((_devfile) => _devfile.tags)) ] return devfileTags.filter((devfileTag) => !devfileTag.toLowerCase().includes('deprecate')); } - -function devfileSort(a: Devfile, b: Devfile): number { - const QUARKUS_REGEX = /[Qq]uarkus/; - const aQuarkus = QUARKUS_REGEX.test(a.name); - const bQuarkus = QUARKUS_REGEX.test(b.name); - if (aQuarkus && !bQuarkus) { - return -1; - } else if (bQuarkus && !aQuarkus) { - return 1; - } - - if (a.supportsDebug && !b.supportsDebug) { - return -1; - } else if (b.supportsDebug && !a.supportsDebug) { - return 1; - } - - return a.name < b.name ? -1 : 1; -} diff --git a/src/webview/common/devfileSearch.tsx b/src/webview/common/devfileSearch.tsx index f66c005b2..76896c9ba 100644 --- a/src/webview/common/devfileSearch.tsx +++ b/src/webview/common/devfileSearch.tsx @@ -52,6 +52,8 @@ type Message = { data: any; }; +const QUARKUS_REGEX = /[Qq]uarkus/; + function LinkButton(props: { href: string; disabled: boolean; onClick: () => void; children }) { return ( @@ -89,8 +91,8 @@ function SearchBar(props: { margin='normal' InputProps={{ startAdornment: ( - - + + ), endAdornment: ( @@ -180,14 +182,33 @@ function RegistriesPicker(props: { * @returns number */ function ascTag(oldTag: { name: string; enabled: boolean }, newTag: { name: string; enabled: boolean }) { - const oldTagEnabled = oldTag.enabled; - const newTagEnabled = newTag.enabled; - if (oldTagEnabled && !newTagEnabled) { + + //Priority order Quarkus, Java, Node.js and Python + const javaPriorites = ['Java', 'Maven']; + const nodeJsPriorities = ['Node.js', 'Next.js', 'Express']; + const pythonPriorities = ['Python', 'Django', 'Pip']; + + const aQuarkus = QUARKUS_REGEX.test(oldTag.name); + const bQuarkus = QUARKUS_REGEX.test(newTag.name); + + if (aQuarkus && !bQuarkus) { + return -1; + } else if (bQuarkus && !aQuarkus) { + return 1; + } else if (javaPriorites.includes(oldTag.name) && !javaPriorites.includes(newTag.name)) { + return -1; + } else if (!javaPriorites.includes(oldTag.name) && javaPriorites.includes(newTag.name)) { + return 1; + } else if (nodeJsPriorities.includes(oldTag.name) && !nodeJsPriorities.includes(newTag.name)) { + return -1; + } else if (!nodeJsPriorities.includes(oldTag.name) && nodeJsPriorities.includes(newTag.name)) { + return 1; + } else if (pythonPriorities.includes(oldTag.name) && !pythonPriorities.includes(newTag.name)) { return -1; - } else if (newTagEnabled && !oldTagEnabled) { + } else if (!pythonPriorities.includes(oldTag.name) && pythonPriorities.includes(newTag.name)) { return 1; } - return 0; + return oldTag.name.localeCompare(newTag.name); } function TagsPicker(props: { @@ -310,7 +331,7 @@ const SelectTemplateProject = React.forwardRef( > - + @@ -481,7 +502,6 @@ function isToBeIncluded(devfile: Devfile, tagFilter: string[], debugSupportFilte export function DevfileSearch(props: DevfileSearchProps) { const ITEMS_PER_PAGE = 12; - const QUARKUS_REGEX = /[Qq]uarkus/; const [selectedDevfile, setSelectedDevfile] = React.useState(); const [currentPage, setCurrentPage] = React.useState(1); @@ -552,7 +572,7 @@ export function DevfileSearch(props: DevfileSearchProps) { enabled: false // All values set to false means that no filter is to be applied }); } - setTagEnabled((_) => enabledArray); + setTagEnabled((_) => enabledArray.sort(ascTag)); } React.useEffect(() => clearDevfileAll(), [devfileTags]); @@ -601,12 +621,12 @@ export function DevfileSearch(props: DevfileSearchProps) { .map((entry) => entry.registryName); const debugSupport = capabilityEnabled // - .filter((_cap) => _cap.name === 'Debug Support') // + .filter((_cap) => _cap.name === 'Debug') // .filter((_cap) => _cap.enabled) // .length > 0; const deploySupport = capabilityEnabled // - .filter((_cap) => _cap.name === 'Deploy Support') // + .filter((_cap) => _cap.name === 'Deploy') // .filter((_cap) => _cap.enabled) // .length > 0; @@ -655,87 +675,99 @@ export function DevfileSearch(props: DevfileSearchProps) { height: 'calc(100vh - 100px)', overflow: 'scroll' }} spacing={0}> - {(devfileCapabilities.length > 0 || devfileTags.length > 0) && ( - <> + + Filter by + + + { + devfileRegistries.length > 1 && ( + <> + + Devfile Registries + + + + + ) + } + + { + devfileCapabilities.length > 0 && ( - - Filter by + + Support - {devfileCapabilities.length > 0 && ( - <> - - - - )} + { + devfileCapabilities.length > 0 && ( + <> + + + + ) + } - {devfileTags.length > 0 && ( - <> - - - Tags - - - - + ) + } + + { + devfileTags.length > 0 && ( + <> + + + Tags + + + + + + { + setShowMore((prev) => !prev); + if (showMore) { + const myDiv = document.getElementById('tags'); + myDiv.scrollTop = 0; + } + }} + > + Show {!showMore ? 'more' : 'less'} + + + { + activeTags.length > 0 && { - setShowMore((prev) => !prev); - if (showMore) { - const myDiv = document.getElementById('tags'); - myDiv.scrollTop = 0; - } + clearDevfileAll() }} > - Show {!showMore ? 'more' : 'less'} + Clear {activeTags.length > 1 ? 'all' : ''} - { - activeTags.length > 0 && - - { - clearDevfileAll() - }} - > - Clear {activeTags.length > 1 ? 'all' : ''} - - - } - - - )} - - )} - {devfileRegistries.length > 1 && ( - <> - - - Devfile Registries - - - - )} + } + + + ) + } @@ -817,7 +849,7 @@ export function DevfileSearch(props: DevfileSearchProps) { closeModal={() => { setSelectedDevfile((_) => undefined); }} - theme = {props.theme} + theme={props.theme} />