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>2021-11-16 00:14:31 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-16 00:14:31 +0300
commitc568cb4dbc0421212a28f3cd5b77223aad8888ba (patch)
treebe3ab3b5d6cf5c23a71b557ed82758c905a437bd /app
parent4481a56a94c579f52e1cdef1cc1f4995f0ee1412 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/crm/components/contacts_root.vue77
-rw-r--r--app/assets/javascripts/crm/components/queries/get_group_contacts.query.graphql22
-rw-r--r--app/assets/javascripts/crm/contacts_bundle.js10
-rw-r--r--app/assets/javascripts/projects/components/project_delete_button.vue56
-rw-r--r--app/assets/javascripts/projects/project_delete_button.js16
-rw-r--r--app/controllers/jwks_controller.rb10
-rw-r--r--app/services/projects/all_issues_count_service.rb15
-rw-r--r--app/services/projects/all_merge_requests_count_service.rb15
-rw-r--r--app/views/groups/crm/contacts.html.haml2
-rw-r--r--app/views/projects/_remove.html.haml4
10 files changed, 219 insertions, 8 deletions
diff --git a/app/assets/javascripts/crm/components/contacts_root.vue b/app/assets/javascripts/crm/components/contacts_root.vue
index 6d32ba41eae..83c02f7d5fe 100644
--- a/app/assets/javascripts/crm/components/contacts_root.vue
+++ b/app/assets/javascripts/crm/components/contacts_root.vue
@@ -1,7 +1,80 @@
<script>
-export default {};
+import { GlLoadingIcon, GlTable } from '@gitlab/ui';
+import createFlash from '~/flash';
+import { s__, __ } from '~/locale';
+import getGroupContactsQuery from './queries/get_group_contacts.query.graphql';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ GlTable,
+ },
+ inject: ['groupFullPath'],
+ data() {
+ return { contacts: [] };
+ },
+ apollo: {
+ contacts: {
+ query() {
+ return getGroupContactsQuery;
+ },
+ variables() {
+ return {
+ groupFullPath: this.groupFullPath,
+ };
+ },
+ update(data) {
+ return this.extractContacts(data);
+ },
+ error(error) {
+ createFlash({
+ message: __('Something went wrong. Please try again.'),
+ error,
+ captureError: true,
+ });
+ },
+ },
+ },
+ computed: {
+ isLoading() {
+ return this.$apollo.queries.contacts.loading;
+ },
+ },
+ methods: {
+ extractContacts(data) {
+ const contacts = data?.group?.contacts?.nodes || [];
+ return contacts.slice().sort((a, b) => a.firstName.localeCompare(b.firstName));
+ },
+ },
+ fields: [
+ { key: 'firstName', sortable: true },
+ { key: 'lastName', sortable: true },
+ { key: 'email', sortable: true },
+ { key: 'phone', sortable: true },
+ { key: 'description', sortable: true },
+ {
+ key: 'organization',
+ formatter: (organization) => {
+ return organization?.name;
+ },
+ sortable: true,
+ },
+ ],
+ i18n: {
+ emptyText: s__('Crm|No contacts found'),
+ },
+};
</script>
<template>
- <div></div>
+ <div>
+ <gl-loading-icon v-if="isLoading" class="gl-mt-5" size="lg" />
+ <gl-table
+ v-else
+ :items="contacts"
+ :fields="$options.fields"
+ :empty-text="$options.i18n.emptyText"
+ show-empty
+ />
+ </div>
</template>
diff --git a/app/assets/javascripts/crm/components/queries/get_group_contacts.query.graphql b/app/assets/javascripts/crm/components/queries/get_group_contacts.query.graphql
new file mode 100644
index 00000000000..f6acd258585
--- /dev/null
+++ b/app/assets/javascripts/crm/components/queries/get_group_contacts.query.graphql
@@ -0,0 +1,22 @@
+query contacts($groupFullPath: ID!) {
+ group(fullPath: $groupFullPath) {
+ __typename
+ id
+ contacts {
+ nodes {
+ __typename
+ id
+ firstName
+ lastName
+ email
+ phone
+ description
+ organization {
+ __typename
+ id
+ name
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/crm/contacts_bundle.js b/app/assets/javascripts/crm/contacts_bundle.js
index a46acfdc2d5..6438953596e 100644
--- a/app/assets/javascripts/crm/contacts_bundle.js
+++ b/app/assets/javascripts/crm/contacts_bundle.js
@@ -1,15 +1,25 @@
import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
import CrmContactsRoot from './components/contacts_root.vue';
+Vue.use(VueApollo);
+
export default () => {
const el = document.getElementById('js-crm-contacts-app');
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+ });
+
if (!el) {
return false;
}
return new Vue({
el,
+ apolloProvider,
+ provide: { groupFullPath: el.dataset.groupFullPath },
render(createElement) {
return createElement(CrmContactsRoot);
},
diff --git a/app/assets/javascripts/projects/components/project_delete_button.vue b/app/assets/javascripts/projects/components/project_delete_button.vue
index 06711e4025a..bac876317b8 100644
--- a/app/assets/javascripts/projects/components/project_delete_button.vue
+++ b/app/assets/javascripts/projects/components/project_delete_button.vue
@@ -18,12 +18,36 @@ export default {
type: String,
required: true,
},
+ isFork: {
+ type: Boolean,
+ required: true,
+ },
+ issuesCount: {
+ type: Number,
+ required: true,
+ },
+ mergeRequestsCount: {
+ type: Number,
+ required: true,
+ },
+ forksCount: {
+ type: Number,
+ required: true,
+ },
+ starsCount: {
+ type: Number,
+ required: true,
+ },
},
strings: {
alertTitle: __('You are about to permanently delete this project'),
alertBody: __(
'Once a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc.',
),
+ isNotForkMessage: __(
+ 'This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:',
+ ),
+ isForkMessage: __('This forked project has the following:'),
},
};
</script>
@@ -37,6 +61,38 @@ export default {
:title="$options.strings.alertTitle"
:dismissible="false"
>
+ <p>
+ <gl-sprintf v-if="isFork" :message="$options.strings.isForkMessage" />
+ <gl-sprintf v-else :message="$options.strings.isNotForkMessage">
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ </p>
+ <ul>
+ <li>
+ <gl-sprintf :message="n__('%d issue', '%d issues', issuesCount)">
+ <template #issuesCount>{{ issuesCount }}</template>
+ </gl-sprintf>
+ </li>
+ <li>
+ <gl-sprintf
+ :message="n__('%d merge requests', '%d merge requests', mergeRequestsCount)"
+ >
+ <template #mergeRequestsCount>{{ mergeRequestsCount }}</template>
+ </gl-sprintf>
+ </li>
+ <li>
+ <gl-sprintf :message="n__('%d fork', '%d forks', forksCount)">
+ <template #forksCount>{{ forksCount }}</template>
+ </gl-sprintf>
+ </li>
+ <li>
+ <gl-sprintf :message="n__('%d star', '%d stars', starsCount)">
+ <template #starsCount>{{ starsCount }}</template>
+ </gl-sprintf>
+ </li>
+ </ul>
<gl-sprintf :message="$options.strings.alertBody">
<template #strong="{ content }">
<strong>{{ content }}</strong>
diff --git a/app/assets/javascripts/projects/project_delete_button.js b/app/assets/javascripts/projects/project_delete_button.js
index aa7fc31d307..b4d388eda3a 100644
--- a/app/assets/javascripts/projects/project_delete_button.js
+++ b/app/assets/javascripts/projects/project_delete_button.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
import ProjectDeleteButton from './components/project_delete_button.vue';
export default (selector = '#js-project-delete-button') => {
@@ -6,7 +7,15 @@ export default (selector = '#js-project-delete-button') => {
if (!el) return;
- const { confirmPhrase, formPath } = el.dataset;
+ const {
+ confirmPhrase,
+ formPath,
+ isFork,
+ issuesCount,
+ mergeRequestsCount,
+ forksCount,
+ starsCount,
+ } = el.dataset;
// eslint-disable-next-line no-new
new Vue({
@@ -16,6 +25,11 @@ export default (selector = '#js-project-delete-button') => {
props: {
confirmPhrase,
formPath,
+ isFork: parseBoolean(isFork),
+ issuesCount: parseInt(issuesCount, 10),
+ mergeRequestsCount: parseInt(mergeRequestsCount, 10),
+ forksCount: parseInt(forksCount, 10),
+ starsCount: parseInt(starsCount, 10),
},
});
},
diff --git a/app/controllers/jwks_controller.rb b/app/controllers/jwks_controller.rb
index e7b839f5590..3b0e6ca2eb1 100644
--- a/app/controllers/jwks_controller.rb
+++ b/app/controllers/jwks_controller.rb
@@ -1,13 +1,17 @@
# frozen_string_literal: true
-class JwksController < ActionController::Base # rubocop:disable Rails/ApplicationController
+class JwksController < Doorkeeper::OpenidConnect::DiscoveryController
def index
- render json: { keys: keys }
+ render json: { keys: payload }
+ end
+
+ def keys
+ index
end
private
- def keys
+ def payload
[
# We keep openid_connect_signing_key so that we can seamlessly
# replace it with ci_jwt_signing_key and remove it on the next release.
diff --git a/app/services/projects/all_issues_count_service.rb b/app/services/projects/all_issues_count_service.rb
new file mode 100644
index 00000000000..15352b14d3e
--- /dev/null
+++ b/app/services/projects/all_issues_count_service.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Projects
+ # Service class for counting and caching the number of all issues of a
+ # project.
+ class AllIssuesCountService < Projects::CountService
+ def relation_for_count
+ @project.issues
+ end
+
+ def cache_key_name
+ 'all_issues_count'
+ end
+ end
+end
diff --git a/app/services/projects/all_merge_requests_count_service.rb b/app/services/projects/all_merge_requests_count_service.rb
new file mode 100644
index 00000000000..db0bab3f799
--- /dev/null
+++ b/app/services/projects/all_merge_requests_count_service.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Projects
+ # Service class for counting and caching the number of all merge requests of
+ # a project.
+ class AllMergeRequestsCountService < Projects::CountService
+ def relation_for_count
+ @project.merge_requests
+ end
+
+ def cache_key_name
+ 'all_merge_requests_count'
+ end
+ end
+end
diff --git a/app/views/groups/crm/contacts.html.haml b/app/views/groups/crm/contacts.html.haml
index f4189612694..c452a969d17 100644
--- a/app/views/groups/crm/contacts.html.haml
+++ b/app/views/groups/crm/contacts.html.haml
@@ -1,4 +1,4 @@
- breadcrumb_title _('Customer Relations Contacts')
- page_title _('Customer Relations Contacts')
-#js-crm-contacts-app
+#js-crm-contacts-app{ data: { group_full_path: @group.full_path } }
diff --git a/app/views/projects/_remove.html.haml b/app/views/projects/_remove.html.haml
index ef4a90a5c08..815e76ebcb9 100644
--- a/app/views/projects/_remove.html.haml
+++ b/app/views/projects/_remove.html.haml
@@ -1,4 +1,6 @@
- return unless can?(current_user, :remove_project, project)
+- merge_requests_count = Projects::AllMergeRequestsCountService.new(project).count
+- issues_count = Projects::AllIssuesCountService.new(project).count
.sub-section
%h4.danger-title= _('Delete project')
@@ -7,4 +9,4 @@
= link_to _('Learn more.'), help_page_path('user/project/settings/index', anchor: 'removing-a-fork-relationship'), target: '_blank', rel: 'noopener noreferrer'
%p
%strong= _('Deleted projects cannot be restored!')
- #js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project) } }
+ #js-project-delete-button{ data: { form_path: project_path(project), confirm_phrase: delete_confirm_phrase(project), is_fork: project.forked?.to_s, issues_count: number_with_delimiter(issues_count), merge_requests_count: number_with_delimiter(merge_requests_count), forks_count: number_with_delimiter(project.forks_count), stars_count: number_with_delimiter(project.star_count) } }