Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
6666461136
commit
a95f7ad8b8
|
|
@ -73,7 +73,6 @@ eslint-report.html
|
||||||
/.gitlab_workhorse_secret
|
/.gitlab_workhorse_secret
|
||||||
/.gitlab_pages_secret
|
/.gitlab_pages_secret
|
||||||
/.gitlab_kas_secret
|
/.gitlab_kas_secret
|
||||||
/.gitlab_suggested_reviewers_secret
|
|
||||||
/webpack-report/
|
/webpack-report/
|
||||||
/crystalball/
|
/crystalball/
|
||||||
/test_results/
|
/test_results/
|
||||||
|
|
|
||||||
|
|
@ -43,23 +43,19 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="gl-display-flex gl-align-items-start">
|
<div class="timeline-event gl-display-grid">
|
||||||
<div
|
<div
|
||||||
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-bg-white gl-text-gray-200 gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-full gl-mt-2 gl-mr-3 gl-w-8 gl-h-8 gl-p-3 gl-z-index-1"
|
class="gl-display-flex gl-align-items-center gl-justify-content-center gl-bg-white gl-text-gray-200 gl-border-gray-100 gl-border-1 gl-border-solid gl-rounded-full gl-mt-2 gl-mr-3 gl-w-8 gl-h-8 gl-p-3 gl-z-index-1"
|
||||||
>
|
>
|
||||||
<gl-icon :name="getEventIcon(action)" class="note-icon" />
|
<gl-icon :name="getEventIcon(action)" class="note-icon" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="timeline-event-note timeline-event-border" data-testid="event-text-container">
|
||||||
class="timeline-event-note timeline-event-border gl-w-full gl-display-flex gl-flex-direction-row"
|
|
||||||
data-testid="event-text-container"
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<strong class="gl-font-lg" data-testid="event-time">
|
<strong class="gl-font-lg" data-testid="event-time">
|
||||||
<gl-sprintf :message="$options.i18n.timeUTC">
|
<gl-sprintf :message="$options.i18n.timeUTC">
|
||||||
<template #time>{{ time }}</template>
|
<template #time>{{ time }}</template>
|
||||||
</gl-sprintf>
|
</gl-sprintf>
|
||||||
</strong>
|
</strong>
|
||||||
<div v-safe-html="noteHtml"></div>
|
<div v-safe-html="noteHtml" class="md"></div>
|
||||||
</div>
|
</div>
|
||||||
<gl-dropdown
|
<gl-dropdown
|
||||||
v-if="canUpdateTimelineEvent"
|
v-if="canUpdateTimelineEvent"
|
||||||
|
|
@ -79,5 +75,4 @@ export default {
|
||||||
</gl-dropdown-item>
|
</gl-dropdown-item>
|
||||||
</gl-dropdown>
|
</gl-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ export const stateAndPropsFromDataset = (dataset = {}) => {
|
||||||
// HTML attributes are always strings, parse other types.
|
// HTML attributes are always strings, parse other types.
|
||||||
dataProps.hasMetrics = parseBoolean(dataProps.hasMetrics);
|
dataProps.hasMetrics = parseBoolean(dataProps.hasMetrics);
|
||||||
dataProps.customMetricsAvailable = parseBoolean(dataProps.customMetricsAvailable);
|
dataProps.customMetricsAvailable = parseBoolean(dataProps.customMetricsAvailable);
|
||||||
dataProps.prometheusAlertsAvailable = parseBoolean(dataProps.prometheusAlertsAvailable);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
initState: {
|
initState: {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
import groupsSelect from '~/groups_select';
|
import groupsSelect from '~/groups_select';
|
||||||
import UserCallout from '~/user_callout';
|
import UserCallout from '~/user_callout';
|
||||||
import UsersSelect from '~/users_select';
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
|
||||||
new UsersSelect();
|
|
||||||
groupsSelect();
|
groupsSelect();
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
// eslint-disable-next-line no-new
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,10 @@
|
||||||
.main-notes-list::before {
|
.main-notes-list::before {
|
||||||
content: none;
|
content: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-event-note {
|
.timeline-event {
|
||||||
p {
|
grid-template-columns: #{$gl-spacing-scale-9} minmax(0, 1fr) #{$gl-spacing-scale-7};
|
||||||
margin-bottom: 0;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,8 @@ $tabs-holder-z-index: 250;
|
||||||
top: 0;
|
top: 0;
|
||||||
// !important is required to override inline styles of resizable sidebar
|
// !important is required to override inline styles of resizable sidebar
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
|
// avoid sticky elements overlap header and other elements
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-list-holder {
|
.tree-list-holder {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
|
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
|
||||||
before_action :init_preferred_language, only: :new
|
before_action :init_preferred_language, only: :new
|
||||||
before_action :load_recaptcha, only: :new
|
before_action :load_recaptcha, only: :new
|
||||||
before_action :set_invite_params, only: :new
|
|
||||||
before_action only: [:create] do
|
before_action only: [:create] do
|
||||||
check_rate_limit!(:user_sign_up, scope: request.ip)
|
check_rate_limit!(:user_sign_up, scope: request.ip)
|
||||||
end
|
end
|
||||||
|
|
@ -32,6 +31,7 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@resource = build_resource
|
@resource = build_resource
|
||||||
|
set_invite_params
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
|
@ -221,7 +221,9 @@ class RegistrationsController < Devise::RegistrationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_invite_params
|
def set_invite_params
|
||||||
@invite_email = ActionController::Base.helpers.sanitize(params[:invite_email])
|
if resource.email.blank? && params[:invite_email].present?
|
||||||
|
resource.email = @invite_email = ActionController::Base.helpers.sanitize(params[:invite_email])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_pending_invitations_hook
|
def after_pending_invitations_hook
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,10 @@ module HasUserType
|
||||||
migration_bot: 7,
|
migration_bot: 7,
|
||||||
security_bot: 8,
|
security_bot: 8,
|
||||||
automation_bot: 9,
|
automation_bot: 9,
|
||||||
admin_bot: 11,
|
admin_bot: 11
|
||||||
suggested_reviewers_bot: 12
|
|
||||||
}.with_indifferent_access.freeze
|
}.with_indifferent_access.freeze
|
||||||
|
|
||||||
BOT_USER_TYPES = %w[
|
BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot migration_bot security_bot automation_bot admin_bot].freeze
|
||||||
alert_bot
|
|
||||||
project_bot
|
|
||||||
support_bot
|
|
||||||
visual_review_bot
|
|
||||||
migration_bot
|
|
||||||
security_bot
|
|
||||||
automation_bot
|
|
||||||
admin_bot
|
|
||||||
suggested_reviewers_bot
|
|
||||||
].freeze
|
|
||||||
|
|
||||||
NON_INTERNAL_USER_TYPES = %w[human project_bot service_user].freeze
|
NON_INTERNAL_USER_TYPES = %w[human project_bot service_user].freeze
|
||||||
INTERNAL_USER_TYPES = (USER_TYPES.keys - NON_INTERNAL_USER_TYPES).freeze
|
INTERNAL_USER_TYPES = (USER_TYPES.keys - NON_INTERNAL_USER_TYPES).freeze
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,9 @@
|
||||||
%div
|
%div
|
||||||
- if @user.new_record?
|
- if @user.new_record?
|
||||||
= f.submit _('Create user'), pajamas_button: true
|
= f.submit _('Create user'), pajamas_button: true
|
||||||
= link_to _('Cancel'), admin_users_path, class: "gl-button btn btn-default btn-cancel"
|
= render Pajamas::ButtonComponent.new(href: admin_users_path) do
|
||||||
|
= _('Cancel')
|
||||||
- else
|
- else
|
||||||
= f.submit _('Save changes'), pajamas_button: true
|
= f.submit _('Save changes'), pajamas_button: true
|
||||||
= link_to _('Cancel'), admin_user_path(@user), class: "gl-button btn btn-default btn-cancel"
|
= render Pajamas::ButtonComponent.new(href: admin_user_path(@user)) do
|
||||||
|
= _('Cancel')
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@
|
||||||
.form-group
|
.form-group
|
||||||
= f.label :email, class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}"
|
= f.label :email, class: "label-bold #{'gl-mb-1' if Feature.enabled?(:restyle_login_page, @project)}"
|
||||||
= f.email_field :email,
|
= f.email_field :email,
|
||||||
value: @invite_email,
|
|
||||||
class: 'form-control gl-form-input middle js-validate-email',
|
class: 'form-control gl-form-input middle js-validate-email',
|
||||||
data: { qa_selector: 'new_user_email_field' },
|
data: { qa_selector: 'new_user_email_field' },
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,12 @@
|
||||||
%p
|
%p
|
||||||
#{_('Status')}: #{current_user.two_factor_enabled? ? _('Enabled') : _('Disabled')}
|
#{_('Status')}: #{current_user.two_factor_enabled? ? _('Enabled') : _('Disabled')}
|
||||||
- if current_user.two_factor_enabled?
|
- if current_user.two_factor_enabled?
|
||||||
= link_to _('Manage two-factor authentication'), profile_two_factor_auth_path, class: 'gl-button btn btn-confirm'
|
= render Pajamas::ButtonComponent.new(variant: :confirm, href: profile_two_factor_auth_path) do
|
||||||
|
= _('Manage two-factor authentication')
|
||||||
- else
|
- else
|
||||||
.gl-mb-3
|
.gl-mb-3
|
||||||
= link_to _('Enable two-factor authentication'), profile_two_factor_auth_path, class: 'gl-button btn btn-confirm', data: { qa_selector: 'enable_2fa_button' }
|
= render Pajamas::ButtonComponent.new(variant: :confirm, href: profile_two_factor_auth_path, button_options: { data: { qa_selector: 'enable_2fa_button' }}) do
|
||||||
|
= _('Enable two-factor authentication')
|
||||||
.col-lg-12
|
.col-lg-12
|
||||||
%hr
|
%hr
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
---
|
|
||||||
name: suggested_reviewers_internal_api
|
|
||||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105975
|
|
||||||
rollout_issue_url:
|
|
||||||
milestone: '15.7'
|
|
||||||
type: ops
|
|
||||||
group: group::applied ml
|
|
||||||
default_enabled: true
|
|
||||||
|
|
@ -1266,11 +1266,6 @@ production: &base
|
||||||
# The URL to the Kubernetes API proxy (used by GitLab users)
|
# The URL to the Kubernetes API proxy (used by GitLab users)
|
||||||
# external_k8s_proxy_url: https://localhost:8154 # default: nil
|
# external_k8s_proxy_url: https://localhost:8154 # default: nil
|
||||||
|
|
||||||
gitlab_suggested_reviewers:
|
|
||||||
# File that contains the secret key for verifying access for gitlab-suggested-reviewers.
|
|
||||||
# Default is '.gitlab_suggested_reviewers_secret' relative to Rails.root (i.e. root of the GitLab app).
|
|
||||||
# secret_file: /home/git/gitlab/.gitlab_suggested_reviewers_secret
|
|
||||||
|
|
||||||
## GitLab Elasticsearch settings
|
## GitLab Elasticsearch settings
|
||||||
elasticsearch:
|
elasticsearch:
|
||||||
indexer_path: /home/git/gitlab-elasticsearch-indexer/
|
indexer_path: /home/git/gitlab-elasticsearch-indexer/
|
||||||
|
|
|
||||||
|
|
@ -866,12 +866,6 @@ Settings.gitlab_kas['external_url'] ||= 'wss://kas.example.com'
|
||||||
Settings.gitlab_kas['internal_url'] ||= 'grpc://localhost:8153'
|
Settings.gitlab_kas['internal_url'] ||= 'grpc://localhost:8153'
|
||||||
# Settings.gitlab_kas['external_k8s_proxy_url'] ||= 'grpc://localhost:8154' # NOTE: Do not set a default until all distributions have been updated with a correct value
|
# Settings.gitlab_kas['external_k8s_proxy_url'] ||= 'grpc://localhost:8154' # NOTE: Do not set a default until all distributions have been updated with a correct value
|
||||||
|
|
||||||
#
|
|
||||||
# GitLab Suggested Reviewers
|
|
||||||
#
|
|
||||||
Settings['gitlab_suggested_reviewers'] ||= Settingslogic.new({})
|
|
||||||
Settings.gitlab_suggested_reviewers['secret_file'] ||= Rails.root.join('.gitlab_suggested_reviewers_secret')
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Repositories
|
# Repositories
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
return unless Gitlab::Runtime.application? && Gitlab.com? && Gitlab.ee?
|
|
||||||
|
|
||||||
Gitlab::AppliedMl::SuggestedReviewers.ensure_secret!
|
|
||||||
|
|
@ -84,6 +84,7 @@ backtraces
|
||||||
backtracing
|
backtracing
|
||||||
badging
|
badging
|
||||||
balancer
|
balancer
|
||||||
|
balancer's
|
||||||
Bamboo
|
Bamboo
|
||||||
Bazel
|
Bazel
|
||||||
bcrypt
|
bcrypt
|
||||||
|
|
@ -100,6 +101,7 @@ boolean
|
||||||
booleans
|
booleans
|
||||||
Bootsnap
|
Bootsnap
|
||||||
bot
|
bot
|
||||||
|
bot's
|
||||||
Bottlerocket
|
Bottlerocket
|
||||||
browsable
|
browsable
|
||||||
bugfix
|
bugfix
|
||||||
|
|
@ -179,6 +181,7 @@ Coinbase
|
||||||
colocate
|
colocate
|
||||||
colocated
|
colocated
|
||||||
colocating
|
colocating
|
||||||
|
commit's
|
||||||
CommonMark
|
CommonMark
|
||||||
compilable
|
compilable
|
||||||
composable
|
composable
|
||||||
|
|
@ -205,7 +208,7 @@ crosslinking
|
||||||
crosslinks
|
crosslinks
|
||||||
Crossplane
|
Crossplane
|
||||||
Crowdin
|
Crowdin
|
||||||
Crypto
|
crypto
|
||||||
CSSComb
|
CSSComb
|
||||||
CSV
|
CSV
|
||||||
CSVs
|
CSVs
|
||||||
|
|
@ -586,6 +589,7 @@ nameserver
|
||||||
nameservers
|
nameservers
|
||||||
namespace
|
namespace
|
||||||
namespaced
|
namespaced
|
||||||
|
namespace's
|
||||||
namespaces
|
namespaces
|
||||||
namespacing
|
namespacing
|
||||||
namespacings
|
namespacings
|
||||||
|
|
@ -916,6 +920,7 @@ sublicensed
|
||||||
sublicenses
|
sublicenses
|
||||||
sublicensing
|
sublicensing
|
||||||
submodule
|
submodule
|
||||||
|
submodule's
|
||||||
subnet
|
subnet
|
||||||
subnets
|
subnets
|
||||||
subnetting
|
subnetting
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
redirect_to: 'downstream_pipelines.md'
|
|
||||||
remove_date: '2022-11-30'
|
|
||||||
---
|
|
||||||
|
|
||||||
This document was moved to [another location](downstream_pipelines.md).
|
|
||||||
|
|
||||||
<!-- This redirect file can be deleted after <2022-11-30>. -->
|
|
||||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
|
||||||
<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
|
|
||||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
redirect_to: 'downstream_pipelines.md'
|
|
||||||
remove_date: '2022-12-05'
|
|
||||||
---
|
|
||||||
|
|
||||||
This document was moved to [another location](downstream_pipelines.md).
|
|
||||||
|
|
||||||
<!-- This redirect file can be deleted after <2022-12-05>. -->
|
|
||||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
|
||||||
<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
|
|
||||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
|
||||||
|
|
@ -288,6 +288,7 @@ module API
|
||||||
mount ::API::Unleash
|
mount ::API::Unleash
|
||||||
mount ::API::UsageData
|
mount ::API::UsageData
|
||||||
mount ::API::UsageDataNonSqlMetrics
|
mount ::API::UsageDataNonSqlMetrics
|
||||||
|
mount ::API::UsageDataQueries
|
||||||
mount ::API::UserCounts
|
mount ::API::UserCounts
|
||||||
mount ::API::Wikis
|
mount ::API::Wikis
|
||||||
|
|
||||||
|
|
@ -332,7 +333,6 @@ module API
|
||||||
mount ::API::Todos
|
mount ::API::Todos
|
||||||
mount ::API::UsageData
|
mount ::API::UsageData
|
||||||
mount ::API::UsageDataNonSqlMetrics
|
mount ::API::UsageDataNonSqlMetrics
|
||||||
mount ::API::UsageDataQueries
|
|
||||||
mount ::API::Users
|
mount ::API::Users
|
||||||
mount ::API::Ml::Mlflow
|
mount ::API::Ml::Mlflow
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,12 @@ module API
|
||||||
|
|
||||||
desc 'Get raw SQL queries for usage data SQL metrics' do
|
desc 'Get raw SQL queries for usage data SQL metrics' do
|
||||||
detail 'This feature was introduced in GitLab 13.11.'
|
detail 'This feature was introduced in GitLab 13.11.'
|
||||||
|
success code: 200
|
||||||
|
failure [
|
||||||
|
{ code: 401, message: 'Unauthorized' },
|
||||||
|
{ code: 403, message: 'Forbidden' },
|
||||||
|
{ code: 404, message: 'Not Found' }
|
||||||
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
get 'queries' do
|
get 'queries' do
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
|
||||||
expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
|
expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
|
||||||
expect(page).to have_content('prohibited this user from being saved')
|
expect(page).to have_content('prohibited this user from being saved')
|
||||||
expect(page).to have_current_path(user_registration_path, ignore_query: true)
|
expect(page).to have_current_path(user_registration_path, ignore_query: true)
|
||||||
|
expect(find_field('Email').value).to eq(group_invite.invite_email)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ RSpec.describe 'Signup', feature_category: :users do
|
||||||
expect(page).to have_content("Email has already been taken")
|
expect(page).to have_content("Email has already been taken")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not redisplay the password' do
|
it 'redisplays all fields except password' do
|
||||||
create(:user, email: new_user.email)
|
create(:user, email: new_user.email)
|
||||||
visit new_user_registration_path
|
visit new_user_registration_path
|
||||||
|
|
||||||
|
|
@ -291,6 +291,11 @@ RSpec.describe 'Signup', feature_category: :users do
|
||||||
|
|
||||||
expect(page).to have_current_path user_registration_path, ignore_query: true
|
expect(page).to have_current_path user_registration_path, ignore_query: true
|
||||||
expect(page.body).not_to match(/#{new_user.password}/)
|
expect(page.body).not_to match(/#{new_user.password}/)
|
||||||
|
|
||||||
|
expect(find_field('First name').value).to eq(new_user.first_name)
|
||||||
|
expect(find_field('Last name').value).to eq(new_user.last_name)
|
||||||
|
expect(find_field('Username').value).to eq(new_user.username)
|
||||||
|
expect(find_field('Email').value).to eq(new_user.email)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ require 'spec_helper'
|
||||||
RSpec.describe User do
|
RSpec.describe User do
|
||||||
specify 'types consistency checks', :aggregate_failures do
|
specify 'types consistency checks', :aggregate_failures do
|
||||||
expect(described_class::USER_TYPES.keys)
|
expect(described_class::USER_TYPES.keys)
|
||||||
.to match_array(%w[human ghost alert_bot project_bot support_bot service_user security_bot visual_review_bot
|
.to match_array(%w[human ghost alert_bot project_bot support_bot service_user security_bot visual_review_bot migration_bot automation_bot admin_bot])
|
||||||
migration_bot automation_bot admin_bot suggested_reviewers_bot])
|
|
||||||
expect(described_class::USER_TYPES).to include(*described_class::BOT_USER_TYPES)
|
expect(described_class::USER_TYPES).to include(*described_class::BOT_USER_TYPES)
|
||||||
expect(described_class::USER_TYPES).to include(*described_class::NON_INTERNAL_USER_TYPES)
|
expect(described_class::USER_TYPES).to include(*described_class::NON_INTERNAL_USER_TYPES)
|
||||||
expect(described_class::USER_TYPES).to include(*described_class::INTERNAL_USER_TYPES)
|
expect(described_class::USER_TYPES).to include(*described_class::INTERNAL_USER_TYPES)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue