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>2019-12-13 21:08:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-13 21:08:06 +0300
commit7cc6c10c68915f5019ab8c2029eeb462c8fed4ef (patch)
tree419e5fee5bb60e71bef076157627812d54e142bc /app
parent630101f7f93847f39a4d2f87d92f514c973cdc1e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue68
-rw-r--r--app/assets/javascripts/error_tracking/services/index.js4
-rw-r--r--app/assets/javascripts/error_tracking/store/list/actions.js30
-rw-r--r--app/assets/javascripts/error_tracking/store/list/mutation_types.js4
-rw-r--r--app/assets/javascripts/error_tracking/store/list/mutations.js12
-rw-r--r--app/assets/javascripts/error_tracking/store/list/state.js4
-rw-r--r--app/assets/javascripts/error_tracking/utils.js13
-rw-r--r--app/assets/javascripts/pages/snippets/show/index.js3
-rw-r--r--app/assets/javascripts/projects/project_new.js18
-rw-r--r--app/assets/javascripts/snippets/components/app.vue31
-rw-r--r--app/assets/javascripts/snippets/index.js34
-rw-r--r--app/assets/javascripts/snippets/queries/getSnippet.query.graphql13
-rw-r--r--app/assets/stylesheets/pages/error_tracking_list.scss5
-rw-r--r--app/assets/stylesheets/pages/groups.scss1
-rw-r--r--app/views/admin/groups/_group.html.haml2
-rw-r--r--app/views/shared/groups/_group.html.haml2
-rw-r--r--app/views/shared/snippets/_snippet.html.haml2
-rw-r--r--app/views/snippets/show.html.haml2
18 files changed, 186 insertions, 62 deletions
diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
index 5cd68687329..23e251e4201 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -17,8 +17,6 @@ import AccessorUtils from '~/lib/utils/accessor';
import Icon from '~/vue_shared/components/icon.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { __ } from '~/locale';
-import TrackEventDirective from '~/vue_shared/directives/track_event';
-import { trackViewInSentryOptions } from '../utils';
export default {
fields: [
@@ -27,6 +25,11 @@ export default {
{ key: 'users', label: __('Users') },
{ key: 'lastSeen', label: __('Last seen'), thClass: 'w-15p' },
],
+ sortFields: {
+ last_seen: __('Last Seen'),
+ first_seen: __('First Seen'),
+ frequency: __('Frequency'),
+ },
components: {
GlEmptyState,
GlButton,
@@ -43,7 +46,6 @@ export default {
},
directives: {
GlTooltip: GlTooltipDirective,
- TrackEvent: TrackEventDirective,
},
props: {
indexPath: {
@@ -74,45 +76,47 @@ export default {
};
},
computed: {
- ...mapState('list', ['errors', 'externalUrl', 'loading', 'recentSearches']),
+ ...mapState('list', ['errors', 'loading', 'searchQuery', 'sortField', 'recentSearches']),
},
created() {
if (this.errorTrackingEnabled) {
- this.startPolling(this.indexPath);
+ this.setEndpoint(this.indexPath);
+ this.startPolling();
}
},
methods: {
...mapActions('list', [
'startPolling',
'restartPolling',
+ 'setEndpoint',
+ 'searchByQuery',
+ 'sortByField',
'addRecentSearch',
'clearRecentSearches',
'loadRecentSearches',
'setIndexPath',
]),
- filterErrors() {
- const searchTerm = this.errorSearchQuery.trim();
- this.addRecentSearch(searchTerm);
-
- this.startPolling(`${this.indexPath}?search_term=${searchTerm}`);
- },
setSearchText(text) {
this.errorSearchQuery = text;
- this.filterErrors();
+ this.searchByQuery(text);
},
- trackViewInSentryOptions,
getDetailsLink(errorId) {
return `error_tracking/${errorId}/details`;
},
+ isCurrentSortField(field) {
+ return field === this.sortField;
+ },
},
};
</script>
<template>
- <div>
+ <div class="error-list">
<div v-if="errorTrackingEnabled">
- <div class="d-flex flex-row justify-content-around bg-secondary border p-3">
- <div class="filtered-search-box">
+ <div
+ class="d-flex flex-row justify-content-around align-items-center bg-secondary border mt-2"
+ >
+ <div class="filtered-search-box flex-grow-1 my-3 ml-3 mr-2">
<gl-dropdown
:text="__('Recent searches')"
class="filtered-search-history-dropdown-wrapper d-none d-md-block"
@@ -143,7 +147,7 @@ export default {
:disabled="loading"
:placeholder="__('Search or filter results…')"
autofocus
- @keyup.enter.native="filterErrors"
+ @keyup.enter.native="searchByQuery(errorSearchQuery)"
/>
</div>
<div class="gl-search-box-by-type-right-icons">
@@ -160,16 +164,28 @@ export default {
</div>
</div>
- <gl-button
- v-track-event="trackViewInSentryOptions(externalUrl)"
- class="ml-3"
- variant="primary"
- :href="externalUrl"
- target="_blank"
+ <gl-dropdown
+ :text="$options.sortFields[sortField]"
+ left
+ :disabled="loading"
+ class="mr-3"
+ menu-class="sort-dropdown"
>
- {{ __('View in Sentry') }}
- <icon name="external-link" class="flex-shrink-0" />
- </gl-button>
+ <gl-dropdown-item
+ v-for="(label, field) in $options.sortFields"
+ :key="field"
+ @click="sortByField(field)"
+ >
+ <span class="d-flex">
+ <icon
+ class="flex-shrink-0 append-right-4"
+ :class="{ invisible: !isCurrentSortField(field) }"
+ name="mobile-issue-close"
+ />
+ {{ label }}
+ </span>
+ </gl-dropdown-item>
+ </gl-dropdown>
</div>
<div v-if="loading" class="py-3">
diff --git a/app/assets/javascripts/error_tracking/services/index.js b/app/assets/javascripts/error_tracking/services/index.js
index 68988296cc2..3b3f8311d67 100644
--- a/app/assets/javascripts/error_tracking/services/index.js
+++ b/app/assets/javascripts/error_tracking/services/index.js
@@ -1,7 +1,7 @@
import axios from '~/lib/utils/axios_utils';
export default {
- getSentryData({ endpoint }) {
- return axios.get(endpoint);
+ getSentryData({ endpoint, params }) {
+ return axios.get(endpoint, { params });
},
};
diff --git a/app/assets/javascripts/error_tracking/store/list/actions.js b/app/assets/javascripts/error_tracking/store/list/actions.js
index 13b15549d81..b1c81b55e58 100644
--- a/app/assets/javascripts/error_tracking/store/list/actions.js
+++ b/app/assets/javascripts/error_tracking/store/list/actions.js
@@ -6,19 +6,24 @@ import { __, sprintf } from '~/locale';
let eTagPoll;
-export function startPolling({ commit, dispatch }, endpoint) {
+export function startPolling({ state, commit, dispatch }) {
commit(types.SET_LOADING, true);
eTagPoll = new Poll({
resource: Service,
method: 'getSentryData',
- data: { endpoint },
+ data: {
+ endpoint: state.endpoint,
+ params: {
+ search_term: state.searchQuery,
+ sort: state.sortField,
+ },
+ },
successCallback: ({ data }) => {
if (!data) {
return;
}
commit(types.SET_ERRORS, data.errors);
- commit(types.SET_EXTERNAL_URL, data.external_url);
commit(types.SET_LOADING, false);
dispatch('stopPolling');
},
@@ -45,7 +50,6 @@ export const stopPolling = () => {
export function restartPolling({ commit }) {
commit(types.SET_ERRORS, []);
- commit(types.SET_EXTERNAL_URL, '');
commit(types.SET_LOADING, true);
if (eTagPoll) eTagPoll.restart();
@@ -67,4 +71,22 @@ export function clearRecentSearches({ commit }) {
commit(types.CLEAR_RECENT_SEARCHES);
}
+export const searchByQuery = ({ commit, dispatch }, query) => {
+ const searchQuery = query.trim();
+ commit(types.SET_SEARCH_QUERY, searchQuery);
+ commit(types.ADD_RECENT_SEARCH, searchQuery);
+ dispatch('stopPolling');
+ dispatch('startPolling');
+};
+
+export const sortByField = ({ commit, dispatch }, field) => {
+ commit(types.SET_SORT_FIELD, field);
+ dispatch('stopPolling');
+ dispatch('startPolling');
+};
+
+export const setEndpoint = ({ commit }, endpoint) => {
+ commit(types.SET_ENDPOINT, endpoint);
+};
+
export default () => {};
diff --git a/app/assets/javascripts/error_tracking/store/list/mutation_types.js b/app/assets/javascripts/error_tracking/store/list/mutation_types.js
index 4199e8d5cda..3ebfef76324 100644
--- a/app/assets/javascripts/error_tracking/store/list/mutation_types.js
+++ b/app/assets/javascripts/error_tracking/store/list/mutation_types.js
@@ -1,7 +1,9 @@
export const SET_ERRORS = 'SET_ERRORS';
-export const SET_EXTERNAL_URL = 'SET_EXTERNAL_URL';
export const SET_INDEX_PATH = 'SET_INDEX_PATH';
export const SET_LOADING = 'SET_LOADING';
export const ADD_RECENT_SEARCH = 'ADD_RECENT_SEARCH';
export const CLEAR_RECENT_SEARCHES = 'CLEAR_RECENT_SEARCHES';
export const LOAD_RECENT_SEARCHES = 'LOAD_RECENT_SEARCHES';
+export const SET_ENDPOINT = 'SET_ENDPOINT';
+export const SET_SORT_FIELD = 'SET_SORT_FIELD';
+export const SET_SEARCH_QUERY = 'SET_SEARCH_QUERY';
diff --git a/app/assets/javascripts/error_tracking/store/list/mutations.js b/app/assets/javascripts/error_tracking/store/list/mutations.js
index 18404d3b0af..048660eaeeb 100644
--- a/app/assets/javascripts/error_tracking/store/list/mutations.js
+++ b/app/assets/javascripts/error_tracking/store/list/mutations.js
@@ -6,9 +6,6 @@ export default {
[types.SET_ERRORS](state, data) {
state.errors = convertObjectPropsToCamelCase(data, { deep: true });
},
- [types.SET_EXTERNAL_URL](state, url) {
- state.externalUrl = url;
- },
[types.SET_LOADING](state, loading) {
state.loading = loading;
},
@@ -47,4 +44,13 @@ export default {
throw e;
}
},
+ [types.SET_SORT_FIELD](state, field) {
+ state.sortField = field;
+ },
+ [types.SET_SEARCH_QUERY](state, query) {
+ state.searchQuery = query;
+ },
+ [types.SET_ENDPOINT](state, endpoint) {
+ state.endpoint = endpoint;
+ },
};
diff --git a/app/assets/javascripts/error_tracking/store/list/state.js b/app/assets/javascripts/error_tracking/store/list/state.js
index f1f0369e5f3..f20b707142e 100644
--- a/app/assets/javascripts/error_tracking/store/list/state.js
+++ b/app/assets/javascripts/error_tracking/store/list/state.js
@@ -1,7 +1,9 @@
export default () => ({
errors: [],
- externalUrl: '',
loading: true,
+ endpoint: null,
+ sortField: 'last_seen',
+ searchQuery: null,
indexPath: '',
recentSearches: [],
});
diff --git a/app/assets/javascripts/error_tracking/utils.js b/app/assets/javascripts/error_tracking/utils.js
index b832b1371b1..3c382ccd1aa 100644
--- a/app/assets/javascripts/error_tracking/utils.js
+++ b/app/assets/javascripts/error_tracking/utils.js
@@ -1,15 +1,4 @@
-/* eslint-disable @gitlab/i18n/no-non-i18n-strings */
-
-/**
- * Tracks snowplow event when user clicks View in Sentry btn
- * @param {String} externalUrl that will be send as a property for the event
- */
-export const trackViewInSentryOptions = url => ({
- category: 'Error Tracking',
- action: 'click_view_in_sentry',
- label: 'External Url',
- property: url,
-});
+/* eslint-disable @gitlab/i18n/no-non-i18n-strings, import/prefer-default-export */
/**
* Tracks snowplow event when User clicks on error link to Sentry
diff --git a/app/assets/javascripts/pages/snippets/show/index.js b/app/assets/javascripts/pages/snippets/show/index.js
index 5efcc901fde..6e00c14f43e 100644
--- a/app/assets/javascripts/pages/snippets/show/index.js
+++ b/app/assets/javascripts/pages/snippets/show/index.js
@@ -3,6 +3,7 @@ import BlobViewer from '~/blob/viewer';
import ZenMode from '~/zen_mode';
import initNotes from '~/init_notes';
import snippetEmbed from '~/snippet/snippet_embed';
+import initSnippetsApp from '~/snippets';
document.addEventListener('DOMContentLoaded', () => {
if (!gon.features.snippetsVue) {
@@ -11,5 +12,7 @@ document.addEventListener('DOMContentLoaded', () => {
initNotes();
new ZenMode(); // eslint-disable-line no-new
snippetEmbed();
+ } else {
+ initSnippetsApp();
}
});
diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js
index dac105d7243..92c4c05bd87 100644
--- a/app/assets/javascripts/projects/project_new.js
+++ b/app/assets/javascripts/projects/project_new.js
@@ -128,15 +128,15 @@ const bindEvents = () => {
},
iosswift: {
text: s__('ProjectTemplates|iOS (Swift)'),
- icon: '.template-option svg.icon-gitlab',
+ icon: '.template-option .icon-iosswift',
},
dotnetcore: {
text: s__('ProjectTemplates|.NET Core'),
- icon: '.template-option .icon-dotnet',
+ icon: '.template-option .icon-dotnetcore',
},
android: {
text: s__('ProjectTemplates|Android'),
- icon: '.template-option svg.icon-android',
+ icon: '.template-option .icon-android',
},
gomicro: {
text: s__('ProjectTemplates|Go Micro'),
@@ -164,27 +164,27 @@ const bindEvents = () => {
},
nfhugo: {
text: s__('ProjectTemplates|Netlify/Hugo'),
- icon: '.template-option .icon-netlify',
+ icon: '.template-option .icon-nfhugo',
},
nfjekyll: {
text: s__('ProjectTemplates|Netlify/Jekyll'),
- icon: '.template-option .icon-netlify',
+ icon: '.template-option .icon-nfjekyll',
},
nfplainhtml: {
text: s__('ProjectTemplates|Netlify/Plain HTML'),
- icon: '.template-option .icon-netlify',
+ icon: '.template-option .icon-nfplainhtml',
},
nfgitbook: {
text: s__('ProjectTemplates|Netlify/GitBook'),
- icon: '.template-option .icon-netlify',
+ icon: '.template-option .icon-nfgitbook',
},
nfhexo: {
text: s__('ProjectTemplates|Netlify/Hexo'),
- icon: '.template-option .icon-netlify',
+ icon: '.template-option .icon-nfhexo',
},
salesforcedx: {
text: s__('ProjectTemplates|SalesforceDX'),
- icon: '.template-option svg.icon-gitlab',
+ icon: '.template-option .icon-salesforcedx',
},
serverless_framework: {
text: s__('ProjectTemplates|Serverless Framework/JS'),
diff --git a/app/assets/javascripts/snippets/components/app.vue b/app/assets/javascripts/snippets/components/app.vue
new file mode 100644
index 00000000000..e3d6cdd4606
--- /dev/null
+++ b/app/assets/javascripts/snippets/components/app.vue
@@ -0,0 +1,31 @@
+<script>
+import getSnippet from '../queries/getSnippet.query.graphql';
+
+export default {
+ apollo: {
+ snippetData: {
+ query: getSnippet,
+ variables() {
+ return {
+ ids: this.snippetGid,
+ };
+ },
+ update: data => data.snippets.edges[0].node,
+ },
+ },
+ props: {
+ snippetGid: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ snippetData: {},
+ };
+ },
+};
+</script>
+<template>
+ <div class="js-snippet-view"></div>
+</template>
diff --git a/app/assets/javascripts/snippets/index.js b/app/assets/javascripts/snippets/index.js
new file mode 100644
index 00000000000..654856f8d14
--- /dev/null
+++ b/app/assets/javascripts/snippets/index.js
@@ -0,0 +1,34 @@
+import Vue from 'vue';
+import Translate from '~/vue_shared/translate';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+
+import SnippetsApp from './components/app.vue';
+
+Vue.use(VueApollo);
+Vue.use(Translate);
+
+export default () => {
+ const el = document.getElementById('js-snippet-view');
+
+ if (!el) {
+ return false;
+ }
+
+ const { snippetGid } = el.dataset;
+ const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+ });
+
+ return new Vue({
+ el,
+ apolloProvider,
+ render(createElement) {
+ return createElement(SnippetsApp, {
+ props: {
+ snippetGid,
+ },
+ });
+ },
+ });
+};
diff --git a/app/assets/javascripts/snippets/queries/getSnippet.query.graphql b/app/assets/javascripts/snippets/queries/getSnippet.query.graphql
new file mode 100644
index 00000000000..5a5f0d05c5b
--- /dev/null
+++ b/app/assets/javascripts/snippets/queries/getSnippet.query.graphql
@@ -0,0 +1,13 @@
+query getSnippet($ids: [ID!]) {
+ snippets(ids: $ids) {
+ edges {
+ node {
+ title
+ description
+ createdAt
+ updatedAt
+ visibility
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/pages/error_tracking_list.scss b/app/assets/stylesheets/pages/error_tracking_list.scss
new file mode 100644
index 00000000000..cd1adb9a754
--- /dev/null
+++ b/app/assets/stylesheets/pages/error_tracking_list.scss
@@ -0,0 +1,5 @@
+.error-list {
+ .sort-dropdown {
+ min-width: auto;
+ }
+}
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index 1502cf18440..1cf72c51ca7 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -25,6 +25,7 @@
.description p {
margin-bottom: 0;
+ color: $gl-text-color-secondary;
}
}
diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml
index 395c469255e..3444e423235 100644
--- a/app/views/admin/groups/_group.html.haml
+++ b/app/views/admin/groups/_group.html.haml
@@ -1,7 +1,7 @@
- group = local_assigns.fetch(:group)
- css_class = 'no-description' if group.description.blank?
-%li.group-row{ class: css_class }
+%li.group-row.py-3{ class: css_class }
.controls
= link_to _('Edit'), admin_group_edit_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
= link_to _('Delete'), [:admin, group], data: { confirm: _("Are you sure you want to remove %{group_name}?") % { group_name: group.name } }, method: :delete, class: 'btn btn-remove'
diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml
index 609b8dce21a..e47967ef622 100644
--- a/app/views/shared/groups/_group.html.haml
+++ b/app/views/shared/groups/_group.html.haml
@@ -1,7 +1,7 @@
- user = local_assigns.fetch(:user, current_user)
- access = user&.max_member_access_for_group(group.id)
-%li.group-row{ class: ('no-description' if group.description.blank?) }
+%li.group-row.py-3{ class: ('no-description' if group.description.blank?) }
.stats
%span
= icon('bookmark')
diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml
index f38e30b0c55..9e038854c59 100644
--- a/app/views/shared/snippets/_snippet.html.haml
+++ b/app/views/shared/snippets/_snippet.html.haml
@@ -1,7 +1,7 @@
- link_project = local_assigns.fetch(:link_project, false)
- notes_count = @noteable_meta_data[snippet.id].user_notes_count
-%li.snippet-row
+%li.snippet-row.py-3
= image_tag avatar_icon_for_user(snippet.author), class: "avatar s40 d-none d-sm-block", alt: ''
.title
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index c77b05e3ea8..080c0ab6ece 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -5,7 +5,7 @@
- page_title "#{@snippet.title} (#{@snippet.to_reference})", _("Snippets")
- if Feature.enabled?(:snippets_vue)
- #js-snippet-view{ 'data-qa-selector': 'snippet_view' }
+ #js-snippet-view{ data: {'qa-selector': 'snippet_view', 'snippet-gid': @snippet.to_global_id} }
- else
= render 'shared/snippets/header'