병합 요청 위젯

병합 요청 위젯은 디자인 프레임워크에 맞는 새로운 기능을 추가할 수 있도록 해줍니다.

이 위젯들로 인해 우리는 큰 노력을 들이지 않고도 다음과 같은 많은 이점을 얻을 수 있습니다:

  • 일관된 모양과 느낌.
  • 위젯이 열릴 때 추적.
  • 성능을 위한 가상 스크롤.

사용법

위젯은 일반 Vue 컴포넌트로서 ~/vue_merge_request_widget/components/widget/widget.vue 컴포넌트를 사용합니다.

사용 사례의 복잡도에 따라 설정 객체를 전달하거나 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를 반환해야 합니다.
구현은 상태 코드와 헤더를 변경하지 않는 것이 중요합니다.

<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_success, expand_warning, expand_failed): 위젯이 확장되었을 때 상태와 관련된 세 가지 추가 이벤트 중 하나.

새로운 위젯 추가

새로운 위젯을 추가할 때, 위의 이벤트는 known으로 마킹해야 하며, 보고서화 가능한 메트릭이 생성되어야 합니다.

참고: EE 전용 이벤트는 아래의 두 셸 명령 끝에 --ee를 포함해야 합니다.

단일 위젯에 대한 이러한 알려진 이벤트를 생성하려면:

  1. 위젯은 Widget${CamelName}로 이름을 지정해야 합니다.
    • 예를 들어: Test Reports에 대한 위젯은 WidgetTestReports이어야 합니다.
  2. 위젯 이름 슬러그를 ${CamelName}을 소문자, 스네이크 케이스로 변환하여 계산합니다.
    • 이전 예는 test_reports가 됩니다.
  3. 새로운 위젯 이름 슬러그를 lib/gitlab/usage_data_counters/merge_request_widget_counter.rbWIDGETS 목록에 추가합니다.
  4. GDK가 실행 중인지 확인합니다 (gdk start).
  5. 다음 명령어를 사용하여 명령줄에서 알려진 이벤트를 생성합니다. 적절한 이름 슬러그로 test_reports를 교체합니다:

    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를 교체합니다.

    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_sourceredis_hll로 변경합니다.

  9. 각 이벤트(7단계 명령에 나열된 것들, 적절한 이름 슬러그로 test_reports를 교체하여) 집계 파일에 추가합니다:
    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.rb에 새로운 이벤트를 KNOWN_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 를 방문하여 모든 위젯이 함께 표시되는 예제를 확인하세요.