Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-16 00:07:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-16 00:07:42 +0300
commit2b5079efdb7c4e7d5a607d95747ddeb0b8af9678 (patch)
tree6d226593a137e111c7d4075ec22d6c4d328c3b57 /app
parent5ff1f808adf841bca979cb2fac6bdfa9c449d028 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/components/editor/ci_editor_header.vue8
-rw-r--r--app/assets/javascripts/ci/pipeline_editor/index.js2
-rw-r--r--app/assets/javascripts/design_management/components/list/item.vue10
-rw-r--r--app/assets/javascripts/design_management/pages/index.vue12
-rw-r--r--app/assets/javascripts/super_sidebar/components/menu_section.vue2
-rw-r--r--app/assets/javascripts/super_sidebar/components/pinned_section.vue7
-rw-r--r--app/assets/javascripts/super_sidebar/components/sidebar_menu.vue49
-rw-r--r--app/assets/javascripts/work_items/components/widget_wrapper.vue2
-rw-r--r--app/assets/stylesheets/page_bundles/design_management.scss6
-rw-r--r--app/helpers/projects/ml/experiments_helper.rb21
-rw-r--r--app/models/organization.rb24
-rw-r--r--app/presenters/ml/candidate_details_presenter.rb88
-rw-r--r--app/views/projects/ml/candidates/show.html.haml3
13 files changed, 179 insertions, 55 deletions
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 66957365261..eabf4749e9c 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
@@ -17,6 +17,7 @@ export default {
GlButton,
},
mixins: [glFeatureFlagMixin(), Tracking.mixin()],
+ inject: ['aiChatAvailable'],
props: {
showDrawer: {
type: Boolean,
@@ -31,6 +32,11 @@ export default {
required: true,
},
},
+ computed: {
+ isAiConfigChatAvailable() {
+ return this.glFeatures.aiCiConfigGenerator && this.aiChatAvailable;
+ },
+ },
methods: {
toggleDrawer() {
if (this.showDrawer) {
@@ -96,7 +102,7 @@ export default {
{{ $options.i18n.jobAssistant }}
</gl-button>
<gl-button
- v-if="glFeatures.aiCiConfigGenerator"
+ v-if="isAiConfigChatAvailable"
icon="bulb"
size="small"
data-testid="ai-assistant-drawer-toggle"
diff --git a/app/assets/javascripts/ci/pipeline_editor/index.js b/app/assets/javascripts/ci/pipeline_editor/index.js
index 09acd805410..b8d6c27435d 100644
--- a/app/assets/javascripts/ci/pipeline_editor/index.js
+++ b/app/assets/javascripts/ci/pipeline_editor/index.js
@@ -46,6 +46,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
usesExternalConfig,
validateTabIllustrationPath,
ymlHelpPagePath,
+ aiChatAvailable,
} = el.dataset;
const configurationPaths = Object.fromEntries(
@@ -115,6 +116,7 @@ export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
el,
apolloProvider,
provide: {
+ aiChatAvailable: parseBoolean(aiChatAvailable),
ciConfigPath,
ciExamplesHelpPagePath,
ciHelpPagePath,
diff --git a/app/assets/javascripts/design_management/components/list/item.vue b/app/assets/javascripts/design_management/components/list/item.vue
index f52486f0629..9c1bcf5bf90 100644
--- a/app/assets/javascripts/design_management/components/list/item.vue
+++ b/app/assets/javascripts/design_management/components/list/item.vue
@@ -133,7 +133,11 @@ export default {
<div
class="card-body gl-p-0 gl-display-flex gl-align-items-center gl-justify-content-center gl-overflow-hidden gl-relative"
>
- <div v-if="icon.name" data-testid="design-event" class="gl-top-5 gl-right-5 gl-absolute">
+ <div
+ v-if="icon.name"
+ data-testid="design-event"
+ class="gl-absolute gl-top-3 gl-right-3 gl-mr-1"
+ >
<span :title="icon.tooltip" :aria-label="icon.tooltip">
<gl-icon
:name="icon.name"
@@ -165,11 +169,11 @@ export default {
/>
</gl-intersection-observer>
</div>
- <div class="card-footer gl-display-flex gl-w-full">
+ <div class="card-footer gl-display-flex gl-w-full gl-bg-white gl-py-3 gl-px-4">
<div class="gl-display-flex gl-flex-direction-column str-truncated-100">
<span
v-gl-tooltip
- class="gl-font-weight-bold str-truncated-100"
+ class="gl-font-weight-semibold str-truncated-100"
data-qa-selector="design_file_name"
:data-testid="`design-img-filename-${id}`"
:title="filename"
diff --git a/app/assets/javascripts/design_management/pages/index.vue b/app/assets/javascripts/design_management/pages/index.vue
index e270613e4eb..dcc65c957fe 100644
--- a/app/assets/javascripts/design_management/pages/index.vue
+++ b/app/assets/javascripts/design_management/pages/index.vue
@@ -141,6 +141,12 @@ export default {
}
return 'col-12';
},
+ designContentWrapperClass() {
+ if (this.hasDesigns) {
+ return 'gl-bg-gray-10 gl-border gl-border-t-0 gl-rounded-bottom-left-base gl-rounded-bottom-right-base gl-px-5';
+ }
+ return null;
+ },
},
mounted() {
if (this.$route.path === '/designs') {
@@ -364,7 +370,7 @@ export default {
</gl-alert>
<header
v-if="showToolbar"
- class="gl-display-flex gl-my-0 gl-text-gray-900"
+ class="gl-border gl-px-5 gl-py-4 gl-display-flex gl-justify-content-space-between gl-bg-white gl-rounded-base gl-rounded-bottom-left-none! gl-rounded-bottom-right-none!"
data-testid="design-toolbar-wrapper"
>
<div
@@ -418,7 +424,7 @@ export default {
</div>
</div>
</header>
- <div>
+ <div :class="designContentWrapperClass">
<gl-loading-icon v-if="isLoading" size="lg" />
<gl-alert v-else-if="error" variant="danger" :dismissible="false">
{{ __('An error occurred while loading designs. Please try again.') }}
@@ -483,7 +489,7 @@ export default {
v-if="canSelectDesign(design.filename)"
:checked="isDesignSelected(design.filename)"
type="checkbox"
- class="design-checkbox"
+ class="design-checkbox gl-absolute gl-top-4 gl-left-6 gl-ml-2"
data-qa-selector="design_checkbox"
:data-qa-design="design.filename"
@change="changeSelectedDesigns(design.filename)"
diff --git a/app/assets/javascripts/super_sidebar/components/menu_section.vue b/app/assets/javascripts/super_sidebar/components/menu_section.vue
index 5de6e04d827..93c249dffeb 100644
--- a/app/assets/javascripts/super_sidebar/components/menu_section.vue
+++ b/app/assets/javascripts/super_sidebar/components/menu_section.vue
@@ -69,6 +69,7 @@ export default {
<template>
<component :is="tag">
+ <hr v-if="separated" aria-hidden="true" class="gl-mx-4 gl-my-2" />
<button
class="gl-rounded-base gl-relative gl-display-flex gl-align-items-center gl-mb-1 gl-py-3 gl-px-0 gl-line-height-normal gl-text-black-normal! gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-text-decoration-none! gl-appearance-none gl-border-0 gl-bg-transparent gl-text-left gl-w-full gl-focus--focus"
:class="computedLinkClasses"
@@ -117,6 +118,5 @@ export default {
/>
</slot>
</gl-collapse>
- <hr v-if="separated" aria-hidden="true" class="gl-mx-4 gl-my-2" />
</component>
</template>
diff --git a/app/assets/javascripts/super_sidebar/components/pinned_section.vue b/app/assets/javascripts/super_sidebar/components/pinned_section.vue
index 4fc86e41ef2..ccd739c8bb1 100644
--- a/app/assets/javascripts/super_sidebar/components/pinned_section.vue
+++ b/app/assets/javascripts/super_sidebar/components/pinned_section.vue
@@ -23,6 +23,11 @@ export default {
required: false,
default: () => [],
},
+ separated: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -69,7 +74,7 @@ export default {
<menu-section
:item="sectionItem"
:expanded="expanded"
- :separated="true"
+ :separated="separated"
@collapse-toggle="expanded = !expanded"
>
<draggable
diff --git a/app/assets/javascripts/super_sidebar/components/sidebar_menu.vue b/app/assets/javascripts/super_sidebar/components/sidebar_menu.vue
index 12abd727ef0..08af9232107 100644
--- a/app/assets/javascripts/super_sidebar/components/sidebar_menu.vue
+++ b/app/assets/javascripts/super_sidebar/components/sidebar_menu.vue
@@ -89,6 +89,9 @@ export default {
supportsPins() {
return PANELS_WITH_PINS.includes(this.panelType);
},
+ hasStaticItems() {
+ return this.staticItems.length > 0;
+ },
},
methods: {
createPin(itemId) {
@@ -126,34 +129,50 @@ export default {
Sentry.captureException(e);
});
},
+ isSection(navItem) {
+ return navItem.items?.length;
+ },
},
};
</script>
<template>
<nav class="gl-p-2 gl-relative">
- <template v-if="staticItems.length > 0">
- <ul class="gl-p-0 gl-m-0">
- <nav-item v-for="item in staticItems" :key="item.id" :item="item" is-static />
- </ul>
- <hr aria-hidden="true" class="gl-my-2 gl-mx-4" />
- </template>
+ <ul v-if="hasStaticItems" class="gl-p-0 gl-m-0">
+ <nav-item v-for="item in staticItems" :key="item.id" :item="item" is-static />
+ </ul>
<pinned-section
v-if="supportsPins"
+ separated
:items="pinnedItems"
@pin-remove="destroyPin"
@pin-reorder="movePin"
/>
+ <hr
+ v-if="supportsPins"
+ aria-hidden="true"
+ class="gl-my-2 gl-mx-4"
+ data-testid="main-menu-separator"
+ />
<ul class="gl-p-0 gl-list-style-none">
- <component
- :is="item.items && item.items.length ? 'MenuSection' : 'NavItem'"
- v-for="item in nonStaticItems"
- :key="item.id"
- :item="item"
- tag="li"
- @pin-add="createPin"
- @pin-remove="destroyPin"
- />
+ <template v-for="item in nonStaticItems">
+ <menu-section
+ v-if="isSection(item)"
+ :key="item.id"
+ :item="item"
+ :separated="item.separated"
+ @pin-add="createPin"
+ @pin-remove="destroyPin"
+ />
+ <nav-item
+ v-else
+ :key="item.id"
+ :item="item"
+ tag="li"
+ @pin-add="createPin"
+ @pin-remove="destroyPin"
+ />
+ </template>
</ul>
</nav>
</template>
diff --git a/app/assets/javascripts/work_items/components/widget_wrapper.vue b/app/assets/javascripts/work_items/components/widget_wrapper.vue
index 3f5ff526e91..6ae30e9b084 100644
--- a/app/assets/javascripts/work_items/components/widget_wrapper.vue
+++ b/app/assets/javascripts/work_items/components/widget_wrapper.vue
@@ -45,7 +45,7 @@ export default {
<template>
<div
id="tasks"
- class="gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-bg-gray-10 gl-mt-4"
+ class="gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-bg-gray-10 gl-mt-5"
>
<div
class="gl-pl-5 gl-pr-4 gl-py-4 gl-display-flex gl-justify-content-space-between gl-bg-white gl-rounded-base"
diff --git a/app/assets/stylesheets/page_bundles/design_management.scss b/app/assets/stylesheets/page_bundles/design_management.scss
index f56eb4ae6fb..b42e6fd85fa 100644
--- a/app/assets/stylesheets/page_bundles/design_management.scss
+++ b/app/assets/stylesheets/page_bundles/design_management.scss
@@ -8,12 +8,6 @@ $t-gray-a-16-design-pin: rgba($black, 0.16);
background: transparent;
}
-.design-checkbox {
- position: absolute;
- top: $gl-padding;
- left: 30px;
-}
-
.layout-page.design-detail-layout {
max-height: 100vh;
}
diff --git a/app/helpers/projects/ml/experiments_helper.rb b/app/helpers/projects/ml/experiments_helper.rb
index 6e5e13ef0b6..7aef208447a 100644
--- a/app/helpers/projects/ml/experiments_helper.rb
+++ b/app/helpers/projects/ml/experiments_helper.rb
@@ -5,27 +5,6 @@ module Projects
require 'json'
include ActionView::Helpers::NumberHelper
- def show_candidate_view_model(candidate)
- data = {
- candidate: {
- params: candidate.params,
- metrics: candidate.latest_metrics,
- info: {
- iid: candidate.iid,
- eid: candidate.eid,
- path_to_artifact: link_to_artifact(candidate),
- experiment_name: candidate.experiment.name,
- path_to_experiment: link_to_experiment(candidate.project, candidate.experiment),
- path: link_to_details(candidate),
- status: candidate.status
- },
- metadata: candidate.metadata
- }
- }
-
- Gitlab::Json.generate(data)
- end
-
def experiment_as_data(experiment)
data = {
name: experiment.name,
diff --git a/app/models/organization.rb b/app/models/organization.rb
index 73a7e84305f..cfbbbf1183e 100644
--- a/app/models/organization.rb
+++ b/app/models/organization.rb
@@ -1,6 +1,26 @@
# frozen_string_literal: true
-# rubocop: disable Gitlab/NamespacedClass
class Organization < ApplicationRecord
+ DEFAULT_ORGANIZATION_ID = 1
+
+ scope :without_default, -> { where.not(id: DEFAULT_ORGANIZATION_ID) }
+
+ before_destroy :check_if_default_organization
+
+ validates :name,
+ presence: true,
+ length: { maximum: 255 },
+ uniqueness: { case_sensitive: false }
+
+ def default?
+ id == DEFAULT_ORGANIZATION_ID
+ end
+
+ private
+
+ def check_if_default_organization
+ return unless default?
+
+ raise ActiveRecord::RecordNotDestroyed, _('Cannot delete the default organization')
+ end
end
-# rubocop: enable Gitlab/NamespacedClass
diff --git a/app/presenters/ml/candidate_details_presenter.rb b/app/presenters/ml/candidate_details_presenter.rb
new file mode 100644
index 00000000000..58ec2aee471
--- /dev/null
+++ b/app/presenters/ml/candidate_details_presenter.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+module Ml
+ class CandidateDetailsPresenter
+ include Rails.application.routes.url_helpers
+
+ def initialize(candidate)
+ @candidate = candidate
+ end
+
+ def present
+ data = {
+ candidate: {
+ info: {
+ iid: candidate.iid,
+ eid: candidate.eid,
+ path_to_artifact: link_to_artifact,
+ experiment_name: candidate.experiment.name,
+ path_to_experiment: link_to_experiment,
+ path: link_to_details,
+ status: candidate.status,
+ ci_job: job_info
+ },
+ params: candidate.params,
+ metrics: candidate.latest_metrics,
+ metadata: candidate.metadata
+ }
+ }
+
+ Gitlab::Json.generate(data)
+ end
+
+ private
+
+ attr_reader :candidate
+
+ def job_info
+ return unless candidate.from_ci?
+
+ build = candidate.ci_build
+
+ {
+ path: project_job_path(build.project, build),
+ name: build.name,
+ **user_info(build.user) || {},
+ **mr_info(build.pipeline.merge_request) || {}
+ }
+ end
+
+ def user_info(user)
+ return unless user
+
+ {
+ user: {
+ path: user_path(user),
+ username: user.username
+ }
+ }
+ end
+
+ def mr_info(mr)
+ return unless mr
+
+ {
+ merge_request: {
+ path: project_merge_request_path(mr.project, mr),
+ title: mr.title
+ }
+ }
+ end
+
+ def link_to_artifact
+ artifact = candidate.artifact
+
+ return unless artifact.present?
+
+ project_package_path(candidate.project, artifact)
+ end
+
+ def link_to_details
+ project_ml_candidate_path(candidate.project, candidate.iid)
+ end
+
+ def link_to_experiment
+ project_ml_experiment_path(candidate.project, candidate.experiment.iid)
+ end
+ end
+end
diff --git a/app/views/projects/ml/candidates/show.html.haml b/app/views/projects/ml/candidates/show.html.haml
index aea74ecfb48..5d5059551d3 100644
--- a/app/views/projects/ml/candidates/show.html.haml
+++ b/app/views/projects/ml/candidates/show.html.haml
@@ -3,5 +3,6 @@
- add_to_breadcrumbs experiment.name, project_ml_experiment_path(@project, experiment.iid)
- breadcrumb_title "Candidate #{@candidate.iid}"
- add_page_specific_style 'page_bundles/ml_experiment_tracking'
+- presenter = ::Ml::CandidateDetailsPresenter.new(@candidate)
-#js-show-ml-candidate{ data: { view_model: show_candidate_view_model(@candidate) } }
+#js-show-ml-candidate{ data: { view_model: presenter.present } }