Commit c8a53a38 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 6ab0d200 f54f18c0
......@@ -19,6 +19,7 @@ import { updateHistory } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import MrWidgetHowToMergeModal from '~/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue';
import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import notesEventHub from '../../notes/event_hub';
import {
......@@ -79,6 +80,7 @@ export default {
MrWidgetHowToMergeModal,
GlAlert,
},
mixins: [glFeatureFlagsMixin()],
alerts: {
ALERT_OVERFLOW_HIDDEN,
ALERT_MERGE_CONFLICT,
......@@ -252,6 +254,10 @@ export default {
return this.treeWidth <= TREE_HIDE_STATS_WIDTH;
},
isLimitedContainer() {
if (this.glFeatures.mrChangesFluidLayout) {
return false;
}
return !this.renderFileTree && !this.isParallelView && !this.isFluidLayout;
},
isFullChangeset() {
......@@ -386,6 +392,8 @@ export default {
diffsApp.instrument();
},
created() {
this.mergeRequestContainers = document.querySelectorAll('.merge-request-container');
this.adjustView();
this.subscribeToEvents();
......@@ -513,6 +521,13 @@ export default {
} else {
this.removeEventListeners();
}
if (!this.isFluidLayout && this.glFeatures.mrChangesFluidLayout) {
this.mergeRequestContainers.forEach((el) => {
el.classList.toggle('limit-container-width', !this.shouldShow);
el.classList.toggle('container-limited', !this.shouldShow);
});
}
},
setEventListeners() {
Mousetrap.bind(keysFor(MR_PREVIOUS_FILE_IN_DIFF), () => this.jumpToFile(-1));
......
<script>
import { GlLink, GlIcon, GlLabel, GlFormCheckbox, GlTooltipDirective } from '@gitlab/ui';
import { GlLink, GlIcon, GlLabel, GlFormCheckbox, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { isScopedLabel } from '~/lib/utils/common_utils';
......@@ -15,6 +15,7 @@ export default {
GlIcon,
GlLabel,
GlFormCheckbox,
GlSprintf,
IssuableAssignees,
},
directives: {
......@@ -82,9 +83,7 @@ export default {
return this.issuable.assignees?.nodes || this.issuable.assignees || [];
},
createdAt() {
return sprintf(__('created %{timeAgo}'), {
timeAgo: getTimeago().format(this.issuable.createdAt),
});
return getTimeago().format(this.issuable.createdAt);
},
updatedAt() {
return sprintf(__('updated %{timeAgo}'), {
......@@ -164,132 +163,132 @@ export default {
<template>
<li
:id="`issuable_${issuableId}`"
class="issue gl-px-5!"
class="issue gl-display-flex! gl-px-5!"
:class="{ closed: issuable.closedAt, today: createdInPastDay }"
:data-labels="labelIdsString"
>
<div class="issuable-info-container">
<div v-if="showCheckbox" class="issue-check">
<gl-form-checkbox
class="gl-mr-0"
:checked="checked"
:data-id="issuableId"
@input="$emit('checked-input', $event)"
<gl-form-checkbox
v-if="showCheckbox"
class="issue-check gl-mr-0"
:checked="checked"
:data-id="issuableId"
@input="$emit('checked-input', $event)"
>
<span class="gl-sr-only">{{ issuable.title }}</span>
</gl-form-checkbox>
<div class="issuable-main-info">
<div data-testid="issuable-title" class="issue-title title">
<gl-icon
v-if="issuable.confidential"
v-gl-tooltip
name="eye-slash"
:title="__('Confidential')"
:aria-label="__('Confidential')"
/>
<gl-link class="issue-title-text" dir="auto" :href="webUrl" v-bind="issuableTitleProps">
{{ issuable.title }}
<gl-icon v-if="isIssuableUrlExternal" name="external-link" class="gl-ml-2" />
</gl-link>
<span
v-if="taskStatus"
class="task-status gl-display-none gl-sm-display-inline-block! gl-ml-3"
data-testid="task-status"
>
<span class="gl-sr-only">{{ issuable.title }}</span>
</gl-form-checkbox>
{{ taskStatus }}
</span>
</div>
<div class="issuable-main-info">
<div data-testid="issuable-title" class="issue-title title">
<span class="issue-title-text" dir="auto">
<gl-icon
v-if="issuable.confidential"
v-gl-tooltip
name="eye-slash"
:title="__('Confidential')"
:aria-label="__('Confidential')"
/>
<gl-link :href="webUrl" v-bind="issuableTitleProps">
{{ issuable.title
}}<gl-icon v-if="isIssuableUrlExternal" name="external-link" class="gl-ml-2"
/></gl-link>
</span>
<span
v-if="taskStatus"
class="task-status gl-display-none gl-sm-display-inline-block! gl-ml-3"
data-testid="task-status"
>
{{ taskStatus }}
</span>
</div>
<div class="issuable-info">
<slot v-if="hasSlotContents('reference')" name="reference"></slot>
<span v-else data-testid="issuable-reference" class="issuable-reference">
{{ reference }}
</span>
<span class="issuable-authored gl-display-none gl-sm-display-inline-block! gl-mr-3">
<span aria-hidden="true">&middot;</span>
<span
v-gl-tooltip:tooltipcontainer.bottom
data-testid="issuable-created-at"
:title="tooltipTitle(issuable.createdAt)"
>{{ createdAt }}</span
>
{{ __('by') }}
<slot v-if="hasSlotContents('author')" name="author"></slot>
<gl-link
v-else
:data-user-id="authorId"
:data-username="author.username"
:data-name="author.name"
:data-avatar-url="author.avatarUrl"
:href="author.webUrl"
data-testid="issuable-author"
class="author-link js-user-link"
>
<span class="author">{{ author.name }}</span>
</gl-link>
<div class="issuable-info">
<slot v-if="hasSlotContents('reference')" name="reference"></slot>
<span v-else data-testid="issuable-reference" class="issuable-reference">
{{ reference }}
</span>
<span class="gl-display-none gl-sm-display-inline-block">
<span aria-hidden="true">&middot;</span>
<span class="issuable-authored gl-mr-3">
<gl-sprintf :message="__('created %{timeAgo} by %{author}')">
<template #timeAgo>
<span
v-gl-tooltip.bottom
:title="tooltipTitle(issuable.createdAt)"
data-testid="issuable-created-at"
>
{{ createdAt }}
</span>
</template>
<template #author>
<slot v-if="hasSlotContents('author')" name="author"></slot>
<gl-link
v-else
:data-user-id="authorId"
:data-username="author.username"
:data-name="author.name"
:data-avatar-url="author.avatarUrl"
:href="author.webUrl"
data-testid="issuable-author"
class="author-link js-user-link"
>
<span class="author">{{ author.name }}</span>
</gl-link>
</template>
</gl-sprintf>
</span>
<slot name="timeframe"></slot>
&nbsp;
<span v-if="labels.length" role="group" :aria-label="__('Labels')">
<gl-label
v-for="(label, index) in labels"
:key="index"
:background-color="label.color"
:title="labelTitle(label)"
:description="label.description"
:scoped="scopedLabel(label)"
:target="labelTarget(label)"
:class="{ 'gl-ml-2': index }"
size="sm"
/>
</span>
</div>
</span>
&nbsp;
<span v-if="labels.length" role="group" :aria-label="__('Labels')">
<gl-label
v-for="(label, index) in labels"
:key="index"
:background-color="label.color"
:title="labelTitle(label)"
:description="label.description"
:scoped="scopedLabel(label)"
:target="labelTarget(label)"
:class="{ 'gl-ml-2': index }"
size="sm"
/>
</span>
</div>
<div class="issuable-meta">
<ul v-if="showIssuableMeta" class="controls">
<li v-if="hasSlotContents('status')" class="issuable-status">
<slot name="status"></slot>
</li>
<li v-if="assignees.length" class="gl-display-flex">
<issuable-assignees
:assignees="assignees"
:icon-size="16"
:max-visible="4"
img-css-classes="gl-mr-2!"
class="gl-align-items-center gl-display-flex gl-ml-3"
/>
</li>
<slot name="statistics"></slot>
<li
v-if="showDiscussions"
data-testid="issuable-discussions"
class="issuable-comments gl-display-none gl-sm-display-block"
>
<gl-link
v-gl-tooltip:tooltipcontainer.top
:title="__('Comments')"
:href="issuableNotesLink"
:class="{ 'no-comments': !notesCount }"
class="gl-reset-color!"
>
<gl-icon name="comments" />
{{ notesCount }}
</gl-link>
</li>
</ul>
<div
data-testid="issuable-updated-at"
class="float-right issuable-updated-at gl-display-none gl-sm-display-inline-block"
</div>
<div class="issuable-meta">
<ul v-if="showIssuableMeta" class="controls">
<li v-if="hasSlotContents('status')" class="issuable-status">
<slot name="status"></slot>
</li>
<li v-if="assignees.length">
<issuable-assignees
:assignees="assignees"
:icon-size="16"
:max-visible="4"
img-css-classes="gl-mr-2!"
class="gl-align-items-center gl-display-flex gl-ml-3"
/>
</li>
<slot name="statistics"></slot>
<li
v-if="showDiscussions"
data-testid="issuable-discussions"
class="issuable-comments gl-display-none gl-sm-display-block"
>
<span
v-gl-tooltip:tooltipcontainer.bottom
:title="tooltipTitle(issuable.updatedAt)"
class="issuable-updated-at"
>{{ updatedAt }}</span
<gl-link
v-gl-tooltip.top
:title="__('Comments')"
:href="issuableNotesLink"
:class="{ 'no-comments': !notesCount }"
class="gl-reset-color!"
>
</div>
<gl-icon name="comments" />
{{ notesCount }}
</gl-link>
</li>
</ul>
<div
v-gl-tooltip.bottom
class="gl-text-gray-500 gl-display-none gl-sm-display-inline-block"
:title="tooltipTitle(issuable.updatedAt)"
data-testid="issuable-updated-at"
>
{{ updatedAt }}
</div>
</div>
</li>
......
......@@ -284,72 +284,70 @@ export default {
<slot name="sidebar-items" :checked-issuables="bulkEditIssuables"></slot>
</template>
</issuable-bulk-edit-sidebar>
<div class="issuables-holder">
<ul v-if="issuablesLoading" class="content-list">
<li v-for="n in skeletonItemCount" :key="n" class="issue gl-px-5! gl-py-5!">
<gl-skeleton-loading />
</li>
</ul>
<template v-else>
<component
:is="issuablesWrapper"
v-if="issuables.length > 0"
class="content-list issuable-list issues-list"
:class="{ 'manual-ordering': isManualOrdering }"
v-bind="$options.vueDraggableAttributes"
@update="handleVueDraggableUpdate"
<ul v-if="issuablesLoading" class="content-list">
<li v-for="n in skeletonItemCount" :key="n" class="issue gl-px-5! gl-py-5!">
<gl-skeleton-loading />
</li>
</ul>
<template v-else>
<component
:is="issuablesWrapper"
v-if="issuables.length > 0"
class="content-list issuable-list issues-list"
:class="{ 'manual-ordering': isManualOrdering }"
v-bind="$options.vueDraggableAttributes"
@update="handleVueDraggableUpdate"
>
<issuable-item
v-for="issuable in issuables"
:key="issuableId(issuable)"
:class="{ 'gl-cursor-grab': isManualOrdering }"
:issuable-symbol="issuableSymbol"
:issuable="issuable"
:enable-label-permalinks="enableLabelPermalinks"
:label-filter-param="labelFilterParam"
:show-checkbox="showBulkEditSidebar"
:checked="issuableChecked(issuable)"
@checked-input="handleIssuableCheckedInput(issuable, $event)"
>
<issuable-item
v-for="issuable in issuables"
:key="issuableId(issuable)"
:class="{ 'gl-cursor-grab': isManualOrdering }"
:issuable-symbol="issuableSymbol"
:issuable="issuable"
:enable-label-permalinks="enableLabelPermalinks"
:label-filter-param="labelFilterParam"
:show-checkbox="showBulkEditSidebar"
:checked="issuableChecked(issuable)"
@checked-input="handleIssuableCheckedInput(issuable, $event)"
>
<template #reference>
<slot name="reference" :issuable="issuable"></slot>
</template>
<template #author>
<slot name="author" :author="issuable.author"></slot>
</template>
<template #timeframe>
<slot name="timeframe" :issuable="issuable"></slot>
</template>
<template #status>
<slot name="status" :issuable="issuable"></slot>
</template>
<template #statistics>
<slot name="statistics" :issuable="issuable"></slot>
</template>
</issuable-item>
</component>
<slot v-else name="empty-state"></slot>
</template>
<template #reference>
<slot name="reference" :issuable="issuable"></slot>
</template>
<template #author>
<slot name="author" :author="issuable.author"></slot>
</template>
<template #timeframe>
<slot name="timeframe" :issuable="issuable"></slot>
</template>
<template #status>
<slot name="status" :issuable="issuable"></slot>
</template>
<template #statistics>
<slot name="statistics" :issuable="issuable"></slot>
</template>
</issuable-item>
</component>
<slot v-else name="empty-state"></slot>
</template>
<div v-if="showPaginationControls && useKeysetPagination" class="gl-text-center gl-mt-3">
<gl-keyset-pagination
:has-next-page="hasNextPage"
:has-previous-page="hasPreviousPage"
@next="$emit('next-page')"
@prev="$emit('previous-page')"
/>
</div>
<gl-pagination
v-else-if="showPaginationControls"
:per-page="defaultPageSize"
:total-items="totalItems"
:value="currentPage"
:prev-page="previousPage"
:next-page="nextPage"
align="center"
class="gl-pagination gl-mt-3"
@input="$emit('page-change', $event)"
<div v-if="showPaginationControls && useKeysetPagination" class="gl-text-center gl-mt-3">
<gl-keyset-pagination
:has-next-page="hasNextPage"
:has-previous-page="hasPreviousPage"
@next="$emit('next-page')"
@prev="$emit('previous-page')"
/>
</div>
<gl-pagination
v-else-if="showPaginationControls"
:per-page="defaultPageSize"
:total-items="totalItems"
:value="currentPage"
:prev-page="previousPage"
:next-page="nextPage"
align="center"
class="gl-pagination gl-mt-3"
@input="$emit('page-change', $event)"
/>
</div>
</template>
......@@ -85,7 +85,7 @@ export default {
<span>
<span
v-if="issue.milestone"
class="issuable-milestone gl-display-none gl-sm-display-inline-block! gl-mr-3"
class="issuable-milestone gl-mr-3"
data-testid="issuable-milestone"
>
<gl-link v-gl-tooltip :href="milestoneLink" :title="milestoneDate">
......@@ -96,7 +96,7 @@ export default {
<span
v-if="issue.dueDate"
v-gl-tooltip
class="issuable-due-date gl-display-none gl-sm-display-inline-block! gl-mr-3"
class="issuable-due-date gl-mr-3"
:class="{ 'gl-text-red-500': showDueDateInRed }"
:title="__('Due date')"
data-testid="issuable-due-date"
......@@ -107,21 +107,14 @@ export default {
<span
v-if="timeEstimate"
v-gl-tooltip
class="gl-display-none gl-sm-display-inline-block! gl-mr-3"
class="gl-mr-3"
:title="__('Estimate')"
data-testid="time-estimate"
>
<gl-icon name="timer" />
{{ timeEstimate }}
</span>
<weight-count
class="issuable-weight gl-display-none gl-sm-display-inline-block gl-mr-3"
:weight="issue.weight"
/>
<issue-health-status
v-if="showHealthStatus"
class="gl-display-none gl-sm-display-inline-block"
:health-status="healthStatus"
/>
<weight-count class="issuable-weight gl-mr-3" :weight="issue.weight" />
<issue-health-status v-if="showHealthStatus" :health-status="healthStatus" />
</span>
</template>
......@@ -77,7 +77,7 @@ export default {
};
</script>
<template>
<div class="issue-assignees">
<div>
<user-avatar-link
v-for="assignee in assigneesToShow"
:key="assignee.id"
......@@ -97,10 +97,9 @@ export default {
</user-avatar-link>
<span
v-if="numHiddenAssignees > 0"
v-gl-tooltip
v-gl-tooltip.bottom
:title="assigneesCounterTooltip"
class="avatar-counter"
data-placement="bottom"
data-qa-selector="avatar_counter_content"
>{{ assigneeCounterLabel }}</span
>
......
......@@ -673,40 +673,40 @@
.issuable-info-container {
flex: 1;
display: flex;
}
.issuable-main-info {
flex: 1 auto;
margin-right: 10px;
min-width: 0;
.issuable-main-info {
flex: 1 auto;
margin-right: 10px;
min-width: 0;
.issue-weight-icon,
.issue-estimate-icon {
vertical-align: sub;
}
.issue-weight-icon,
.issue-estimate-icon {
vertical-align: sub;
}
}
.issuable-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
flex: 1 0 auto;
.controls {
margin-bottom: 2px;
line-height: 20px;
padding: 0;
}
.issuable-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
flex: 1 0 auto;
.issue-updated-at {
line-height: 20px;
}
.controls {
margin-bottom: 2px;
line-height: 20px;
padding: 0;
}
@include media-breakpoint-down(xs) {
.issuable-meta {
.controls li {
margin-right: 0;
}
.issue-updated-at {
line-height: 20px;
}
}
@include media-breakpoint-down(xs) {
.issuable-meta {
.controls li {
margin-right: 0;
}
}
}
......
......@@ -41,6 +41,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml)
push_frontend_feature_flag(:diffs_virtual_scrolling, project, default_enabled: :yaml)
push_frontend_feature_flag(:restructured_mr_widget, project, default_enabled: :yaml)
push_frontend_feature_flag(:mr_changes_fluid_layout, project, default_enabled: :yaml)
# Usage data feature flags
push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml)
......
---
name: mr_changes_fluid_layout
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70815
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341809
milestone: '14.4'
type: development
group: group::code review
default_enabled: false
......@@ -4,7 +4,7 @@ Rails.backtrace_cleaner.remove_silencers!
# This allows us to see the proper caller of SQL calls in {development,test}.log
if (Rails.env.development? || Rails.env.test?) && Gitlab.ee?
Rails.backtrace_cleaner.add_silencer { |line| %r(^ee/lib/gitlab/database/load_balancing).match?(line) }
Rails.backtrace_cleaner.add_silencer { |line| %r(^lib/gitlab/database/load_balancing).match?(line) }
end
Rails.backtrace_cleaner.add_silencer { |line| !Gitlab::APP_DIRS_PATTERN.match?(line) }
......@@ -9,6 +9,7 @@ type: index, concepts, howto
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/4466) in GitLab Ultimate 10.6.
> - [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24780) to GitLab Free in 11.9.
> - `CHAT_USER_ID` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341798) in GitLab 14.4.
GitLab ChatOps provides a method to interact with CI/CD jobs through chat services
like Slack. Many organizations' discussion, collaboration, and troubleshooting takes
......@@ -30,6 +31,7 @@ to the job:
- `CHAT_INPUT` contains any additional arguments.
- `CHAT_CHANNEL` is set to the name of channel the action was triggered in.
- `CHAT_USER_ID` is set to the chat service's user ID of the user who triggered the slash command.
When executed, ChatOps looks up the specified job name and attempts to match it
to a corresponding job in [`.gitlab-ci.yml`](../yaml/index.md). If a matching job
......
......@@ -20,6 +20,7 @@ There are also [Kubernetes-specific deployment variables](../../user/project/clu
|------------------------------------------|--------|--------|-------------|
| `CHAT_CHANNEL` | 10.6 | all | The Source chat channel that triggered the [ChatOps](../chatops/index.md) command. |
| `CHAT_INPUT` | 10.6 | all | The additional arguments passed with the [ChatOps](../chatops/index.md) command. |
| `CHAT_USER_ID` | 14.4 | all | The chat service's user ID of the user who triggered the [ChatOps](../chatops/index.md) command. |
| `CI` | all | 0.4 | Available for all jobs executed in CI/CD. `true` when available. |
| `CI_API_V4_URL` | 11.7 | all | The GitLab API v4 root URL. |
| `CI_BUILDS_DIR` | all | 11.10 | The top-level directory where builds are executed. |
......
......@@ -24,11 +24,11 @@ export default {
</script>
<template>
<div class="health-status">
<span class="health-status">
<span class="gl-label gl-label-sm" :class="statusClass">
<span v-gl-tooltip class="gl-label-text" :title="__('Health status')">
{{ statusText }}
</span>
</span>
</div>
</span>
</template>
......@@ -240,20 +240,19 @@ RSpec.describe 'epics list', :js do
end
it 'renders epics item with metadata', :aggregate_failures do
page.within('.issuable-list-container .issuable-list') do
expect(page.all('.issuable-info-container')[0].find('.issue-title')).to have_content(epic2.title)
expect(page.all('.issuable-info-container')[0].find('.issuable-reference')).to have_content("&#{epic2.iid}")
expect(page.all('.issuable-info-container')[0].find('.issuable-authored')).to have_content('created')
expect(page.all('.issuable-info-container')[0].find('.issuable-authored')).to have_content("by #{epic2.author.name}")
page.within('.issuable-list .issue:first-of-type') do
expect(page).to have_link(epic2.title)
expect(page).to have_text("&#{epic2.iid}")
expect(page).to have_text("created just now by #{epic2.author.name}")
end
end
it 'renders epic item timeframe', :aggregate_failures do
page.within('.issuable-list-container .issuable-list') do
expect(page.all('.issuable-info-container')[0].find('.issuable-info')).to have_content('Dec 15, 2020 – No due date')
expect(page.all('.issuable-info-container')[1].find('.issuable-info')).to have_content('Dec 15, 2020 – Jan 15, 2021')
expect(page.all('.issuable-info-container')[2].find('.issuable-info')).to have_content('No start date – Jan 15, 2021')
end
issues = page.all('.issue')
expect(issues[0]).to have_text('Dec 15, 2020 – No due date')
expect(issues[1]).to have_text('Dec 15, 2020 – Jan 15, 2021')
expect(issues[2]).to have_text('No start date – Jan 15, 2021')
end
end
......
......@@ -74,12 +74,11 @@ RSpec.describe 'Test Cases', :js do
it 'shows test cases title and metadata' do
page.within('.issuable-list-container .issuable-list li.issue', match: :first) do
expect(page.find('.issue-title')).to have_content(test_case1.title)
expect(page.find('.issuable-reference')).to have_content("##{test_case1.iid}")
expect(page.find('.issuable-info')).to have_link(label.title, href: "?label_name[]=#{label.title}")
expect(page.find('.issuable-authored')).to have_content('created 5 days ago by')
expect(page.find('.author')).to have_content(user.name)
expect(page.find('div.issuable-updated-at')).to have_content('updated 2 days ago')
expect(page).to have_link(test_case1.title)
expect(page).to have_text("##{test_case1.iid}")
expect(page).to have_link(label.title, href: "?label_name[]=#{label.title}")
expect(page).to have_text("created 5 days ago by #{user.name}")
expect(page).to have_text('updated 2 days ago')
end
end
end
......
......@@ -66,7 +66,8 @@ module Gitlab
def build_environment_variables(pipeline)
pipeline.variables.build(
[{ key: 'CHAT_INPUT', value: arguments },
{ key: 'CHAT_CHANNEL', value: channel }]
{ key: 'CHAT_CHANNEL', value: channel },
{ key: 'CHAT_USER_ID', value: chat_name.chat_id }]
)
end
......
......@@ -39900,6 +39900,9 @@ msgstr ""
msgid "created %{timeAgo}"
msgstr ""
msgid "created %{timeAgo} by %{author}"
msgstr ""
msgid "created by"
msgstr ""
......
......@@ -702,4 +702,23 @@ describe('diffs/components/app', () => {
);
});
});
describe('fluid layout', () => {
beforeEach(() => {
setFixtures(
'<div><div class="merge-request-container limit-container-width container-limited"></div></div>',
);
});
it('removes limited container classes when on diffs tab', () => {
createComponent({ isFluidLayout: false, shouldShow: true }, () => {}, {
glFeatures: { mrChangesFluidLayout: true },
});
const containerClassList = document.querySelector('.merge-request-container').classList;
expect(containerClassList).not.toContain('container-limited');
expect(containerClassList).not.toContain('limit-container-width');
});
});
});
import { GlLink, GlLabel, GlIcon, GlFormCheckbox } from '@gitlab/ui';
import { GlLink, GlLabel, GlIcon, GlFormCheckbox, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { useFakeDate } from 'helpers/fake_date';
import IssuableItem from '~/issuable_list/components/issuable_item.vue';
......@@ -16,6 +16,9 @@ const createComponent = ({ issuableSymbol = '#', issuable = mockIssuable, slots
showCheckbox: false,
},
slots,
stubs: {
GlSprintf,
},
});
const MOCK_GITLAB_URL = 'http://0.0.0.0:3000';
......@@ -135,13 +138,6 @@ describe('IssuableItem', () => {
});
});
describe('createdAt', () => {
it('returns string containing timeago string based on `issuable.createdAt`', () => {
expect(wrapper.vm.createdAt).toContain('created');
expect(wrapper.vm.createdAt).toContain('ago');
});
});
describe('updatedAt', () => {
it('returns string containing timeago string based on `issuable.updatedAt`', () => {
expect(wrapper.vm.updatedAt).toContain('updated');
......@@ -449,8 +445,7 @@ describe('IssuableItem', () => {
it('renders issuable updatedAt info', () => {
const updatedAtEl = wrapper.find('[data-testid="issuable-updated-at"]');
expect(updatedAtEl.exists()).toBe(true);
expect(updatedAtEl.find('span').attributes('title')).toBe('Sep 10, 2020 11:41am UTC');
expect(updatedAtEl.attributes('title')).toBe('Sep 10, 2020 11:41am UTC');
expect(updatedAtEl.text()).toBe(wrapper.vm.updatedAt);
});
......
......@@ -94,10 +94,6 @@ describe('IssueAssigneesComponent', () => {
expect(vm.avatarUrlTitle(mockAssigneesList[0])).toBe('Assigned to Terrell Graham');
});
it('renders component root element with class `issue-assignees`', () => {
expect(wrapper.element.classList.contains('issue-assignees')).toBe(true);
});
it('renders assignee', () => {
const data = findAvatars().wrappers.map((x) => ({
...x.props(),
......
......@@ -72,6 +72,7 @@ RSpec.describe Gitlab::Chat::Command do
expect(vars['CHAT_INPUT']).to eq('foo')
expect(vars['CHAT_CHANNEL']).to eq('123')
expect(vars['CHAT_USER_ID']).to eq(chat_name.chat_id)
end
end
end
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