Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8d78e95a9c
commit
80e5134020
32 changed files with 350 additions and 48 deletions
2
Gemfile
2
Gemfile
|
@ -139,7 +139,7 @@ gem 'html-pipeline', '~> 2.8'
|
|||
gem 'deckar01-task_list', '2.2.1'
|
||||
gem 'gitlab-markup', '~> 1.7.0'
|
||||
gem 'github-markup', '~> 1.7.0', require: 'github/markup'
|
||||
gem 'commonmarker', '~> 0.17'
|
||||
gem 'commonmarker', '~> 0.20'
|
||||
gem 'RedCloth', '~> 4.3.2'
|
||||
gem 'rdoc', '~> 6.0'
|
||||
gem 'org-ruby', '~> 0.9.12'
|
||||
|
|
|
@ -157,7 +157,7 @@ GEM
|
|||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
colored2 (3.1.2)
|
||||
commonmarker (0.17.13)
|
||||
commonmarker (0.20.1)
|
||||
ruby-enum (~> 0.5)
|
||||
concord (0.1.5)
|
||||
adamantium (~> 0.2.0)
|
||||
|
@ -1146,7 +1146,7 @@ DEPENDENCIES
|
|||
carrierwave (~> 1.3)
|
||||
charlock_holmes (~> 0.7.5)
|
||||
chronic (~> 0.10.2)
|
||||
commonmarker (~> 0.17)
|
||||
commonmarker (~> 0.20)
|
||||
concurrent-ruby (~> 1.1)
|
||||
connection_pool (~> 2.0)
|
||||
countries (~> 3.0)
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
import $ from 'jquery';
|
||||
import Sortable from 'sortablejs';
|
||||
import Vue from 'vue';
|
||||
import { GlButtonGroup, GlButton, GlTooltip } from '@gitlab/ui';
|
||||
import { n__, s__ } from '~/locale';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import Tooltip from '~/vue_shared/directives/tooltip';
|
||||
import isWipLimitsOn from 'ee_else_ce/boards/mixins/is_wip_limits';
|
||||
import AccessorUtilities from '../../lib/utils/accessor';
|
||||
import BoardBlankState from './board_blank_state.vue';
|
||||
import BoardDelete from './board_delete';
|
||||
import BoardList from './board_list.vue';
|
||||
import IssueCount from './issue_count.vue';
|
||||
import boardsStore from '../stores/boards_store';
|
||||
import { getBoardSortableDefaultOptions, sortableEnd } from '../mixins/sortable_default_options';
|
||||
import { ListType } from '../constants';
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
|
@ -17,10 +21,15 @@ export default Vue.extend({
|
|||
BoardDelete,
|
||||
BoardList,
|
||||
Icon,
|
||||
GlButtonGroup,
|
||||
IssueCount,
|
||||
GlButton,
|
||||
GlTooltip,
|
||||
},
|
||||
directives: {
|
||||
Tooltip,
|
||||
},
|
||||
mixins: [isWipLimitsOn],
|
||||
props: {
|
||||
list: {
|
||||
type: Object,
|
||||
|
@ -53,6 +62,11 @@ export default Vue.extend({
|
|||
isLoggedIn() {
|
||||
return Boolean(gon.current_user_id);
|
||||
},
|
||||
showListHeaderButton() {
|
||||
return (
|
||||
!this.disabled && this.list.type !== ListType.closed && this.list.type !== ListType.blank
|
||||
);
|
||||
},
|
||||
counterTooltip() {
|
||||
const { issuesSize } = this.list;
|
||||
return `${n__('%d issue', '%d issues', issuesSize)}`;
|
||||
|
@ -61,11 +75,19 @@ export default Vue.extend({
|
|||
return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand');
|
||||
},
|
||||
isNewIssueShown() {
|
||||
return this.list.type === ListType.backlog || this.showListHeaderButton;
|
||||
},
|
||||
isSettingsShown() {
|
||||
return (
|
||||
this.list.type === 'backlog' ||
|
||||
(!this.disabled && this.list.type !== 'closed' && this.list.type !== 'blank')
|
||||
this.list.type !== ListType.backlog &&
|
||||
this.showListHeaderButton &&
|
||||
this.list.isExpanded &&
|
||||
this.isWipLimitsOn
|
||||
);
|
||||
},
|
||||
showBoardListAndBoardInfo() {
|
||||
return this.list.type !== ListType.blank && this.list.type !== ListType.promotion;
|
||||
},
|
||||
uniqueKey() {
|
||||
// eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
|
||||
return `boards.${this.boardId}.${this.list.type}.${this.list.id}`;
|
||||
|
|
|
@ -71,6 +71,9 @@ export default {
|
|||
total: this.list.issuesSize,
|
||||
});
|
||||
},
|
||||
issuesSizeExceedsMax() {
|
||||
return this.list.maxIssueCount > 0 && this.list.issuesSize > this.list.maxIssueCount;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
filters: {
|
||||
|
@ -435,7 +438,7 @@ export default {
|
|||
ref="list"
|
||||
:data-board="list.id"
|
||||
:data-board-type="list.type"
|
||||
:class="{ 'is-smaller': showIssueForm }"
|
||||
:class="{ 'is-smaller': showIssueForm, 'bg-danger-100': issuesSizeExceedsMax }"
|
||||
class="board-list w-100 h-100 list-unstyled mb-0 p-1 js-board-list"
|
||||
>
|
||||
<board-card
|
||||
|
|
36
app/assets/javascripts/boards/components/issue_count.vue
Normal file
36
app/assets/javascripts/boards/components/issue_count.vue
Normal file
|
@ -0,0 +1,36 @@
|
|||
<script>
|
||||
export default {
|
||||
name: 'IssueCount',
|
||||
props: {
|
||||
maxIssueCount: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
issuesSize: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isMaxLimitSet() {
|
||||
return this.maxIssueCount !== 0;
|
||||
},
|
||||
issuesExceedMax() {
|
||||
return this.isMaxLimitSet && this.issuesSize > this.maxIssueCount;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="issue-count">
|
||||
<span class="js-issue-size" :class="{ 'text-danger': issuesExceedMax }">
|
||||
{{ issuesSize }}
|
||||
</span>
|
||||
<span v-if="isMaxLimitSet" class="js-max-issue-size">
|
||||
{{ maxIssueCount }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
|
@ -4,6 +4,8 @@ export const ListType = {
|
|||
backlog: 'backlog',
|
||||
closed: 'closed',
|
||||
label: 'label',
|
||||
promotion: 'promotion',
|
||||
blank: 'blank',
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
7
app/assets/javascripts/boards/mixins/is_wip_limits.js
Normal file
7
app/assets/javascripts/boards/mixins/is_wip_limits.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
export default {
|
||||
computed: {
|
||||
isWipLimitsOn() {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
};
|
|
@ -52,6 +52,9 @@ class List {
|
|||
this.loadingMore = false;
|
||||
this.issues = obj.issues || [];
|
||||
this.issuesSize = obj.issuesSize ? obj.issuesSize : 0;
|
||||
this.maxIssueCount = Object.hasOwnProperty.call(obj, 'max_issue_count')
|
||||
? obj.max_issue_count
|
||||
: 0;
|
||||
this.defaultAvatar = defaultAvatar;
|
||||
|
||||
if (obj.label) {
|
||||
|
|
|
@ -72,7 +72,7 @@ export default {
|
|||
{{ __('Related merge requests') }}
|
||||
</span>
|
||||
<div v-if="totalCount" class="d-inline-flex lh-100 align-middle">
|
||||
<div class="mr-count-badge">
|
||||
<div class="mr-count-badge border-width-1px border-style-solid border-color-default">
|
||||
<div class="mr-count-badge-count">
|
||||
<svg class="s16 mr-1 text-secondary">
|
||||
<icon name="merge-request" class="mr-1 text-secondary" />
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
color: $gl-text-color;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $border-radius-default;
|
||||
margin-bottom: $gl-padding;
|
||||
margin-bottom: $gl-padding-8;
|
||||
|
||||
.card.card-body-segment {
|
||||
padding: $gl-padding;
|
||||
|
|
|
@ -187,6 +187,10 @@
|
|||
font-size: 1em;
|
||||
border-bottom: 1px solid $border-color;
|
||||
padding: $gl-padding-8 $gl-padding;
|
||||
|
||||
.js-max-issue-size::before {
|
||||
content: '/';
|
||||
}
|
||||
}
|
||||
|
||||
.board-title-text {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
.mr-count-badge {
|
||||
display: inline-flex;
|
||||
border-radius: $border-radius-base;
|
||||
border: 1px solid $border-color;
|
||||
padding: 5px $gl-padding-8;
|
||||
}
|
||||
|
||||
|
|
|
@ -748,7 +748,7 @@
|
|||
display: inline-block;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: $gl-padding;
|
||||
margin-right: $gl-padding-8;
|
||||
}
|
||||
|
||||
&.right {
|
||||
|
@ -798,7 +798,7 @@
|
|||
}
|
||||
|
||||
.btn {
|
||||
margin-top: $gl-padding;
|
||||
margin-top: $gl-padding-8;
|
||||
padding: $gl-btn-vert-padding $gl-btn-padding;
|
||||
line-height: $gl-btn-line-height;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.tree-holder {
|
||||
.nav-block {
|
||||
margin: 10px 0;
|
||||
margin: 16px 0;
|
||||
|
||||
.btn .fa,
|
||||
.btn svg {
|
||||
|
@ -15,8 +15,13 @@
|
|||
}
|
||||
|
||||
.tree-controls {
|
||||
display: flex;
|
||||
text-align: right;
|
||||
|
||||
.btn {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ module BoardsActions
|
|||
|
||||
before_action :boards, only: :index
|
||||
before_action :board, only: :show
|
||||
before_action :push_wip_limits, only: :index
|
||||
end
|
||||
|
||||
def index
|
||||
|
@ -24,6 +25,10 @@ module BoardsActions
|
|||
|
||||
private
|
||||
|
||||
# Noop on FOSS
|
||||
def push_wip_limits
|
||||
end
|
||||
|
||||
def boards
|
||||
strong_memoize(:boards) do
|
||||
Boards::ListService.new(parent, current_user).execute
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
- public_project_count = ProjectsFinder.new(current_user: current_user).execute.count
|
||||
|
||||
.blank-state-row
|
||||
- if current_user.can_create_project?
|
||||
= link_to new_project_path, class: "blank-state blank-state-link" do
|
||||
|
@ -30,19 +28,15 @@
|
|||
%p.blank-state-text
|
||||
Groups are the best way to manage projects and members.
|
||||
|
||||
- if public_project_count > 0
|
||||
= link_to trending_explore_projects_path, class: "blank-state blank-state-link" do
|
||||
.blank-state-icon
|
||||
= custom_icon("globe", size: 50)
|
||||
.blank-state-body
|
||||
%h3.blank-state-title
|
||||
Explore public projects
|
||||
%p.blank-state-text
|
||||
There are
|
||||
= number_with_delimiter(public_project_count)
|
||||
public projects on this server.
|
||||
Public projects are an easy way to allow
|
||||
everyone to have read-only access.
|
||||
= link_to trending_explore_projects_path, class: "blank-state blank-state-link" do
|
||||
.blank-state-icon
|
||||
= custom_icon("globe", size: 50)
|
||||
.blank-state-body
|
||||
%h3.blank-state-title
|
||||
Explore public projects
|
||||
%p.blank-state-text
|
||||
Public projects are an easy way to allow
|
||||
everyone to have read-only access.
|
||||
|
||||
= link_to "https://docs.gitlab.com/", class: "blank-state blank-state-link" do
|
||||
.blank-state-icon
|
||||
|
|
|
@ -42,23 +42,27 @@
|
|||
%button.board-delete.no-drag.p-0.border-0.has-tooltip.float-right{ type: "button", title: _("Delete list"), ":class": "{ 'd-none': !list.isExpanded }", "aria-label" => _("Delete list"), data: { placement: "bottom" }, "@click.stop" => "deleteBoard" }
|
||||
= icon("trash")
|
||||
|
||||
.issue-count-badge.no-drag.text-secondary{ "v-if" => 'list.type !== "blank" && list.type !== "promotion"', ":title": "counterTooltip", "v-tooltip": true, data: { placement: "top" } }
|
||||
.issue-count-badge.pr-0.no-drag.text-secondary{ "v-if" => "showBoardListAndBoardInfo", ":title": "counterTooltip", "v-tooltip": true, data: { placement: "top" } }
|
||||
%span.d-inline-flex
|
||||
%span.issue-count-badge-count
|
||||
%icon.mr-1{ name: "issues" }
|
||||
{{ list.issuesSize }}
|
||||
%issue-count{ ":maxIssueCount" => "list.maxIssueCount",
|
||||
":issuesSize" => "list.issuesSize" }
|
||||
= render_if_exists "shared/boards/components/list_weight"
|
||||
|
||||
%button.issue-count-badge-add-button.no-drag.btn.btn-sm.btn-default.ml-1.has-tooltip{ type: "button",
|
||||
"@click" => "showNewIssueForm",
|
||||
"v-if" => "isNewIssueShown",
|
||||
":class": "{ 'd-none': !list.isExpanded }",
|
||||
"aria-label" => _("New issue"),
|
||||
"title" => _("New issue"),
|
||||
data: { placement: "top", container: "body" } }
|
||||
= icon("plus")
|
||||
%gl-button-group.board-list-button-group.pl-2{ "v-if" => "isNewIssueShown || isSettingsShown" }
|
||||
%gl-button.issue-count-badge-add-button.no-drag{ type: "button",
|
||||
"@click" => "showNewIssueForm",
|
||||
"v-if" => "isNewIssueShown",
|
||||
":class": "{ 'd-none': !list.isExpanded, 'rounded-right': isNewIssueShown && !isSettingsShown }",
|
||||
"aria-label" => _("New issue"),
|
||||
"ref" => "newIssueBtn" }
|
||||
= icon("plus")
|
||||
%gl-tooltip{ ":target" => "() => $refs.newIssueBtn" }
|
||||
= _("New Issue")
|
||||
= render_if_exists 'shared/boards/components/list_settings'
|
||||
|
||||
%board-list{ "v-if" => 'list.type !== "blank" && list.type !== "promotion"',
|
||||
%board-list{ "v-if" => "showBoardListAndBoardInfo",
|
||||
":list" => "list",
|
||||
":issues" => "list.issues",
|
||||
":loading" => "list.loading",
|
||||
|
|
5
changelogs/unreleased/13768-fix-redo-icn.yml
Normal file
5
changelogs/unreleased/13768-fix-redo-icn.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Replacing incorrect icon for Retry in Pipeline list page
|
||||
merge_request: 20510
|
||||
author:
|
||||
type: changed
|
5
changelogs/unreleased/35468-fixdetail-margins.yml
Normal file
5
changelogs/unreleased/35468-fixdetail-margins.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fixes to inconsistent margins/sapcing in the project detail page
|
||||
merge_request: 20395
|
||||
author:
|
||||
type: changed
|
5
changelogs/unreleased/fix-env-doc-link.yml
Normal file
5
changelogs/unreleased/fix-env-doc-link.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix documentation link from empty environment dashboard
|
||||
merge_request: 20415
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Disable public project counts on welcome page
|
||||
merge_request: 20517
|
||||
author:
|
||||
type: performance
|
|
@ -110,12 +110,23 @@ following.
|
|||
|
||||
1. [Restart GitLab][restart] for the changes to take effect.
|
||||
|
||||
To take advantage of group sync, group owners or maintainers will need to create an
|
||||
LDAP group link in their group **Settings > LDAP Groups** page.
|
||||
To take advantage of group sync, group owners or maintainers will need to [create one
|
||||
or more LDAP group links](#adding-group-links).
|
||||
|
||||
Multiple LDAP groups and [filters](#filters-premium-only) can be linked with
|
||||
a single GitLab group. When the link is created, an access level/role is
|
||||
specified (Guest, Reporter, Developer, Maintainer, or Owner).
|
||||
### Adding group links
|
||||
|
||||
Once [group sync has been configured](#group-sync) on the instance, one or more LDAP
|
||||
groups can be linked to a GitLab group to grant their members access to its
|
||||
contents.
|
||||
|
||||
Group owners or maintainers can add and use LDAP group links by:
|
||||
|
||||
1. Navigating to the group's **Settings > LDAP Synchronization** page. Here, one or more
|
||||
LDAP groups and [filters](#filters-premium-only) can be linked to this GitLab group,
|
||||
each one with a configured [permission level](../../user/permissions.md#group-members-permissions)
|
||||
for its members.
|
||||
1. Updating the group's membership by navigating to the group's **Settings > Members**
|
||||
page and clicking **Sync now**.
|
||||
|
||||
### Filters **(PREMIUM ONLY)**
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -718,6 +718,14 @@ Note that `enforced="true"`, meaning that authentication is being enforced.
|
|||
|
||||
## Troubleshooting Gitaly
|
||||
|
||||
### Checking versions when using standalone Gitaly nodes
|
||||
|
||||
When using standalone Gitaly nodes, you must make sure they are the same version
|
||||
as GitLab to ensure full compatibility. Check **Admin Area > Gitaly Servers** on
|
||||
your GitLab instance and confirm all Gitaly Servers are `Up to date`.
|
||||
|
||||
![Gitaly standalone software versions diagram](img/gitlab_gitaly_version_mismatch_v12_4.png)
|
||||
|
||||
### `gitaly-debug`
|
||||
|
||||
The `gitaly-debug` command provides "production debugging" tools for Gitaly and Git
|
||||
|
|
|
@ -766,10 +766,17 @@ or a `.buildpacks` file in your project:
|
|||
and add the URL of the buildpack to use on a line in the file. If you want to
|
||||
use multiple buildpacks, you can enter them in, one on each line.
|
||||
|
||||
CAUTION: **Caution:**
|
||||
Using multiple buildpacks isn't yet supported by Auto DevOps.
|
||||
#### Multiple buildpacks
|
||||
|
||||
CAUTION: **Caution:** When using the `.buildpacks` file, Auto Test will not work. The buildpack [heroku-buildpack-multi](https://github.com/heroku/heroku-buildpack-multi/) (which is used under the hood to parse the `.buildpacks` file) doesn't provide the necessary commands `bin/test-compile` and `bin/test`. Make sure to provide the project variable `BUILDPACK_URL` instead.
|
||||
Using multiple buildpacks isn't fully supported by Auto DevOps because, when using the `.buildpacks`
|
||||
file, Auto Test will not work.
|
||||
|
||||
The buildpack [heroku-buildpack-multi](https://github.com/heroku/heroku-buildpack-multi/),
|
||||
which is used under the hood to parse the `.buildpacks` file, doesn't provide the necessary commands
|
||||
`bin/test-compile` and `bin/test`.
|
||||
|
||||
If your goal is to use only a single custom buildpack, you should provide the project variable
|
||||
`BUILDPACK_URL` instead.
|
||||
|
||||
### Custom `Dockerfile`
|
||||
|
||||
|
|
|
@ -123,6 +123,25 @@ NOTE: **Note:** GitLab is unable to provide support for IdPs that are not listed
|
|||
|
||||
When [configuring your identify provider](#configuring-your-identity-provider), please consider the notes below for specific providers to help avoid common issues and as a guide for terminology used.
|
||||
|
||||
### Azure setup notes
|
||||
|
||||
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
|
||||
For a demo of the Azure SAML setup including SCIM, see [SCIM Provisioning on Azure Using SAML SSO for Groups Demo](https://youtu.be/24-ZxmTeEBU).
|
||||
|
||||
| GitLab Setting | Azure Field |
|
||||
|--------------|----------------|
|
||||
| Identifier | Identifier (Entity ID) |
|
||||
| Assertion consumer service URL | Reply URL (Assertion Consumer Service URL) |
|
||||
| Identity provider single sign on URL | Login URL |
|
||||
| Certificate fingerprint | Thumbprint |
|
||||
|
||||
We recommend:
|
||||
|
||||
- **Unique User Identifier (Name identifier)** set to `user.objectID`.
|
||||
- **nameid-format** set to persistent.
|
||||
|
||||
Set other user attributes and claims according to the [assertions table](#assertions).
|
||||
|
||||
### Okta setup notes
|
||||
|
||||
| GitLab Setting | Okta Field |
|
||||
|
|
|
@ -29,7 +29,9 @@ module Banzai
|
|||
# If in the future the syntax is about to be made GitHub-compatible, please, add `:GITHUB_PRE_LANG` render option below
|
||||
# and remove `code_block` method from `lib/banzai/renderer/common_mark/html.rb`.
|
||||
RENDER_OPTIONS = [
|
||||
:DEFAULT # default rendering system. Nothing special.
|
||||
# as of commonmarker 0.18.0, we need to use :UNSAFE to get the same as the original :DEFAULT
|
||||
# https://github.com/gjtorikian/commonmarker/pull/81
|
||||
:UNSAFE
|
||||
].freeze
|
||||
|
||||
RENDER_OPTIONS_SOURCEPOS = RENDER_OPTIONS + [
|
||||
|
|
|
@ -10291,6 +10291,9 @@ msgstr ""
|
|||
msgid "List"
|
||||
msgstr ""
|
||||
|
||||
msgid "List Settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "List Your Gitea Repositories"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ FactoryBot.define do
|
|||
board
|
||||
label
|
||||
list_type { :label }
|
||||
max_issue_count { 0 }
|
||||
sequence(:position)
|
||||
end
|
||||
|
||||
|
|
|
@ -72,7 +72,6 @@ describe 'Issue Boards', :js do
|
|||
let!(:closed) { create(:label, project: project, name: 'Closed') }
|
||||
let!(:accepting) { create(:label, project: project, name: 'Accepting Merge Requests') }
|
||||
let!(:a_plus) { create(:label, project: project, name: 'A+') }
|
||||
|
||||
let!(:list1) { create(:list, board: board, label: planning, position: 0) }
|
||||
let!(:list2) { create(:list, board: board, label: development, position: 1) }
|
||||
|
||||
|
@ -289,6 +288,17 @@ describe 'Issue Boards', :js do
|
|||
expect(page).to have_selector('.avatar', count: 1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'list header' do
|
||||
let(:total_planning_issues) { "8" }
|
||||
|
||||
it 'shows issue count on the list' do
|
||||
page.within(find(".board:nth-child(2)")) do
|
||||
expect(page.find('.js-issue-size')).to have_text(total_planning_issues)
|
||||
expect(page).not_to have_selector('.js-max-issue-size')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'new list' do
|
||||
|
|
85
spec/frontend/boards/components/issue_count_spec.js
Normal file
85
spec/frontend/boards/components/issue_count_spec.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import IssueCount from '~/boards/components/issue_count.vue';
|
||||
|
||||
describe('IssueCount', () => {
|
||||
let vm;
|
||||
let maxIssueCount;
|
||||
let issuesSize;
|
||||
|
||||
const createComponent = props => {
|
||||
vm = shallowMount(IssueCount, { propsData: props });
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
maxIssueCount = 0;
|
||||
issuesSize = 0;
|
||||
|
||||
if (vm) vm.destroy();
|
||||
});
|
||||
|
||||
describe('when maxIssueCount is zero', () => {
|
||||
beforeEach(() => {
|
||||
issuesSize = 3;
|
||||
|
||||
createComponent({ maxIssueCount: 0, issuesSize });
|
||||
});
|
||||
|
||||
it('contains issueSize in the template', () => {
|
||||
expect(vm.find('.js-issue-size').text()).toEqual(String(issuesSize));
|
||||
});
|
||||
|
||||
it('does not contains maxIssueCount in the template', () => {
|
||||
expect(vm.contains('.js-max-issue-size')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when maxIssueCount is greater than zero', () => {
|
||||
beforeEach(() => {
|
||||
maxIssueCount = 2;
|
||||
issuesSize = 1;
|
||||
|
||||
createComponent({ maxIssueCount, issuesSize });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.destroy();
|
||||
});
|
||||
|
||||
it('contains issueSize in the template', () => {
|
||||
expect(vm.find('.js-issue-size').text()).toEqual(String(issuesSize));
|
||||
});
|
||||
|
||||
it('contains maxIssueCount in the template', () => {
|
||||
expect(vm.find('.js-max-issue-size').text()).toEqual(String(maxIssueCount));
|
||||
});
|
||||
|
||||
it('does not have text-danger class when issueSize is less than maxIssueCount', () => {
|
||||
expect(vm.classes('.text-danger')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when issueSize is greater than maxIssueCount', () => {
|
||||
beforeEach(() => {
|
||||
issuesSize = 3;
|
||||
maxIssueCount = 2;
|
||||
|
||||
createComponent({ maxIssueCount, issuesSize });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.destroy();
|
||||
});
|
||||
|
||||
it('contains issueSize in the template', () => {
|
||||
expect(vm.find('.js-issue-size').text()).toEqual(String(issuesSize));
|
||||
});
|
||||
|
||||
it('contains maxIssueCount in the template', () => {
|
||||
expect(vm.find('.js-max-issue-size').text()).toEqual(String(maxIssueCount));
|
||||
});
|
||||
|
||||
it('has text-danger class', () => {
|
||||
expect(vm.find('.text-danger').text()).toEqual(String(issuesSize));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -207,4 +207,56 @@ describe('Board list component', () => {
|
|||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('max issue count warning', () => {
|
||||
beforeEach(done => {
|
||||
({ mock, component } = createComponent({
|
||||
done,
|
||||
listProps: { type: 'closed', collapsed: true, issuesSize: 50 },
|
||||
}));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mock.restore();
|
||||
component.$destroy();
|
||||
});
|
||||
|
||||
describe('when issue count exceeds max issue count', () => {
|
||||
it('sets background to bg-danger-100', done => {
|
||||
component.list.issuesSize = 4;
|
||||
component.list.maxIssueCount = 3;
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(component.$el.querySelector('.bg-danger-100')).not.toBeNull();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when list issue count does NOT exceed list max issue count', () => {
|
||||
it('does not sets background to bg-danger-100', done => {
|
||||
component.list.issuesSize = 2;
|
||||
component.list.maxIssueCount = 3;
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(component.$el.querySelector('.bg-danger-100')).toBeNull();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when list max issue count is 0', () => {
|
||||
it('does not sets background to bg-danger-100', done => {
|
||||
component.list.maxIssueCount = 0;
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(component.$el.querySelector('.bg-danger-100')).toBeNull();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue