Cascading Settings

캐스케이딩 설정 프레임워크는 그룹이 본질적으로 조상(상위 그룹 및 인스턴스 수준 응용 프로그램 설정)에서 설정 값을 상속하고 하위 계층의 그룹에서 설정 값을 강제로 적용할 수 있도록 합니다.

캐스케이딩 설정은 현재 NamespaceSetting에서만 정의할 수 있지만 향후에 프레임워크가 다른 객체로 확장될 수 있습니다.

Add a new cascading setting

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

  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 값 허용하지 않음.

Convenience methods

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. 이 네임스페이스의 속성이 null이 아니면 해당 속성을 반환합니다.
  5. 값이 null이 아닌 가장 가까운 조상부터 값을 반환합니다.
  6. 인스턴스 수준 응용 프로그램 설정 반환합니다.

_locked? 메소드

기본적으로 _locked? 메소드(delayed_project_removal_locked?)는 그룹 또는 응용 프로그램 설정의 조상이 속성을 잠그면 true를 반환합니다. 속성을 잠근 그룹에서 호출할 때 false를 반환합니다.

include_self: true가 지정된 경우, 속성을 프로젝트에서 잠그는지 확인할 때 true를 반환합니다.

예를 들어 속성이 프로젝트에서 잠겨 있는지 확인할 때 relevant 할 수 있습니다.

프론트엔드에 캐스케이딩 설정 표시

프론트엔드에 캐스케이딩 설정을 표시하는 데 사용할 수 있는 몇 가지 Rails 뷰 도우미, HAML 부분 및 JavaScript 함수가 있습니다.

Rails 뷰 도우미

cascading_namespace_setting_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 폼 빌더 객체. ActionView::Helpers::FormBuilder true
setting_locked 조상 그룹 또는 관리자 설정에 의해 설정이 잠겨 있는지 여부. cascading_namespace_setting_locked?로 계산할 수 있습니다. 부울 true
help_text 체크박스 아래에 표시되는 텍스트. String false (하위 그룹은 해당 설정을 변경할 수 없음.)

_setting_label_checkbox.html.haml

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

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

_lock_popovers.html.haml

커서를 꽂으면 팝오버를 표시하는 데 사용되는 JavaScript를 초기화하는 마운트 요소를 렌더링합니다. 이 부분은 페이지당 한 번만 필요합니다.

JavaScript

initCascadingSettingsLockPopovers

호버링하여 잠금 아이콘() 위에 마우스를 올렸을 때 팝오버를 표시하는 데 필요한 JavaScript를 초기화합니다. 이 함수는 페이지별 JavaScript에서 가져와서 호출해야 합니다.

모두 함께 넣기

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

= render 'shared/namespaces/cascading_settings/lock_popovers'

- 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' } }
    .gl-form-checkbox.custom-control.custom-checkbox
      = f.check_box :delayed_project_removal, checked: @group.namespace_settings.delayed_project_removal?, disabled: delayed_project_removal_locked, class: 'custom-control-input'
      = render 'shared/namespaces/cascading_settings/setting_label_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|Projects will be permanently deleted after a 7-day delay. Inherited by subgroups.') do
        = s_('Settings|Enable delayed project deletion')
      = 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|Determine what happens to the commit history when you merge a merge request.') do
      = s_('Settings|Merge method')
    
    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :merge, s_('Settings|Merge commit'), help_text: s_('Settings|Every merge creates a merge commit.'), radio_options: { disabled: merge_method_locked }
    
    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :rebase_merge, s_('Settings|Merge commit with semi-linear history'), help_text: s_('Settings|Every merge creates a merge commit.'), radio_options: { disabled: merge_method_locked }
    
    .gl-form-radio.custom-control.custom-radio
      = f.gitlab_ui_radio_component :merge_method, :ff, s_('Settings|Fast-forward merge'), help_text: s_('Settings|No merge commits are created.'), 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 { initCascadingSettingsLockPopovers } from '~/namespaces/cascading_settings';

initCascadingSettingsLockPopovers();