Просмотр исходного кода

feat(pageFilters): Add pinned state to store (#31199)

Evan Purkhiser 3 лет назад
Родитель
Сommit
77bf461ecf

+ 7 - 0
static/app/actionCreators/pageFilters.tsx

@@ -21,6 +21,7 @@ import {
   MinimalProject,
   Organization,
   PageFilters,
+  PinnedPageFilter,
   Project,
 } from 'sentry/types';
 import {defined} from 'sentry/utils';
@@ -294,6 +295,12 @@ export function updateEnvironments(
   updateParams({environment}, router, options);
 }
 
+export function pinFilter(filter: PinnedPageFilter, pin: boolean) {
+  PageFiltersActions.pin(filter, pin);
+
+  // TODO: Persist into storage
+}
+
 /**
  * Updates router/URL with new query params
  *

+ 1 - 0
static/app/actions/pageFiltersActions.tsx

@@ -7,6 +7,7 @@ const PageFiltersActions = Reflux.createActions([
   'updateProjects',
   'updateDateTime',
   'updateEnvironments',
+  'pin',
 ]);
 
 export default PageFiltersActions;

+ 18 - 3
static/app/stores/pageFiltersStore.tsx

@@ -3,19 +3,21 @@ import Reflux from 'reflux';
 
 import PageFiltersActions from 'sentry/actions/pageFiltersActions';
 import {getDefaultSelection} from 'sentry/components/organizations/pageFilters/utils';
-import {Organization, PageFilters} from 'sentry/types';
+import {Organization, PageFilters, PinnedPageFilter} from 'sentry/types';
 import {isEqualWithDates} from 'sentry/utils/isEqualWithDates';
 
 import {CommonStoreInterface} from './types';
 
 type State = {
   selection: PageFilters;
+  pinnedFilters: Set<PinnedPageFilter>;
   organization: Organization | null;
   isReady: boolean;
 };
 
 type Internals = {
   selection: PageFilters;
+  pinnedFilters: Set<PinnedPageFilter>;
   hasInitialState: boolean;
   organization: Organization | null;
 };
@@ -28,10 +30,12 @@ type PageFiltersStoreInterface = CommonStoreInterface<State> & {
   updateProjects(projects: PageFilters['projects'], environments: null | string[]): void;
   updateDateTime(datetime: PageFilters['datetime']): void;
   updateEnvironments(environments: string[]): void;
+  pin(filter: PinnedPageFilter, pin: boolean): void;
 };
 
 const storeConfig: Reflux.StoreDefinition & Internals & PageFiltersStoreInterface = {
   selection: getDefaultSelection(),
+  pinnedFilters: new Set(),
   hasInitialState: false,
   organization: null,
 
@@ -43,6 +47,7 @@ const storeConfig: Reflux.StoreDefinition & Internals & PageFiltersStoreInterfac
     this.listenTo(PageFiltersActions.updateProjects, this.updateProjects);
     this.listenTo(PageFiltersActions.updateDateTime, this.updateDateTime);
     this.listenTo(PageFiltersActions.updateEnvironments, this.updateEnvironments);
+    this.listenTo(PageFiltersActions.pin, this.pin);
   },
 
   reset(selection) {
@@ -65,9 +70,9 @@ const storeConfig: Reflux.StoreDefinition & Internals & PageFiltersStoreInterfac
 
   getState() {
     const isReady = this._hasInitialState;
-    const {selection, organization} = this;
+    const {selection, pinnedFilters, organization} = this;
 
-    return {selection, isReady, organization};
+    return {selection, pinnedFilters, isReady, organization};
   },
 
   onReset() {
@@ -111,6 +116,16 @@ const storeConfig: Reflux.StoreDefinition & Internals & PageFiltersStoreInterfac
     };
     this.trigger(this.getState());
   },
+
+  pin(filter, pin) {
+    if (pin) {
+      this.pinnedFilters.add(filter);
+    } else {
+      this.pinnedFilters.delete(filter);
+    }
+
+    this.trigger(this.getState());
+  },
 };
 
 const PageFiltersStore = Reflux.createStore(storeConfig) as Reflux.Store &

+ 5 - 0
static/app/types/core.tsx

@@ -80,6 +80,11 @@ export const DataCategoryName = {
 export type RelativePeriod = keyof typeof DEFAULT_RELATIVE_PERIODS;
 export type IntervalPeriod = ReturnType<typeof getInterval>;
 
+/**
+ * Represents a pinned page filter sentinel value
+ */
+export type PinnedPageFilter = 'projects' | 'environments' | 'datetime';
+
 export type PageFilters = {
   /**
    * Currently selected Project IDs

+ 4 - 0
tests/js/spec/components/organizations/globalSelectionHeader.spec.jsx

@@ -313,6 +313,7 @@ describe('GlobalSelectionHeader', function () {
     expect(PageFiltersStore.getState()).toEqual({
       organization,
       isReady: true,
+      pinnedFilters: new Set(),
       selection: {
         datetime: {
           period: '14d',
@@ -341,6 +342,7 @@ describe('GlobalSelectionHeader', function () {
     expect(PageFiltersStore.getState()).toEqual({
       organization,
       isReady: true,
+      pinnedFilters: new Set(),
       selection: {
         datetime: {
           period: '14d',
@@ -368,6 +370,7 @@ describe('GlobalSelectionHeader', function () {
     expect(PageFiltersStore.getState()).toEqual({
       organization,
       isReady: true,
+      pinnedFilters: new Set(),
       selection: {
         datetime: {
           period: '14d',
@@ -414,6 +417,7 @@ describe('GlobalSelectionHeader', function () {
     expect(PageFiltersStore.getState()).toEqual({
       organization,
       isReady: true,
+      pinnedFilters: new Set(),
       selection: {
         datetime: {
           period: '7d',

+ 19 - 0
tests/js/spec/stores/pageFiltersStore.spec.jsx

@@ -1,4 +1,5 @@
 import {
+  pinFilter,
   updateDateTime,
   updateEnvironments,
   updateProjects,
@@ -19,6 +20,7 @@ describe('PageFiltersStore', function () {
     expect(PageFiltersStore.getState()).toEqual({
       organization: null,
       isReady: false,
+      pinnedFilters: new Set(),
       selection: {
         projects: [],
         environments: [],
@@ -84,4 +86,21 @@ describe('PageFiltersStore', function () {
     await tick();
     expect(PageFiltersStore.getState().selection.environments).toEqual(['alpha']);
   });
+
+  it('can mark filters as pinned', async function () {
+    expect(PageFiltersStore.getState().pinnedFilters).toEqual(new Set());
+    pinFilter('projects', true);
+    await tick();
+    expect(PageFiltersStore.getState().pinnedFilters).toEqual(new Set(['projects']));
+
+    pinFilter('environments', true);
+    await tick();
+    expect(PageFiltersStore.getState().pinnedFilters).toEqual(
+      new Set(['projects', 'environments'])
+    );
+
+    pinFilter('projects', false);
+    await tick();
+    expect(PageFiltersStore.getState().pinnedFilters).toEqual(new Set(['environments']));
+  });
 });