Commit dc7b40af authored by Martin Wortschack's avatar Martin Wortschack

Merge branch '217943-vsa-filter-bar-app-skeleton' into 'master'

VSA filter bar app skeleton

See merge request gitlab-org/gitlab!34170
parents 60ba024c d6f4799c
...@@ -130,11 +130,13 @@ export default { ...@@ -130,11 +130,13 @@ export default {
return this.activeStages.length; return this.activeStages.length;
}, },
hasProject() { hasProject() {
return this.selectedProjectIds.length; return this.selectedProjectIds.length > 0;
}, },
}, },
mounted() { mounted() {
const { const {
labelsPath,
milestonesPath,
glFeatures: { glFeatures: {
cycleAnalyticsScatterplotEnabled: hasDurationChart, cycleAnalyticsScatterplotEnabled: hasDurationChart,
cycleAnalyticsScatterplotMedianEnabled: hasDurationChartMedian, cycleAnalyticsScatterplotMedianEnabled: hasDurationChartMedian,
...@@ -149,6 +151,8 @@ export default { ...@@ -149,6 +151,8 @@ export default {
hasPathNavigation, hasPathNavigation,
hasFilterBar, hasFilterBar,
}); });
this.setPaths({ labelsPath, milestonesPath });
}, },
methods: { methods: {
...mapActions([ ...mapActions([
...@@ -171,6 +175,7 @@ export default { ...@@ -171,6 +175,7 @@ export default {
'createStage', 'createStage',
'clearFormErrors', 'clearFormErrors',
]), ]),
...mapActions('filters', ['setPaths']),
onGroupSelect(group) { onGroupSelect(group) {
this.setSelectedGroup(group); this.setSelectedGroup(group);
this.fetchCycleAnalyticsData(); this.fetchCycleAnalyticsData();
...@@ -217,6 +222,7 @@ export default { ...@@ -217,6 +222,7 @@ export default {
}, },
maxDateRange: DATE_RANGE_LIMIT, maxDateRange: DATE_RANGE_LIMIT,
STAGE_ACTIONS, STAGE_ACTIONS,
commonFilterClasses: ['gl-display-flex gl-flex-direction-column gl-md-flex-direction-row'],
}; };
</script> </script>
<template> <template>
...@@ -236,11 +242,12 @@ export default { ...@@ -236,11 +242,12 @@ export default {
/> />
</div> </div>
<div <div
class="gl-display-flex gl-flex-direction-column gl-justify-content-space-between flex-lg-row" :class="$options.commonFilterClasses"
class="gl-justify-content-space-between gl-align-items-center"
> >
<groups-dropdown-filter <groups-dropdown-filter
v-if="!hideGroupDropDown" v-if="!hideGroupDropDown"
class="js-groups-dropdown-filter mr-0 mr-lg-2" class="js-groups-dropdown-filter"
:query-params="$options.groupsQueryParams" :query-params="$options.groupsQueryParams"
:default-group="selectedGroup" :default-group="selectedGroup"
@selected="onGroupSelect" @selected="onGroupSelect"
...@@ -248,7 +255,7 @@ export default { ...@@ -248,7 +255,7 @@ export default {
<projects-dropdown-filter <projects-dropdown-filter
v-if="shouldDisplayFilters" v-if="shouldDisplayFilters"
:key="selectedGroup.id" :key="selectedGroup.id"
class="js-projects-dropdown-filter my-2 my-lg-0" class="js-projects-dropdown-filter gl-ml-0"
:group-id="selectedGroup.id" :group-id="selectedGroup.id"
:query-params="$options.projectsQueryParams" :query-params="$options.projectsQueryParams"
:multi-select="$options.multiProjectSelect" :multi-select="$options.multiProjectSelect"
...@@ -257,12 +264,13 @@ export default { ...@@ -257,12 +264,13 @@ export default {
/> />
<filter-bar <filter-bar
v-if="featureFlags.hasFilterBar" v-if="featureFlags.hasFilterBar"
class="js-filter-bar filtered-search-box mx-2 gl-display-none" class="js-filter-bar filtered-search-box gl-display-flex gl-mt-3 mt-md-0 mx-2"
:disabled="!hasProject" :disabled="!hasProject"
/> />
<div <div
v-if="shouldDisplayFilters" v-if="shouldDisplayFilters"
class="ml-0 ml-md-auto mt-2 mt-md-0 d-flex flex-column flex-md-row align-items-md-center justify-content-md-end" :class="$options.commonFilterClasses"
class="gl-justify-content-end gl-white-space-nowrap"
> >
<date-range <date-range
:start-date="startDate" :start-date="startDate"
......
<script> <script>
import { mapState } from 'vuex';
import { GlFilteredSearch } from '@gitlab/ui';
export default { export default {
name: 'FilterBar', name: 'FilterBar',
components: {}, components: {
GlFilteredSearch,
},
props: { props: {
disabled: { disabled: {
type: Boolean, type: Boolean,
...@@ -9,8 +14,22 @@ export default { ...@@ -9,8 +14,22 @@ export default {
default: false, default: false,
}, },
}, },
data() {
return {
searchTerms: [],
};
},
computed: {
...mapState('filters', ['milestonesPath', 'labelsPath']),
},
}; };
</script> </script>
<template> <template>
<div></div> <gl-filtered-search
:disabled="disabled"
:v-model="searchTerms"
:placeholder="__('Filter results')"
:clear-button-title="__('Clear')"
:close-button-title="__('Close')"
/>
</template> </template>
...@@ -16,7 +16,6 @@ export default () => { ...@@ -16,7 +16,6 @@ export default () => {
} = el.dataset; } = el.dataset;
const initialData = buildCycleAnalyticsInitialData(el.dataset); const initialData = buildCycleAnalyticsInitialData(el.dataset);
const store = createStore(); const store = createStore();
store.dispatch('initializeCycleAnalytics', initialData); store.dispatch('initializeCycleAnalytics', initialData);
......
...@@ -7,6 +7,7 @@ import state from './state'; ...@@ -7,6 +7,7 @@ import state from './state';
import customStages from './modules/custom_stages/index'; import customStages from './modules/custom_stages/index';
import durationChart from './modules/duration_chart/index'; import durationChart from './modules/duration_chart/index';
import typeOfWork from './modules/type_of_work/index'; import typeOfWork from './modules/type_of_work/index';
import filters from './modules/filters/index';
Vue.use(Vuex); Vue.use(Vuex);
...@@ -16,5 +17,5 @@ export default () => ...@@ -16,5 +17,5 @@ export default () =>
getters, getters,
mutations, mutations,
state, state,
modules: { customStages, durationChart, typeOfWork }, modules: { customStages, durationChart, typeOfWork, filters },
}); });
import * as types from './mutation_types';
// eslint-disable-next-line import/prefer-default-export
export const setPaths = ({ commit }, { milestonesPath = '', labelsPath = '' }) => {
commit(types.SET_MILESTONES_PATH, milestonesPath);
commit(types.SET_LABELS_PATH, labelsPath);
};
import state from './state';
import * as actions from './actions';
import mutations from './mutations';
export default {
namespaced: true,
actions,
mutations,
state: state(),
};
export const SET_MILESTONES_PATH = 'SET_MILESTONES_PATH';
export const SET_LABELS_PATH = 'SET_LABELS_PATH';
import * as types from './mutation_types';
export default {
[types.SET_MILESTONES_PATH](state, milestonesPath) {
state.milestonesPath = milestonesPath;
},
[types.SET_LABELS_PATH](state, labelsPath) {
state.labelsPath = labelsPath;
},
};
export default () => ({
milestonesPath: '',
labelsPath: '',
});
import testAction from 'helpers/vuex_action_helper';
import * as actions from 'ee/analytics/cycle_analytics/store/modules/filters/actions';
import * as types from 'ee/analytics/cycle_analytics/store/modules/filters/mutation_types';
describe('Filters actions', () => {
let state;
beforeEach(() => {
state = {};
});
describe('setPaths', () => {
it('dispatches error', () => {
return testAction(
actions.setPaths,
{
milestonesPath: 'milestones_path',
labelsPath: 'labels_path',
},
state,
[
{ payload: 'milestones_path', type: types.SET_MILESTONES_PATH },
{ payload: 'labels_path', type: types.SET_LABELS_PATH },
],
[],
);
});
});
});
import mutations from 'ee/analytics/cycle_analytics/store/modules/filters/mutations';
import * as types from 'ee/analytics/cycle_analytics/store/modules/filters/mutation_types';
let state = null;
describe('Filters mutations', () => {
beforeEach(() => {
state = {};
});
afterEach(() => {
state = null;
});
it.each`
mutation | stateKey | value
${types.SET_MILESTONES_PATH} | ${'milestonesPath'} | ${'new-milestone-path'}
${types.SET_LABELS_PATH} | ${'labelsPath'} | ${'new-label-path'}
`('$mutation will set $stateKey=$value', ({ mutation, stateKey, value }) => {
mutations[mutation](state, value);
expect(state[stateKey]).toEqual(value);
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment