diff options
Diffstat (limited to 'app/assets/javascripts/pages')
38 files changed, 234 insertions, 158 deletions
diff --git a/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js b/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js index 7c81cf80dc6..8cecc1d3ef7 100644 --- a/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js +++ b/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js @@ -19,7 +19,7 @@ export default class PayloadDownloader { } requestPayload() { - this.spinner.classList.add('d-inline-flex'); + this.spinner.classList.add('gl-display-inline'); return axios .get(this.trigger.dataset.endpoint, { @@ -34,7 +34,7 @@ export default class PayloadDownloader { }); }) .finally(() => { - this.spinner.classList.remove('d-inline-flex'); + this.spinner.classList.remove('gl-display-inline'); }); } diff --git a/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js index ae08806fe4c..84027203783 100644 --- a/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js +++ b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js @@ -29,7 +29,7 @@ export default class PayloadPreviewer { requestPayload() { if (this.isInserted) return this.showPayload(); - this.spinner.classList.add('gl-display-inline-flex'); + this.spinner.classList.add('gl-display-inline'); const container = this.getContainer(); @@ -38,11 +38,11 @@ export default class PayloadPreviewer { responseType: 'text', }) .then(({ data }) => { - this.spinner.classList.remove('gl-display-inline-flex'); + this.spinner.classList.remove('gl-display-inline'); this.insertPayload(data); }) .catch(() => { - this.spinner.classList.remove('gl-display-inline-flex'); + this.spinner.classList.remove('gl-display-inline'); createFlash({ message: __('Error fetching payload data.'), }); diff --git a/app/assets/javascripts/pages/admin/application_settings/repository/index.js b/app/assets/javascripts/pages/admin/application_settings/repository/index.js new file mode 100644 index 00000000000..9a67fe7b6f8 --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/repository/index.js @@ -0,0 +1,3 @@ +import initInactiveProjectDeletion from '~/admin/application_settings/inactive_project_deletion'; + +initInactiveProjectDeletion(); diff --git a/app/assets/javascripts/pages/admin/groups/edit/index.js b/app/assets/javascripts/pages/admin/groups/edit/index.js index 01e03ed437d..a4df1cf8274 100644 --- a/app/assets/javascripts/pages/admin/groups/edit/index.js +++ b/app/assets/javascripts/pages/admin/groups/edit/index.js @@ -1,3 +1,5 @@ import initFilePickers from '~/file_pickers'; +import { initGroupNameAndPath } from '~/groups/create_edit_form'; initFilePickers(); +initGroupNameAndPath(); diff --git a/app/assets/javascripts/pages/admin/groups/new/index.js b/app/assets/javascripts/pages/admin/groups/new/index.js index 710d2d72f4c..a341ef9656d 100644 --- a/app/assets/javascripts/pages/admin/groups/new/index.js +++ b/app/assets/javascripts/pages/admin/groups/new/index.js @@ -1,6 +1,7 @@ import initFilePickers from '~/file_pickers'; import BindInOut from '~/behaviors/bind_in_out'; import Group from '~/group'; +import { initGroupNameAndPath } from '~/groups/create_edit_form'; (() => { BindInOut.initAll(); @@ -8,3 +9,5 @@ import Group from '~/group'; return new Group(); })(); + +initGroupNameAndPath(); diff --git a/app/assets/javascripts/pages/admin/impersonation_tokens/index.js b/app/assets/javascripts/pages/admin/impersonation_tokens/index.js index 8fbc8dc17bc..d86ac891977 100644 --- a/app/assets/javascripts/pages/admin/impersonation_tokens/index.js +++ b/app/assets/javascripts/pages/admin/impersonation_tokens/index.js @@ -1,8 +1,14 @@ -import { initExpiresAtField } from '~/access_tokens'; +import { + initAccessTokenTableApp, + initExpiresAtField, + initNewAccessTokenApp, +} from '~/access_tokens'; import { initAdminUserActions, initDeleteUserModals } from '~/admin/users'; import initConfirmModal from '~/confirm_modal'; +initAccessTokenTableApp(); +initExpiresAtField(); +initNewAccessTokenApp(); initAdminUserActions(); initDeleteUserModals(); -initExpiresAtField(); initConfirmModal(); diff --git a/app/assets/javascripts/pages/dashboard/todos/index/todos.js b/app/assets/javascripts/pages/dashboard/todos/index/todos.js index c4bbbdcd8ec..44299d235d5 100644 --- a/app/assets/javascripts/pages/dashboard/todos/index/todos.js +++ b/app/assets/javascripts/pages/dashboard/todos/index/todos.js @@ -31,6 +31,7 @@ export default class Todos { $('.js-done-todo, .js-undo-todo, .js-add-todo').off('click', this.updateRowStateClickedWrapper); $('.js-todos-mark-all', '.js-todos-undo-all').off('click', this.updateallStateClickedWrapper); $('.todo').off('click', this.goToTodoUrl); + $('.todo').off('auxclick', this.goToTodoUrl); } bindEvents() { @@ -40,6 +41,7 @@ export default class Todos { $('.js-done-todo, .js-undo-todo, .js-add-todo').on('click', this.updateRowStateClickedWrapper); $('.js-todos-mark-all, .js-todos-undo-all').on('click', this.updateAllStateClickedWrapper); $('.todo').on('click', this.goToTodoUrl); + $('.todo').on('auxclick', this.goToTodoUrl); } initFilters() { @@ -198,11 +200,13 @@ export default class Todos { e.stopPropagation(); e.preventDefault(); + const isPrimaryClick = e.button === 0; + if (isMetaClick(e)) { const windowTarget = '_blank'; window.open(todoLink, windowTarget); - } else { + } else if (isPrimaryClick) { visitUrl(todoLink); } } diff --git a/app/assets/javascripts/pages/groups/group_members/index.js b/app/assets/javascripts/pages/groups/group_members/index.js index 79ac31f1659..c7c2f6f773e 100644 --- a/app/assets/javascripts/pages/groups/group_members/index.js +++ b/app/assets/javascripts/pages/groups/group_members/index.js @@ -32,25 +32,19 @@ initMembersApp(document.querySelector('.js-group-members-list-app'), { }, }, [MEMBER_TYPES.group]: { - tableFields: gon?.features?.groupMemberInheritedGroup - ? SHARED_FIELDS.concat(['source', 'granted']) - : SHARED_FIELDS.concat(['granted']), + tableFields: SHARED_FIELDS.concat(['source', 'granted']), tableAttrs: { table: { 'data-qa-selector': 'groups_list' }, tr: { 'data-qa-selector': 'group_row' }, }, requestFormatter: groupLinkRequestFormatter, - ...(gon?.features?.groupMemberInheritedGroup - ? { - filteredSearchBar: { - show: true, - tokens: ['with_inherited_permissions'], - searchParam: 'search_groups', - placeholder: s__('Members|Filter groups'), - recentSearchesStorageKey: 'group_links_members', - }, - } - : {}), + filteredSearchBar: { + show: true, + tokens: ['groups_with_inherited_permissions'], + searchParam: 'search_groups', + placeholder: s__('Members|Filter groups'), + recentSearchesStorageKey: 'group_links_members', + }, }, [MEMBER_TYPES.invite]: { tableFields: SHARED_FIELDS.concat('invited'), diff --git a/app/assets/javascripts/pages/groups/issues/index.js b/app/assets/javascripts/pages/groups/issues/index.js index 725c38defc3..912a4ea2c11 100644 --- a/app/assets/javascripts/pages/groups/issues/index.js +++ b/app/assets/javascripts/pages/groups/issues/index.js @@ -1,26 +1,3 @@ -import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys'; -import { initBulkUpdateSidebar } from '~/issuable/bulk_update_sidebar'; import { mountIssuesListApp } from '~/issues/list'; -import initManualOrdering from '~/issues/manual_ordering'; -import { FILTERED_SEARCH } from '~/filtered_search/constants'; -import initFilteredSearch from '~/pages/search/init_filtered_search'; -import projectSelect from '~/project_select'; -if (gon.features?.vueIssuesList) { - mountIssuesListApp(); -} else { - const ISSUE_BULK_UPDATE_PREFIX = 'issue_'; - - IssuableFilteredSearchTokenKeys.addExtraTokensForIssues(); - IssuableFilteredSearchTokenKeys.removeTokensForKeys('release'); - initBulkUpdateSidebar(ISSUE_BULK_UPDATE_PREFIX); - - initFilteredSearch({ - page: FILTERED_SEARCH.ISSUES, - isGroupDecendent: true, - useDefaultState: true, - filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys, - }); - projectSelect(); - initManualOrdering(); -} +mountIssuesListApp(); diff --git a/app/assets/javascripts/pages/groups/new/index.js b/app/assets/javascripts/pages/groups/new/index.js index 702b152d25a..7c409010510 100644 --- a/app/assets/javascripts/pages/groups/new/index.js +++ b/app/assets/javascripts/pages/groups/new/index.js @@ -2,18 +2,19 @@ import Vue from 'vue'; import BindInOut from '~/behaviors/bind_in_out'; import initFilePickers from '~/file_pickers'; import Group from '~/group'; +import { initGroupNameAndPath } from '~/groups/create_edit_form'; import { parseBoolean } from '~/lib/utils/common_utils'; import NewGroupCreationApp from './components/app.vue'; import GroupPathValidator from './group_path_validator'; import initToggleInviteMembers from './toggle_invite_members'; new GroupPathValidator(); // eslint-disable-line no-new +new Group(); // eslint-disable-line no-new +initGroupNameAndPath(); BindInOut.initAll(); initFilePickers(); -new Group(); // eslint-disable-line no-new - function initNewGroupCreation(el) { const { hasErrors, verificationRequired, verificationFormUrl, subscriptionsUrl } = el.dataset; diff --git a/app/assets/javascripts/pages/groups/settings/access_tokens/index.js b/app/assets/javascripts/pages/groups/settings/access_tokens/index.js index dc1bb88bf4b..b9f282a123c 100644 --- a/app/assets/javascripts/pages/groups/settings/access_tokens/index.js +++ b/app/assets/javascripts/pages/groups/settings/access_tokens/index.js @@ -1,3 +1,9 @@ -import { initExpiresAtField } from '~/access_tokens'; +import { + initAccessTokenTableApp, + initExpiresAtField, + initNewAccessTokenApp, +} from '~/access_tokens'; +initAccessTokenTableApp(); initExpiresAtField(); +initNewAccessTokenApp(); diff --git a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js index 52add416f38..bf77d968e7d 100644 --- a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js +++ b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js @@ -1,3 +1,4 @@ +import initStaleRunnerCleanupSetting from 'ee_else_ce/group_settings/stale_runner_cleanup'; import initVariableList from '~/ci_variable_list'; import initSharedRunnersForm from '~/group_settings/mount_shared_runners'; import initSettingsPanels from '~/settings_panels'; @@ -6,4 +7,5 @@ import initSettingsPanels from '~/settings_panels'; initSettingsPanels(); initSharedRunnersForm(); +initStaleRunnerCleanupSetting(); initVariableList(); diff --git a/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue index 35a8d3d979a..6748a62e777 100644 --- a/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue +++ b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue @@ -137,7 +137,7 @@ export default { {{ s__('BulkImport|Group import history') }} </h1> </div> - <gl-loading-icon v-if="loading" size="md" class="gl-mt-5" /> + <gl-loading-icon v-if="loading" size="lg" class="gl-mt-5" /> <gl-empty-state v-else-if="!hasHistoryItems" :title="s__('BulkImport|No history is available')" diff --git a/app/assets/javascripts/pages/import/history/components/import_error_details.vue b/app/assets/javascripts/pages/import/history/components/import_error_details.vue index 33ba73317f8..6af137cd722 100644 --- a/app/assets/javascripts/pages/import/history/components/import_error_details.vue +++ b/app/assets/javascripts/pages/import/history/components/import_error_details.vue @@ -36,7 +36,7 @@ export default { }; </script> <template> - <gl-loading-icon v-if="loading" size="md" /> + <gl-loading-icon v-if="loading" size="lg" /> <pre v-else ><code>{{ error || s__('BulkImport|No additional information provided.') }}</code></pre> diff --git a/app/assets/javascripts/pages/import/history/components/import_history_app.vue b/app/assets/javascripts/pages/import/history/components/import_history_app.vue index 557e25f66e2..db6f0c23dbd 100644 --- a/app/assets/javascripts/pages/import/history/components/import_history_app.vue +++ b/app/assets/javascripts/pages/import/history/components/import_history_app.vue @@ -137,7 +137,7 @@ export default { {{ s__('BulkImport|Project import history') }} </h1> </div> - <gl-loading-icon v-if="loading" size="md" class="gl-mt-5" /> + <gl-loading-icon v-if="loading" size="lg" class="gl-mt-5" /> <gl-empty-state v-else-if="!hasHistoryItems" :title="s__('BulkImport|No history is available')" diff --git a/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js b/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js index 37e9b7e99d4..3fae9809e51 100644 --- a/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js +++ b/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js @@ -1,5 +1,13 @@ -import { initExpiresAtField, initProjectsField, initTokensApp } from '~/access_tokens'; +import { + initAccessTokenTableApp, + initExpiresAtField, + initNewAccessTokenApp, + initProjectsField, + initTokensApp, +} from '~/access_tokens'; +initAccessTokenTableApp(); initExpiresAtField(); +initNewAccessTokenApp(); initProjectsField(); initTokensApp(); diff --git a/app/assets/javascripts/pages/profiles/two_factor_auths/index.js b/app/assets/javascripts/pages/profiles/two_factor_auths/index.js index f6f136f2402..49fdf5bb6b5 100644 --- a/app/assets/javascripts/pages/profiles/two_factor_auths/index.js +++ b/app/assets/javascripts/pages/profiles/two_factor_auths/index.js @@ -6,7 +6,7 @@ const twoFactorNode = document.querySelector('.js-two-factor-auth'); const skippable = twoFactorNode ? parseBoolean(twoFactorNode.dataset.twoFactorSkippable) : false; if (skippable) { - const button = `<a class="btn btn-sm btn-warning float-right" data-qa-selector="configure_it_later_button" data-method="patch" href="${twoFactorNode.dataset.two_factor_skip_url}">Configure it later</a>`; + const button = `<br/><a class="btn gl-button btn-sm btn-confirm gl-mt-3" data-qa-selector="configure_it_later_button" data-method="patch" href="${twoFactorNode.dataset.two_factor_skip_url}">Configure it later</a>`; const flashAlert = document.querySelector('.flash-alert'); if (flashAlert) flashAlert.insertAdjacentHTML('beforeend', button); } diff --git a/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue index 3b5e764b712..92ae8128285 100644 --- a/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue +++ b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue @@ -1,8 +1,8 @@ <script> import { GlAlert, GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui'; import { GlAreaChart } from '@gitlab/ui/dist/charts'; -import dateFormat from 'dateformat'; import { get } from 'lodash'; +import { formatDate } from '~/lib/utils/datetime_utility'; import axios from '~/lib/utils/axios_utils'; import { __ } from '~/locale'; @@ -38,7 +38,10 @@ export default { }, xAxis: { name: '', - type: 'category', + type: 'time', + axisLabel: { + formatter: (value) => formatDate(value, 'mmm dd'), + }, }, }, }; @@ -74,7 +77,7 @@ export default { ); }, formattedData() { - return this.sortedData.map((value) => [dateFormat(value.date, 'mmm dd'), value.coverage]); + return this.sortedData.map((value) => [value.date, value.coverage]); }, chartData() { return [ @@ -106,7 +109,7 @@ export default { this.selectedCoverageIndex = index; }, formatTooltipText(params) { - this.tooltipTitle = params.value; + this.tooltipTitle = formatDate(params.value, 'mmm dd'); this.coveragePercentage = get(params, 'seriesData[0].data[1]', ''); }, }, diff --git a/app/assets/javascripts/pages/projects/incidents/show/index.js b/app/assets/javascripts/pages/projects/incidents/show/index.js index 5a8cfcf8462..a83c4f1c0d2 100644 --- a/app/assets/javascripts/pages/projects/incidents/show/index.js +++ b/app/assets/javascripts/pages/projects/incidents/show/index.js @@ -1,7 +1,7 @@ import { initShow } from '~/issues'; -import initRelatedIssues from '~/related_issues'; import initSidebarBundle from '~/sidebar/sidebar_bundle'; +import initWorkItemLinks from '~/work_items/components/work_item_links'; initShow(); initSidebarBundle(); -initRelatedIssues(); +initWorkItemLinks(); diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js index 44b1d5277d1..b320d8a61c2 100644 --- a/app/assets/javascripts/pages/projects/issues/index/index.js +++ b/app/assets/javascripts/pages/projects/issues/index/index.js @@ -1,34 +1,6 @@ -import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys'; import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation'; -import { initCsvImportExportButtons, initIssuableByEmail } from '~/issuable'; -import { initBulkUpdateSidebar, initIssueStatusSelect } from '~/issuable/bulk_update_sidebar'; import { mountIssuesListApp, mountJiraIssuesListApp } from '~/issues/list'; -import initManualOrdering from '~/issues/manual_ordering'; -import { FILTERED_SEARCH } from '~/filtered_search/constants'; -import { ISSUABLE_INDEX } from '~/issuable/constants'; -import initFilteredSearch from '~/pages/search/init_filtered_search'; -import UsersSelect from '~/users_select'; - -if (gon.features?.vueIssuesList) { - mountIssuesListApp(); -} else { - IssuableFilteredSearchTokenKeys.addExtraTokensForIssues(); - - initFilteredSearch({ - page: FILTERED_SEARCH.ISSUES, - filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys, - useDefaultState: true, - }); - - initBulkUpdateSidebar(ISSUABLE_INDEX.ISSUE); - initIssueStatusSelect(); - new UsersSelect(); // eslint-disable-line no-new - - initCsvImportExportButtons(); - initIssuableByEmail(); - initManualOrdering(); -} - -new ShortcutsNavigation(); // eslint-disable-line no-new +mountIssuesListApp(); mountJiraIssuesListApp(); +new ShortcutsNavigation(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js index 46a34c025b6..ca2b1a08be8 100644 --- a/app/assets/javascripts/pages/projects/issues/show/index.js +++ b/app/assets/javascripts/pages/projects/issues/show/index.js @@ -2,7 +2,9 @@ import { initShow } from '~/issues'; import { store } from '~/notes/stores'; import initRelatedIssues from '~/related_issues'; import initSidebarBundle from '~/sidebar/sidebar_bundle'; +import initWorkItemLinks from '~/work_items/components/work_item_links'; initShow(); initSidebarBundle(store); initRelatedIssues(); +initWorkItemLinks(); diff --git a/app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js b/app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js index 545a39f4cf1..d3599ce5741 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js +++ b/app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js @@ -1,5 +1,3 @@ import initMergeConflicts from '~/merge_conflicts/merge_conflicts_bundle'; -import initSidebarBundle from '~/sidebar/sidebar_bundle'; -initSidebarBundle(); initMergeConflicts(); diff --git a/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js b/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js index d61209f904d..2d26d3922bf 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js +++ b/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js @@ -4,7 +4,8 @@ import { localTimeAgo } from '~/lib/utils/datetime_utility'; import initCompareAutocomplete from './compare_autocomplete'; import initTargetProjectDropdown from './target_project_dropdown'; -const updateCommitList = (url, $loadingIndicator, $commitList, params) => { +const updateCommitList = (url, $emptyState, $loadingIndicator, $commitList, params) => { + $emptyState.hide(); $loadingIndicator.show(); $commitList.empty(); @@ -16,6 +17,10 @@ const updateCommitList = (url, $loadingIndicator, $commitList, params) => { $loadingIndicator.hide(); $commitList.html(data); localTimeAgo($commitList.get(0).querySelectorAll('.js-timeago')); + + if (!data) { + $emptyState.show(); + } }); }; @@ -26,6 +31,7 @@ export default (mrNewCompareNode) => { const updateSourceBranchCommitList = () => updateCommitList( sourceBranchUrl, + $(mrNewCompareNode).find('.js-source-commit-empty'), $(mrNewCompareNode).find('.js-source-loading'), $(mrNewCompareNode).find('.mr_source_commit'), { @@ -35,6 +41,7 @@ export default (mrNewCompareNode) => { const updateTargetBranchCommitList = () => updateCommitList( targetBranchUrl, + $(mrNewCompareNode).find('.js-target-commit-empty'), $(mrNewCompareNode).find('.js-target-loading'), $(mrNewCompareNode).find('.mr_target_commit'), { diff --git a/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare_autocomplete.js b/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare_autocomplete.js index e5f97530c02..9a38c2cc765 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare_autocomplete.js +++ b/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare_autocomplete.js @@ -12,6 +12,7 @@ export default function initCompareAutocomplete(limitTo = null, clickHandler = ( $('.js-compare-dropdown').each(function () { const $dropdown = $(this); const selected = $dropdown.data('selected'); + const defaultText = $dropdown.data('defaultText').trim(); const $dropdownContainer = $dropdown.closest('.dropdown'); const $fieldInput = $(`input[name="${$dropdown.data('fieldName')}"]`, $dropdownContainer); const $filterInput = $('input[type="search"]', $dropdownContainer); @@ -63,7 +64,11 @@ export default function initCompareAutocomplete(limitTo = null, clickHandler = ( return $el.attr('data-ref'); }, toggleLabel(obj, $el) { - return $el.text().trim(); + if ($el.hasClass('is-active')) { + return $el.text().trim(); + } + + return defaultText; }, clicked: () => clickHandler($dropdown), }); diff --git a/app/assets/javascripts/pages/projects/settings/access_tokens/index.js b/app/assets/javascripts/pages/projects/settings/access_tokens/index.js index dc1bb88bf4b..b9f282a123c 100644 --- a/app/assets/javascripts/pages/projects/settings/access_tokens/index.js +++ b/app/assets/javascripts/pages/projects/settings/access_tokens/index.js @@ -1,3 +1,9 @@ -import { initExpiresAtField } from '~/access_tokens'; +import { + initAccessTokenTableApp, + initExpiresAtField, + initNewAccessTokenApp, +} from '~/access_tokens'; +initAccessTokenTableApp(); initExpiresAtField(); +initNewAccessTokenApp(); diff --git a/app/assets/javascripts/pages/projects/settings/branch_rules/index.js b/app/assets/javascripts/pages/projects/settings/branch_rules/index.js new file mode 100644 index 00000000000..c3d36ad5651 --- /dev/null +++ b/app/assets/javascripts/pages/projects/settings/branch_rules/index.js @@ -0,0 +1,3 @@ +import mountBranchRules from '~/projects/settings/branch_rules/mount_branch_rules'; + +mountBranchRules(document.getElementById('js-branch-rules')); diff --git a/app/assets/javascripts/pages/projects/services/edit/index.js b/app/assets/javascripts/pages/projects/settings/integrations/edit/index.js index 64df0d07d74..64df0d07d74 100644 --- a/app/assets/javascripts/pages/projects/services/edit/index.js +++ b/app/assets/javascripts/pages/projects/settings/integrations/edit/index.js diff --git a/app/assets/javascripts/pages/projects/settings/integrations/show/index.js b/app/assets/javascripts/pages/projects/settings/integrations/index/index.js index 53068f72d3f..53068f72d3f 100644 --- a/app/assets/javascripts/pages/projects/settings/integrations/show/index.js +++ b/app/assets/javascripts/pages/projects/settings/integrations/index/index.js diff --git a/app/assets/javascripts/pages/projects/settings/repository/show/index.js b/app/assets/javascripts/pages/projects/settings/repository/show/index.js index d45052d76f4..655243eee30 100644 --- a/app/assets/javascripts/pages/projects/settings/repository/show/index.js +++ b/app/assets/javascripts/pages/projects/settings/repository/show/index.js @@ -1,7 +1,10 @@ import MirrorRepos from '~/mirrors/mirror_repos'; +import mountBranchRules from '~/projects/settings/repository/branch_rules/mount_branch_rules'; import initForm from '../form'; initForm(); const mirrorReposContainer = document.querySelector('.js-mirror-settings'); if (mirrorReposContainer) new MirrorRepos(mirrorReposContainer).init(); + +mountBranchRules(document.getElementById('js-branch-rules')); diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue index 03bab0fa773..81b0dbec0bd 100644 --- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue +++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue @@ -2,6 +2,7 @@ import { GlButton, GlIcon, GlSprintf, GlLink, GlFormCheckbox, GlToggle } from '@gitlab/ui'; import ConfirmDanger from '~/vue_shared/components/confirm_danger/confirm_danger.vue'; import settingsMixin from 'ee_else_ce/pages/projects/shared/permissions/mixins/settings_pannel_mixin'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { __, s__ } from '~/locale'; import { visibilityOptions, @@ -16,7 +17,7 @@ import { toggleHiddenClassBySelector } from '../external'; import projectFeatureSetting from './project_feature_setting.vue'; import projectSettingRow from './project_setting_row.vue'; -const PAGE_FEATURE_ACCESS_LEVEL = s__('ProjectSettings|Everyone'); +const FEATURE_ACCESS_LEVEL_ANONYMOUS = [30, s__('ProjectSettings|Everyone')]; export default { i18n: { @@ -28,7 +29,14 @@ export default { lfsLabel: s__('ProjectSettings|Git Large File Storage (LFS)'), mergeRequestsLabel: s__('ProjectSettings|Merge requests'), operationsLabel: s__('ProjectSettings|Operations'), + packagesHelpText: s__( + 'ProjectSettings|Every project can have its own space to store its packages. Note: The Package Registry is always visible when a project is public.', + ), + packageRegistryHelpText: s__( + 'ProjectSettings|Every project can have its own space to store its packages.', + ), packagesLabel: s__('ProjectSettings|Packages'), + packageRegistryLabel: s__('ProjectSettings|Package registry'), pagesLabel: s__('ProjectSettings|Pages'), ciCdLabel: __('CI/CD'), repositoryLabel: s__('ProjectSettings|Repository'), @@ -54,7 +62,7 @@ export default { GlToggle, ConfirmDanger, }, - mixins: [settingsMixin], + mixins: [settingsMixin, glFeatureFlagsMixin()], props: { requestCveAvailable: { @@ -183,6 +191,7 @@ export default { repositoryAccessLevel: featureAccessLevel.EVERYONE, forkingAccessLevel: featureAccessLevel.EVERYONE, mergeRequestsAccessLevel: featureAccessLevel.EVERYONE, + packageRegistryAccessLevel: featureAccessLevel.EVERYONE, buildsAccessLevel: featureAccessLevel.EVERYONE, wikiAccessLevel: featureAccessLevel.EVERYONE, snippetsAccessLevel: featureAccessLevel.EVERYONE, @@ -196,6 +205,7 @@ export default { warnAboutPotentiallyUnwantedCharacters: true, lfsEnabled: true, requestAccessEnabled: true, + enforceAuthChecksOnUploads: true, highlightChangesClass: false, emailsDisabled: false, cveIdRequestEnabled: true, @@ -229,6 +239,18 @@ export default { ); }, + packageRegistryFeatureAccessLevelOptions() { + const options = [FEATURE_ACCESS_LEVEL_ANONYMOUS]; + + if (this.visibilityLevel === visibilityOptions.PRIVATE) { + options.unshift(featureAccessLevelMembers); + } else if (this.visibilityLevel === visibilityOptions.INTERNAL) { + options.unshift(featureAccessLevelEveryone); + } + + return options; + }, + pagesFeatureAccessLevelOptions() { const options = [featureAccessLevelMembers]; @@ -242,7 +264,7 @@ export default { } if (this.visibilityLevel !== visibilityOptions.PUBLIC) { - options.push([30, PAGE_FEATURE_ACCESS_LEVEL]); + options.push(FEATURE_ACCESS_LEVEL_ANONYMOUS); } } return options; @@ -285,6 +307,16 @@ export default { this.visibilityLevel < this.currentSettings.visibilityLevel ); }, + packageRegistryAccessLevelEnabled() { + return this.glFeatures.packageRegistryAccessLevel; + }, + showAdditonalSettings() { + if (this.glFeatures.enforceAuthChecksOnUploads) { + return true; + } + + return this.visibilityLevel !== this.visibilityOptions.PRIVATE; + }, }, watch: { @@ -307,6 +339,15 @@ export default { featureAccessLevel.PROJECT_MEMBERS, this.buildsAccessLevel, ); + if (this.packageRegistryAccessLevelEnabled) { + if ( + this.packageRegistryAccessLevel === featureAccessLevel.EVERYONE || + (this.packageRegistryAccessLevel > featureAccessLevel.EVERYONE && + oldValue === visibilityOptions.PUBLIC) + ) { + this.packageRegistryAccessLevel = featureAccessLevel.PROJECT_MEMBERS; + } + } this.wikiAccessLevel = Math.min(featureAccessLevel.PROJECT_MEMBERS, this.wikiAccessLevel); this.snippetsAccessLevel = Math.min( featureAccessLevel.PROJECT_MEMBERS, @@ -349,6 +390,14 @@ export default { this.repositoryAccessLevel = featureAccessLevel.EVERYONE; if (this.mergeRequestsAccessLevel > featureAccessLevel.NOT_ENABLED) this.mergeRequestsAccessLevel = featureAccessLevel.EVERYONE; + if ( + this.packageRegistryAccessLevelEnabled && + this.packageRegistryAccessLevel === featureAccessLevel.PROJECT_MEMBERS + ) { + this.packageRegistryAccessLevel = Math.min( + ...this.packageRegistryFeatureAccessLevelOptions.map((option) => option[0]), + ); + } if (this.buildsAccessLevel > featureAccessLevel.NOT_ENABLED) this.buildsAccessLevel = featureAccessLevel.EVERYONE; if (this.wikiAccessLevel > featureAccessLevel.NOT_ENABLED) @@ -369,6 +418,19 @@ export default { this.containerRegistryAccessLevel = featureAccessLevel.EVERYONE; this.highlightChanges(); + } else if (this.packageRegistryAccessLevelEnabled) { + if ( + value === visibilityOptions.PUBLIC && + this.packageRegistryAccessLevel === featureAccessLevel.EVERYONE + ) { + // eslint-disable-next-line prefer-destructuring + this.packageRegistryAccessLevel = FEATURE_ACCESS_LEVEL_ANONYMOUS[0]; + } else if ( + value === visibilityOptions.INTERNAL && + this.packageRegistryAccessLevel === FEATURE_ACCESS_LEVEL_ANONYMOUS[0] + ) { + this.packageRegistryAccessLevel = featureAccessLevel.EVERYONE; + } } }, @@ -465,15 +527,38 @@ export default { ) }}</span> <span class="form-text text-muted">{{ visibilityLevelDescription }}</span> - <label v-if="visibilityLevel !== visibilityOptions.PRIVATE" class="gl-line-height-28"> - <input - :value="requestAccessEnabled" - type="hidden" - name="project[request_access_enabled]" - /> - <input v-model="requestAccessEnabled" type="checkbox" /> - {{ s__('ProjectSettings|Users can request access') }} - </label> + <div v-if="showAdditonalSettings" class="gl-mt-4"> + <strong class="gl-display-block">{{ s__('ProjectSettings|Additional options') }}</strong> + <label + v-if="visibilityLevel !== visibilityOptions.PRIVATE" + class="gl-line-height-28 gl-font-weight-normal gl-mb-0" + > + <input + :value="requestAccessEnabled" + type="hidden" + name="project[request_access_enabled]" + /> + <input v-model="requestAccessEnabled" type="checkbox" /> + {{ s__('ProjectSettings|Users can request access') }} + </label> + <label + v-if=" + visibilityLevel !== visibilityOptions.PUBLIC && glFeatures.enforceAuthChecksOnUploads + " + class="gl-line-height-28 gl-font-weight-normal gl-display-block gl-mb-0" + > + <input + :value="enforceAuthChecksOnUploads" + type="hidden" + name="project[project_setting_attributes][enforce_auth_checks_on_uploads]" + /> + <input v-model="enforceAuthChecksOnUploads" type="checkbox" /> + {{ s__('ProjectSettings|Require authentication to view media files') }} + <span class="gl-text-gray-500 gl-display-block gl-ml-5 gl-mt-n3">{{ + s__('ProjectSettings|Prevents direct linking to potentially sensitive media files') + }}</span> + </label> + </div> </project-setting-row> </div> <div @@ -587,15 +672,11 @@ export default { </p> </project-setting-row> <project-setting-row - v-if="packagesAvailable" + v-if="packagesAvailable && !packageRegistryAccessLevelEnabled" ref="package-settings" :help-path="packagesHelpPath" :label="$options.i18n.packagesLabel" - :help-text=" - s__( - 'ProjectSettings|Every project can have its own space to store its packages. Note: The Package Registry is always visible when a project is public.', - ) - " + :help-text="$options.i18n.packagesHelpText" > <gl-toggle v-model="packagesEnabled" @@ -710,6 +791,20 @@ export default { /> </project-setting-row> <project-setting-row + v-if="packageRegistryAccessLevelEnabled && packagesAvailable" + :help-path="packagesHelpPath" + :label="$options.i18n.packageRegistryLabel" + :help-text="$options.i18n.packageRegistryHelpText" + data-testid="package-registry-access-level" + > + <project-feature-setting + v-model="packageRegistryAccessLevel" + :label="$options.i18n.packageRegistryLabel" + :options="packageRegistryFeatureAccessLevelOptions" + name="project[project_feature_attributes][package_registry_access_level]" + /> + </project-setting-row> + <project-setting-row v-if="pagesAvailable && pagesAccessControlEnabled" ref="pages-settings" :help-path="pagesHelpPath" diff --git a/app/assets/javascripts/pages/projects/shared/save_project_loader.js b/app/assets/javascripts/pages/projects/shared/save_project_loader.js index aa3589ac88d..7fd9e24549f 100644 --- a/app/assets/javascripts/pages/projects/shared/save_project_loader.js +++ b/app/assets/javascripts/pages/projects/shared/save_project_loader.js @@ -1,12 +1,14 @@ -import $ from 'jquery'; - export default function initProjectLoadingSpinner() { - const $formContainer = $('.project-edit-container'); - const $loadingSpinner = $('.save-project-loader'); + const formContainer = document.querySelector('.project-edit-container'); + if (formContainer == null) { + return; + } + + const loadingSpinner = document.querySelector('.save-project-loader'); // show loading spinner when saving - $formContainer.on('ajax:before', () => { - $formContainer.hide(); - $loadingSpinner.show(); + formContainer.addEventListener('ajax:before', () => { + formContainer.style.display = 'none'; + loadingSpinner.style.display = 'block'; }); } diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js index e2b1a702560..eff39a744ad 100644 --- a/app/assets/javascripts/pages/projects/show/index.js +++ b/app/assets/javascripts/pages/projects/show/index.js @@ -2,6 +2,7 @@ import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation'; import initInviteMembersModal from '~/invite_members/init_invite_members_modal'; import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger'; +import initClustersDeprecationAlert from '~/projects/clusters_deprecation_alert'; import leaveByUrl from '~/namespaces/leave_by_url'; import initVueNotificationsDropdown from '~/notifications'; import Star from '~/projects/star'; @@ -50,6 +51,7 @@ new ShortcutsNavigation(); // eslint-disable-line no-new initUploadFileTrigger(); initInviteMembersModal(); initInviteMembersTrigger(); +initClustersDeprecationAlert(); initReadMore(); new Star(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/pages/projects/static_site_editor/show/index.js b/app/assets/javascripts/pages/projects/static_site_editor/show/index.js deleted file mode 100644 index d9d265e4e4a..00000000000 --- a/app/assets/javascripts/pages/projects/static_site_editor/show/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import initStaticSiteEditor from '~/static_site_editor'; - -initStaticSiteEditor(document.querySelector('#static-site-editor')); diff --git a/app/assets/javascripts/pages/projects/tags/index/index.js b/app/assets/javascripts/pages/projects/tags/index/index.js index 9e48dd9e463..e62bdc7a8c0 100644 --- a/app/assets/javascripts/pages/projects/tags/index/index.js +++ b/app/assets/javascripts/pages/projects/tags/index/index.js @@ -1,9 +1,5 @@ import TagSortDropdown from '~/tags'; -import { initRemoveTag } from '../remove_tag'; +import initDeleteTagModal from '~/tags/init_delete_tag_modal'; -initRemoveTag({ - onDelete: (path) => { - document.querySelector(`[data-path="${path}"]`).closest('.js-tag-list').remove(); - }, -}); +initDeleteTagModal(); TagSortDropdown(); diff --git a/app/assets/javascripts/pages/projects/tags/remove_tag.js b/app/assets/javascripts/pages/projects/tags/remove_tag.js deleted file mode 100644 index 7b95560df7b..00000000000 --- a/app/assets/javascripts/pages/projects/tags/remove_tag.js +++ /dev/null @@ -1,16 +0,0 @@ -import initConfirmModal from '~/confirm_modal'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; - -export const initRemoveTag = ({ onDelete = () => {} }) => { - return initConfirmModal({ - handleSubmit: (path = '') => - axios - .delete(path) - .then(() => onDelete(path)) - .catch(({ response: { data } }) => { - const { message } = data; - createFlash({ message }); - }), - }); -}; diff --git a/app/assets/javascripts/pages/projects/tags/show/index.js b/app/assets/javascripts/pages/projects/tags/show/index.js index 6f5406f554f..0967540f42c 100644 --- a/app/assets/javascripts/pages/projects/tags/show/index.js +++ b/app/assets/javascripts/pages/projects/tags/show/index.js @@ -1,8 +1,3 @@ -import { redirectTo, getBaseURL, stripFinalUrlSegment } from '~/lib/utils/url_utility'; -import { initRemoveTag } from '../remove_tag'; +import initDeleteTagModal from '~/tags/init_delete_tag_modal'; -initRemoveTag({ - onDelete: (path = '') => { - redirectTo(stripFinalUrlSegment([getBaseURL(), path].join(''))); - }, -}); +initDeleteTagModal(); diff --git a/app/assets/javascripts/pages/shared/nav/sidebar_tracking.js b/app/assets/javascripts/pages/shared/nav/sidebar_tracking.js index 79ce1a37d21..47aae36ecbb 100644 --- a/app/assets/javascripts/pages/shared/nav/sidebar_tracking.js +++ b/app/assets/javascripts/pages/shared/nav/sidebar_tracking.js @@ -1,6 +1,6 @@ function onSidebarLinkClick() { const setDataTrackAction = (element, action) => { - element.setAttribute('data-track-action', action); + element.dataset.trackAction = action; }; const setDataTrackExtra = (element, value) => { @@ -12,10 +12,10 @@ function onSidebarLinkClick() { ? SIDEBAR_COLLAPSED : SIDEBAR_EXPANDED; - element.setAttribute( - 'data-track-extra', - JSON.stringify({ sidebar_display: sidebarCollapsed, menu_display: value }), - ); + element.dataset.trackExtra = JSON.stringify({ + sidebar_display: sidebarCollapsed, + menu_display: value, + }); }; const EXPANDED = 'Expanded'; diff --git a/app/assets/javascripts/pages/users/activity_calendar.js b/app/assets/javascripts/pages/users/activity_calendar.js index 996e12bc105..94506d33b33 100644 --- a/app/assets/javascripts/pages/users/activity_calendar.js +++ b/app/assets/javascripts/pages/users/activity_calendar.js @@ -298,7 +298,7 @@ export default class ActivityCalendar { .querySelector(this.activitiesContainer) .querySelectorAll('.js-localtime') .forEach((el) => { - el.setAttribute('title', formatDate(el.getAttribute('data-datetime'))); + el.setAttribute('title', formatDate(el.dataset.datetime)); }); }) .catch(() => |