Skip to content

Commit

Permalink
feat(widget-builder): Add filters bar to widget builder (#81467)
Browse files Browse the repository at this point in the history
Adding the same filters bar that's on the dashboards detail page to the
slide-out. Not connected with any hooks yet. It automatically has url
query parameter functionality built in so that works without hooks. It
looks like this so far:

<img width="1507" alt="image"
src="https://github.com/user-attachments/assets/5b6f817c-69a9-4dd6-ac09-4f9697de07fa">
  • Loading branch information
nikkikapadia authored Nov 29, 2024
1 parent cf5b4d2 commit 9bd46be
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
import PageFiltersContainer from 'sentry/components/organizations/pageFilters/container';
import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
import {DEFAULT_STATS_PERIOD} from 'sentry/constants';
import {ReleasesProvider} from 'sentry/utils/releases/releasesProvider';
import useOrganization from 'sentry/utils/useOrganization';
import usePageFilters from 'sentry/utils/usePageFilters';
import ReleasesSelectControl from 'sentry/views/dashboards/releasesSelectControl';

function WidgetBuilderFilterBar() {
const organization = useOrganization();
const {selection} = usePageFilters();
return (
<PageFiltersContainer
disablePersistence
defaultSelection={{
datetime: {
start: null,
end: null,
utc: false,
period: DEFAULT_STATS_PERIOD,
},
}}
>
<PageFilterBar>
<ProjectPageFilter disabled onChange={() => {}} />
<EnvironmentPageFilter disabled onChange={() => {}} />
<DatePageFilter disabled onChange={() => {}} />
<ReleasesProvider organization={organization} selection={selection}>
<ReleasesSelectControl
isDisabled
handleChangeFilter={() => {}}
selectedReleases={[]}
/>
</ReleasesProvider>
</PageFilterBar>
</PageFiltersContainer>
);
}

export default WidgetBuilderFilterBar;
Original file line number Diff line number Diff line change
@@ -1,14 +1,74 @@
import {initializeOrg} from 'sentry-test/initializeOrg';
import {render, screen} from 'sentry-test/reactTestingLibrary';

import OrganizationStore from 'sentry/stores/organizationStore';
import PageFiltersStore from 'sentry/stores/pageFiltersStore';
import ProjectsStore from 'sentry/stores/projectsStore';
import DevWidgetBuilder from 'sentry/views/dashboards/widgetBuilder/components/newWidgetBuilder';

const {organization, projects, router} = initializeOrg({
organization: {features: ['global-views', 'open-membership']},
projects: [
{id: '1', slug: 'project-1', isMember: true},
{id: '2', slug: 'project-2', isMember: true},
{id: '3', slug: 'project-3', isMember: false},
],
router: {
location: {
pathname: '/organizations/org-slug/dashboard/1/',
query: {project: '-1'},
},
params: {},
},
});

describe('NewWidgetBuiler', function () {
const onCloseMock = jest.fn();

beforeEach(function () {
OrganizationStore.init();

PageFiltersStore.init();
PageFiltersStore.onInitializeUrlState(
{
projects: [],
environments: [],
datetime: {start: null, end: null, period: '14d', utc: null},
},
new Set(['projects'])
);

OrganizationStore.onUpdate(organization, {replace: true});
ProjectsStore.loadInitialData(projects);

MockApiClient.addMockResponse({
url: '/organizations/org-slug/releases/',
body: [],
});

MockApiClient.addMockResponse({
url: '/organizations/org-slug/dashboard/1/',
body: [],
});
});

afterEach(() => PageFiltersStore.reset());

it('renders', async function () {
render(<DevWidgetBuilder isOpen onClose={onCloseMock} />);
render(<DevWidgetBuilder isOpen onClose={onCloseMock} />, {
router,
organization,
});

expect(await screen.findByText('Create Custom Widget')).toBeInTheDocument();

expect(await screen.findByLabelText('Close Widget Builder')).toBeInTheDocument();

expect(await screen.findByRole('button', {name: 'All Projects'})).toBeInTheDocument();
expect(await screen.findByRole('button', {name: 'All Envs'})).toBeInTheDocument();
expect(await screen.findByRole('button', {name: '14D'})).toBeInTheDocument();
expect(await screen.findByRole('button', {name: 'All Releases'})).toBeInTheDocument();

expect(await screen.findByText('TEST WIDGET')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ type DevWidgetBuilderProps = {
function DevWidgetBuilder({isOpen, onClose}: DevWidgetBuilderProps) {
const escapeKeyPressed = useKeyPress('Escape');

// TODO(nikki): be able to handle clicking outside widget to close

useEffect(() => {
if (escapeKeyPressed) {
if (isOpen) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import SlideOverPanel from 'sentry/components/slideOverPanel';
import {IconClose} from 'sentry/icons';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import WidgetBuilderFilterBar from 'sentry/views/dashboards/widgetBuilder/components/filtersBar';

type WidgetBuilderSlideoutProps = {
isOpen: boolean;
onClose: () => void;
};

export default WidgetBuilderSlideout;

function WidgetBuilderSlideout({isOpen, onClose}: WidgetBuilderSlideoutProps) {
return (
<SlideOverPanel collapsed={!isOpen} slidePosition="left">
Expand All @@ -29,22 +28,36 @@ function WidgetBuilderSlideout({isOpen, onClose}: WidgetBuilderSlideoutProps) {
{t('Close')}
</CloseButton>
</SlideoutHeaderWrapper>
<SlideoutBodyWrapper>
<WidgetBuilderFilterBar />
</SlideoutBodyWrapper>
</SlideOverPanel>
);
}

export default WidgetBuilderSlideout;

const CloseButton = styled(Button)`
color: ${p => p.theme.gray300};
height: fit-content;
&:hover {
color: ${p => p.theme.gray400};
}
z-index: 100;
`;

const SlideoutTitle = styled('h5')``;
const SlideoutTitle = styled('h5')`
margin: 0;
`;

const SlideoutHeaderWrapper = styled('div')`
padding: ${space(4)};
padding: ${space(3)} ${space(4)};
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid ${p => p.theme.border};
`;

const SlideoutBodyWrapper = styled('div')`
padding: ${space(4)};
`;

0 comments on commit 9bd46be

Please sign in to comment.