From 83ffdf48518e121c1ccab9d7913d3f7e79d7766c Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 24 Nov 2023 12:12:29 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../components/editor/ci_editor_header.vue | 18 +++++++- .../components/pipeline_editor_tabs.vue | 2 +- app/assets/javascripts/ci/pipeline_editor/index.js | 2 +- .../javascripts/ci/pipeline_editor/options.js | 2 + .../lib/utils/datetime/locale_dateformat.js | 53 +++++++++++++++++++++- .../repository/components/table/index.vue | 27 ++++++----- .../repository/components/tree_content.vue | 8 +--- .../set_status_modal/set_status_form.vue | 6 +-- .../global_search/components/frequent_groups.vue | 16 ------- .../global_search/components/frequent_item.vue | 28 ------------ .../global_search/components/frequent_items.vue | 47 ++----------------- .../global_search/components/frequent_projects.vue | 16 ------- app/assets/javascripts/super_sidebar/constants.js | 3 -- app/assets/javascripts/super_sidebar/utils.js | 49 +++----------------- .../resolvers/ci/catalog/resources_resolver.rb | 18 +++----- .../resolvers/users/frecent_groups_resolver.rb | 6 --- .../resolvers/users/frecent_projects_resolver.rb | 4 -- .../types/ci/catalog/resource_scope_enum.rb | 1 + app/graphql/types/query_type.rb | 6 +-- app/helpers/ci/pipeline_editor_helper.rb | 1 + app/models/ci/catalog/listing.rb | 19 ++++---- 21 files changed, 125 insertions(+), 207 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue index 204eaf20664..51ca69478b0 100644 --- a/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue +++ b/app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue @@ -14,6 +14,7 @@ import { export default { i18n: { + browseCatalog: __('Browse CI/CD Catalog'), browseTemplates: __('Browse templates'), help: __('Help'), jobAssistant: s__('JobAssistant|Job assistant'), @@ -24,7 +25,7 @@ export default { GlButton, }, mixins: [glFeatureFlagMixin(), Tracking.mixin()], - inject: ['aiChatAvailable'], + inject: ['aiChatAvailable', 'ciCatalogPath'], props: { showHelpDrawer: { type: Boolean, @@ -65,6 +66,11 @@ export default { this.showAiAssistantDrawer ? EDITOR_APP_DRAWER_NONE : EDITOR_APP_DRAWER_AI_ASSISTANT, ); }, + trackCatalogBrowsing() { + const { label, actions } = pipelineEditorTrackingOptions; + + this.track(actions.browseCatalog, { label }); + }, trackHelpDrawerClick() { const { label, actions } = pipelineEditorTrackingOptions; this.track(actions.openHelpDrawer, { label }); @@ -83,6 +89,16 @@ export default { class="gl-display-flex gl-p-3 gl-gap-3 gl-border-solid gl-border-gray-100 gl-border-1 gl-flex-direction-column gl-md-flex-direction-row" > + + {{ $options.i18n.browseCatalog }} + import { GlAlert, GlLoadingIcon, GlTabs } from '@gitlab/ui'; -import CiEditorHeader from 'ee_else_ce/ci/pipeline_editor/components/editor/ci_editor_header.vue'; import { s__, __ } from '~/locale'; import PipelineGraph from '~/ci/pipeline_editor/components/graph/pipeline_graph.vue'; import { getParameterValues, setUrlParams, updateHistory } from '~/lib/utils/url_utility'; @@ -20,6 +19,7 @@ import { } from '../constants'; import getAppStatus from '../graphql/queries/client/app_status.query.graphql'; import CiConfigMergedPreview from './editor/ci_config_merged_preview.vue'; +import CiEditorHeader from './editor/ci_editor_header.vue'; import CiValidate from './validate/ci_validate.vue'; import TextEditor from './editor/text_editor.vue'; import EditorTab from './ui/editor_tab.vue'; diff --git a/app/assets/javascripts/ci/pipeline_editor/index.js b/app/assets/javascripts/ci/pipeline_editor/index.js index bc20e478876..408e91a4d62 100644 --- a/app/assets/javascripts/ci/pipeline_editor/index.js +++ b/app/assets/javascripts/ci/pipeline_editor/index.js @@ -1,6 +1,6 @@ import Vue from 'vue'; -import { createAppOptions } from 'ee_else_ce/ci/pipeline_editor/options'; +import { createAppOptions } from '~/ci/pipeline_editor/options'; export const initPipelineEditor = (selector = '#js-pipeline-editor') => { const el = document.querySelector(selector); diff --git a/app/assets/javascripts/ci/pipeline_editor/options.js b/app/assets/javascripts/ci/pipeline_editor/options.js index 340cb6ab979..2a34a2fad42 100644 --- a/app/assets/javascripts/ci/pipeline_editor/options.js +++ b/app/assets/javascripts/ci/pipeline_editor/options.js @@ -19,6 +19,7 @@ export const createAppOptions = (el) => { initialBranchName, pipelineEtag, // Add to provide/inject API for static values + ciCatalogPath, ciConfigPath, ciExamplesHelpPagePath, ciHelpPagePath, @@ -110,6 +111,7 @@ export const createAppOptions = (el) => { apolloProvider, provide: { aiChatAvailable: parseBoolean(aiChatAvailable), + ciCatalogPath, ciConfigPath, ciExamplesHelpPagePath, ciHelpPagePath, diff --git a/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js b/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js index f1446fa5ac4..a4d911a6699 100644 --- a/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js +++ b/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js @@ -31,8 +31,24 @@ export const DATE_TIME_FULL_FORMAT = 'asDateTimeFull'; * localeDateFormat[DATE_ONLY_FORMAT].formatRange(date, date) // returns 'Jul 05 - Jul 07, 2023' */ export const DATE_ONLY_FORMAT = 'asDate'; + +/** + * Format a Date with the help of {@link DateTimeFormat.asTime} + * + * Note: In case you can use localeDateFormat.asTime directly, please do that. + * + * @example + * localeDateFormat[TIME_ONLY_FORMAT].format(date) // returns '2:43' + * localeDateFormat[TIME_ONLY_FORMAT].formatRange(date, date) // returns '2:43 - 6:27 PM' + */ +export const TIME_ONLY_FORMAT = 'asTime'; export const DEFAULT_DATE_TIME_FORMAT = DATE_WITH_TIME_FORMAT; -export const DATE_TIME_FORMATS = [DATE_WITH_TIME_FORMAT, DATE_TIME_FULL_FORMAT, DATE_ONLY_FORMAT]; +export const DATE_TIME_FORMATS = [ + DATE_WITH_TIME_FORMAT, + DATE_TIME_FULL_FORMAT, + DATE_ONLY_FORMAT, + TIME_ONLY_FORMAT, +]; /** * The DateTimeFormat utilities support formatting a number of types, @@ -132,6 +148,38 @@ class DateTimeFormat { ); } + /** + * Locale aware formatter to display only the time. + * + * Use {@link DateTimeFormat.asDateTime} if you also need to display the date. + * + * + * @example + * // en-US: returns something like 2:43 PM + * // en-GB: returns something like 14:43 + * localeDateFormat.asTime.format(date) + * + * Note: If formatting a _range_ and the dates are not on the same day, + * the formatter will do something sensible like: + * 7/9/1983, 2:43 PM – 7/12/1983, 12:36 PM + * + * @example + * // en-US: returns something like 2:43 – 6:27 PM + * // en-GB: returns something like 14:43 – 18:27 + * localeDateFormat.asTime.formatRange(date, date2) + * + * @returns {DateTimeFormatter} + */ + get asTime() { + return ( + this.#formatters[TIME_ONLY_FORMAT] || + this.#createFormatter(TIME_ONLY_FORMAT, { + timeStyle: 'short', + hourCycle: DateTimeFormat.#hourCycle, + }) + ); + } + /** * Resets the memoized formatters * @@ -218,5 +266,8 @@ class DateTimeFormat { * * Date (showing date only): * - {@link DateTimeFormat.asDate localeDateFormat.asDate} - the default format for a date + * + * Time (showing time only): + * - {@link DateTimeFormat.asTime localeDateFormat.asTime} - the default format for a time */ export const localeDateFormat = new DateTimeFormat(); diff --git a/app/assets/javascripts/repository/components/table/index.vue b/app/assets/javascripts/repository/components/table/index.vue index 3da7daa3eec..912cc4d2b1c 100644 --- a/app/assets/javascripts/repository/components/table/index.vue +++ b/app/assets/javascripts/repository/components/table/index.vue @@ -81,22 +81,27 @@ export default { return ['', '/'].indexOf(this.path) === -1; }, }, - watch: { - $route: function routeChange() { - this.$options.totalRowsLoaded = -1; - }, - }, - totalRowsLoaded: -1, methods: { showMore() { this.$emit('showMore'); }, - generateRowNumber(path, id, index) { - const key = `${path}-${id}-${index}`; + generateRowNumber(entry, index) { + const { flatPath, id } = entry; + const key = `${flatPath}-${id}-${index}`; + + // We adjust the offset that we request based on the type of entry + const numTrees = this.entries?.trees?.length || 0; + const numBlobs = this.entries?.blobs?.length || 0; if (!this.rowNumbers[key] && this.rowNumbers[key] !== 0) { - this.$options.totalRowsLoaded += 1; - this.rowNumbers[key] = this.$options.totalRowsLoaded; + if (entry.type === 'commit') { + // submodules are rendered before blobs but are in the last pages the api response + this.rowNumbers[key] = numTrees + numBlobs + index; + } else if (entry.type === 'blob') { + this.rowNumbers[key] = numTrees + index; + } else { + this.rowNumbers[key] = index; + } } return this.rowNumbers[key]; @@ -145,7 +150,7 @@ export default { :lfs-oid="entry.lfsOid" :loading-path="loadingPath" :total-entries="totalEntries" - :row-number="generateRowNumber(entry.flatPath, entry.id, index)" + :row-number="generateRowNumber(entry, index)" :commit-info="getCommit(entry.name)" v-on="$listeners" /> diff --git a/app/assets/javascripts/repository/components/tree_content.vue b/app/assets/javascripts/repository/components/tree_content.vue index dd2cfddc94e..49d9e09dde5 100644 --- a/app/assets/javascripts/repository/components/tree_content.vue +++ b/app/assets/javascripts/repository/components/tree_content.vue @@ -165,12 +165,8 @@ export default { return; } - // Since a user could scroll either up or down, we want to support lazy loading in both directions - this.loadCommitData(rowNumber); - - if (rowNumber - COMMIT_BATCH_SIZE >= 0) { - this.loadCommitData(rowNumber - COMMIT_BATCH_SIZE); - } + // Assume we are loading from the top and greedily choose offsets in multiples of COMMIT_BATCH_SIZE to minimize number of requests + this.loadCommitData(rowNumber - (rowNumber % COMMIT_BATCH_SIZE)); }, loadCommitData(rowNumber) { loadCommits(this.projectPath, this.path, this.ref, rowNumber, this.refType) diff --git a/app/assets/javascripts/set_status_modal/set_status_form.vue b/app/assets/javascripts/set_status_modal/set_status_form.vue index 60ed0d073fe..b6d609ab1fa 100644 --- a/app/assets/javascripts/set_status_modal/set_status_form.vue +++ b/app/assets/javascripts/set_status_modal/set_status_form.vue @@ -14,7 +14,7 @@ import SafeHtml from '~/vue_shared/directives/safe_html'; import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete'; import * as Emoji from '~/emoji'; import { s__ } from '~/locale'; -import { formatDate, newDate, nSecondsAfter, isToday } from '~/lib/utils/datetime_utility'; +import { newDate, nSecondsAfter, isToday, localeDateFormat } from '~/lib/utils/datetime_utility'; import { TIME_RANGES_WITH_NEVER, AVAILABILITY_STATUS, NEVER_TIME_RANGE } from './constants'; export default { @@ -148,10 +148,10 @@ export default { }, formatClearStatusAfterDate(date) { if (isToday(date)) { - return formatDate(date, 'h:MMtt'); + return localeDateFormat.asTime.format(date); } - return formatDate(date, 'mmm d, yyyy h:MMtt'); + return localeDateFormat.asDateTime.format(date); }, }, TIME_RANGES_WITH_NEVER, diff --git a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_groups.vue b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_groups.vue index e7e7e54ce77..252967b33b5 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_groups.vue +++ b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_groups.vue @@ -1,7 +1,5 @@ @@ -41,8 +27,6 @@ export default { :loading="$apollo.queries.frecentGroups.loading" :empty-state-text="$options.i18n.emptyStateText" :group-name="$options.i18n.groupName" - :max-items="$options.MAX_FREQUENT_GROUPS_COUNT" - :storage-key="storageKey" :items="frecentGroups" view-all-items-icon="group" :view-all-items-text="$options.i18n.viewAllText" diff --git a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_item.vue b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_item.vue index b0007c21cdc..b76d238c559 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_item.vue +++ b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_item.vue @@ -1,33 +1,17 @@ @@ -51,17 +35,5 @@ export default { {{ item.subtitle }} - - diff --git a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_items.vue b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_items.vue index 2e431c4f8da..60692361683 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_items.vue +++ b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_items.vue @@ -1,9 +1,7 @@ diff --git a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_projects.vue b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_projects.vue index 4a269d1b876..2d13ab3dd4a 100644 --- a/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_projects.vue +++ b/app/assets/javascripts/super_sidebar/components/global_search/components/frequent_projects.vue @@ -1,7 +1,5 @@ @@ -41,8 +27,6 @@ export default { :loading="$apollo.queries.frecentProjects.loading" :empty-state-text="$options.i18n.emptyStateText" :group-name="$options.i18n.groupName" - :max-items="$options.MAX_FREQUENT_PROJECTS_COUNT" - :storage-key="storageKey" :items="frecentProjects" view-all-items-icon="project" :view-all-items-text="$options.i18n.viewAllText" diff --git a/app/assets/javascripts/super_sidebar/constants.js b/app/assets/javascripts/super_sidebar/constants.js index e96dca3f365..f4da76f4a6e 100644 --- a/app/assets/javascripts/super_sidebar/constants.js +++ b/app/assets/javascripts/super_sidebar/constants.js @@ -25,9 +25,6 @@ export const helpCenterState = Vue.observable({ showTanukiBotChatDrawer: false, }); -export const MAX_FREQUENT_PROJECTS_COUNT = 5; -export const MAX_FREQUENT_GROUPS_COUNT = 3; - export const SUPER_SIDEBAR_PEEK_OPEN_DELAY = 200; export const SUPER_SIDEBAR_PEEK_CLOSE_DELAY = 500; export const SUPER_SIDEBAR_PEEK_STATE_CLOSED = 'closed'; diff --git a/app/assets/javascripts/super_sidebar/utils.js b/app/assets/javascripts/super_sidebar/utils.js index 3d6eef62ad2..dbea306eced 100644 --- a/app/assets/javascripts/super_sidebar/utils.js +++ b/app/assets/javascripts/super_sidebar/utils.js @@ -26,24 +26,14 @@ const sortItemsByFrequencyAndLastAccess = (items) => return 0; }); -// This imitates getTopFrequentItems from app/assets/javascripts/frequent_items/utils.js, but -// adjusts the rules to accommodate for the context switcher's designs. -export const getTopFrequentItems = (items, maxCount) => { - if (!Array.isArray(items)) return []; - - const frequentItems = items.filter((item) => item.frequency >= FREQUENT_ITEMS.ELIGIBLE_FREQUENCY); - sortItemsByFrequencyAndLastAccess(frequentItems); - - return frequentItems.slice(0, maxCount); -}; - /** * This tracks projects' and groups' visits in order to suggest a list of frequently visited - * entities to the user. Currently, this track visits in two ways: - * - The legacy approach uses a simple counting algorithm and stores the data in the local storage. - * - The above approach is being migrated to a backend-based one, where visits will be stored in the - * DB, and suggestions will be made through a smarter algorithm. When we are ready to transition - * to the newer approach, the legacy one will be cleaned up. + * entities to the user. The suggestion logic is implemented server-side and computed items can be + * retrieved through the GraphQL API. + * To persist a visit in the DB, an AJAX request needs to be triggered by the client. To avoid making + * the request on every visited page, we also keep track of the visits in the local storage so that + * the request is only sent once every 15 minutes per namespace per user. + * * @param {object} item The project/group item being tracked. * @param {string} namespace A string indicating whether the tracked entity is a project or a group. * @param {string} trackVisitsPath The API endpoint to track visits server-side. @@ -115,31 +105,4 @@ export const trackContextAccess = (username, context, trackVisitsPath) => { return localStorage.setItem(storageKey, JSON.stringify(storedItems)); }; -export const getItemsFromLocalStorage = ({ storageKey, maxItems }) => { - if (!AccessorUtilities.canUseLocalStorage()) { - return []; - } - - try { - const parsedCachedFrequentItems = JSON.parse(localStorage.getItem(storageKey)); - return getTopFrequentItems(parsedCachedFrequentItems, maxItems); - } catch (e) { - Sentry.captureException(e); - return []; - } -}; - -export const removeItemFromLocalStorage = ({ storageKey, item }) => { - try { - const parsedCachedFrequentItems = JSON.parse(localStorage.getItem(storageKey)); - const filteredItems = parsedCachedFrequentItems.filter((i) => i.id !== item.id); - localStorage.setItem(storageKey, JSON.stringify(filteredItems)); - - return filteredItems; - } catch (e) { - Sentry.captureException(e); - return []; - } -}; - export const ariaCurrent = (isActive) => (isActive ? 'page' : null); diff --git a/app/graphql/resolvers/ci/catalog/resources_resolver.rb b/app/graphql/resolvers/ci/catalog/resources_resolver.rb index c6904dcd7f6..ec415cf25c1 100644 --- a/app/graphql/resolvers/ci/catalog/resources_resolver.rb +++ b/app/graphql/resolvers/ci/catalog/resources_resolver.rb @@ -27,17 +27,13 @@ module Resolvers description: 'Project with the namespace catalog.' def resolve_with_lookahead(scope:, project_path: nil, search: nil, sort: nil) - if project_path.present? - project = Project.find_by_full_path(project_path) - - apply_lookahead( - ::Ci::Catalog::Listing - .new(context[:current_user]) - .resources(namespace: project.root_namespace, sort: sort, search: search) - ) - elsif scope == :all - apply_lookahead(::Ci::Catalog::Listing.new(context[:current_user]).resources(sort: sort, search: search)) - end + project = Project.find_by_full_path(project_path) + + apply_lookahead( + ::Ci::Catalog::Listing + .new(context[:current_user]) + .resources(namespace: project&.root_namespace, sort: sort, search: search, scope: scope) + ) end private diff --git a/app/graphql/resolvers/users/frecent_groups_resolver.rb b/app/graphql/resolvers/users/frecent_groups_resolver.rb index 2fc757e31ab..f6b43297898 100644 --- a/app/graphql/resolvers/users/frecent_groups_resolver.rb +++ b/app/graphql/resolvers/users/frecent_groups_resolver.rb @@ -10,12 +10,6 @@ module Resolvers def resolve return unless current_user.present? - if Feature.disabled?(:frecent_namespaces_suggestions, current_user) - raise_resource_not_available_error!("'frecent_namespaces_suggestions' feature flag is disabled") - end - - return unless Feature.enabled?(:frecent_namespaces_suggestions, current_user) - ::Users::GroupVisit.frecent_groups(user_id: current_user.id) end end diff --git a/app/graphql/resolvers/users/frecent_projects_resolver.rb b/app/graphql/resolvers/users/frecent_projects_resolver.rb index 397d4ca0cfd..9508195800a 100644 --- a/app/graphql/resolvers/users/frecent_projects_resolver.rb +++ b/app/graphql/resolvers/users/frecent_projects_resolver.rb @@ -10,10 +10,6 @@ module Resolvers def resolve return unless current_user.present? - if Feature.disabled?(:frecent_namespaces_suggestions, current_user) - raise_resource_not_available_error!("'frecent_namespaces_suggestions' feature flag is disabled") - end - ::Users::ProjectVisit.frecent_projects(user_id: current_user.id) end end diff --git a/app/graphql/types/ci/catalog/resource_scope_enum.rb b/app/graphql/types/ci/catalog/resource_scope_enum.rb index b825c3a7925..728670ba913 100644 --- a/app/graphql/types/ci/catalog/resource_scope_enum.rb +++ b/app/graphql/types/ci/catalog/resource_scope_enum.rb @@ -8,6 +8,7 @@ module Types description 'Values for scoping catalog resources' value 'ALL', 'All catalog resources visible to the current user.', value: :all + value 'NAMESPACES', 'Catalog resources belonging to authorized namespaces of the user.', value: :namespaces end end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 9acff9eb2b1..9c64e056f87 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -57,12 +57,10 @@ module Types field :echo, resolver: Resolvers::EchoResolver field :frecent_groups, [Types::GroupType], resolver: Resolvers::Users::FrecentGroupsResolver, - description: "A user's frecently visited groups. Requires the `frecent_namespaces_suggestions` feature flag to be enabled.", - alpha: { milestone: '16.6' } + description: "A user's frecently visited groups" field :frecent_projects, [Types::ProjectType], resolver: Resolvers::Users::FrecentProjectsResolver, - description: "A user's frecently visited projects. Requires the `frecent_namespaces_suggestions` feature flag to be enabled.", - alpha: { milestone: '16.6' } + description: "A user's frecently visited projects" field :gitpod_enabled, GraphQL::Types::Boolean, null: true, description: "Whether Gitpod is enabled in application settings." diff --git a/app/helpers/ci/pipeline_editor_helper.rb b/app/helpers/ci/pipeline_editor_helper.rb index 4d1bdf5fa7f..b40d633dc69 100644 --- a/app/helpers/ci/pipeline_editor_helper.rb +++ b/app/helpers/ci/pipeline_editor_helper.rb @@ -14,6 +14,7 @@ module Ci total_branches = project.repository_exists? ? project.repository.branch_count : 0 { + "ci-catalog-path" => explore_catalog_index_path, "ci-config-path": project.ci_config_path_or_default, "ci-examples-help-page-path" => help_page_path('ci/examples/index'), "ci-help-page-path" => help_page_path('ci/index'), diff --git a/app/models/ci/catalog/listing.rb b/app/models/ci/catalog/listing.rb index 14d043ad156..7a50a8ea94a 100644 --- a/app/models/ci/catalog/listing.rb +++ b/app/models/ci/catalog/listing.rb @@ -13,8 +13,9 @@ module Ci @current_user = current_user end - def resources(namespace: nil, sort: nil, search: nil) - relation = all_resources + def resources(namespace: nil, sort: nil, search: nil, scope: :all) + relation = Ci::Catalog::Resource.published.joins(:project).includes(:project) + relation = by_scope(relation, scope) relation = by_namespace(relation, namespace) relation = by_search(relation, search) @@ -43,12 +44,6 @@ module Ci attr_reader :current_user - def all_resources - Ci::Catalog::Resource.published - .joins(:project).includes(:project) - .merge(Project.public_or_visible_to_user(current_user)) - end - def by_namespace(relation, namespace) return relation unless namespace raise ArgumentError, 'Namespace is not a root namespace' unless namespace.root? @@ -62,6 +57,14 @@ module Ci relation.search(search) end + + def by_scope(relation, scope) + if scope == :namespaces && Feature.enabled?(:ci_guard_for_catalog_resource_scope, current_user) + relation.merge(Project.public_and_internal_only.visible_to_user(current_user)) + else + relation.merge(Project.public_or_visible_to_user(current_user)) + end + end end end end -- cgit v1.2.3