Commit 1f4c6c40 authored by Martin Wortschack's avatar Martin Wortschack

Merge branch '207981-requirements-list-vue-app' into 'master'

[Part-1] Adds Requirements page tabs and app root

Closes #207981

See merge request gitlab-org/gitlab!27498
parents 365ebd02 66b95cb9
import initRequirementsApp from 'ee/requirements/requirements_bundle';
document.addEventListener('DOMContentLoaded', () => {
initRequirementsApp();
});
<script>
export default {
props: {
filterBy: {
type: String,
required: true,
},
showCreateRequirement: {
type: Boolean,
required: true,
},
},
};
</script>
<template>
<div class="card card-small card-without-border">
<!-- eslint-disable-next-line @gitlab/vue-i18n/no-bare-strings -->
<h3 v-if="showCreateRequirement">Create Requirement Form visible!</h3>
<!-- eslint-disable-next-line @gitlab/vue-i18n/no-bare-strings -->
<h2>Hello World from Requirements app!</h2>
</div>
</template>
// eslint-disable-next-line import/prefer-default-export
export const FilterState = {
Open: 'opened',
Closed: 'closed',
All: 'all',
};
import Vue from 'vue';
import RequirementsRoot from './components/requirements_root.vue';
import { FilterState } from './constants';
export default () => {
const btnNewRequirement = document.querySelector('.js-new-requirement');
const el = document.getElementById('js-requirements-app');
if (!el) {
return false;
}
return new Vue({
el,
components: {
RequirementsRoot,
},
data() {
return {
showCreateRequirement: false,
filterBy: el?.dataset?.filterBy || FilterState.Open,
};
},
mounted() {
btnNewRequirement.addEventListener('click', this.handleClickNewRequirement);
},
beforeDestroy() {
btnNewRequirement.removeEventListener('click', this.handleClickNewRequirement);
},
methods: {
handleClickNewRequirement() {
this.showCreateRequirement = !this.showCreateRequirement;
},
},
render(createElement) {
return createElement('requirements-root', {
props: {
filterBy: this.filterBy,
showCreateRequirement: this.showCreateRequirement,
},
});
},
});
};
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= nav_link(path: 'requirements#index') do = nav_link(path: 'requirements#index') do
= link_to project_requirements_path(project), class: 'qa-project-requirements-link' do = link_to project_requirements_path(project), class: 'qa-project-requirements-link' do
.nav-icon-container .nav-icon-container
= sprite_icon('list-task') = sprite_icon('requirements')
%span.nav-item-name %span.nav-item-name
= _('Requirements') = _('Requirements')
%ul.sidebar-sub-level-items %ul.sidebar-sub-level-items
......
- page_title _('Requirements') - page_title _('Requirements')
- type = :requirements
- page_context_word = type.to_s.humanize(capitalize: false)
-# haml-lint:disable NoPlainNodes .top-area
%h1 Hello World from Requirements! %ul.nav-links.mobile-separator.requirements-state-filters
%li{ class: active_when(params[:state].nil? || params[:state] == 'opened') }>
= link_to page_filter_path(state: 'opened'), id: 'state-opened', title: (_("Filter by %{issuable_type} that are currently opened.") % { issuable_type: page_context_word }), data: { state: 'opened' } do
= _('Open')
%li{ class: active_when(params[:state] == 'archived') }>
= link_to page_filter_path(state: 'archived'), id: 'state-archived', title: (_("Filter by %{issuable_type} that are currently archived.") % { issuable_type: page_context_word }), data: { state: 'archived' } do
= _('Archived')
= render 'shared/issuable/nav_links/all', page_context_word: page_context_word, counter: _('All')
.nav-controls
%button.btn.btn-success.js-new-requirement.qa-new-requirement-button{ type: 'button' }
= _('New requirement')
#js-requirements-app{ data: { filter_by: params[:state] } }
# frozen_string_literal: true
require 'spec_helper'
describe 'Requirements list', :js do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
before do
stub_licensed_features(requirements: true)
project.add_maintainer(user)
sign_in(user)
end
context 'when requirements exist for the project' do
before do
visit project_requirements_path(project)
end
it 'shows the requirements in the navigation sidebar' do
expect(first('.nav-sidebar .active a .nav-item-name')).to have_content('Requirements')
end
it 'shows requirements tabs for each status type' do
page.within('.requirements-state-filters') do
expect(page).to have_selector('li > a#state-opened')
expect(find('li > a#state-opened')[:title]).to eq('Filter by requirements that are currently opened.')
expect(page).to have_selector('li > a#state-archived')
expect(find('li > a#state-archived')[:title]).to eq('Filter by requirements that are currently archived.')
expect(page).to have_selector('li > a#state-all')
expect(find('li > a#state-all')[:title]).to eq('Show all requirements.')
end
end
it 'shows button "New requirement"' do
page.within('.nav-controls') do
expect(page).to have_selector('button.js-new-requirement')
expect(find('button.js-new-requirement')).to have_content('New requirement')
end
end
end
end
...@@ -2247,6 +2247,9 @@ msgstr "" ...@@ -2247,6 +2247,9 @@ msgstr ""
msgid "Archive project" msgid "Archive project"
msgstr "" msgstr ""
msgid "Archived"
msgstr ""
msgid "Archived project! Repository and other project resources are read only" msgid "Archived project! Repository and other project resources are read only"
msgstr "" msgstr ""
...@@ -8776,6 +8779,9 @@ msgstr "" ...@@ -8776,6 +8779,9 @@ msgstr ""
msgid "Filter" msgid "Filter"
msgstr "" msgstr ""
msgid "Filter by %{issuable_type} that are currently archived."
msgstr ""
msgid "Filter by %{issuable_type} that are currently closed." msgid "Filter by %{issuable_type} that are currently closed."
msgstr "" msgstr ""
...@@ -13112,6 +13118,9 @@ msgstr "" ...@@ -13112,6 +13118,9 @@ msgstr ""
msgid "New release" msgid "New release"
msgstr "" msgstr ""
msgid "New requirement"
msgstr ""
msgid "New runners registration token has been generated!" msgid "New runners registration token has been generated!"
msgstr "" msgstr ""
......
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