diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-31 15:13:01 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-31 15:13:01 +0300 |
commit | 3034c7e6aa99d21c3d9fa1df01f60fdd3f32d914 (patch) | |
tree | 424f5a291abf1a93ff9870667ecb301b899972fc /app/assets/javascripts/runner | |
parent | 6170bdc060501ecf6f817a530b3dc9f2e39ad4c3 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/runner')
5 files changed, 180 insertions, 7 deletions
diff --git a/app/assets/javascripts/runner/components/cells/runner_stacked_summary_cell.vue b/app/assets/javascripts/runner/components/cells/runner_stacked_summary_cell.vue new file mode 100644 index 00000000000..37099edc7d2 --- /dev/null +++ b/app/assets/javascripts/runner/components/cells/runner_stacked_summary_cell.vue @@ -0,0 +1,112 @@ +<script> +import { GlIcon, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; + +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; +import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; +import RunnerName from '../runner_name.vue'; +import RunnerTags from '../runner_tags.vue'; +import RunnerTypeBadge from '../runner_type_badge.vue'; + +import { formatJobCount } from '../../utils'; +import { + I18N_LOCKED_RUNNER_DESCRIPTION, + I18N_VERSION_LABEL, + I18N_LAST_CONTACT_LABEL, + I18N_CREATED_AT_LABEL, +} from '../../constants'; +import RunnerSummaryField from './runner_summary_field.vue'; + +export default { + components: { + GlIcon, + GlSprintf, + TimeAgo, + RunnerSummaryField, + RunnerName, + RunnerTags, + RunnerTypeBadge, + RunnerUpgradeStatusIcon: () => + import('ee_component/runner/components/runner_upgrade_status_icon.vue'), + TooltipOnTruncate, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + runner: { + type: Object, + required: true, + }, + }, + computed: { + jobCount() { + return formatJobCount(this.runner.jobCount); + }, + }, + i18n: { + I18N_LOCKED_RUNNER_DESCRIPTION, + I18N_VERSION_LABEL, + I18N_LAST_CONTACT_LABEL, + I18N_CREATED_AT_LABEL, + }, +}; +</script> + +<template> + <div> + <div> + <slot :runner="runner" name="runner-name"> + <runner-name :runner="runner" /> + </slot> + <gl-icon + v-if="runner.locked" + v-gl-tooltip + :title="$options.i18n.I18N_LOCKED_RUNNER_DESCRIPTION" + name="lock" + /> + <runner-type-badge :type="runner.runnerType" size="sm" /> + </div> + + <div class="gl-ml-auto gl-display-inline-flex gl-max-w-full gl-py-2"> + <div class="gl-flex-shrink-0"> + <runner-upgrade-status-icon :runner="runner" /> + <gl-sprintf v-if="runner.version" :message="$options.i18n.I18N_VERSION_LABEL"> + <template #version>{{ runner.version }}</template> + </gl-sprintf> + </div> + <div class="gl-text-secondary gl-mx-2" aria-hidden="true">ยท</div> + <tooltip-on-truncate class="gl-text-truncate gl-display-block" :title="runner.description"> + {{ runner.description }} + </tooltip-on-truncate> + </div> + + <div> + <runner-summary-field icon="clock"> + <gl-sprintf :message="$options.i18n.I18N_LAST_CONTACT_LABEL"> + <template #timeAgo> + <time-ago v-if="runner.contactedAt" :time="runner.contactedAt" /> + <template v-else>{{ __('Never') }}</template> + </template> + </gl-sprintf> + </runner-summary-field> + + <runner-summary-field v-if="runner.ipAddress" icon="disk" :tooltip="__('IP Address')"> + {{ runner.ipAddress }} + </runner-summary-field> + + <runner-summary-field icon="pipeline" data-testid="job-count" :tooltip="__('Jobs')"> + {{ jobCount }} + </runner-summary-field> + + <runner-summary-field icon="calendar"> + <gl-sprintf :message="$options.i18n.I18N_CREATED_AT_LABEL"> + <template #timeAgo> + <time-ago v-if="runner.createdAt" :time="runner.createdAt" /> + </template> + </gl-sprintf> + </runner-summary-field> + </div> + + <runner-tags class="gl-display-block gl-pt-2" :tag-list="runner.tagList" size="sm" /> + </div> +</template> diff --git a/app/assets/javascripts/runner/components/cells/runner_summary_field.vue b/app/assets/javascripts/runner/components/cells/runner_summary_field.vue new file mode 100644 index 00000000000..1bbbd55089a --- /dev/null +++ b/app/assets/javascripts/runner/components/cells/runner_summary_field.vue @@ -0,0 +1,33 @@ +<script> +import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; + +export default { + components: { + GlIcon, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + props: { + icon: { + type: String, + required: false, + default: '', + }, + tooltip: { + type: String, + required: false, + default: '', + }, + }, +}; +</script> + +<template> + <div v-gl-tooltip="tooltip" class="gl-display-inline-block gl-text-secondary gl-my-2 gl-mr-2"> + <gl-icon v-if="icon" :name="icon" /> + <!-- display tooltip as a label for screen readers --> + <span class="gl-sr-only">{{ tooltip }}</span> + <slot></slot> + </div> +</template> diff --git a/app/assets/javascripts/runner/components/runner_list.vue b/app/assets/javascripts/runner/components/runner_list.vue index 708375b0426..534317d6a57 100644 --- a/app/assets/javascripts/runner/components/runner_list.vue +++ b/app/assets/javascripts/runner/components/runner_list.vue @@ -2,11 +2,13 @@ import { GlFormCheckbox, GlTableLite, GlTooltipDirective, GlSkeletonLoader } from '@gitlab/ui'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { __, s__ } from '~/locale'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import checkedRunnerIdsQuery from '../graphql/list/checked_runner_ids.query.graphql'; import { formatJobCount, tableField } from '../utils'; import RunnerSummaryCell from './cells/runner_summary_cell.vue'; +import RunnerStackedSummaryCell from './cells/runner_stacked_summary_cell.vue'; import RunnerStatusPopover from './runner_status_popover.vue'; import RunnerStatusCell from './cells/runner_status_cell.vue'; @@ -19,6 +21,12 @@ const defaultFields = [ tableField({ key: 'actions', label: '' }), ]; +const stackedLayoutFields = [ + tableField({ key: 'status', label: s__('Runners|Status'), thClasses: ['gl-w-15p'] }), + tableField({ key: 'summary', label: s__('Runners|Runner') }), + tableField({ key: 'actions', label: '', thClasses: ['gl-w-15p'] }), +]; + export default { components: { GlFormCheckbox, @@ -28,11 +36,13 @@ export default { TimeAgo, RunnerStatusPopover, RunnerSummaryCell, + RunnerStackedSummaryCell, RunnerStatusCell, }, directives: { GlTooltip: GlTooltipDirective, }, + mixins: [glFeatureFlagMixin()], apollo: { checkedRunnerIds: { query: checkedRunnerIdsQuery, @@ -62,6 +72,11 @@ export default { return { checkedRunnerIds: [] }; }, computed: { + stackedLayout() { + // runner_list_stacked_layout_admin or runner_list_stacked_layout + const { runnerListStackedLayoutAdmin, runnerListStackedLayout } = this.glFeatures || {}; + return runnerListStackedLayoutAdmin || runnerListStackedLayout; + }, tableClass() { // <gl-table-lite> does not provide a busy state, add // simple support for it. @@ -71,6 +86,8 @@ export default { }; }, fields() { + const fields = this.stackedLayout ? stackedLayoutFields : defaultFields; + if (this.checkable) { const checkboxField = tableField({ key: 'checkbox', @@ -78,9 +95,9 @@ export default { thClasses: ['gl-w-9'], tdClass: ['gl-text-center'], }); - return [checkboxField, ...defaultFields]; + return [checkboxField, ...fields]; } - return defaultFields; + return fields; }, }, methods: { @@ -138,24 +155,30 @@ export default { </template> <template #cell(summary)="{ item, index }"> - <runner-summary-cell :runner="item"> + <runner-stacked-summary-cell v-if="stackedLayout" :runner="item"> + <template #runner-name="{ runner }"> + <slot name="runner-name" :runner="runner" :index="index"></slot> + </template> + </runner-stacked-summary-cell> + + <runner-summary-cell v-else :runner="item"> <template #runner-name="{ runner }"> <slot name="runner-name" :runner="runner" :index="index"></slot> </template> </runner-summary-cell> </template> - <template #cell(version)="{ item: { version } }"> + <template v-if="!stackedLayout" #cell(version)="{ item: { version } }"> <tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="version"> {{ version }} </tooltip-on-truncate> </template> - <template #cell(jobCount)="{ item: { jobCount } }"> - {{ formatJobCount(jobCount) }} + <template v-if="!stackedLayout" #cell(jobCount)="{ item: { jobCount } }"> + <span data-testid="job-count">{{ formatJobCount(jobCount) }}</span> </template> - <template #cell(contactedAt)="{ item: { contactedAt } }"> + <template v-if="!stackedLayout" #cell(contactedAt)="{ item: { contactedAt } }"> <time-ago v-if="contactedAt" :time="contactedAt" /> <template v-else>{{ __('Never') }}</template> </template> diff --git a/app/assets/javascripts/runner/constants.js b/app/assets/javascripts/runner/constants.js index ed1afcbf691..5485ea35e81 100644 --- a/app/assets/javascripts/runner/constants.js +++ b/app/assets/javascripts/runner/constants.js @@ -77,9 +77,13 @@ export const I18N_DELETE_DISABLED_UNKNOWN_REASON = s__( ); export const I18N_DELETED_TOAST = s__('Runners|Runner %{name} was deleted'); +// List export const I18N_LOCKED_RUNNER_DESCRIPTION = s__( 'Runners|Runner is locked and available for currently assigned projects only. Only administrators can change the assigned projects.', ); +export const I18N_VERSION_LABEL = s__('Runners|Version %{version}'); +export const I18N_LAST_CONTACT_LABEL = s__('Runners|Last contact: %{timeAgo}'); +export const I18N_CREATED_AT_LABEL = s__('Runners|Created %{timeAgo}'); // Runner details diff --git a/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql b/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql index ce23bddb898..a12ba7a751a 100644 --- a/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql +++ b/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql @@ -9,6 +9,7 @@ fragment ListItemShared on CiRunner { locked jobCount tagList + createdAt contactedAt status(legacyMode: null) userPermissions { |