diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-01 12:13:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-01 12:13:14 +0300 |
commit | a67852da7f1243becda660d7619e3f5ccc68c1e1 (patch) | |
tree | 99dd6dc58162afbb7c726e01b13ee5c0a0dd9b56 /app | |
parent | 01600ff2d11bb7f77bb70bf143a95efdf59931e1 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
18 files changed, 277 insertions, 63 deletions
diff --git a/app/assets/javascripts/clusters/agents/index.js b/app/assets/javascripts/clusters/agents/index.js index bcb5b271203..ec6b6c6fc35 100644 --- a/app/assets/javascripts/clusters/agents/index.js +++ b/app/assets/javascripts/clusters/agents/index.js @@ -12,7 +12,12 @@ export default () => { return null; } - const defaultClient = createDefaultClient(); + const defaultClient = createDefaultClient( + {}, + { + assumeImmutableResults: true, + }, + ); const { agentName, projectPath } = el.dataset; return new Vue({ diff --git a/app/assets/javascripts/cycle_analytics/components/value_stream_metrics.vue b/app/assets/javascripts/cycle_analytics/components/value_stream_metrics.vue index a132931de60..9671742e564 100644 --- a/app/assets/javascripts/cycle_analytics/components/value_stream_metrics.vue +++ b/app/assets/javascripts/cycle_analytics/components/value_stream_metrics.vue @@ -91,24 +91,20 @@ export default { </script> <template> <div class="gl-display-flex gl-flex-wrap" data-testid="vsa-time-metrics"> - <div v-if="isLoading" class="gl-h-auto gl-py-3 gl-pr-9 gl-my-6"> - <gl-skeleton-loading /> + <gl-skeleton-loading v-if="isLoading" class="gl-h-auto gl-py-3 gl-pr-9 gl-my-6" /> + <div v-for="metric in metrics" v-show="!isLoading" :key="metric.key" class="gl-my-6 gl-pr-9"> + <gl-single-stat + :id="metric.key" + :value="`${metric.value}`" + :title="metric.label" + :unit="metric.unit || ''" + :should-animate="true" + :animation-decimal-places="1" + :class="{ 'gl-hover-cursor-pointer': hasLinks(metric.links) }" + tabindex="0" + @click="clickHandler(metric)" + /> + <metric-popover :metric="metric" :target="metric.key" /> </div> - <template v-else> - <div v-for="metric in metrics" :key="metric.key" class="gl-my-6 gl-pr-9"> - <gl-single-stat - :id="metric.key" - :value="`${metric.value}`" - :title="metric.label" - :unit="metric.unit || ''" - :should-animate="true" - :animation-decimal-places="1" - :class="{ 'gl-hover-cursor-pointer': hasLinks(metric.links) }" - tabindex="0" - @click="clickHandler(metric)" - /> - <metric-popover :metric="metric" :target="metric.key" /> - </div> - </template> </div> </template> diff --git a/app/assets/javascripts/environments/components/new_environments_app.vue b/app/assets/javascripts/environments/components/new_environments_app.vue new file mode 100644 index 00000000000..11fa0e24572 --- /dev/null +++ b/app/assets/javascripts/environments/components/new_environments_app.vue @@ -0,0 +1,6 @@ +<script> +export default {}; +</script> +<template> + <div></div> +</template> diff --git a/app/assets/javascripts/environments/graphql/client.js b/app/assets/javascripts/environments/graphql/client.js new file mode 100644 index 00000000000..498163c7abc --- /dev/null +++ b/app/assets/javascripts/environments/graphql/client.js @@ -0,0 +1,29 @@ +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import environmentApp from './queries/environmentApp.query.graphql'; +import { resolvers } from './resolvers'; +import typedefs from './typedefs.graphql'; + +export const apolloProvider = (endpoint) => { + const defaultClient = createDefaultClient( + resolvers(endpoint), + { + assumeImmutableResults: true, + }, + typedefs, + ); + const { cache } = defaultClient; + + cache.writeQuery({ + query: environmentApp, + data: { + availableCount: 0, + environments: [], + reviewApp: {}, + stoppedCount: 0, + }, + }); + return new VueApollo({ + defaultClient, + }); +}; diff --git a/app/assets/javascripts/environments/graphql/mutations/cancel_auto_stop.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/cancel_auto_stop.mutation.graphql new file mode 100644 index 00000000000..c4d0f8b854a --- /dev/null +++ b/app/assets/javascripts/environments/graphql/mutations/cancel_auto_stop.mutation.graphql @@ -0,0 +1,5 @@ +mutation($environment: Environment) { + cancelAutoStop(environment: $environment) @client { + errors + } +} diff --git a/app/assets/javascripts/environments/graphql/mutations/delete_environment.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/delete_environment.mutation.graphql new file mode 100644 index 00000000000..fba321dff73 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/mutations/delete_environment.mutation.graphql @@ -0,0 +1,5 @@ +mutation($environment: Environment) { + deleteEnvironment(environment: $environment) @client { + errors + } +} diff --git a/app/assets/javascripts/environments/graphql/mutations/rollback_environment.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/rollback_environment.mutation.graphql new file mode 100644 index 00000000000..b2fd2dd893c --- /dev/null +++ b/app/assets/javascripts/environments/graphql/mutations/rollback_environment.mutation.graphql @@ -0,0 +1,5 @@ +mutation($environment: Environment) { + rollbackEnvironment(environment: $environment) @client { + errors + } +} diff --git a/app/assets/javascripts/environments/graphql/mutations/stop_environment.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/stop_environment.mutation.graphql new file mode 100644 index 00000000000..26836697306 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/mutations/stop_environment.mutation.graphql @@ -0,0 +1,5 @@ +mutation($environment: Environment) { + stopEnvironment(environment: $environment) @client { + errors + } +} diff --git a/app/assets/javascripts/environments/graphql/queries/environmentApp.query.graphql b/app/assets/javascripts/environments/graphql/queries/environmentApp.query.graphql new file mode 100644 index 00000000000..faa76c0a42c --- /dev/null +++ b/app/assets/javascripts/environments/graphql/queries/environmentApp.query.graphql @@ -0,0 +1,8 @@ +query getEnvironmentApp { + environmentApp @client { + availableCount + environments + reviewApp + stoppedCount + } +} diff --git a/app/assets/javascripts/environments/graphql/queries/folder.query.graphql b/app/assets/javascripts/environments/graphql/queries/folder.query.graphql new file mode 100644 index 00000000000..0943d1aa800 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/queries/folder.query.graphql @@ -0,0 +1,7 @@ +query getEnvironmentFolder($environment: NestedEnvironment) { + folder(environment: $environment) @client { + availableCount + environments + stoppedCount + } +} diff --git a/app/assets/javascripts/environments/graphql/resolvers.js b/app/assets/javascripts/environments/graphql/resolvers.js new file mode 100644 index 00000000000..c9eb6ccdcae --- /dev/null +++ b/app/assets/javascripts/environments/graphql/resolvers.js @@ -0,0 +1,51 @@ +import axios from '~/lib/utils/axios_utils'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; + +const mapNestedEnvironment = (env) => ({ + ...convertObjectPropsToCamelCase(env, { deep: true }), + __typename: 'NestedEnvironment', +}); +const mapEnvironment = (env) => ({ + ...convertObjectPropsToCamelCase(env), + // eslint-disable-next-line @gitlab/require-i18n-strings + __typename: 'Environment', +}); + +export const resolvers = (endpoint) => ({ + Query: { + environmentApp() { + return axios.get(endpoint, { params: { nested: true } }).then((res) => ({ + availableCount: res.data.available_count, + environments: res.data.environments.map(mapNestedEnvironment), + reviewApp: { + ...convertObjectPropsToCamelCase(res.data.review_app), + __typename: 'ReviewApp', + }, + stoppedCount: res.data.stopped_count, + __typename: 'EnvironmentApp', + })); + }, + folder(_, { environment: { folderPath } }) { + return axios.get(folderPath, { params: { per_page: 3 } }).then((res) => ({ + availableCount: res.data.available_count, + environments: res.data.environments.map(mapEnvironment), + stoppedCount: res.data.stopped_count, + __typename: 'EnvironmentFolder', + })); + }, + }, + Mutations: { + stopEnvironment(_, { environment: { stopPath } }) { + return axios.post(stopPath); + }, + deleteEnvironment(_, { environment: { deletePath } }) { + return axios.delete(deletePath); + }, + rollbackEnvironment(_, { environment: { retryUrl } }) { + return axios.post(retryUrl); + }, + cancelAutoStop(_, { environment: { autoStopPath } }) { + return axios.post(autoStopPath); + }, + }, +}); diff --git a/app/assets/javascripts/environments/graphql/typedefs.graphql b/app/assets/javascripts/environments/graphql/typedefs.graphql new file mode 100644 index 00000000000..44c985941d4 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/typedefs.graphql @@ -0,0 +1,35 @@ +type Environment { + id: Int! + globalId: ID! + name: String! + folderPath: String + stopPath: String + deletePath: String + retryUrl: String + autoStopPath: String +} + +type NestedEnvironment { + name: String! + size: Int! + latest: Environment! +} + +type EnvironmentFolder { + environments: [Environment!]! + availableCount: Int! + stoppedCount: Int! +} + +type ReviewApp { + canSetupReviewApp: Boolean! + allClustersEmpty: Boolean! + reviewSnippet: String +} + +type EnvironmentApp { + stoppedCount: Int! + availableCount: Int! + environments: [NestedEnvironment!]! + reviewApp: ReviewApp! +} diff --git a/app/assets/javascripts/environments/index.js b/app/assets/javascripts/environments/index.js index 5e33923d518..99a1d12adf7 100644 --- a/app/assets/javascripts/environments/index.js +++ b/app/assets/javascripts/environments/index.js @@ -12,37 +12,40 @@ const apolloProvider = new VueApollo({ defaultClient: createDefaultClient({}, { assumeImmutableResults: true }), }); -export default () => { - const el = document.getElementById('environments-list-view'); - return new Vue({ - el, - components: { - environmentsComponent, - }, - apolloProvider, - provide: { - projectPath: el.dataset.projectPath, - defaultBranchName: el.dataset.defaultBranchName, - }, - data() { - const environmentsData = el.dataset; +export default (el) => { + if (el) { + return new Vue({ + el, + components: { + environmentsComponent, + }, + apolloProvider, + provide: { + projectPath: el.dataset.projectPath, + defaultBranchName: el.dataset.defaultBranchName, + }, + data() { + const environmentsData = el.dataset; - return { - endpoint: environmentsData.environmentsDataEndpoint, - newEnvironmentPath: environmentsData.newEnvironmentPath, - helpPagePath: environmentsData.helpPagePath, - canCreateEnvironment: parseBoolean(environmentsData.canCreateEnvironment), - }; - }, - render(createElement) { - return createElement('environments-component', { - props: { - endpoint: this.endpoint, - newEnvironmentPath: this.newEnvironmentPath, - helpPagePath: this.helpPagePath, - canCreateEnvironment: this.canCreateEnvironment, - }, - }); - }, - }); + return { + endpoint: environmentsData.environmentsDataEndpoint, + newEnvironmentPath: environmentsData.newEnvironmentPath, + helpPagePath: environmentsData.helpPagePath, + canCreateEnvironment: parseBoolean(environmentsData.canCreateEnvironment), + }; + }, + render(createElement) { + return createElement('environments-component', { + props: { + endpoint: this.endpoint, + newEnvironmentPath: this.newEnvironmentPath, + helpPagePath: this.helpPagePath, + canCreateEnvironment: this.canCreateEnvironment, + }, + }); + }, + }); + } + + return null; }; diff --git a/app/assets/javascripts/environments/new_index.js b/app/assets/javascripts/environments/new_index.js new file mode 100644 index 00000000000..dd5c709c75a --- /dev/null +++ b/app/assets/javascripts/environments/new_index.js @@ -0,0 +1,38 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import { parseBoolean } from '../lib/utils/common_utils'; +import { apolloProvider } from './graphql/client'; +import EnvironmentsApp from './components/new_environments_app.vue'; + +Vue.use(VueApollo); + +export default (el) => { + if (el) { + const { + canCreateEnvironment, + endpoint, + newEnvironmentPath, + helpPagePath, + projectPath, + defaultBranchName, + } = el.dataset; + + return new Vue({ + el, + apolloProvider: apolloProvider(endpoint), + provide: { + projectPath, + defaultBranchName, + endpoint, + newEnvironmentPath, + helpPagePath, + canCreateEnvironment: parseBoolean(canCreateEnvironment), + }, + render(h) { + return h(EnvironmentsApp); + }, + }); + } + + return null; +}; diff --git a/app/assets/javascripts/pages/projects/environments/index/index.js b/app/assets/javascripts/pages/projects/environments/index/index.js index 554ed4f9786..f0554d64ddc 100644 --- a/app/assets/javascripts/pages/projects/environments/index/index.js +++ b/app/assets/javascripts/pages/projects/environments/index/index.js @@ -1,3 +1,11 @@ import initEnvironments from '~/environments/'; +import initNewEnvironments from '~/environments/new_index'; -initEnvironments(); +let el = document.getElementById('environments-list-view'); + +if (el) { + initEnvironments(el); +} else { + el = document.getElementById('environments-table'); + initNewEnvironments(el); +} diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js index dadf0988582..194e273e261 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js +++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js @@ -28,8 +28,7 @@ export default function initMergeRequestShow() { const el = document.querySelector('.js-mr-status-box'); const apolloProvider = new VueApollo({ - assumeImmutableResults: true, - defaultClient: createDefaultClient(), + defaultClient: createDefaultClient({}, { assumeImmutableResults: true }), }); // eslint-disable-next-line no-new new Vue({ diff --git a/app/assets/javascripts/projects/terraform_notification/index.js b/app/assets/javascripts/projects/terraform_notification/index.js index 362e71ed902..21c8d09b7fc 100644 --- a/app/assets/javascripts/projects/terraform_notification/index.js +++ b/app/assets/javascripts/projects/terraform_notification/index.js @@ -6,7 +6,7 @@ import TerraformNotification from './components/terraform_notification.vue'; Vue.use(VueApollo); const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(), + defaultClient: createDefaultClient({}, { assumeImmtableResults: true }), }); export default () => { diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml index 0136184f80d..72ccc8d830c 100644 --- a/app/views/projects/environments/index.html.haml +++ b/app/views/projects/environments/index.html.haml @@ -1,10 +1,19 @@ - page_title _("Environments") -- add_page_specific_style 'page_bundles/environments' -#environments-list-view{ data: { environments_data: environments_list_data, - "can-read-environment" => can?(current_user, :read_environment, @project).to_s, - "can-create-environment" => can?(current_user, :create_environment, @project).to_s, - "new-environment-path" => new_project_environment_path(@project), - "help-page-path" => help_page_path("ci/environments/index.md"), - "project-path" => @project.full_path, - "default-branch-name" => @project.default_branch_or_main } } +- if Feature.enabled?(:new_environments_table) + #environments-table{ data: { endpoint: project_environments_path(@project, format: :json), + "can-read-environment" => can?(current_user, :read_environment, @project).to_s, + "can-create-environment" => can?(current_user, :create_environment, @project).to_s, + "new-environment-path" => new_project_environment_path(@project), + "help-page-path" => help_page_path("ci/environments/index.md"), + "project-path" => @project.full_path, + "default-branch-name" => @project.default_branch_or_main } } +- else + - add_page_specific_style 'page_bundles/environments' + #environments-list-view{ data: { environments_data: environments_list_data, + "can-read-environment" => can?(current_user, :read_environment, @project).to_s, + "can-create-environment" => can?(current_user, :create_environment, @project).to_s, + "new-environment-path" => new_project_environment_path(@project), + "help-page-path" => help_page_path("ci/environments/index.md"), + "project-path" => @project.full_path, + "default-branch-name" => @project.default_branch_or_main } } |