diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-20 03:10:18 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-20 03:10:18 +0300 |
commit | 27272e0696cedeed1f55f3ce09983fe8e849f7ba (patch) | |
tree | 258187438d804f0aaf06dde432d711100da29194 /app | |
parent | ec2d2ecdf734e48f6603c90aea01abc67c6bb293 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/components/pajamas/avatar_component.rb | 29 | ||||
-rw-r--r-- | app/graphql/resolvers/ml/find_models_resolver.rb | 35 | ||||
-rw-r--r-- | app/graphql/types/ml/model_links_type.rb | 17 | ||||
-rw-r--r-- | app/graphql/types/ml/model_type.rb | 11 | ||||
-rw-r--r-- | app/graphql/types/ml/model_version_links_type.rb | 3 | ||||
-rw-r--r-- | app/graphql/types/ml/models_order_by_enum.rb | 15 | ||||
-rw-r--r-- | app/graphql/types/project_type.rb | 6 | ||||
-rw-r--r-- | app/models/merge_request.rb | 2 | ||||
-rw-r--r-- | app/views/shared/members/_member.html.haml | 2 |
9 files changed, 108 insertions, 12 deletions
diff --git a/app/components/pajamas/avatar_component.rb b/app/components/pajamas/avatar_component.rb index 423934b6887..0821818103a 100644 --- a/app/components/pajamas/avatar_component.rb +++ b/app/components/pajamas/avatar_component.rb @@ -1,16 +1,21 @@ # frozen_string_literal: true module Pajamas + AvatarEmail = Struct.new(:email) do + def name + email + end + end class AvatarComponent < Pajamas::Component include Gitlab::Utils::StrongMemoize - # @param record [User, Project, Group] + # @param item [User, Project, Group, AvatarEmail] # @param alt [String] text for the alt tag # @param class [String] custom CSS class(es) # @param size [Integer] size in pixel # @param [Hash] avatar_options - def initialize(record, alt: nil, class: "", size: 64, avatar_options: {}) - @record = record + def initialize(item, alt: nil, class: "", size: 64, avatar_options: {}) + @item = item @alt = alt @class = binding.local_variable_get(:class) @size = filter_attribute(size.to_i, SIZE_OPTIONS, default: 64) @@ -23,11 +28,11 @@ module Pajamas def avatar_classes classes = ["gl-avatar", "gl-avatar-s#{@size}", @class] - classes.push("gl-avatar-circle") if @record.is_a?(User) + classes.push("gl-avatar-circle") if @item.is_a?(User) || @item.is_a?(AvatarEmail) unless src classes.push("gl-avatar-identicon") - classes.push("gl-avatar-identicon-bg#{((@record.id || 0) % 7) + 1}") + classes.push("gl-avatar-identicon-bg#{((@item.id || 0) % 7) + 1}") end classes.join(' ') @@ -35,7 +40,7 @@ module Pajamas def src strong_memoize(:src) do - if @record.is_a?(User) + if @item.is_a?(User) # Users show a gravatar instead of an identicon. Also avatars of # blocked users are only shown if the current_user is an admin. # To not duplicate this logic, we are using existing helpers here. @@ -44,9 +49,11 @@ module Pajamas rescue StandardError nil end - helpers.avatar_icon_for_user(@record, @size, current_user: current_user) - elsif @record.try(:avatar_url) - "#{@record.avatar_url}?width=#{@size}" + helpers.avatar_icon_for_user(@item, @size, current_user: current_user) + elsif @item.is_a?(AvatarEmail) + helpers.avatar_icon_for_email(@item.email, @size) + elsif @item.try(:avatar_url) + "#{@item.avatar_url}?width=#{@size}" end end end @@ -59,11 +66,11 @@ module Pajamas end def alt - @alt || @record.name + @alt || @item.name end def initial - @record.name[0, 1].upcase + @item.name[0, 1].upcase end end end diff --git a/app/graphql/resolvers/ml/find_models_resolver.rb b/app/graphql/resolvers/ml/find_models_resolver.rb new file mode 100644 index 00000000000..b9901100e22 --- /dev/null +++ b/app/graphql/resolvers/ml/find_models_resolver.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Resolvers + module Ml + class FindModelsResolver < Resolvers::BaseResolver + extension ::Gitlab::Graphql::Limit::FieldCallCount, limit: 1 + + type ::Types::Ml::ModelType.connection_type, null: true + + argument :name, GraphQL::Types::String, + required: false, + description: 'Search for names that include the string.' + + argument :order_by, ::Types::Ml::ModelsOrderByEnum, + required: false, + description: 'Ordering column. Default is created_at.' + + argument :sort, ::Types::SortDirectionEnum, + required: false, + description: 'Ordering column. Default is desc.' + + def resolve(**args) + return unless current_user.can?(:read_model_registry, object) + + find_params = { + name: args[:name], + order_by: args[:order_by].to_s, + sort: args[:sort].to_s + } + + ::Projects::Ml::ModelFinder.new(object, find_params).execute + end + end + end +end diff --git a/app/graphql/types/ml/model_links_type.rb b/app/graphql/types/ml/model_links_type.rb new file mode 100644 index 00000000000..9d18efb2e17 --- /dev/null +++ b/app/graphql/types/ml/model_links_type.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Types + module Ml + # rubocop: disable Graphql/AuthorizeTypes -- authorization in ModelDetailsResolver + class ModelLinksType < BaseObject + graphql_name 'MLModelLinks' + description 'Represents links to perform actions on the model' + + present_using ::Ml::ModelPresenter + + field :show_path, GraphQL::Types::String, + null: true, description: 'Path to the details page of the model.', method: :path + end + # rubocop: enable Graphql/AuthorizeTypes + end +end diff --git a/app/graphql/types/ml/model_type.rb b/app/graphql/types/ml/model_type.rb index ca63918b370..e677b37547a 100644 --- a/app/graphql/types/ml/model_type.rb +++ b/app/graphql/types/ml/model_type.rb @@ -7,10 +7,21 @@ module Types graphql_name 'MlModel' description 'Machine learning model in the model registry' + connection_type_class Types::LimitedCountableConnectionType + field :id, ::Types::GlobalIDType[::Ml::Model], null: false, description: 'ID of the model.' field :name, ::GraphQL::Types::String, null: false, description: 'Name of the model.' + field :created_at, Types::TimeType, null: false, description: 'Date of creation.' + + field :latest_version, ::Types::Ml::ModelVersionType, null: true, description: 'Latest version of the model.' + + field :version_count, ::GraphQL::Types::Int, null: true, description: 'Count of versions in the model.' + + field :_links, ::Types::Ml::ModelLinksType, null: false, method: :itself, + description: 'Map of links to perform actions on the model.' + field :versions, ::Types::Ml::ModelVersionType.connection_type, null: true, description: 'Versions of the model.' diff --git a/app/graphql/types/ml/model_version_links_type.rb b/app/graphql/types/ml/model_version_links_type.rb index 142f62bfad2..a8497334fc6 100644 --- a/app/graphql/types/ml/model_version_links_type.rb +++ b/app/graphql/types/ml/model_version_links_type.rb @@ -11,6 +11,9 @@ module Types field :show_path, GraphQL::Types::String, null: true, description: 'Path to the details page of the model version.', method: :path + + field :package_path, GraphQL::Types::String, + null: true, description: 'Path to the package of the model version.', method: :package_path end # rubocop: enable Graphql/AuthorizeTypes end diff --git a/app/graphql/types/ml/models_order_by_enum.rb b/app/graphql/types/ml/models_order_by_enum.rb new file mode 100644 index 00000000000..db96a2e2d7d --- /dev/null +++ b/app/graphql/types/ml/models_order_by_enum.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Types + module Ml + class ModelsOrderByEnum < BaseEnum + graphql_name 'MlModelsOrderBy' + description 'Values for ordering machine learning models by a specific field' + + value 'NAME', 'Ordered by name.', value: :name + value 'CREATED_AT', 'Ordered by creation time.', value: :created_at + value 'UPDATED_AT', 'Ordered by update time.', value: :updated_at + value 'ID', 'Ordered by id.', value: :id + end + end +end diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index 8e84605cb05..68a55687419 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -663,6 +663,12 @@ module Types null: true, resolver: Resolvers::Analytics::CycleAnalytics::ValueStreamsResolver + field :ml_models, ::Types::Ml::ModelType.connection_type, + null: true, + alpha: { milestone: '16.8' }, + description: 'Finds machine learning models', + resolver: Resolvers::Ml::FindModelsResolver + def timelog_categories object.project_namespace.timelog_categories if Feature.enabled?(:timelog_categories) end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index bf21eca8857..2471c0bdb29 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -2194,6 +2194,8 @@ class MergeRequest < ApplicationRecord attr_accessor :skip_fetch_ref def merge_base_pipelines + return ::Ci::Pipeline.none unless actual_head_pipeline + target_branch_pipelines_for(sha: actual_head_pipeline.target_sha) end diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml index c86993f5b77..47ab2d5f4be 100644 --- a/app/views/shared/members/_member.html.haml +++ b/app/views/shared/members/_member.html.haml @@ -49,7 +49,7 @@ = _("Expires %{preposition} %{expires_at}").html_safe % { expires_at: time_ago_with_tooltip(member.expires_at), preposition: preposition } - else - = image_tag avatar_icon_for_email(member.invite_email, 40), class: "avatar s40 flex-shrink-0 flex-grow-0", alt: '' + = render Pajamas::AvatarComponent.new(Pajamas::AvatarEmail.new(member.invite_email), size: 32, class: 'gl-mr-3 flex-shrink-0 flex-grow-0') .user-info .member= member.invite_email .cgray |