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>2020-11-19 11:27:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
commit7e9c479f7de77702622631cff2628a9c8dcbc627 (patch)
treec8f718a08e110ad7e1894510980d2155a6549197 /app/assets/javascripts/pipeline_editor
parente852b0ae16db4052c1c567d9efa4facc81146e88 (diff)
Add latest changes from gitlab-org/gitlab@13-6-stable-eev13.6.0-rc42
Diffstat (limited to 'app/assets/javascripts/pipeline_editor')
-rw-r--r--app/assets/javascripts/pipeline_editor/components/text_editor.vue26
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/queries/blob_content.graphql5
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/resolvers.js16
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/typedefs.graphql7
-rw-r--r--app/assets/javascripts/pipeline_editor/index.js34
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue108
6 files changed, 196 insertions, 0 deletions
diff --git a/app/assets/javascripts/pipeline_editor/components/text_editor.vue b/app/assets/javascripts/pipeline_editor/components/text_editor.vue
new file mode 100644
index 00000000000..a925077c906
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/components/text_editor.vue
@@ -0,0 +1,26 @@
+<script>
+import EditorLite from '~/vue_shared/components/editor_lite.vue';
+
+export default {
+ components: {
+ EditorLite,
+ },
+ props: {
+ value: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+};
+</script>
+<template>
+ <div class="gl-border-solid gl-border-gray-100 gl-border-1">
+ <editor-lite
+ v-model="value"
+ file-name="*.yml"
+ :editor-options="{ readOnly: true }"
+ @editor-ready="$emit('editor-ready')"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_editor/graphql/queries/blob_content.graphql b/app/assets/javascripts/pipeline_editor/graphql/queries/blob_content.graphql
new file mode 100644
index 00000000000..9f1b5b13088
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/graphql/queries/blob_content.graphql
@@ -0,0 +1,5 @@
+query getBlobContent($projectPath: ID!, $path: String, $ref: String!) {
+ blobContent(projectPath: $projectPath, path: $path, ref: $ref) @client {
+ rawData
+ }
+}
diff --git a/app/assets/javascripts/pipeline_editor/graphql/resolvers.js b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
new file mode 100644
index 00000000000..7b8c70ac93e
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
@@ -0,0 +1,16 @@
+import Api from '~/api';
+
+export const resolvers = {
+ Query: {
+ blobContent(_, { projectPath, path, ref }) {
+ return {
+ __typename: 'BlobContent',
+ rawData: Api.getRawFile(projectPath, path, { ref }).then(({ data }) => {
+ return data;
+ }),
+ };
+ },
+ },
+};
+
+export default resolvers;
diff --git a/app/assets/javascripts/pipeline_editor/graphql/typedefs.graphql b/app/assets/javascripts/pipeline_editor/graphql/typedefs.graphql
new file mode 100644
index 00000000000..f4f65262158
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/graphql/typedefs.graphql
@@ -0,0 +1,7 @@
+type BlobContent {
+ rawData: String!
+}
+
+extend type Query {
+ blobContent: BlobContent
+}
diff --git a/app/assets/javascripts/pipeline_editor/index.js b/app/assets/javascripts/pipeline_editor/index.js
new file mode 100644
index 00000000000..ccd7b74064f
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/index.js
@@ -0,0 +1,34 @@
+import Vue from 'vue';
+
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import typeDefs from './graphql/typedefs.graphql';
+import { resolvers } from './graphql/resolvers';
+
+import PipelineEditorApp from './pipeline_editor_app.vue';
+
+export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
+ const el = document.querySelector(selector);
+
+ const { projectPath, defaultBranch, ciConfigPath } = el?.dataset;
+
+ Vue.use(VueApollo);
+
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(resolvers, { typeDefs }),
+ });
+
+ return new Vue({
+ el,
+ apolloProvider,
+ render(h) {
+ return h(PipelineEditorApp, {
+ props: {
+ projectPath,
+ defaultBranch,
+ ciConfigPath,
+ },
+ });
+ },
+ });
+};
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
new file mode 100644
index 00000000000..50b946af456
--- /dev/null
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -0,0 +1,108 @@
+<script>
+import { GlLoadingIcon, GlAlert, GlTabs, GlTab } from '@gitlab/ui';
+import { __, s__, sprintf } from '~/locale';
+
+import TextEditor from './components/text_editor.vue';
+import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
+
+import getBlobContent from './graphql/queries/blob_content.graphql';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ GlAlert,
+ GlTabs,
+ GlTab,
+ TextEditor,
+ PipelineGraph,
+ },
+ props: {
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ defaultBranch: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ ciConfigPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ error: null,
+ content: '',
+ editorIsReady: false,
+ };
+ },
+ apollo: {
+ content: {
+ query: getBlobContent,
+ variables() {
+ return {
+ projectPath: this.projectPath,
+ path: this.ciConfigPath,
+ ref: this.defaultBranch,
+ };
+ },
+ update(data) {
+ return data?.blobContent?.rawData;
+ },
+ error(error) {
+ this.error = error;
+ },
+ },
+ },
+ computed: {
+ loading() {
+ return this.$apollo.queries.content.loading;
+ },
+ errorMessage() {
+ const { message: generalReason, networkError } = this.error ?? {};
+
+ const { data } = networkError?.response ?? {};
+ // 404 for missing file uses `message`
+ // 400 for a missing ref uses `error`
+ const networkReason = data?.message ?? data?.error;
+
+ const reason = networkReason ?? generalReason ?? this.$options.i18n.unknownError;
+ return sprintf(this.$options.i18n.errorMessageWithReason, { reason });
+ },
+ pipelineData() {
+ // Note data will loaded as part of https://gitlab.com/gitlab-org/gitlab/-/issues/263141
+ return {};
+ },
+ },
+ i18n: {
+ unknownError: __('Unknown Error'),
+ errorMessageWithReason: s__('Pipelines|CI file could not be loaded: %{reason}'),
+ tabEdit: s__('Pipelines|Write pipeline configuration'),
+ tabGraph: s__('Pipelines|Visualize'),
+ },
+};
+</script>
+
+<template>
+ <div class="gl-mt-4">
+ <gl-alert v-if="error" :dismissible="false" variant="danger">{{ errorMessage }}</gl-alert>
+ <div class="gl-mt-4">
+ <gl-loading-icon v-if="loading" size="lg" />
+ <div v-else class="file-editor">
+ <gl-tabs>
+ <!-- editor should be mounted when its tab is visible, so the container has a size -->
+ <gl-tab :title="$options.i18n.tabEdit" :lazy="!editorIsReady">
+ <!-- editor should be mounted only once, when the tab is displayed -->
+ <text-editor v-model="content" @editor-ready="editorIsReady = true" />
+ </gl-tab>
+
+ <gl-tab :title="$options.i18n.tabGraph">
+ <pipeline-graph :pipeline-data="pipelineData" />
+ </gl-tab>
+ </gl-tabs>
+ </div>
+ </div>
+ </div>
+</template>