계층 설정

계층 설정 프레임워크는 그룹이 본질적으로 조상의 설정 값을 상속받을 수 있도록 하며 (부모 그룹에서 그룹 계층까지) 인스턴스 수준의 애플리케이션 설정에서도 마찬가지입니다. 이 프레임워크는 또한 계층 하위 그룹에 대해 설정 값이 강제 적용될 수 있도록 합니다.

현재 계층 설정은 NamespaceSetting 내에서만 정의할 수 있지만, 향후 다른 객체로 확장될 수 있습니다.

새 계층 설정 추가

설정은 기본적으로 계층적이지 않습니다. 계층 설정을 정의하려면 다음 단계를 따르세요:

  1. NamespaceSetting 모델에서 cascading_attr 도우미 메서드를 사용하여 새 속성을 정의합니다. 여러 속성을 한 줄에서 정의하려면 배열을 사용할 수 있습니다.

    class NamespaceSetting
      include CascadingNamespaceSettingAttribute
    
      cascading_attr :delayed_project_removal
    end
    
  2. 데이터베이스 열을 만듭니다.

    완전히 새로운 설정에 대해 다음 데이터베이스 마이그레이션 도우미를 사용할 수 있습니다. 이 도우미는 namespace_settingsapplication_settings에서 각각 두 개의 열을 포함하여 총 네 개의 열을 생성합니다.

    class AddDelayedProjectRemovalCascadingSetting < Gitlab::Database::Migration[2.1]
      include Gitlab::Database::MigrationHelpers::CascadingNamespaceSettings
    
      def up
        add_cascading_namespace_setting :delayed_project_removal, :boolean, default: false, null: false
      end
    
      def down
       remove_cascading_namespace_setting :delayed_project_removal
      end
    end
    

    계층 설정으로 변환되는 기존 설정은 열을 추가하고 기존 열을 변경하는 개별 마이그레이션이 필요합니다. 필요한 경우 아래 사양을 사용하여 마이그레이션을 생성하세요:

    1. namespace_settings 테이블의 열:
      • delayed_project_removal: 기본값 없음. null 값 허용. 모든 열 유형 사용 가능.
      • lock_delayed_project_removal: 불리언 열. 기본값은 false. null 값 허용되지 않음.
    2. application_settings 테이블의 열:
      • delayed_project_removal: namespace_settings에 생성된 열과 일치하는 유형. 원하는 대로 기본값 설정. null 값 허용되지 않음.
      • lock_delayed_project_removal: 불리언 열. 기본값은 false. null 값 허용되지 않음.

편의 메서드

cascading_attr 메서드를 사용하여 속성을 정의함으로써 여러 편의 메서드가 자동으로 정의됩니다.

정의:

cascading_attr :delayed_project_removal

사용 가능한 편의 메서드:

  • delayed_project_removal
  • delayed_project_removal=
  • delayed_project_removal_locked?
  • delayed_project_removal_locked_by_ancestor?
  • delayed_project_removal_locked_by_application_setting?
  • delayed_project_removal? (불리언 속성만 해당)
  • delayed_project_removal_locked_ancestor (잠금된 네임스페이스 설정 객체 [namespace_id] 반환)

속성 리더 메서드 (delayed_project_removal)

속성 리더 메서드 (delayed_project_removal)는 다음 기준을 사용하여 올바른 계층화된 값을 반환합니다:

  1. 속성이 변경된 경우 더러운 값을 반환합니다. 이를 통해 표준 Rails 유효성 검사기를 속성에 사용할 수 있지만, nil 값은 반드시 허용되어야 합니다.

  2. 잠금된 조상 값을 반환합니다.

  3. 잠금된 인스턴스 수준 애플리케이션 설정 값을 반환합니다.

  4. nil이 아닐 경우 이 네임스페이스의 속성을 반환합니다.

  5. 값이 nil이 아닌 가장 가까운 조상에서 값을 반환합니다.

  6. 인스턴스 수준 애플리케이션 설정 값을 반환합니다.

_locked? 메서드

기본적으로, _locked? 메서드 (delayed_project_removal_locked?)는 그룹이나 애플리케이션 설정의 상위가 속성을 잠글 경우 true를 반환합니다.

속성을 잠근 그룹에서 호출할 때는 false를 반환합니다.

include_self: true가 지정되면, 속성을 잠근 그룹에서 호출할 때 true를 반환합니다.

이는 속성이 프로젝트에서 잠겨 있는지 확인할 때 관련이 있습니다.

프론트엔드에서 계단식 설정 표시

프론트엔드에서 계단식 설정을 표시하기 위해 사용할 수 있는 몇 가지 Rails 뷰 헬퍼, HAML 부분 및 JavaScript 함수가 있습니다.

Rails 뷰 헬퍼

cascading_namespace_setting_locked?

설정이 잠겨 있는지 확인하기 위해 _locked? 메서드를 호출합니다.

인자 설명 유형 필수 (기본값)
attribute 설정의 이름. 예를 들어, :delayed_project_removal. String 또는 Symbol true
group 현재 그룹. Group true
**args _locked? 메서드로 전달할 추가 인자   false

HAML 부분

_enforcement_checkbox.html.haml

강제 체크박스를 렌더링합니다.

지역 설명 유형 필수 (기본값)
attribute 설정의 이름. 예를 들어, :delayed_project_removal. String 또는 Symbol true
group 현재 그룹. Group true
form Rails FormBuilder 객체. ActionView::Helpers::FormBuilder true
setting_locked 설정이 상위 그룹이나 관리자 설정에 의해 잠겨 있는지 여부. cascading_namespace_setting_locked?로 계산할 수 있습니다. Boolean true
help_text 체크박스 아래에 표시되는 텍스트. String false (하위 그룹은 이 설정을 변경할 수 없습니다.)

_setting_checkbox.html.haml

체크박스 설정의 레이블을 렌더링합니다.

지역 설명 유형 필수 (기본값)
attribute 설정의 이름. 예를 들어, :delayed_project_removal. String 또는 Symbol true
group 현재 그룹. Group true
form Rails FormBuilder 객체. ActionView::Helpers::FormBuilder true
setting_locked 설정이 상위 그룹이나 관리자 설정에 의해 잠겨 있는지 여부. cascading_namespace_setting_locked?로 계산할 수 있습니다. Boolean true
settings_path_helper 상위 설정으로의 경로를 생성하는 람다 함수. 예를 들어, settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') } Lambda true
help_text 체크박스 아래에 표시되는 텍스트. String false (nil)

_setting_label_fieldset.html.haml

fieldset 설정의 레이블을 렌더링합니다.

지역 설명 유형 필수 (기본값)
attribute 설정의 이름. 예를 들어, :delayed_project_removal. String 또는 Symbol true
group 현재 그룹. Group true
setting_locked 설정이 잠겨 있는지 여부. cascading_namespace_setting_locked?로 계산할 수 있습니다. Boolean true
settings_path_helper 상위 설정으로의 경로를 생성하는 람다 함수. 예를 들어, -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') } Lambda true
help_text 체크박스 아래에 표시되는 텍스트. String false (nil)

_lock_tooltips.html.haml

잠금 아이콘 위에 마우스를 올릴 때 툴팁을 표시하는 데 사용되는 JavaScript를 초기화하는 데 필요한 마운트 요소를 렌더링합니다. 이 부분은 페이지당 한 번만 필요합니다.

JavaScript

initCascadingSettingsLockTooltips

잠금을 나타내는 아이콘( ) 위에 마우스를 올릴 때 툴팁을 표시하는 데 필요한 JavaScript를 초기화합니다.

이 함수는 페이지별 JavaScript에서 가져와 호출해야 합니다.

모든 것을 종합하기

-# app/views/groups/edit.html.haml

= render 'shared/namespaces/cascading_settings/lock_tooltips'

- delayed_project_removal_locked = cascading_namespace_setting_locked?(:delayed_project_removal, @group)
- merge_method_locked = cascading_namespace_setting_locked?(:merge_method, @group)

= form_for @group do |f|
  .form-group{ data: { testid: 'delayed-project-removal-form-group' } }
    = render 'shared/namespaces/cascading_settings/setting_checkbox', attribute: :delayed_project_removal,
        group: @group,
        form: f,
        setting_locked: delayed_project_removal_locked,
        settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') },
        help_text: s_('Settings|프로젝트는 7일 지연 후 영구적으로 삭제됩니다. 하위 그룹에서 상속됩니다.') do
      = s_('Settings|지연된 프로젝트 삭제 활성화')
    = render 'shared/namespaces/cascading_settings/enforcement_checkbox',
        attribute: :delayed_project_removal,
        group: @group,
        form: f,
        setting_locked: delayed_project_removal_locked

  %fieldset.form-group
    = render 'shared/namespaces/cascading_settings/setting_label_fieldset', attribute: :merge_method,
        group: @group,
        setting_locked: merge_method_locked,
        settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') },
        help_text: s_('Settings|머지 요청을 머지할 때 커밋 기록에 어떤 일이 발생하는지 결정합니다.') do
      = s_('Settings|머지 방법')

    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :merge, s_('Settings|머지 커밋'), help_text: s_('Settings|모든 머지는 머지 커밋을 생성합니다.'), radio_options: { disabled: merge_method_locked }

    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :rebase_merge, s_('Settings|반선형 기록을 갖는 머지 커밋'), help_text: s_('Settings|모든 머지는 머지 커밋을 생성합니다.'), radio_options: { disabled: merge_method_locked }

    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :ff, s_('Settings|빠른 머지'), help_text: s_('Settings|머지 커밋이 생성되지 않습니다.'), radio_options: { disabled: merge_method_locked }

    = render 'shared/namespaces/cascading_settings/enforcement_checkbox',
      attribute: :merge_method,
      group: @group,
      form: f,
      setting_locked: merge_method_locked
// app/assets/javascripts/pages/groups/edit/index.js

import { initCascadingSettingsLockTooltips } from '~/namespaces/cascading_settings';

initCascadingSettingsLockTooltips();

Vue

cascading_lock_icon.vue

지역 설명 유형 필수 (기본값)
ancestorNamespace 관련 그룹의 조상 네임스페이스입니다. Object false (null)
isLockedByApplicationSettings 인스턴스에서 locked_by_application_settings가 설정되어 있는지 여부를 나타내는 불리언입니다. Boolean true
isLockedByGroupAncestor 그룹에 대해 locked_by_ancestor가 설정되어 있는지 여부를 나타내는 불리언입니다. Boolean true

Vue 사용하기

  1. Ruby 헬퍼에서 다음을 호출하여 Vue 컴포넌트를 전송해야 합니다. :replace_attribute_here를 귀하의 cascading 속성으로 교체하는 것을 잊지 마세요.
 # 그룹에 대한 Ruby 헬퍼 메서드의 예
 cascading_settings_data = cascading_namespace_settings_tooltip_data(:replace_attribute_here, @group, method(:edit_group_path))[:tooltip_data]
 # 프로젝트에 대한 Ruby 헬퍼 메서드의 예
 cascading_settings_data = project_cascading_namespace_settings_tooltip_data(:duo_features_enabled, project, method(:edit_group_path)).to_json
  1. Vue의 index.js 파일에서 데이터를 JSON 및 camel case 형식으로 변환해야 합니다. 이렇게 하면 Vue에서 사용하기가 더 쉬워집니다.
let cascadingSettingsDataParsed;
try {
  cascadingSettingsDataParsed = convertObjectPropsToCamelCase(JSON.parse(cascadingSettingsData), {
    deep: true,
  });
} catch {
  cascadingSettingsDataParsed = null;
}
  1. Vue 컴포넌트에서 provide/inject 또는 cascadingSettingsDataParsed 변수를 컴포넌트에 전달합니다. 또한 cascading 데이터가 null이거나 빈 객체인 경우 cascading-lock-icon 컴포넌트를 표시하지 않는 헬퍼 메서드를 만들어야 합니다.
// ./ee/my_component.vue

<script>
export default {
  computed: {
    showCascadingIcon() {
      return (
        this.cascadingSettingsData &&
        Object.keys(this.cascadingSettingsData).length
      );
    },
  },
}
</script>

<template>
  <cascading-lock-icon
    v-if="showCascadingIcon"
    :is-locked-by-group-ancestor="cascadingSettingsData.lockedByAncestor"
    :is-locked-by-application-settings="cascadingSettingsData.lockedByApplicationSetting"
    :ancestor-namespace="cascadingSettingsData.ancestorNamespace"
    class="gl-ml-1"
  />
</template>

다음의 MR 예시를 살펴보십시오. cascading_lock_icon.vue를 다른 Vue 컴포넌트에 구현하는 방법:

HAML과 Vue 모두 지원하는 이유

모든 새로운 프론트엔드 기능은 Vue로 개발하는 것이 목표이며, 궁극적으로 HAML로 기능을 구축하는 것을 벗어나려고 합니다. 그러나 여전히 계단식 설정을 활용하는 HAML 프론트엔드 기능이 있으므로, 이러한 구성 요소가 Vue로 마이그레이션될 때까지 initCascadingSettingsLockTooltips에 대한 지원은 유지될 것입니다.