diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-10 21:14:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-10 21:14:42 +0300 |
commit | ca5de528358c23e9cfcb0ff0f42c4106310c3811 (patch) | |
tree | 92a0375549df74e40c3f3799a5de7a91fcd1a3a7 /app/assets/javascripts/jobs | |
parent | ecc11e5d608ff4393fb6c44d02416569e7d2785d (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/jobs')
6 files changed, 201 insertions, 4 deletions
diff --git a/app/assets/javascripts/jobs/bridge/app.vue b/app/assets/javascripts/jobs/bridge/app.vue new file mode 100644 index 00000000000..67c22712776 --- /dev/null +++ b/app/assets/javascripts/jobs/bridge/app.vue @@ -0,0 +1,20 @@ +<script> +import BridgeEmptyState from './components/empty_state.vue'; +import BridgeSidebar from './components/sidebar.vue'; + +export default { + name: 'BridgePageApp', + components: { + BridgeEmptyState, + BridgeSidebar, + }, +}; +</script> +<template> + <div> + <!-- TODO: get job details and show CI header --> + <!-- TODO: add downstream pipeline path --> + <bridge-empty-state downstream-pipeline-path="#" /> + <bridge-sidebar /> + </div> +</template> diff --git a/app/assets/javascripts/jobs/bridge/components/constants.js b/app/assets/javascripts/jobs/bridge/components/constants.js new file mode 100644 index 00000000000..33310b3157a --- /dev/null +++ b/app/assets/javascripts/jobs/bridge/components/constants.js @@ -0,0 +1 @@ +export const SIDEBAR_COLLAPSE_BREAKPOINTS = ['xs', 'sm']; diff --git a/app/assets/javascripts/jobs/bridge/components/empty_state.vue b/app/assets/javascripts/jobs/bridge/components/empty_state.vue new file mode 100644 index 00000000000..bd07d863719 --- /dev/null +++ b/app/assets/javascripts/jobs/bridge/components/empty_state.vue @@ -0,0 +1,45 @@ +<script> +import { GlButton } from '@gitlab/ui'; +import { __ } from '~/locale'; + +export default { + name: 'BridgeEmptyState', + i18n: { + title: __('This job triggers a downstream pipeline'), + linkBtnText: __('View downstream pipeline'), + }, + components: { + GlButton, + }, + inject: { + emptyStateIllustrationPath: { + type: String, + require: true, + }, + }, + props: { + downstreamPipelinePath: { + type: String, + required: false, + default: undefined, + }, + }, +}; +</script> + +<template> + <div class="gl-display-flex gl-flex-direction-column gl-align-items-center gl-mt-11"> + <img :src="emptyStateIllustrationPath" /> + <h1 class="gl-font-size-h1">{{ $options.i18n.title }}</h1> + <gl-button + v-if="downstreamPipelinePath" + class="gl-mt-3" + category="secondary" + variant="confirm" + size="medium" + :href="downstreamPipelinePath" + > + {{ $options.i18n.linkBtnText }} + </gl-button> + </div> +</template> diff --git a/app/assets/javascripts/jobs/bridge/components/sidebar.vue b/app/assets/javascripts/jobs/bridge/components/sidebar.vue new file mode 100644 index 00000000000..68b767408f0 --- /dev/null +++ b/app/assets/javascripts/jobs/bridge/components/sidebar.vue @@ -0,0 +1,98 @@ +<script> +import { GlButton, GlDropdown, GlDropdownItem } from '@gitlab/ui'; +import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils'; +import { __ } from '~/locale'; +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; +import { JOB_SIDEBAR } from '../../constants'; +import { SIDEBAR_COLLAPSE_BREAKPOINTS } from './constants'; + +export default { + styles: { + top: '75px', + width: '290px', + }, + name: 'BridgeSidebar', + i18n: { + ...JOB_SIDEBAR, + retryButton: __('Retry'), + retryTriggerJob: __('Retry the trigger job'), + retryDownstreamPipeline: __('Retry the downstream pipeline'), + }, + borderTopClass: ['gl-border-t-solid', 'gl-border-t-1', 'gl-border-t-gray-100'], + components: { + GlButton, + GlDropdown, + GlDropdownItem, + TooltipOnTruncate, + }, + inject: { + buildName: { + type: String, + default: '', + }, + }, + data() { + return { + isSidebarExpanded: true, + }; + }, + created() { + window.addEventListener('resize', this.onResize); + }, + mounted() { + this.onResize(); + }, + methods: { + toggleSidebar() { + this.isSidebarExpanded = !this.isSidebarExpanded; + }, + onResize() { + const breakpoint = bp.getBreakpointSize(); + if (SIDEBAR_COLLAPSE_BREAKPOINTS.includes(breakpoint)) { + this.isSidebarExpanded = false; + } else if (!this.isSidebarExpanded) { + this.isSidebarExpanded = true; + } + }, + }, +}; +</script> +<template> + <aside + class="gl-fixed gl-right-0 gl-px-5 gl-bg-gray-10 gl-h-full gl-border-l-solid gl-border-1 gl-border-gray-100 gl-z-index-200 gl-overflow-hidden" + :style="this.$options.styles" + :class="{ + 'gl-display-none': !isSidebarExpanded, + }" + > + <div class="gl-py-5 gl-display-flex gl-align-items-center"> + <tooltip-on-truncate :title="buildName" truncate-target="child" + ><h4 class="gl-mb-0 gl-mr-2 gl-text-truncate"> + {{ buildName }} + </h4> + </tooltip-on-truncate> + <!-- TODO: implement retry actions --> + <div class="gl-flex-grow-1 gl-flex-shrink-0 gl-text-right"> + <gl-dropdown + :text="$options.i18n.retryButton" + category="primary" + variant="confirm" + right + size="medium" + > + <gl-dropdown-item>{{ $options.i18n.retryTriggerJob }}</gl-dropdown-item> + <gl-dropdown-item>{{ $options.i18n.retryDownstreamPipeline }}</gl-dropdown-item> + </gl-dropdown> + </div> + <gl-button + :aria-label="$options.i18n.toggleSidebar" + data-testid="sidebar-expansion-toggle" + category="tertiary" + class="gl-md-display-none gl-ml-2" + icon="chevron-double-lg-right" + @click="toggleSidebar" + /> + </div> + <!-- TODO: get job details and show commit block, stage dropdown, jobs list --> + </aside> +</template> diff --git a/app/assets/javascripts/jobs/components/job_log_controllers.vue b/app/assets/javascripts/jobs/components/job_log_controllers.vue index 6105299e15c..97141a27a5e 100644 --- a/app/assets/javascripts/jobs/components/job_log_controllers.vue +++ b/app/assets/javascripts/jobs/components/job_log_controllers.vue @@ -5,7 +5,7 @@ import { __, s__, sprintf } from '~/locale'; export default { i18n: { - eraseLogButtonLabel: s__('Job|Erase job log'), + eraseLogButtonLabel: s__('Job|Erase job log and artifacts'), scrollToBottomButtonLabel: s__('Job|Scroll to bottom'), scrollToTopButtonLabel: s__('Job|Scroll to top'), showRawButtonLabel: s__('Job|Show complete raw'), diff --git a/app/assets/javascripts/jobs/index.js b/app/assets/javascripts/jobs/index.js index 1fb6a6f9850..e078a6c2319 100644 --- a/app/assets/javascripts/jobs/index.js +++ b/app/assets/javascripts/jobs/index.js @@ -1,10 +1,11 @@ import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import BridgeApp from './bridge/app.vue'; import JobApp from './components/job_app.vue'; import createStore from './store'; -export default () => { - const element = document.getElementById('js-job-vue-app'); - +const initializeJobPage = (element) => { const store = createStore(); // Let's start initializing the store (i.e. fetching data) right away @@ -51,3 +52,35 @@ export default () => { }, }); }; + +const initializeBridgePage = (el) => { + const { buildName, emptyStateIllustrationPath } = el.dataset; + + Vue.use(VueApollo); + const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient(), + }); + + return new Vue({ + el, + apolloProvider, + provide: { + buildName, + emptyStateIllustrationPath, + }, + render(h) { + return h(BridgeApp); + }, + }); +}; + +export default () => { + const jobElement = document.getElementById('js-job-page'); + const bridgeElement = document.getElementById('js-bridge-page'); + + if (jobElement) { + initializeJobPage(jobElement); + } else { + initializeBridgePage(bridgeElement); + } +}; |