Pass pipelines count to on-demands scans app

This brings the on-demand scans app closer to its meaningful
implementation state. Instead of relying on hardcoded state properties,
we are now passing the actual pipelines count to the app.
parent e111069e
......@@ -6,14 +6,7 @@ import { HELP_PAGE_PATH } from '../constants';
import AllTab from './tabs/all.vue';
import EmptyState from './empty_state.vue';
const TABS = {
all: {
component: AllTab,
},
};
export default {
TABS,
HELP_PAGE_PATH,
components: {
GlButton,
......@@ -25,16 +18,33 @@ export default {
EmptyState,
},
inject: ['newDastScanPath'],
props: {
pipelinesCount: {
type: Number,
required: false,
default: 0,
},
},
data() {
return {
activeTabIndex: 0,
hasData: false,
};
},
computed: {
hasData() {
return this.pipelinesCount > 0;
},
tabs() {
return {
all: {
component: AllTab,
itemsCount: this.pipelinesCount,
},
};
},
activeTab: {
set(newTabIndex) {
const newTabId = Object.keys(TABS)[newTabIndex];
const newTabId = Object.keys(this.tabs)[newTabIndex];
if (this.$route.params.tabId !== newTabId) {
this.$router.push(`/${newTabId}`);
}
......@@ -46,7 +56,7 @@ export default {
},
},
created() {
const tabIndex = Object.keys(TABS).findIndex((tab) => tab === this.$route.params.tabId);
const tabIndex = Object.keys(this.tabs).findIndex((tab) => tab === this.$route.params.tabId);
if (tabIndex !== -1) {
this.activeTabIndex = tabIndex;
}
......@@ -81,12 +91,7 @@ export default {
</gl-sprintf>
</template>
<gl-tabs v-model="activeTab">
<component
:is="tab.component"
v-for="(tab, key) in $options.TABS"
:key="key"
:item-count="0"
/>
<component :is="tab.component" v-for="(tab, key) in tabs" :key="key" :item-count="tab.itemsCount" />
</gl-tabs>
</configuration-page-layout>
<empty-state v-else />
......
......@@ -8,17 +8,22 @@ export default () => {
return null;
}
const { newDastScanPath, emptyStateSvgPath } = el.dataset;
const { pipelinesCount, projectPath, newDastScanPath, emptyStateSvgPath } = el.dataset;
return new Vue({
el,
router: createRouter(),
provide: {
projectPath,
newDastScanPath,
emptyStateSvgPath,
},
render(h) {
return h(OnDemandScans);
return h(OnDemandScans, {
props: {
pipelinesCount: Number(pipelinesCount),
},
});
},
});
};
# frozen_string_literal: true
module Projects::OnDemandScansHelper
include API::Helpers::GraphqlHelpers
def on_demand_scans_data(project)
{
query = %(
{
project(fullPath: "#{project.full_path}") {
pipelines(source: "dast") {
count
}
}
}
)
pipelines_count = run_graphql!(
query: query,
context: { current_user: current_user },
transform: -> (result) { result.dig('data', 'project', 'pipelines', 'count') }
)
common_data(project).merge({
'pipelines-count' => pipelines_count,
'new-dast-scan-path' => new_project_on_demand_scan_path(project),
'empty-state-svg-path' => image_path('illustrations/empty-state/ondemand-scan-empty.svg')
}
})
end
def on_demand_scans_form_data(project)
{
common_data(project).merge({
'default-branch' => project.default_branch,
'project-path' => project.path_with_namespace,
'profiles-library-path' => project_security_configuration_dast_scans_path(project),
'scanner-profiles-library-path' => project_security_configuration_dast_scans_path(project, anchor: 'scanner-profiles'),
'site-profiles-library-path' => project_security_configuration_dast_scans_path(project, anchor: 'site-profiles'),
'new-scanner-profile-path' => new_project_security_configuration_dast_scans_dast_scanner_profile_path(project),
'new-site-profile-path' => new_project_security_configuration_dast_scans_dast_site_profile_path(project),
'timezones' => timezone_data(format: :full).to_json
})
end
private
def common_data(project)
{
'project-path' => project.path_with_namespace
}
end
end
import { GlSprintf } from '@gitlab/ui';
import { merge } from 'lodash';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import OnDemandScans from 'ee/on_demand_scans/components/on_demand_scans.vue';
import ConfigurationPageLayout from 'ee/security_configuration/components/configuration_page_layout.vue';
......@@ -19,17 +20,23 @@ describe('OnDemandScans', () => {
const findAllTab = () => wrapper.findComponent(AllTab);
const findEmptyState = () => wrapper.findComponent(EmptyState);
const createComponent = () => {
wrapper = shallowMountExtended(OnDemandScans, {
router,
provide: {
newDastScanPath,
},
stubs: {
ConfigurationPageLayout,
GlSprintf,
},
});
const createComponent = (options = {}) => {
wrapper = shallowMountExtended(
OnDemandScans,
merge(
{
router,
provide: {
newDastScanPath,
},
stubs: {
ConfigurationPageLayout,
GlSprintf,
},
},
options,
),
);
};
beforeEach(() => {
......@@ -48,8 +55,11 @@ describe('OnDemandScans', () => {
describe('when there is data', () => {
beforeEach(() => {
createComponent();
wrapper.setData({ hasData: true });
createComponent({
propsData: {
pipelinesCount: 12,
},
});
});
it('renders a link to the docs', () => {
......
......@@ -3,13 +3,25 @@
require 'spec_helper'
RSpec.describe Projects::OnDemandScansHelper do
include Devise::Test::ControllerHelpers
let_it_be(:project) { create(:project) }
before do
allow(project).to receive(:path_with_namespace).and_return("foo/bar")
end
describe '#on_demand_scans_data' do
before do
allow(helper).to receive(:run_graphql!).and_return(12)
end
it 'returns proper data' do
expect(helper.on_demand_scans_data(project)).to match(
'project-path' => "foo/bar",
'new-dast-scan-path' => "/#{project.full_path}/-/on_demand_scans/new",
'empty-state-svg-path' => match_asset_path('/assets/illustrations/empty-state/ondemand-scan-empty.svg')
'empty-state-svg-path' => match_asset_path('/assets/illustrations/empty-state/ondemand-scan-empty.svg'),
'pipelines-count' => 12
)
end
end
......@@ -17,11 +29,12 @@ RSpec.describe Projects::OnDemandScansHelper do
describe '#on_demand_scans_form_data' do
let_it_be(:timezones) { [{ identifier: "Europe/Paris" }] }
# rubocop: disable CodeReuse/ActiveRecord
before do
allow(project).to receive(:default_branch).and_return("default-branch")
allow(project).to receive(:path_with_namespace).and_return("foo/bar")
allow(helper).to receive(:timezone_data).with(format: :full).and_return(timezones)
end
# rubocop: enable CodeReuse/ActiveRecord
it 'returns proper data' do
expect(helper.on_demand_scans_form_data(project)).to match(
......
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