Skip to content

Commit

Permalink
fix(marketplace): align search/filter input with backstage/material-t…
Browse files Browse the repository at this point in the history
…able

Signed-off-by: Christoph Jerolimov <[email protected]>
  • Loading branch information
christoph-jerolimov committed Dec 10, 2024
1 parent a899b71 commit faec927
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 24 deletions.
6 changes: 1 addition & 5 deletions workspaces/marketplace/app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ catalog:
locations:
# Local example data, file locations are relative to the backend process, typically `packages/backend`
- type: file
target: ../../examples/all-org.yaml
target: ../../examples/all-orgs.yaml
rules:
- allow: [Group]
- type: file
Expand All @@ -91,10 +91,6 @@ catalog:
target: ../../examples/all-pluginlists.yaml
rules:
- allow: [PluginList]
- type: file
target: ../../examples/all-orgs.yaml
rules:
- allow: [User, Group]

- type: file
target: ../../examples/catalog-demo.yaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,33 @@
*/
import React from 'react';

import { useQueryParamState } from '@backstage/core-components';

import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';

import { MarketplaceCatalogGrid } from './MarketplaceCatalogGrid';
import { usePlugins } from '../hooks/usePlugins';
import { MarketplaceCatalogGrid } from './MarketplaceCatalogGrid';
import { SearchTextField } from './SearchTextField';

export const MarketplaceCatalogTab = () => {
const [search, setSearch] = useQueryParamState<string | undefined>('q');

const plugins = usePlugins();

return (
<Card>
<Box sx={{ p: 2 }}>
<Stack direction="row">
<Typography variant="h2" sx={{ pb: 2 }}>
<Stack gap={3} sx={{ p: 2 }}>
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
>
<Typography variant="h5">
All plugins
{plugins.data ? ` (${plugins.data.length})` : null}
</Typography>

{/* TODO: Align with Backstage UI */}
<TextField
value={search || ''}
onChange={event =>
setSearch(event.target.value ? event.target.value : undefined)
}
/>
<SearchTextField variant="filter" />
</Stack>
<MarketplaceCatalogGrid />
</Box>
</Stack>
</Card>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';

import { useQueryParamState } from '@backstage/core-components';

import FormControl from '@mui/material/FormControl';
import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import Tooltip from '@mui/material/Tooltip';
import IconButton from '@mui/material/IconButton';

import SearchIcon from '@mui/icons-material/Search';
import FilterIcon from '@mui/icons-material/FilterList';
import ClearIcon from '@mui/icons-material/Clear';

export interface SearchTextFieldProps {
variant: 'search' | 'filter';
filterValue?: string;
onFilterChanged?: (value: string | undefined) => void;
}

// TODO: extract this later into a shared package
export const SearchTextField = (props: SearchTextFieldProps) => {
const [queryParam, setQueryParam] = useQueryParamState<string | undefined>(
'q',
);

const labels =
props.variant === 'search'
? {
placeholder: 'Search',
clear: 'Clear Search',
}
: {
placeholder: 'Filter',
clear: 'Clear Filter',
};
const Icon = props.variant === 'search' ? SearchIcon : FilterIcon;

const value = props.filterValue || queryParam;
const onChange = (newValue: string | undefined) => {
if (props.onFilterChanged) {
props.onFilterChanged(newValue);
} else {
setQueryParam(newValue);
}
};

return (
<FormControl>
<TextField
variant="standard"
hiddenLabel
placeholder={labels.placeholder}
value={value}
onChange={event =>
onChange(event.target.value ? event.target.value : undefined)
}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Tooltip title={labels.placeholder}>
<Icon fontSize="small" />
</Tooltip>
</InputAdornment>
),
endAdornment: (
<InputAdornment position="end">
<IconButton
disabled={!value}
onClick={() => onChange(undefined)}
aria-label={labels.clear}
>
<ClearIcon fontSize="small" />
</IconButton>
</InputAdornment>
),
}}
inputProps={{
'aria-label': labels.placeholder,
}}
/>
</FormControl>
);
};

0 comments on commit faec927

Please sign in to comment.