Commit 4b353e8d authored by Adam Hegyi's avatar Adam Hegyi

Similarity search in projects dropdown

parent 83d8d7b1
......@@ -5,7 +5,7 @@ import { featureAccessLevel } from '~/pages/projects/shared/permissions/constant
import { PROJECTS_PER_PAGE, STAGE_ACTIONS } from '../constants';
import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue';
import ProjectsDropdownFilter from '../../shared/components/projects_dropdown_filter.vue';
import { LAST_ACTIVITY_AT, DATE_RANGE_LIMIT } from '../../shared/constants';
import { SIMILARITY_ORDER, LAST_ACTIVITY_AT, DATE_RANGE_LIMIT } from '../../shared/constants';
import DateRange from '../../shared/components/daterange.vue';
import StageTable from './stage_table.vue';
import DurationChart from './duration_chart.vue';
......@@ -143,6 +143,16 @@ export default {
hasProject() {
return this.selectedProjectIds.length > 0;
},
projectsQueryParams() {
return {
per_page: PROJECTS_PER_PAGE,
with_shared: false,
order_by: this.featureFlags.hasAnalyticsSimilaritySearch
? SIMILARITY_ORDER
: LAST_ACTIVITY_AT,
include_subgroups: true,
};
},
},
methods: {
......@@ -203,12 +213,6 @@ export default {
groupsQueryParams: {
min_access_level: featureAccessLevel.EVERYONE,
},
projectsQueryParams: {
per_page: PROJECTS_PER_PAGE,
with_shared: false,
order_by: LAST_ACTIVITY_AT,
include_subgroups: true,
},
maxDateRange: DATE_RANGE_LIMIT,
STAGE_ACTIONS,
};
......@@ -252,7 +256,7 @@ export default {
:key="selectedGroup.id"
class="js-projects-dropdown-filter project-select"
:group-id="selectedGroup.id"
:query-params="$options.projectsQueryParams"
:query-params="projectsQueryParams"
:multi-select="$options.multiProjectSelect"
:default-projects="selectedProjects"
@selected="onProjectsSelect"
......
......@@ -18,6 +18,7 @@ export default () => {
valueStreamAnalyticsPathNavigation: hasPathNavigation = false,
valueStreamAnalyticsFilterBar: hasFilterBar = false,
valueStreamAnalyticsCreateMultipleValueStreams: hasCreateMultipleValueStreams = false,
analyticsSimilaritySearch: hasAnalyticsSimilaritySearch = false,
} = gon?.features;
store.dispatch('initializeCycleAnalytics', {
......@@ -28,6 +29,7 @@ export default () => {
hasPathNavigation,
hasFilterBar,
hasCreateMultipleValueStreams,
hasAnalyticsSimilaritySearch,
},
});
......
<script>
import { mapState, mapActions } from 'vuex';
import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ProjectsDropdownFilter from '../../shared/components/projects_dropdown_filter.vue';
import { accessLevelReporter, projectsPerPage } from '../constants';
import { LAST_ACTIVITY_AT } from '../../shared/constants';
import { SIMILARITY_ORDER, LAST_ACTIVITY_AT } from '../../shared/constants';
export default {
components: {
GroupsDropdownFilter,
ProjectsDropdownFilter,
},
mixins: [glFeatureFlagsMixin()],
props: {
group: {
type: Object,
......@@ -40,6 +42,14 @@ export default {
projects() {
return this.project && Object.keys(this.project).length ? [this.project] : null;
},
projectsQueryParams() {
return {
per_page: projectsPerPage,
with_shared: false, // exclude forks
order_by: this.glFeatures.analyticsSimilaritySearch ? SIMILARITY_ORDER : LAST_ACTIVITY_AT,
include_subgroups: true,
};
},
},
methods: {
...mapActions('filters', ['setGroupNamespace', 'setProjectPath']),
......@@ -69,12 +79,6 @@ export default {
groupsQueryParams: {
min_access_level: accessLevelReporter,
},
projectsQueryParams: {
per_page: projectsPerPage,
with_shared: false, // exclude forks
order_by: LAST_ACTIVITY_AT,
include_subgroups: true,
},
};
</script>
......@@ -92,7 +96,7 @@ export default {
:key="groupId"
class="project-select"
:default-projects="projects"
:query-params="$options.projectsQueryParams"
:query-params="projectsQueryParams"
:group-id="groupId"
@selected="onProjectsSelected"
/>
......
......@@ -16,6 +16,8 @@ export const scatterChartLineProps = {
export const LAST_ACTIVITY_AT = 'last_activity_at';
export const SIMILARITY_ORDER = 'similarity';
export const DATE_RANGE_LIMIT = 180;
export const OFFSET_DATE_BY_ONE = 1;
......
......@@ -17,6 +17,7 @@ class Analytics::CycleAnalyticsController < Analytics::ApplicationController
push_frontend_feature_flag(:value_stream_analytics_path_navigation, @group)
push_frontend_feature_flag(:value_stream_analytics_filter_bar, @group)
push_frontend_feature_flag(:value_stream_analytics_create_multiple_value_streams, @group)
push_frontend_feature_flag(:analytics_similarity_search, @group)
end
private
......
......@@ -19,6 +19,7 @@ module Analytics
before_action -> {
push_frontend_feature_flag(:productivity_analytics_scatterplot_enabled, default_enabled: true)
push_frontend_feature_flag(:analytics_similarity_search, @group)
}
before_action :validate_params, only: :show, if: -> { request.format.json? }
......
......@@ -19,6 +19,7 @@ class Groups::Analytics::ProductivityAnalyticsController < Groups::Analytics::Ap
}
before_action -> {
push_frontend_feature_flag(:productivity_analytics_scatterplot_enabled, default_enabled: true)
push_frontend_feature_flag(:analytics_similarity_search, @group)
}
before_action :validate_params, only: :show, if: -> { request.format.json? }
......
......@@ -21,7 +21,8 @@ RSpec.describe 'Group value stream analytics' do
cycleAnalyticsScatterplotEnabled: true,
cycleAnalyticsScatterplotMedianEnabled: true,
valueStreamAnalyticsPathNavigation: true,
valueStreamAnalyticsFilterBar: true
valueStreamAnalyticsFilterBar: true,
analyticsSimilaritySearch: true
)
end
......
......@@ -304,13 +304,32 @@ describe('Cycle Analytics component', () => {
expect(wrapper.find(ProjectsDropdownFilter).props()).toEqual(
expect.objectContaining({
queryParams: wrapper.vm.$options.projectsQueryParams,
queryParams: wrapper.vm.projectsQueryParams,
groupId: mockData.group.id,
multiSelect: wrapper.vm.$options.multiProjectSelect,
}),
);
});
describe('when analyticsSimilaritySearch feature flag is on', () => {
beforeEach(() => {
wrapper = createComponent({
withStageSelected: true,
featureFlags: {
hasAnalyticsSimilaritySearch: true,
},
});
});
it('uses similarity as the order param', () => {
displaysProjectsDropdownFilter(true);
expect(wrapper.find(ProjectsDropdownFilter).props().queryParams.order_by).toEqual(
'similarity',
);
});
});
it('displays the date range picker', () => {
displaysDateRangePicker(true);
});
......
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