code.gitea.io/gitea@v1.22.3/web_src/js/features/repo-settings.js (about)

     1  import $ from 'jquery';
     2  import {minimatch} from 'minimatch';
     3  import {createMonaco} from './codeeditor.js';
     4  import {onInputDebounce, toggleElem} from '../utils/dom.js';
     5  import {POST} from '../modules/fetch.js';
     6  
     7  const {appSubUrl, csrfToken} = window.config;
     8  
     9  export function initRepoSettingsCollaboration() {
    10    // Change collaborator access mode
    11    $('.page-content.repository .ui.dropdown.access-mode').each((_, el) => {
    12      const $dropdown = $(el);
    13      const $text = $dropdown.find('> .text');
    14      $dropdown.dropdown({
    15        async action(_text, value) {
    16          const lastValue = el.getAttribute('data-last-value');
    17          try {
    18            el.setAttribute('data-last-value', value);
    19            $dropdown.dropdown('hide');
    20            const data = new FormData();
    21            data.append('uid', el.getAttribute('data-uid'));
    22            data.append('mode', value);
    23            await POST(el.getAttribute('data-url'), {data});
    24          } catch {
    25            $text.text('(error)'); // prevent from misleading users when error occurs
    26            el.setAttribute('data-last-value', lastValue);
    27          }
    28        },
    29        onChange(_value, text, _$choice) {
    30          $text.text(text); // update the text when using keyboard navigating
    31        },
    32        onHide() {
    33          // set to the really selected value, defer to next tick to make sure `action` has finished its work because the calling order might be onHide -> action
    34          setTimeout(() => {
    35            const $item = $dropdown.dropdown('get item', el.getAttribute('data-last-value'));
    36            if ($item) {
    37              $dropdown.dropdown('set selected', el.getAttribute('data-last-value'));
    38            } else {
    39              $text.text('(none)'); // prevent from misleading users when the access mode is undefined
    40            }
    41          }, 0);
    42        },
    43      });
    44    });
    45  }
    46  
    47  export function initRepoSettingSearchTeamBox() {
    48    const searchTeamBox = document.getElementById('search-team-box');
    49    if (!searchTeamBox) return;
    50  
    51    $(searchTeamBox).search({
    52      minCharacters: 2,
    53      apiSettings: {
    54        url: `${appSubUrl}/org/${searchTeamBox.getAttribute('data-org-name')}/teams/-/search?q={query}`,
    55        headers: {'X-Csrf-Token': csrfToken},
    56        onResponse(response) {
    57          const items = [];
    58          $.each(response.data, (_i, item) => {
    59            items.push({
    60              title: item.name,
    61              description: `${item.permission} access`, // TODO: translate this string
    62            });
    63          });
    64  
    65          return {results: items};
    66        },
    67      },
    68      searchFields: ['name', 'description'],
    69      showNoResults: false,
    70    });
    71  }
    72  
    73  export function initRepoSettingGitHook() {
    74    if (!$('.edit.githook').length) return;
    75    const filename = document.querySelector('.hook-filename').textContent;
    76    const _promise = createMonaco($('#content')[0], filename, {language: 'shell'});
    77  }
    78  
    79  export function initRepoSettingBranches() {
    80    if (!document.querySelector('.repository.settings.branches')) return;
    81  
    82    for (const el of document.getElementsByClassName('toggle-target-enabled')) {
    83      el.addEventListener('change', function () {
    84        const target = document.querySelector(this.getAttribute('data-target'));
    85        target?.classList.toggle('disabled', !this.checked);
    86      });
    87    }
    88  
    89    for (const el of document.getElementsByClassName('toggle-target-disabled')) {
    90      el.addEventListener('change', function () {
    91        const target = document.querySelector(this.getAttribute('data-target'));
    92        if (this.checked) target?.classList.add('disabled'); // only disable, do not auto enable
    93      });
    94    }
    95  
    96    document.getElementById('dismiss_stale_approvals')?.addEventListener('change', function () {
    97      document.getElementById('ignore_stale_approvals_box')?.classList.toggle('disabled', this.checked);
    98    });
    99  
   100    // show the `Matched` mark for the status checks that match the pattern
   101    const markMatchedStatusChecks = () => {
   102      const patterns = (document.getElementById('status_check_contexts').value || '').split(/[\r\n]+/);
   103      const validPatterns = patterns.map((item) => item.trim()).filter(Boolean);
   104      const marks = document.getElementsByClassName('status-check-matched-mark');
   105  
   106      for (const el of marks) {
   107        let matched = false;
   108        const statusCheck = el.getAttribute('data-status-check');
   109        for (const pattern of validPatterns) {
   110          if (minimatch(statusCheck, pattern)) {
   111            matched = true;
   112            break;
   113          }
   114        }
   115        toggleElem(el, matched);
   116      }
   117    };
   118    markMatchedStatusChecks();
   119    document.getElementById('status_check_contexts').addEventListener('input', onInputDebounce(markMatchedStatusChecks));
   120  }