Work items widgets

프런트엔드 아키텍처

작업 항목 위젯은 프런트엔드 위젯에 크게 영감을 받았습니다. 작업 항목은 이슈와 아키텍처적으로 다르기 때문에 몇 가지 차이가 있을 수 있습니다.

GraphQL (Vue Apollo)은 작업 항목 위젯 스택의 핵심을 구성합니다.

작업 항목 위젯에 대한 위젯 정보 검색

작업 항목 페이지를 표시하려면 프런트엔드는 표시하려는 작업 항목에 사용 가능한 위젯을 알아야 합니다. 이를 위해 이러한 쿼리를 사용하여 위젯 디렉터리을 가져와야 합니다.

query WorkItem($workItemId: ID!) {
  workItem(workItemId: $id) @client {
    id
    type
    widgets {
      nodes {
        type
      }
    }
  }
}

GraphQL 쿼리와 뮤테이션

GraphQL 쿼리와 뮤테이션은 작업 항목에 대해 무관합니다. 작업 항목 쿼리와 뮤테이션은 위젯 레벨에서 발생해야 하므로 위젯은 독립적으로 재사용 가능한 컴포넌트여야 합니다. 작업 항목 쿼리와 뮤테이션은 모든 작업 항목 유형을 지원하고 동적이어야 합니다. 위젯 식별자를 지정하여 어떤 작업 항목 속성이든 쿼리하고 변경할 수 있어야 합니다.

이 쿼리 예제에서 설명 위젯은 어떤 작업 항목의 설명을 표시하고 업데이트하기 위해 쿼리와 뮤테이션을 사용합니다.

query {
  workItem(input: {
    workItemId: "gid://gitlab/AnyWorkItem/2207",
    widgetIdentifier: "description",
  }) {
    id
    type
    widgets {
      nodes {
        ... on DescriptionWidget {
          contentText
        }
      }
    }
  }
}

뮤테이션 예제:

mutation {
  updateWorkItem(input: {
    workItemId: "gid://gitlab/AnyWorkItem/2207",
    widgetIdentifier: "description",
    value: "the updated description"
  }) {
    workItem {
      id
      description
    }
  }
}

위젯 책임 및 구조

위젯은 제목, 설명 또는 레이블과 같은 단일 속성을 표시하고 업데이트하는 데 책임이 있습니다. 위젯은 모든 종류의 작업 항목을 지원해야 합니다. 컴포넌트 재사용성을 극대화하기 위해 위젯은 소유하고 있는 필드 래퍼여야 합니다 담당하는 속성의 작업 항목 쿼리와 뮤테이션을 포함하여야 합니다.

필드 컴포넌트는 일반적이고 간단한 컴포넌트입니다. 입력 필드, 날짜 선택기 또는 드롭다운 디렉터리과 같은 속성이나 작업 항목 세부 정보를 알지 못합니다.

위젯은 작업 항목에 따라 다양한 사용 사례를 지원할 수 있도록 구성할 수 있어야 합니다. 위젯을 구축할 때는 프롭과 주입된 속성의 사용을 최소화하고 추가적인 컨텍스트를 제공하기 위해 슬롯을 사용해야 합니다.

예시

참고용으로 드롭다운 디렉터리 컴포넌트가 있습니다.

어떤 작업 항목 위젯이든 드롭다운 디렉터리을 랩핑할 수 있습니다. 위젯은 자신이 변경하는 속성을 알고 있으며 해당 속성을 위한 뮤테이션을 소유합니다. 여러 위젯이 동일한 필드 컴포넌트를 사용할 수 있습니다. 예를 들어:

  • 제목 및 설명 위젯은 입력 필드 컴포넌트를 사용합니다.
  • 시작 및 종료 날짜는 날짜 선택기 컴포넌트를 사용합니다.
  • 레이블, 마일스톤 및 담당자 선택기는 드롭다운 디렉터리을 사용합니다.

일부 프런트엔드 위젯은 이미 드롭다운 디렉터리을 사용합니다. 작업 항목 위젯 개발에 참고할 수 있습니다:

  • ee/app/assets/javascripts/boards/components/assignee_select.vue
  • ee/app/assets/javascripts/boards/components/milestone_select.vue

작업 항목 유형에 위젯 매핑

모든 작업 항목 유형은 미리 정의된 위젯 풀을 공유하며 특정 유형에서 활성화된 위젯에 따라 사용자 정의됩니다. 사용자가 새로운 작업 항목 유형을 만들고 해당 유형에 대한 일련의 위젯을 정의할 수 있도록 계획 중이므로 각 작업 항목 유형에 대한 위젯 매핑은 데이터베이스에 저장됩니다. 위젯 매핑은 widget_definitions 테이블에 저장되며 기본 작업 항목 유형 및 사용자 정의된 유형 모두에 대한 위젯 정의에 사용될 수 있습니다. 예상된 데이터베이스 테이블 구조에 대한 자세한 내용은 이 이슈 설명에서 확인할 수 있습니다.

새로운 위젯을 작업 항목 유형에 추가

각 작업 항목 유형에 어떤 위젯이 할당되어 있는지에 대한 정보가 데이터베이스에 저장되므로 작업 항목 유형에 새 위젯을 추가하려면 데이터베이스 마이그레이션을 통해 수행해야 합니다. 또한 위젯 가져오기자(lib/gitlab/database_importers/work_items/widgets_importer.rb)를 업데이트해야 합니다.

위젯 정의 테이블 구조

테이블의 각 레코드는 위젯을 작업 항목 유형에 매핑합니다. 현재 “global” 정의(널 namespace_id를 가진 정의)만 사용됩니다. 다음 단계에서는 이러한 매핑을 사용자 정의하도록 계획 중입니다. 예를 들어 아래 테이블은 다음을 정의합니다:

  • Weight 위젯은 작업 항목 유형 0 및 1에 대해 활성화되어 있습니다.
  • 1번 namespace에서 Weight 위젯은 MyWeight로 이름이 변경되었습니다. 사용자가 위젯 이름을 바꿀 때는 모든 위젯 매핑을 네임스페이스에 대해 바꾸는 것이 합리적입니다. 왜냐하면 name 속성이 정규화되어 있으므로 이 위젯 유형에 대한 모든 작업 항목 유형에 대해 네임스페이스 매핑을 만들어야 합니다.
  • Weight 위젯은 특정 작업 항목 유형에 대해 비활성화될 수 있습니다(3번 namespace에서는 작업 항목 유형 0에 대해 비활성화되었지만 작업 항목 유형 1에 대해 여전히 활성화되어 있습니다)
ID namespace_id work_item_type_id widget_type_enum Position Name Disabled
1   0 1 1 Weight false
2   1 1 1 Weight false
3 1 0 1 0 MyWeight false
4 1 1 1 0 MyWeight false
5 2 0 1 1 Other Weight false
6 3 0 1 1 Weight true

백엔드 아키텍처

사용자 지정한 미세한 조정 뮤테이션(예: WorkItemCreateFromTask)을 사용하거나 workItemCreate 또는 workItemUpdate 뮤테이션의 일부로 위젯을 업데이트할 수 있습니다.

위젯 콜백

작업 항목의 뮤테이션과 함께 위젯을 업데이트할 때, 백엔드 코드는 WorkItems::Callbacks::Base를 상속하는 콜백 클래스를 사용하여 구현해야 합니다. 이러한 클래스에는 ActiveRecord 콜백과 유사한 이름의 콜백 메서드가 있으며 유사한 방식으로 동작합니다.

위젯과 동일한 이름의 콜백 클래스는 자동으로 사용됩니다. 예를 들어, AwardEmoji 위젯이 있는 작업 항목에 대해 WorkItems::Callbacks::AwardEmoji가 호출됩니다. 다른 클래스를 사용하려면 callback_class 클래스 메서드를 재정의할 수 있습니다.

콜백 클래스가 Merge Request이나 이슈 같은 다른 이슈들에 대해서도 사용될 경우, 해당 클래스를 Issuable::Callbacks 아래에 정의하고 IssuableBaseService#available_callbacks 디렉터리에 추가해야 합니다. 이러한 콜백은 작업 항목 업데이트와 레거시 이슈, Merge Request 또는 epic 업데이트 모두에 대해 실행됩니다.

가능한 콜백

  • after_initialize은 작업 항목이 BuildService에 의해 초기화된 후에 호출되며 CreateServiceUpdateService에 의해 저장되기 전에 호출됩니다. 이 콜백은 생성 또는 업데이트 데이터베이스 트랜잭션 밖에서 실행됩니다.
  • before_create은 작업 항목이 CreateService에 의해 저장되기 전에 호출됩니다. 이 콜백은 생성 데이터베이스 트랜잭션 내에서 실행됩니다.
  • before_update은 작업 항목이 UpdateService에 의해 저장되기 전에 호출됩니다. 이 콜백은 업데이트 데이터베이스 트랜잭션 내에서 실행됩니다.
  • after_update_commitUpdateService에 의해 DB 업데이트 트랜잭션이 커밋된 후에 호출됩니다.
  • after_save_commitCreateService 또는 UpdateService에 의해 생성 또는 DB 업데이트 트랜잭션이 커밋된 후에 호출됩니다.