diff options
Diffstat (limited to 'app/assets')
16 files changed, 245 insertions, 75 deletions
diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue index 21622d8f750..e15ade142d7 100644 --- a/app/assets/javascripts/alert_management/components/alert_details.vue +++ b/app/assets/javascripts/alert_management/components/alert_details.vue @@ -1,6 +1,8 @@ <script> import { GlNewDropdown, GlNewDropdownItem, GlTabs, GlTab } from '@gitlab/ui'; import { s__ } from '~/locale'; +import query from '../graphql/queries/details.query.graphql'; +import { fetchPolicies } from '~/lib/graphql'; export default { statuses: { @@ -18,11 +20,40 @@ export default { GlTab, GlTabs, }, + props: { + alertId: { + type: String, + required: true, + }, + projectPath: { + type: String, + required: true, + }, + }, + apollo: { + alert: { + fetchPolicy: fetchPolicies.CACHE_AND_NETWORK, + query, + variables() { + return { + fullPath: this.projectPath, + alertId: this.alertId, + }; + }, + update(data) { + return data?.project?.alertManagementAlerts?.nodes?.[0] ?? null; + }, + }, + }, + data() { + return { alert: null }; + }, }; </script> <template> <div> - <div class="d-flex justify-content-between border-bottom pb-2 pt-1"> + <div v-if="alert" class="d-flex justify-content-between border-bottom pb-2 pt-1"> + <div></div> <gl-new-dropdown class="align-self-center" right> <gl-new-dropdown-item v-for="(label, field) in $options.statuses" @@ -33,23 +64,21 @@ export default { </gl-new-dropdown-item> </gl-new-dropdown> </div> - <div class="d-flex"> - <gl-tabs> - <gl-tab data-testid="overviewTab" :title="$options.i18n.overviewTitle"> - <ul class="pl-3"> - <li data-testid="startTimeItem" class="font-weight-bold mb-3 mt-2"> - {{ s__('AlertManagement|Start time:') }} - </li> - <li class="font-weight-bold my-3"> - {{ s__('AlertManagement|End time:') }} - </li> - <li class="font-weight-bold my-3"> - {{ s__('AlertManagement|Events:') }} - </li> - </ul> - </gl-tab> - <gl-tab data-testid="fullDetailsTab" :title="$options.i18n.fullAlertDetailsTitle" /> - </gl-tabs> - </div> + <gl-tabs v-if="alert" data-testid="alertDetailsTabs"> + <gl-tab data-testid="overviewTab" :title="$options.i18n.overviewTitle"> + <ul class="pl-3"> + <li data-testid="startTimeItem" class="font-weight-bold mb-3 mt-2"> + {{ s__('AlertManagement|Start time:') }} + </li> + <li class="font-weight-bold my-3"> + {{ s__('AlertManagement|End time:') }} + </li> + <li class="font-weight-bold my-3"> + {{ s__('AlertManagement|Events:') }} + </li> + </ul> + </gl-tab> + <gl-tab data-testid="fullDetailsTab" :title="$options.i18n.fullAlertDetailsTitle" /> + </gl-tabs> </div> </template> diff --git a/app/assets/javascripts/alert_management/details.js b/app/assets/javascripts/alert_management/details.js index 23c3b8a742a..0fb11595a04 100644 --- a/app/assets/javascripts/alert_management/details.js +++ b/app/assets/javascripts/alert_management/details.js @@ -1,15 +1,32 @@ import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; import AlertDetails from './components/alert_details.vue'; +Vue.use(VueApollo); + export default selector => { + const domEl = document.querySelector(selector); + const { alertId, projectPath } = domEl.dataset; + + const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient(), + }); + // eslint-disable-next-line no-new new Vue({ el: selector, + apolloProvider, components: { AlertDetails, }, render(createElement) { - return createElement('alert-details', {}); + return createElement('alert-details', { + props: { + alertId, + projectPath, + }, + }); }, }); }; diff --git a/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql b/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql new file mode 100644 index 00000000000..81e95500e05 --- /dev/null +++ b/app/assets/javascripts/alert_management/graphql/queries/details.query.graphql @@ -0,0 +1,17 @@ +query alertDetails($fullPath: ID!, $alertId: String) { + project(fullPath: $fullPath) { + alertManagementAlerts(iid: $alertId) { + nodes { + iid + endedAt + eventCount + monitoringTool + service + severity + startedAt + status + title + } + } + } +} diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index 4e44cb5e6f4..a6185746bb1 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -665,5 +665,25 @@ export function changeCurrentCommit({ dispatch, commit, state }, { commitId }) { return dispatch('fetchDiffFilesMeta'); } +export function moveToNeighboringCommit({ dispatch, state }, { direction }) { + const previousCommitId = state.commit?.prev_commit_id; + const nextCommitId = state.commit?.next_commit_id; + const canMove = { + next: !state.isLoading && nextCommitId, + previous: !state.isLoading && previousCommitId, + }; + let commitId; + + if (direction === 'next' && canMove.next) { + commitId = nextCommitId; + } else if (direction === 'previous' && canMove.previous) { + commitId = previousCommitId; + } + + if (commitId) { + dispatch('changeCurrentCommit', { commitId }); + } +} + // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/helpers/event_hub_factory.js b/app/assets/javascripts/helpers/event_hub_factory.js new file mode 100644 index 00000000000..4bd390c3535 --- /dev/null +++ b/app/assets/javascripts/helpers/event_hub_factory.js @@ -0,0 +1,11 @@ +import mitt from 'mitt'; + +export default () => { + const emitter = mitt(); + + emitter.$on = emitter.on; + emitter.$off = emitter.off; + emitter.$emit = emitter.emit; + + return emitter; +}; diff --git a/app/assets/javascripts/ide/eventhub.js b/app/assets/javascripts/ide/eventhub.js index 0948c2e5352..e31806ad199 100644 --- a/app/assets/javascripts/ide/eventhub.js +++ b/app/assets/javascripts/ide/eventhub.js @@ -1,3 +1,3 @@ -import Vue from 'vue'; +import createEventHub from '~/helpers/event_hub_factory'; -export default new Vue(); +export default createEventHub(); diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue index b8b3a4f44fd..6edcb974670 100644 --- a/app/assets/javascripts/issue_show/components/app.vue +++ b/app/assets/javascripts/issue_show/components/app.vue @@ -329,7 +329,7 @@ export default { }, deleteIssuable(payload) { - this.service + return this.service .deleteIssuable(payload) .then(res => res.data) .then(data => { @@ -340,7 +340,7 @@ export default { }) .catch(() => { createFlash( - sprintf(s__('Error deleting %{issuableType}'), { issuableType: this.issuableType }), + sprintf(s__('Error deleting %{issuableType}'), { issuableType: this.issuableType }), ); }); }, @@ -365,7 +365,12 @@ export default { :issuable-type="issuableType" /> - <recaptcha-modal v-show="showRecaptcha" :html="recaptchaHTML" @close="closeRecaptchaModal" /> + <recaptcha-modal + v-show="showRecaptcha" + ref="recaptchaModal" + :html="recaptchaHTML" + @close="closeRecaptchaModal" + /> </div> <div v-else> <title-component diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js index 8d3b87d5cc0..b6c41ffa7ab 100644 --- a/app/assets/javascripts/lib/graphql.js +++ b/app/assets/javascripts/lib/graphql.js @@ -33,6 +33,7 @@ export default (resolvers = {}, config = {}) => { }; return new ApolloClient({ + typeDefs: config.typeDefs, link: ApolloLink.split( operation => operation.getContext().hasUpload || operation.getContext().isSingleRequest, createUploadLink(httpOptions), diff --git a/app/assets/javascripts/mr_notes/init_notes.js b/app/assets/javascripts/mr_notes/init_notes.js index 2580f8e86b1..ec9c800b7a2 100644 --- a/app/assets/javascripts/mr_notes/init_notes.js +++ b/app/assets/javascripts/mr_notes/init_notes.js @@ -15,19 +15,6 @@ export default () => { notesApp, }, store, - data() { - const notesDataset = document.getElementById('js-vue-mr-discussions').dataset; - const noteableData = JSON.parse(notesDataset.noteableData); - noteableData.noteableType = notesDataset.noteableType; - noteableData.targetType = notesDataset.targetType; - - return { - noteableData, - currentUserData: JSON.parse(notesDataset.currentUserData), - notesData: JSON.parse(notesDataset.notesData), - helpPagePath: notesDataset.helpPagePath, - }; - }, computed: { ...mapGetters(['discussionTabCounter']), ...mapState({ @@ -67,6 +54,19 @@ export default () => { updateDiscussionTabCounter() { this.notesCountBadge.text(this.discussionTabCounter); }, + dataset() { + const data = this.$el.dataset; + const noteableData = JSON.parse(data.noteableData); + noteableData.noteableType = data.noteableType; + noteableData.targetType = data.targetType; + + return { + noteableData, + notesData: JSON.parse(data.notesData), + userData: JSON.parse(data.currentUserData), + helpPagePath: data.helpPagePath, + }; + }, }, render(createElement) { // NOTE: Even though `discussionKeyboardNavigator` is added to the `notes-app`, @@ -76,11 +76,8 @@ export default () => { return createElement(discussionKeyboardNavigator, [ createElement('notes-app', { props: { - noteableData: this.noteableData, - notesData: this.notesData, - userData: this.currentUserData, + ...this.dataset(), shouldShow: this.isShowTabActive, - helpPagePath: this.helpPagePath, }, }), ]); diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js index 8f9e2359e0d..6fd3cee5340 100644 --- a/app/assets/javascripts/notes/index.js +++ b/app/assets/javascripts/notes/index.js @@ -14,38 +14,36 @@ document.addEventListener('DOMContentLoaded', () => { notesApp, }, store, - data() { - const notesDataset = document.getElementById('js-vue-notes').dataset; - const parsedUserData = JSON.parse(notesDataset.currentUserData); - const noteableData = JSON.parse(notesDataset.noteableData); - let currentUserData = {}; + methods: { + setData() { + const notesDataset = this.$el.dataset; + const parsedUserData = JSON.parse(notesDataset.currentUserData); + const noteableData = JSON.parse(notesDataset.noteableData); + let currentUserData = {}; - noteableData.noteableType = notesDataset.noteableType; - noteableData.targetType = notesDataset.targetType; + noteableData.noteableType = notesDataset.noteableType; + noteableData.targetType = notesDataset.targetType; - if (parsedUserData) { - currentUserData = { - id: parsedUserData.id, - name: parsedUserData.name, - username: parsedUserData.username, - avatar_url: parsedUserData.avatar_path || parsedUserData.avatar_url, - path: parsedUserData.path, - }; - } + if (parsedUserData) { + currentUserData = { + id: parsedUserData.id, + name: parsedUserData.name, + username: parsedUserData.username, + avatar_url: parsedUserData.avatar_path || parsedUserData.avatar_url, + path: parsedUserData.path, + }; + } - return { - noteableData, - currentUserData, - notesData: JSON.parse(notesDataset.notesData), - }; + return { + noteableData, + userData: currentUserData, + notesData: JSON.parse(notesDataset.notesData), + }; + }, }, render(createElement) { return createElement('notes-app', { - props: { - noteableData: this.noteableData, - notesData: this.notesData, - userData: this.currentUserData, - }, + props: { ...this.setData() }, }); }, }); diff --git a/app/assets/javascripts/static_site_editor/graphql/index.js b/app/assets/javascripts/static_site_editor/graphql/index.js new file mode 100644 index 00000000000..129e75b5bf6 --- /dev/null +++ b/app/assets/javascripts/static_site_editor/graphql/index.js @@ -0,0 +1,25 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import typeDefs from './typedefs.graphql'; + +Vue.use(VueApollo); + +const createApolloProvider = data => { + const defaultClient = createDefaultClient( + {}, + { + typeDefs, + }, + ); + + defaultClient.cache.writeData({ + data, + }); + + return new VueApollo({ + defaultClient, + }); +}; + +export default createApolloProvider; diff --git a/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql b/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql new file mode 100644 index 00000000000..efff746a3a9 --- /dev/null +++ b/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql @@ -0,0 +1,7 @@ +extend type Query { + isSupportedContent: Boolean! + projectId: String! + returnUrl: String + sourcePath: String! + username: String! +} diff --git a/app/assets/javascripts/static_site_editor/index.js b/app/assets/javascripts/static_site_editor/index.js index b53d461f5a9..01b01762391 100644 --- a/app/assets/javascripts/static_site_editor/index.js +++ b/app/assets/javascripts/static_site_editor/index.js @@ -3,9 +3,12 @@ import { parseBoolean } from '~/lib/utils/common_utils'; import App from './components/app.vue'; import createStore from './store'; import createRouter from './router'; +import createApolloProvider from './graphql'; const initStaticSiteEditor = el => { - const { isSupportedContent, projectId, path: sourcePath, returnUrl, baseUrl } = el.dataset; + const { isSupportedContent, projectId, path: sourcePath, baseUrl } = el.dataset; + const { current_username: username } = window.gon; + const returnUrl = el.dataset.returnUrl || null; const store = createStore({ initialState: { @@ -13,15 +16,23 @@ const initStaticSiteEditor = el => { projectId, returnUrl, sourcePath, - username: window.gon.current_username, + username, }, }); const router = createRouter(baseUrl); + const apolloProvider = createApolloProvider({ + isSupportedContent: parseBoolean(isSupportedContent), + projectId, + returnUrl, + sourcePath, + username, + }); return new Vue({ el, store, router, + apolloProvider, components: { App, }, diff --git a/app/assets/javascripts/static_site_editor/pages/home.vue b/app/assets/javascripts/static_site_editor/pages/home.vue index 3de4a4a27cf..8a9fff47623 100644 --- a/app/assets/javascripts/static_site_editor/pages/home.vue +++ b/app/assets/javascripts/static_site_editor/pages/home.vue @@ -2,6 +2,8 @@ import { mapState, mapGetters, mapActions } from 'vuex'; import { GlSkeletonLoader } from '@gitlab/ui'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; +import RichContentEditor from '~/vue_shared/components/rich_content_editor/rich_content_editor.vue'; import EditArea from '../components/edit_area.vue'; import EditHeader from '../components/edit_header.vue'; import SavedChangesMessage from '../components/saved_changes_message.vue'; @@ -11,6 +13,7 @@ import SubmitChangesError from '../components/submit_changes_error.vue'; export default { components: { + RichContentEditor, EditArea, EditHeader, InvalidContentMessage, @@ -19,6 +22,7 @@ export default { PublishToolbar, SubmitChangesError, }, + mixins: [glFeatureFlagsMixin()], computed: { ...mapState([ 'content', @@ -76,7 +80,14 @@ export default { @dismiss="dismissSubmitChangesError" /> <edit-header class="w-75 align-self-center py-2" :title="title" /> + <rich-content-editor + v-if="glFeatures.richContentEditor" + class="w-75 gl-align-self-center" + :value="content" + @input="setContent" + /> <edit-area + v-else class="w-75 h-100 shadow-none align-self-center" :value="content" @input="setContent" diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js index 01c5329b4d7..3e8f3dd548f 100644 --- a/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/constants.js @@ -23,3 +23,5 @@ export const EDITOR_OPTIONS = { export const EDITOR_TYPES = { wysiwyg: 'wysiwyg', }; + +export const EDITOR_HEIGHT = '100%'; diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue b/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue index e02d8661ceb..0b10424ad1e 100644 --- a/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/rich_content_editor.vue @@ -2,7 +2,7 @@ import 'codemirror/lib/codemirror.css'; import '@toast-ui/editor/dist/toastui-editor.css'; -import { EDITOR_OPTIONS, EDITOR_TYPES } from './constants'; +import { EDITOR_OPTIONS, EDITOR_TYPES, EDITOR_HEIGHT } from './constants'; export default { components: { @@ -16,6 +16,26 @@ export default { type: String, required: true, }, + options: { + type: Object, + required: false, + default: () => EDITOR_OPTIONS, + }, + initialEditType: { + type: String, + required: false, + default: EDITOR_TYPES.wysiwyg, + }, + height: { + type: String, + required: false, + default: EDITOR_HEIGHT, + }, + }, + computed: { + editorOptions() { + return { ...EDITOR_OPTIONS, ...this.options }; + }, }, methods: { onContentChanged() { @@ -25,16 +45,15 @@ export default { return this.$refs.editor.invoke('getMarkdown'); }, }, - editorOptions: EDITOR_OPTIONS, - initialEditType: EDITOR_TYPES.wysiwyg, }; </script> <template> <toast-editor ref="editor" - :initial-edit-type="$options.initialEditType" :initial-value="value" - :options="$options.editorOptions" + :options="editorOptions" + :initial-edit-type="initialEditType" + :height="height" @change="onContentChanged" /> </template> |