Work items 위젯

프론트엔드 아키텍처

Work items 위젯은 프론트엔드 위젯에서 많은 영감을 받았습니다. 이슈와는 아키텍처적으로 다르기 때문에 일부 차이가 있을 수 있습니다.

GraphQL (Vue Apollo)이 work items 위젯 스택의 핵심을 구성합니다.

Work items를 위한 위젯 정보 검색

Work item 페이지를 표시하려면 프론트엔드는 표시하려는 work item에서 사용 가능한 위젯을 알아야 합니다. 이를 위해 다음과 같은 쿼리를 사용하여 위젯 목록을 가져와야 합니다.

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

GraphQL 쿼리 및 뮤테이션

GraphQL 쿼리 및 뮤테이션은 work item에 상관없이 동작합니다. Work item 쿼리 및 뮤테이션은 위젯 레벨에서 발생해야 합니다. 따라서 위젯은 독립적으로 재사용 가능한 구성 요소여야 합니다. Work item 쿼리와 뮤테이션은 모든 work item 유형을 지원하고 동적이어야 합니다. 위젯 식별자를 지정하여 모든 work item 속성을 쿼리하고 변경할 수 있어야 합니다.

이 쿼리 예제에서 description 위젯은 쿼리 및 뮤테이션을 사용하여 모든 work item의 설명을 표시하고 업데이트합니다.

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
    }
  }
}

위젯 책임과 구조

위젯은 제목, 설명 또는 레이블과 같은 단일 속성을 표시하고 업데이트하는 역할을 합니다. 위젯은 모든 work item 유형을 지원해야 합니다. 컴포넌트 재사용성을 극대화하기 위해 위젯은 소유하는 속성의 work item 쿼리와 뮤테이션을 보유한 필드 래퍼여야 합니다.

필드 컴포넌트는 범용적이고 간단한 컴포넌트입니다. 입력 필드, 날짜 선택기 또는 드롭다운 목록과 같은 속성이나 work item 상세 정보를 알지 못합니다.

위젯은 work item에 따라 자주 사용되는 여러 사용 사례를 지원할 수 있도록 구성할 수 있어야 합니다. 위젯을 작성할 때 슬롯을 사용하여 속성 및 주입된 속성의 사용을 최소화하고 추가 컨텍스트를 제공해야 합니다.

예제

참조용 드롭다운 목록 컴포넌트가 있습니다.

모든 work item 위젯은 드롭다운 목록을 래핑할 수 있습니다. 위젯은 자신이 변경하는 속성을 알고 있으며 해당 속성에 대한 뮤테이션을 보유합니다. 여러 위젯이 동일한 필드 컴포넌트를 사용할 수 있습니다. 예를 들어:

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

일부 프론트엔드 위젯은 이미 드롭다운 목록을 사용합니다. Work items 위젯 개발에 참고하세요:

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

Work item 유형에 위젯 매핑

모든 Work Item 유형은 미리 정의된 위젯 풀을 공유하며 특정 유형의 활성화된 위젯에 따라 사용자 지정됩니다. 사용자가 새로운 Work Item 유형을 만들고 해당 유형에 대한 위젯 집합을 정의할 수 있도록 계획하기 때문에 각 Work Item 유형에 대한 위젯 매핑은 데이터베이스에 저장됩니다. 위젯 매핑은 widget_definitions 테이블에 저장되며 기본 Work Item 유형 및 향후 사용자 정의 유형에 대한 위젯 정의에 사용할 수 있습니다. 예상되는 데이터베이스 테이블 구조에 대한 자세한 내용은 이 이슈 설명에서 찾을 수 있습니다.

새로운 위젯을 Work Item 유형에 추가

각 work item 유형에 어떤 위젯이 할당되어 있는지에 대한 정보는 데이터베이스에 저장되기 때문에 새로운 위젯을 Work Item 유형에 추가하려면 데이터베이스 마이그레이션을 통해 수행해야 합니다. 또한 위젯 인포터(lib/gitlab/database_importers/work_items/widgets_importer.rb)도 업데이트해야 합니다.

위젯 정의 테이블 구조

테이블의 각 레코드는 위젯을 Work Item 유형에 매핑합니다. 현재 “전역” 정의(널 namespace_id를 가진 정의)만 사용됩니다. 다음 반복에서는 이러한 매핑을 사용자 정의할 수 있도록 계획하고 있습니다. 예를 들어 아래 테이블은 다음을 정의합니다:

  • Weight 위젯은 work item 유형 0 및 1에 대해 활성화됩니다.
  • 네임스페이스 1에서 Weight 위젯은 MyWeight로 이름이 변경됩니다. 사용자가 위젯 이름을 변경하면 해당 위젯 유형에 대한 모든 위젯 매핑을 변경하는 것이 의미가 있습니다. 왜냐하면 name 속성이 정규화되기 때문에 이 외래 키에 대해 모든 work item 유형에 대한 네임스페이스 매핑을 생성해야 합니다.
  • Weight 위젯은 특정 work item 유형에서 비활성화될 수 있습니다 (네임스페이스 3에서 work item 유형 0에 대해 비활성화되지만 work item 유형 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 콜백과 유사한 이름을 가진 콜백 메서드가 있으며 동일하게 작동합니다.

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

콜백 클래스가 병합 요청 또는 에픽과 같은 다른 이슈 가능과도 동일하게 사용될 때는 Issuable::Callbacks 아래에 클래스를 정의하고, IssuableBaseService#available_callbacks 목록에 클래스를 추가합니다. 이러한 것들은 작업 항목 업데이트뿐만 아니라 레거시 이슈, 병합 요청 또는 에픽 업데이트에 대해 실행됩니다.

사용 가능한 콜백

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