Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/dropzone_input.js3
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_item.vue79
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_list_root.vue45
-rw-r--r--app/assets/javascripts/issuable_list/components/issuable_tabs.vue5
-rw-r--r--app/assets/javascripts/issuable_list/constants.js49
-rw-r--r--app/assets/javascripts/notes/components/note_attachment.vue7
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue7
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue9
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/estimate_only_pane.vue5
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/help_state.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/no_tracking_pane.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue10
-rw-r--r--app/assets/javascripts/tracking.js1
-rw-r--r--app/assets/stylesheets/_page_specific_files.scss1
-rw-r--r--app/assets/stylesheets/fontawesome_custom.scss4
-rw-r--r--app/assets/stylesheets/page_bundles/ci_status.scss (renamed from app/assets/stylesheets/pages/status.scss)2
-rw-r--r--app/assets/stylesheets/page_bundles/todos.scss1
20 files changed, 203 insertions, 39 deletions
diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js
index f65e22a31c5..f56c402091f 100644
--- a/app/assets/javascripts/dropzone_input.js
+++ b/app/assets/javascripts/dropzone_input.js
@@ -7,6 +7,7 @@ import csrf from './lib/utils/csrf';
import axios from './lib/utils/axios_utils';
import { n__, __ } from '~/locale';
import { getFilename } from '~/lib/utils/file_upload';
+import { spriteIcon } from '~/lib/utils/common_utils';
Dropzone.autoDiscover = false;
@@ -25,7 +26,7 @@ function getErrorMessage(res) {
export default function dropzoneInput(form, config = { parallelUploads: 2 }) {
const divHover = '<div class="div-dropzone-hover"></div>';
- const iconPaperclip = '<i class="fa fa-paperclip div-dropzone-icon"></i>';
+ const iconPaperclip = spriteIcon('paperclip', 'div-dropzone-icon');
const $attachButton = form.find('.button-attach-file');
const $attachingFileMessage = form.find('.attaching-file-message');
const $cancelButton = form.find('.button-cancel-uploading-files');
diff --git a/app/assets/javascripts/issuable_list/components/issuable_item.vue b/app/assets/javascripts/issuable_list/components/issuable_item.vue
index d8cb1ab07cd..283e49c287a 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_item.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_item.vue
@@ -1,15 +1,20 @@
<script>
-import { GlLink, GlLabel, GlTooltipDirective } from '@gitlab/ui';
+import { GlLink, GlIcon, GlLabel, GlTooltipDirective } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { getTimeago } from '~/lib/utils/datetime_utility';
import { isScopedLabel } from '~/lib/utils/common_utils';
import timeagoMixin from '~/vue_shared/mixins/timeago';
+import IssuableAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
+
export default {
components: {
GlLink,
+ GlIcon,
GlLabel,
+ IssuableAssignees,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -24,25 +29,33 @@ export default {
type: Object,
required: true,
},
+ enableLabelPermalinks: {
+ type: Boolean,
+ required: true,
+ },
},
computed: {
author() {
return this.issuable.author;
},
authorId() {
- const id = parseInt(this.author.id, 10);
-
- if (Number.isNaN(id)) {
- return this.author.id.includes('gid')
- ? this.author.id.split('gid://gitlab/User/').pop()
- : '';
+ return getIdFromGraphQLId(`${this.author.id}`);
+ },
+ isIssuableUrlExternal() {
+ // Check if URL is relative, which means it is internal.
+ if (!/^https?:\/\//g.test(this.issuable.webUrl)) {
+ return false;
}
-
- return id;
+ // In case URL is absolute, it may or may not be internal,
+ // hence use `gon.gitlab_url` which is current instance domain.
+ return !this.issuable.webUrl.includes(gon.gitlab_url);
},
labels() {
return this.issuable.labels?.nodes || this.issuable.labels || [];
},
+ assignees() {
+ return this.issuable.assignees || [];
+ },
createdAt() {
return sprintf(__('created %{timeAgo}'), {
timeAgo: getTimeago().format(this.issuable.createdAt),
@@ -53,11 +66,33 @@ export default {
timeAgo: getTimeago().format(this.issuable.updatedAt),
});
},
+ issuableTitleProps() {
+ if (this.isIssuableUrlExternal) {
+ return {
+ target: '_blank',
+ };
+ }
+ return {};
+ },
},
methods: {
+ hasSlotContents(slotName) {
+ return Boolean(this.$slots[slotName]);
+ },
scopedLabel(label) {
return isScopedLabel(label);
},
+ labelTitle(label) {
+ return label.title || label.name;
+ },
+ labelTarget(label) {
+ if (this.enableLabelPermalinks) {
+ const key = encodeURIComponent('label_name[]');
+ const value = encodeURIComponent(this.labelTitle(label));
+ return `?${key}=${value}`;
+ }
+ return '#';
+ },
/**
* This is needed as an independent method since
* when user changes current page, `$refs.authorLink`
@@ -74,17 +109,20 @@ export default {
</script>
<template>
- <li class="issue">
+ <li class="issue px-3">
<div class="issue-box">
<div class="issuable-info-container">
<div class="issuable-main-info">
<div data-testid="issuable-title" class="issue-title title">
<span class="issue-title-text" dir="auto">
- <gl-link :href="issuable.webUrl">{{ issuable.title }}</gl-link>
+ <gl-link :href="issuable.webUrl" v-bind="issuableTitleProps"
+ >{{ issuable.title }}<gl-icon v-if="isIssuableUrlExternal" name="external-link"
+ /></gl-link>
</span>
</div>
<div class="issuable-info">
- <span data-testid="issuable-reference" class="issuable-reference"
+ <slot v-if="hasSlotContents('reference')" name="reference"></slot>
+ <span v-else data-testid="issuable-reference" class="issuable-reference"
>{{ issuableSymbol }}{{ issuable.iid }}</span
>
<span class="issuable-authored d-none d-sm-inline-block">
@@ -113,15 +151,30 @@ export default {
v-for="(label, index) in labels"
:key="index"
:background-color="label.color"
- :title="label.title"
+ :title="labelTitle(label)"
:description="label.description"
:scoped="scopedLabel(label)"
+ :target="labelTarget(label)"
:class="{ 'gl-ml-2': index }"
size="sm"
/>
</div>
</div>
<div class="issuable-meta">
+ <ul v-if="hasSlotContents('status') || issuable.assignees" 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="issuable.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>
+ </ul>
<div
data-testid="issuable-updated-at"
class="float-right issuable-updated-at d-none d-sm-inline-block"
diff --git a/app/assets/javascripts/issuable_list/components/issuable_list_root.vue b/app/assets/javascripts/issuable_list/components/issuable_list_root.vue
index 7535203dea1..52ebb9acdc3 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_list_root.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_list_root.vue
@@ -1,6 +1,7 @@
<script>
import { GlLoadingIcon, GlPagination } from '@gitlab/ui';
+import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import IssuableTabs from './issuable_tabs.vue';
@@ -35,6 +36,11 @@ export default {
type: Array,
required: true,
},
+ urlParams: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
initialFilterValue: {
type: Array,
required: false,
@@ -55,7 +61,8 @@ export default {
},
tabCounts: {
type: Object,
- required: true,
+ required: false,
+ default: null,
},
currentTab: {
type: String,
@@ -81,6 +88,11 @@ export default {
required: false,
default: 20,
},
+ totalPages: {
+ type: Number,
+ required: false,
+ default: 0,
+ },
currentPage: {
type: Number,
required: false,
@@ -96,6 +108,26 @@ export default {
required: false,
default: 2,
},
+ enableLabelPermalinks: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ },
+ watch: {
+ urlParams: {
+ deep: true,
+ immediate: true,
+ handler(params) {
+ if (Object.keys(params).length) {
+ updateHistory({
+ url: setUrlParams(params, window.location.href, true),
+ title: document.title,
+ replace: true,
+ });
+ }
+ },
+ },
},
};
</script>
@@ -135,12 +167,21 @@ export default {
:key="issuable.id"
:issuable-symbol="issuableSymbol"
:issuable="issuable"
- />
+ :enable-label-permalinks="enableLabelPermalinks"
+ >
+ <template #reference>
+ <slot name="reference" :issuable="issuable"></slot>
+ </template>
+ <template #status>
+ <slot name="status" :issuable="issuable"></slot>
+ </template>
+ </issuable-item>
</ul>
<slot v-if="!issuablesLoading && !issuables.length" name="empty-state"></slot>
<gl-pagination
v-if="showPaginationControls"
:per-page="defaultPageSize"
+ :total-items="totalPages"
:value="currentPage"
:prev-page="previousPage"
:next-page="nextPage"
diff --git a/app/assets/javascripts/issuable_list/components/issuable_tabs.vue b/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
index df544ce69e7..d9aab004077 100644
--- a/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
+++ b/app/assets/javascripts/issuable_list/components/issuable_tabs.vue
@@ -14,7 +14,8 @@ export default {
},
tabCounts: {
type: Object,
- required: true,
+ required: false,
+ default: null,
},
currentTab: {
type: String,
@@ -40,7 +41,7 @@ export default {
>
<template #title>
<span :title="tab.titleTooltip">{{ tab.title }}</span>
- <gl-badge variant="neutral" size="sm" class="gl-px-2 gl-py-1!">{{
+ <gl-badge v-if="tabCounts" variant="neutral" size="sm" class="gl-px-2 gl-py-1!">{{
tabCounts[tab.name]
}}</gl-badge>
</template>
diff --git a/app/assets/javascripts/issuable_list/constants.js b/app/assets/javascripts/issuable_list/constants.js
new file mode 100644
index 00000000000..4d3ce61366a
--- /dev/null
+++ b/app/assets/javascripts/issuable_list/constants.js
@@ -0,0 +1,49 @@
+import { __ } from '~/locale';
+
+export const IssuableStates = {
+ Opened: 'opened',
+ Closed: 'closed',
+ All: 'all',
+};
+
+export const IssuableListTabs = [
+ {
+ id: 'state-opened',
+ name: IssuableStates.Opened,
+ title: __('Open'),
+ titleTooltip: __('Filter by issues that are currently opened.'),
+ },
+ {
+ id: 'state-closed',
+ name: IssuableStates.Closed,
+ title: __('Closed'),
+ titleTooltip: __('Filter by issues that are currently closed.'),
+ },
+ {
+ id: 'state-all',
+ name: IssuableStates.All,
+ title: __('All'),
+ titleTooltip: __('Show all issues.'),
+ },
+];
+
+export const AvailableSortOptions = [
+ {
+ id: 1,
+ title: __('Created date'),
+ sortDirection: {
+ descending: 'created_desc',
+ ascending: 'created_asc',
+ },
+ },
+ {
+ id: 2,
+ title: __('Last updated'),
+ sortDirection: {
+ descending: 'updated_desc',
+ ascending: 'updated_asc',
+ },
+ },
+];
+
+export const DEFAULT_PAGE_SIZE = 20;
diff --git a/app/assets/javascripts/notes/components/note_attachment.vue b/app/assets/javascripts/notes/components/note_attachment.vue
index 72f9a4c7e74..b20facc4032 100644
--- a/app/assets/javascripts/notes/components/note_attachment.vue
+++ b/app/assets/javascripts/notes/components/note_attachment.vue
@@ -1,6 +1,11 @@
<script>
+import { GlIcon } from '@gitlab/ui';
+
export default {
name: 'NoteAttachment',
+ components: {
+ GlIcon,
+ },
props: {
attachment: {
type: Object,
@@ -29,7 +34,7 @@ export default {
target="_blank"
rel="noopener noreferrer"
>
- <i class="fa fa-paperclip" aria-hidden="true"> </i> {{ attachment.filename }}
+ <gl-icon name="paperclip" /> {{ attachment.filename }}
</a>
</div>
</div>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue
index 97595e5d2ce..e52afe08336 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue
@@ -87,7 +87,7 @@ export default {
:aria-label="__('Run manual or delayed jobs')"
>
<gl-icon name="play" class="icon-play" />
- <i class="fa fa-caret-down" aria-hidden="true"></i>
+ <gl-icon name="chevron-down" />
<gl-loading-icon v-if="isLoading" />
</button>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue
index 4a3d134685e..55c71e299be 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_artifacts.vue
@@ -29,7 +29,7 @@ export default {
:aria-label="__('Artifacts')"
>
<gl-icon name="download" />
- <i class="fa fa-caret-down" aria-hidden="true"></i>
+ <gl-icon name="chevron-down" />
</button>
<ul class="dropdown-menu dropdown-menu-right">
<li v-for="(artifact, i) in artifacts" :key="i">
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue b/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue
index 9d72bf4394e..7b67c34ded6 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/collapsed_state.vue
@@ -96,7 +96,12 @@ export default {
</script>
<template>
- <div v-gl-tooltip:body.viewport.left :title="tooltipText" class="sidebar-collapsed-icon">
+ <div
+ v-gl-tooltip:body.viewport.left
+ :title="tooltipText"
+ data-testid="collapsedState"
+ class="sidebar-collapsed-icon"
+ >
<gl-icon name="timer" />
<div class="time-tracking-collapsed-summary">
<div :class="divClass">
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
index d4cc98e3743..99302993b9a 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
@@ -70,14 +70,19 @@ export default {
</script>
<template>
- <div class="time-tracking-comparison-pane">
+ <div data-testid="timeTrackingComparisonPane">
<div
v-gl-tooltip
+ data-testid="compareMeter"
:title="timeRemainingTooltip"
:class="timeRemainingStatusClass"
class="compare-meter"
>
- <gl-progress-bar :value="timeRemainingPercent" :variant="progressBarVariant" />
+ <gl-progress-bar
+ data-testid="timeRemainingProgress"
+ :value="timeRemainingPercent"
+ :variant="progressBarVariant"
+ />
<div class="compare-display-container">
<div class="compare-display float-left">
<span class="compare-label">{{ s__('TimeTracking|Spent') }}</span>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/estimate_only_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/estimate_only_pane.vue
index 305726d9725..8a80b1bf13f 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/estimate_only_pane.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/estimate_only_pane.vue
@@ -11,7 +11,8 @@ export default {
</script>
<template>
- <div class="time-tracking-estimate-only-pane">
- <span class="bold"> {{ s__('TimeTracking|Estimated:') }} </span> {{ timeEstimateHumanReadable }}
+ <div data-testid="estimateOnlyPane">
+ <span class="gl-font-weight-bold">{{ s__('TimeTracking|Estimated:') }} </span
+ >{{ timeEstimateHumanReadable }}
</div>
</template>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue b/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue
index b45746e789d..8bc828091c0 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/help_state.vue
@@ -34,7 +34,7 @@ export default {
</script>
<template>
- <div class="time-tracking-help-state">
+ <div data-testid="helpPane" class="time-tracking-help-state">
<div class="time-tracking-info">
<h4>{{ __('Track time with quick actions') }}</h4>
<p>{{ __('Quick actions can be used in the issues description and comment boxes.') }}</p>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/no_tracking_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/no_tracking_pane.vue
index 45552589e50..2d3d0ce8dc5 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/no_tracking_pane.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/no_tracking_pane.vue
@@ -5,7 +5,7 @@ export default {
</script>
<template>
- <div class="time-tracking-no-tracking-pane">
- <span class="no-value"> {{ __('No estimate or time spent') }} </span>
+ <div data-testid="noTrackingPane">
+ <span class="no-value">{{ __('No estimate or time spent') }}</span>
</div>
</template>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
index b2b3b289c5c..33c6ac6e2ba 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/spent_only_pane.vue
@@ -15,7 +15,7 @@ export default {
return sprintf(
s__('TimeTracking|%{startTag}Spent: %{endTag}%{timeSpentHumanReadable}'),
{
- startTag: '<span class="bold">',
+ startTag: '<span class="gl-font-weight-bold">',
endTag: '</span>',
timeSpentHumanReadable: this.timeSpentHumanReadable,
},
@@ -27,5 +27,5 @@ export default {
</script>
<template>
- <div class="time-tracking-spend-only-pane" v-html="timeSpent"></div>
+ <div data-testid="spentOnlyPane" v-html="timeSpent"></div>
</template>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
index a2fb0ebcbc6..95864462a68 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -105,11 +105,17 @@ export default {
/>
<div class="title hide-collapsed">
{{ __('Time tracking') }}
- <div v-if="!showHelpState" class="help-button float-right" @click="toggleHelpState(true)">
+ <div
+ v-if="!showHelpState"
+ data-testid="helpButton"
+ class="help-button float-right"
+ @click="toggleHelpState(true)"
+ >
<gl-icon name="question-o" />
</div>
<div
- v-if="showHelpState"
+ v-else
+ data-testid="closeHelpButton"
class="close-help-button float-right"
@click="toggleHelpState(false)"
>
diff --git a/app/assets/javascripts/tracking.js b/app/assets/javascripts/tracking.js
index c1521882682..0a1211d0a76 100644
--- a/app/assets/javascripts/tracking.js
+++ b/app/assets/javascripts/tracking.js
@@ -12,6 +12,7 @@ const DEFAULT_SNOWPLOW_OPTIONS = {
contexts: { webPage: true, performanceTiming: true },
formTracking: false,
linkClickTracking: false,
+ pageUnloadTimer: 10,
};
const createEventPayload = (el, { suffix = '' } = {}) => {
diff --git a/app/assets/stylesheets/_page_specific_files.scss b/app/assets/stylesheets/_page_specific_files.scss
index a31cb0b0485..ad4d42abae6 100644
--- a/app/assets/stylesheets/_page_specific_files.scss
+++ b/app/assets/stylesheets/_page_specific_files.scss
@@ -39,7 +39,6 @@
@import './pages/settings';
@import './pages/settings_ci_cd';
@import './pages/sherlock';
-@import './pages/status';
@import './pages/storage_quota';
@import './pages/tree';
@import './pages/trials';
diff --git a/app/assets/stylesheets/fontawesome_custom.scss b/app/assets/stylesheets/fontawesome_custom.scss
index 7b1953be69d..937ed5119cb 100644
--- a/app/assets/stylesheets/fontawesome_custom.scss
+++ b/app/assets/stylesheets/fontawesome_custom.scss
@@ -117,10 +117,6 @@
content: '\f077';
}
-.fa-paperclip::before {
- content: '\f0c6';
-}
-
.fa-bug::before {
content: '\f188';
}
diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/page_bundles/ci_status.scss
index b37c5172ad2..8522a0a8fe4 100644
--- a/app/assets/stylesheets/pages/status.scss
+++ b/app/assets/stylesheets/page_bundles/ci_status.scss
@@ -1,3 +1,5 @@
+@import 'mixins_and_variables_and_functions';
+
.ci-status {
padding: 2px 7px 4px;
border: 1px solid $gray-darker;
diff --git a/app/assets/stylesheets/page_bundles/todos.scss b/app/assets/stylesheets/page_bundles/todos.scss
index 3eec5b53a30..3e20ca9c62f 100644
--- a/app/assets/stylesheets/page_bundles/todos.scss
+++ b/app/assets/stylesheets/page_bundles/todos.scss
@@ -219,7 +219,6 @@
.todos-empty-content {
align-self: center;
max-width: 480px;
- margin-right: 20px;
}
.todos-empty-hero {