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
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-03 18:11:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-03 18:11:11 +0300
commit5429e3d4e0d5f1601ff8989bcb26bd822b3c7c5a (patch)
tree0f08e912ce115cd8ad0a5bdc0717fc64aae59c85 /app/assets
parent3682bf2cf22082c9b57c99b50816fdfe98629792 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/ml/model_registry/apps/index.js3
-rw-r--r--app/assets/javascripts/ml/model_registry/apps/index_ml_models.vue17
-rw-r--r--app/assets/javascripts/ml/model_registry/apps/new_ml_model.vue127
-rw-r--r--app/assets/javascripts/ml/model_registry/graphql/mutations/create_model.mutation.graphql11
-rw-r--r--app/assets/javascripts/ml/model_registry/translations.js9
-rw-r--r--app/assets/javascripts/pages/projects/ml/models/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/ml/models/new/index.js4
7 files changed, 170 insertions, 3 deletions
diff --git a/app/assets/javascripts/ml/model_registry/apps/index.js b/app/assets/javascripts/ml/model_registry/apps/index.js
index 92d159f68be..60fe5dfa804 100644
--- a/app/assets/javascripts/ml/model_registry/apps/index.js
+++ b/app/assets/javascripts/ml/model_registry/apps/index.js
@@ -1,5 +1,6 @@
import ShowMlModel from './show_ml_model.vue';
import ShowMlModelVersion from './show_ml_model_version.vue';
import IndexMlModels from './index_ml_models.vue';
+import NewMlModel from './new_ml_model.vue';
-export { ShowMlModel, ShowMlModelVersion, IndexMlModels };
+export { ShowMlModel, ShowMlModelVersion, IndexMlModels, NewMlModel };
diff --git a/app/assets/javascripts/ml/model_registry/apps/index_ml_models.vue b/app/assets/javascripts/ml/model_registry/apps/index_ml_models.vue
index e5e093db5ca..3956a1f86e8 100644
--- a/app/assets/javascripts/ml/model_registry/apps/index_ml_models.vue
+++ b/app/assets/javascripts/ml/model_registry/apps/index_ml_models.vue
@@ -1,6 +1,6 @@
<script>
import { isEmpty } from 'lodash';
-import { GlBadge } from '@gitlab/ui';
+import { GlBadge, GlButton } from '@gitlab/ui';
import Pagination from '~/vue_shared/components/incubation/pagination.vue';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
@@ -21,6 +21,7 @@ export default {
TitleArea,
GlBadge,
EmptyState,
+ GlButton,
},
props: {
models: {
@@ -31,11 +32,20 @@ export default {
type: Object,
required: true,
},
+ createModelPath: {
+ type: String,
+ required: true,
+ },
modelCount: {
type: Number,
required: false,
default: 0,
},
+ canWriteModelRegistry: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
hasModels() {
@@ -63,6 +73,11 @@ export default {
<template #metadata-models-count>
<metadata-item icon="machine-learning" :text="$options.i18n.modelsCountLabel(modelCount)" />
</template>
+ <template #right-actions>
+ <gl-button v-if="canWriteModelRegistry" :href="createModelPath">{{
+ $options.i18n.CREATE_MODEL_LABEL
+ }}</gl-button>
+ </template>
</title-area>
<template v-if="hasModels">
<search-bar :sortable-fields="$options.sortableFields" />
diff --git a/app/assets/javascripts/ml/model_registry/apps/new_ml_model.vue b/app/assets/javascripts/ml/model_registry/apps/new_ml_model.vue
new file mode 100644
index 00000000000..618d4cea1a5
--- /dev/null
+++ b/app/assets/javascripts/ml/model_registry/apps/new_ml_model.vue
@@ -0,0 +1,127 @@
+<script>
+import {
+ GlForm,
+ GlFormGroup,
+ GlFormInput,
+ GlFormTextarea,
+ GlAlert,
+ GlButton,
+ GlLink,
+ GlSprintf,
+} from '@gitlab/ui';
+import TitleArea from '~/vue_shared/components/registry/title_area.vue';
+import { visitUrl } from '~/lib/utils/url_utility';
+import * as Sentry from '~/sentry/sentry_browser_wrapper';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import createModelMutation from '../graphql/mutations/create_model.mutation.graphql';
+import {
+ NEW_MODEL_LABEL,
+ ERROR_CREATING_MODEL_LABEL,
+ CREATE_MODEL_WITH_CLIENT_LABEL,
+ NAME_LABEL,
+ DESCRIPTION_LABEL,
+ CREATE_MODEL_LABEL,
+} from '../translations';
+
+export default {
+ name: 'NewMlModel',
+ components: {
+ TitleArea,
+ GlForm,
+ GlFormInput,
+ GlFormGroup,
+ GlFormTextarea,
+ GlAlert,
+ GlButton,
+ GlLink,
+ GlSprintf,
+ },
+ props: {
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ errorMessage: '',
+ modelName: '',
+ modelDescription: '',
+ };
+ },
+ methods: {
+ async createModel() {
+ this.errorMessage = '';
+ try {
+ const variables = {
+ projectPath: this.projectPath,
+ name: this.modelName,
+ description: this.modelDescription,
+ };
+
+ const { data } = await this.$apollo.mutate({
+ mutation: createModelMutation,
+ variables,
+ });
+
+ const [error] = data?.mlModelCreate?.errors || [];
+
+ if (error) {
+ this.errorMessage = data.mlModelCreate.errors.join(', ');
+ } else {
+ visitUrl(data?.mlModelCreate?.model?._links?.showPath);
+ }
+ } catch (error) {
+ Sentry.captureException(error);
+ this.errorMessage = ERROR_CREATING_MODEL_LABEL;
+ }
+ },
+ },
+ i18n: {
+ NEW_MODEL_LABEL,
+ CREATE_MODEL_WITH_CLIENT_LABEL,
+ NAME_LABEL,
+ DESCRIPTION_LABEL,
+ CREATE_MODEL_LABEL,
+ },
+ docHref: helpPagePath('user/project/ml/model_registry/index.md'),
+};
+</script>
+
+<template>
+ <div>
+ <title-area :title="$options.i18n.NEW_MODEL_LABEL" />
+
+ <gl-alert variant="tip" icon="bulb" class="gl-mb-3" :dismissible="false">
+ <gl-sprintf :message="$options.i18n.CREATE_MODEL_WITH_CLIENT_LABEL">
+ <template #link="{ content }">
+ <gl-link :href="$options.docHref" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+
+ <gl-alert
+ v-if="errorMessage"
+ :dismissible="false"
+ variant="danger"
+ class="gl-mb-3"
+ data-testid="new-model-errors"
+ >
+ {{ errorMessage }}
+ </gl-alert>
+
+ <gl-form @submit.prevent="createModel">
+ <gl-form-group :label="$options.i18n.NAME_LABEL">
+ <gl-form-input v-model="modelName" />
+ </gl-form-group>
+
+ <gl-form-group :label="$options.i18n.DESCRIPTION_LABEL" optional>
+ <gl-form-textarea v-model="modelDescription" />
+ </gl-form-group>
+
+ <gl-button type="submit" variant="confirm" class="js-no-auto-disable">{{
+ $options.i18n.CREATE_MODEL_LABEL
+ }}</gl-button>
+ </gl-form>
+ </div>
+</template>
diff --git a/app/assets/javascripts/ml/model_registry/graphql/mutations/create_model.mutation.graphql b/app/assets/javascripts/ml/model_registry/graphql/mutations/create_model.mutation.graphql
new file mode 100644
index 00000000000..af801474e80
--- /dev/null
+++ b/app/assets/javascripts/ml/model_registry/graphql/mutations/create_model.mutation.graphql
@@ -0,0 +1,11 @@
+mutation createModel($projectPath: ID!, $name: String!, $description: String) {
+ mlModelCreate(input: { projectPath: $projectPath, name: $name, description: $description }) {
+ model {
+ id
+ _links {
+ showPath
+ }
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/ml/model_registry/translations.js b/app/assets/javascripts/ml/model_registry/translations.js
index 968ec83434d..006142979e2 100644
--- a/app/assets/javascripts/ml/model_registry/translations.js
+++ b/app/assets/javascripts/ml/model_registry/translations.js
@@ -32,6 +32,15 @@ export const CI_SECTION_LABEL = s__('MlModelRegistry|CI Info');
export const JOB_LABEL = __('Job');
export const CI_USER_LABEL = s__('MlModelRegistry|Triggered by');
export const CI_MR_LABEL = __('Merge request');
+export const NEW_MODEL_LABEL = s__('MlModelRegistry|New model');
+export const CREATE_MODEL_LABEL = s__('MlModelRegistry|Create model');
+export const ERROR_CREATING_MODEL_LABEL = s__(
+ 'MlModelRegistry|An error has occurred when saving the model.',
+);
+export const CREATE_MODEL_WITH_CLIENT_LABEL = s__(
+ 'MlModelRegistry|Creating models is also possible through the MLflow client. %{linkStart}Follow the documentation to learn more.%{linkEnd}',
+);
+export const NAME_LABEL = __('Name');
export const makeLoadVersionsErrorMessage = (message) =>
sprintf(s__('MlModelRegistry|Failed to load model versions with error: %{message}'), {
diff --git a/app/assets/javascripts/pages/projects/ml/models/index/index.js b/app/assets/javascripts/pages/projects/ml/models/index/index.js
index 3f8ef4910a7..54dcf28164f 100644
--- a/app/assets/javascripts/pages/projects/ml/models/index/index.js
+++ b/app/assets/javascripts/pages/projects/ml/models/index/index.js
@@ -1,4 +1,4 @@
import { initSimpleApp } from '~/helpers/init_simple_app_helper';
import { IndexMlModels } from '~/ml/model_registry/apps';
-initSimpleApp('#js-index-ml-models', IndexMlModels);
+initSimpleApp('#js-index-ml-models', IndexMlModels, { withApolloProvider: true });
diff --git a/app/assets/javascripts/pages/projects/ml/models/new/index.js b/app/assets/javascripts/pages/projects/ml/models/new/index.js
new file mode 100644
index 00000000000..8dc5c5aea4e
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/ml/models/new/index.js
@@ -0,0 +1,4 @@
+import { initSimpleApp } from '~/helpers/init_simple_app_helper';
+import { NewMlModel } from '~/ml/model_registry/apps';
+
+initSimpleApp('#js-mount-new-ml-model', NewMlModel, { withApolloProvider: true });