Help us learn about your current experience with the documentation. Take the survey.

合并请求小部件

合并请求小部件让您能够添加符合设计框架的新功能。 通过这些小部件,我们可以获得许多开箱即用的好处,无需太多努力,例如:

  • 一致的外观和感觉
  • 追踪小部件的打开时间
  • 虚拟滚动以提升性能

使用方法

这些小部件是常规的 Vue 组件,使用了 ~/vue_merge_request_widget/components/widget/widget.vue 组件。 根据用例的复杂性,可以传递配置对象,或通过 slot 扩展组件。

使用 slot 的示例请参考以下文件: ee/app/assets/javascripts/vue_merge_request_widget/widgets/security_reports/mr_widget_security_reports.vue

使用数据对象的示例请参考以下文件: ee/app/assets/javascripts/vue_merge_request_widget/widgets/metrics/index.vue

这是一个渲染 Hello World 小部件的最小示例:

<script>
import MrWidget from '~/vue_merge_request_widget/components/widget/widget.vue';
import { __ } from '~/locale';

export default {
  name: 'WidgetHelloWorld',
  components: {
    MrWidget,
  },
  computed: {
    summary() {
      return { title: __('Hello World') };
    },
  },
};
</script>
<template>
  <mr-widget :summary="summary" :is-collapsible="false" :widget-name="$options.name" />
</template>

注册小部件

上面的示例不会在页面的任何地方渲染。为了将其挂载到合并请求小部件部分,我们必须在以下两个位置中的一个或两个中注册该小部件:

  • app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue(用于 CE 小部件)
  • ee/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue(用于 CE 和 EE 小部件)

在组件列表中定义组件并将名称添加到 widgets 计算属性中,即可挂载该小部件:

<script>
export default {
  components: {
    MrHelloWorldWidget: () =>
      import('ee/vue_merge_request_widget/widgets/hello_world/index.vue'),
  },
  computed: {
    mrHelloWorldWidget() {
      return this.mr.shouldRenderHelloWorldWidget ? 'MrHelloWorldWidget' : undefined;
    },
    widgets() {
      return [
        this.mrHelloWorldWidget,
      ].filter((w) => w);
    },
  },
};
</script>

数据获取

在小部件挂载时获取数据,请向 :fetch-collapsed-data 属性传递一个执行 API 调用的函数。

该函数必须返回一个解析为 response 对象的 Promise。实现依赖于 POLL-INTERVAL 头来保持轮询,因此切勿更改状态码和头信息。

<script>
export default {
  // ...
  data() {
    return {
      collapsedData: [],
    };
  },
  methods: {
    fetchCollapsedData() {
      return axios.get('/my/path').then((response) => {
        this.collapsedData = response.data;
        return response;
      });
    },
  },
};
</script>
<template>
  <mr-widget :fetch-collapsed-data="fetchCollapsedData" />
</template>

:fetch-expanded-data 以相同方式工作,但仅在用户展开小部件时调用。

数据结构

可以使用 contentsummary 属性来渲染 Widget。以下是这两个属性的文档:

// content
{
  text: '',           // 必需:行的主文本
  subtext: '',        // 可选:显示在主文本下方的较小子文本
  supportingText: '', // 可选:显示在子文本下方的段落
  icon: {             // 可选:图标对象
    name: EXTENSION_ICONS.success, // 必需:该行的图标名称
  },
  badge: {            // 可选:显示在文本后的徽章
    text: '',         // 必需:显示在徽章内的文本
    variant: '',      // 可选:GitLab UI 徽章变体,默认为 info
  },
  link: {             // 可选:显示在文本后的 URL 链接
    text: '',         // 必需:链接文本
    href: '',         // 可选:链接的 URL
  },
  actions: [],        // 可选:行的操作按钮
  children: [],       // 可选:要渲染的子内容,结构相同
  helpPopover: {      // 可选:如果提供,将在内容行的最右角显示信息图标
    options: {
      title: ''       // 必需:弹出框的标题
    },
    content: {
      text: '',           // 可选:弹出框的文本内容
      learnMorePath: '',  // 可选:文档路径。如果提供,将显示"了解更多"链接。
    }
  }
}

// summary
{
  title: '',    // 必需:摘要部分的主文本
  subtitle: '', // 可选:摘要部分的子文本
}

错误处理

如果 :fetch-collapsed-data:fetch-expanded-data 方法抛出错误。要自定义错误文本,可以使用 :error-text 属性:

<template>
  <mr-widget :error-text="__('Failed to load.')" />
</template>

遥测

小部件框架的基础实现包含一些遥测事件。每个小部件会报告:

  • view:当它被渲染到屏幕上时
  • expand:当它被展开时
  • full_report_clicked:当点击(可选)输入以查看完整报告时
  • 结果(expand_successexpand_warningexpand_failed):三个与展开时小部件状态相关的额外事件之一

添加新小部件

添加新小部件时,必须将上述事件标记为 known,并创建指标以便报告。

仅用于 EE 的事件应在以下两个 shell 命令的末尾包含 --ee

为单个小部件生成这些已知事件:

  1. 小部件应命名为 Widget${CamelName}

    • 例如:测试报告的小部件应为 WidgetTestReports
  2. 通过将 ${CamelName} 转换为小写、蛇形大小写来计算小部件名称 slug。

    • 前面的示例将是 test_reports
  3. 将新的小部件名称 slug 添加到 lib/gitlab/usage_data_counters/merge_request_widget_counter.rbWIDGETS 列表中。

  4. 确保 GDK 正在运行(gdk start)。

  5. 使用以下命令在命令行生成已知事件。将 test_reports 替换为适当的名称 slug:

    bundle exec rails generate gitlab:usage_metric_definition \
    counts.i_code_review_merge_request_widget_test_reports_count_view \
    counts.i_code_review_merge_request_widget_test_reports_count_full_report_clicked \
    counts.i_code_review_merge_request_widget_test_reports_count_expand \
    counts.i_code_review_merge_request_widget_test_reports_count_expand_success \
    counts.i_code_review_merge_request_widget_test_reports_count_expand_warning \
    counts.i_code_review_merge_request_widget_test_reports_count_expand_failed \
    --dir=all
  6. 修改每个新生成的文件,以匹配合并请求小部件扩展遥测的现有文件。

    • 通过执行 glob 搜索查找现有示例,如:metrics/**/*_i_code_review_merge_request_widget_*
    • 粗略地说,每个文件应具有以下值:
      1. description = 此值的纯英文描述。查看现有小部件扩展遥测文件以获取示例。
      2. product_section = dev
      3. product_stage = create
      4. product_group = code_review
      5. introduced_by_url = '[your MR]'
      6. options.events = (上面命令中生成此文件的事件,如 i_code_review_merge_request_widget_test_reports_count_view
        • 此值是将遥测事件链接到"指标"的方式,因此这可能是较重要的值之一。
      7. data_source = redis
      8. data_category = optional
  7. 使用以下命令在命令行生成已知 HLL 事件。将 test_reports 替换为适当的名称 slug。

    bundle exec rails generate gitlab:usage_metric_definition:redis_hll code_review \
    i_code_review_merge_request_widget_test_reports_view \
    i_code_review_merge_request_widget_test_reports_full_report_clicked \
    i_code_review_merge_request_widget_test_reports_expand \
    i_code_review_merge_request_widget_test_reports_expand_success \
    i_code_review_merge_request_widget_test_reports_expand_warning \
    i_code_review_merge_request_widget_test_reports_expand_failed \
    --class_name=RedisHLLMetric
  8. 重复步骤 6,但将 data_source 更改为 redis_hll

  9. 将每个事件(步骤 7 命令中列出的事件,将 test_reports 替换为适当的名称 slug)添加到聚合文件中:

    1. config/metrics/counts_7d/{timestamp}_code_review_category_monthly_active_users.yml
    2. config/metrics/counts_7d/{timestamp}_code_review_group_monthly_active_users.yml
    3. config/metrics/counts_28d/{timestamp}_code_review_category_monthly_active_users.yml
    4. config/metrics/counts_28d/{timestamp}_code_review_group_monthly_active_users.yml

添加新事件

如果您要向已知事件添加新事件,请将新事件包含在 lib/gitlab/usage_data_counters/merge_request_widget_extension_counter.rbKNOWN_EVENTS 列表中。

图标

第 1 级和所有后续级别都可以有自己的状态图标。为了遵循设计框架,请从 constants.js 文件导入 EXTENSION_ICONS 常量:

import { EXTENSION_ICONS } from '~/vue_merge_request_widget/constants.js';

此常量包含以下可用的图标。根据设计框架,第 1 级只应使用其中一些图标:

  • failed
  • warning
  • success
  • neutral
  • error
  • notice
  • severityCritical
  • severityHigh
  • severityMedium
  • severityLow
  • severityInfo
  • severityUnknown

操作按钮

您可以在每个扩展的所有第 1 级和第 2 级添加操作按钮。这些按钮旨在为每一行提供链接或操作:

  • 第 1 级的操作按钮可以通过 tertiaryButtons 计算属性设置。该属性应返回每个操作按钮的对象数组。
  • 第 2 级的操作按钮可以通过向第 2 级行对象添加 actions 键来设置。该键的值也必须是每个操作按钮的对象数组。

链接必须遵循以下结构:

{
  text: 'Click me',
  href: this.someLinkHref,
  target: '_blank', // 可选
}

对于内部操作按钮,请遵循以下结构:

{
  text: 'Click me',
  onClick() {}
}

演示

访问 GitLab MR Widgets Demo 查看所有小部件一起显示的示例。