diff options
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/javascripts/api.js | 14 | ||||
-rw-r--r-- | app/assets/javascripts/ref/constants.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/ref/stores/actions.js | 65 | ||||
-rw-r--r-- | app/assets/javascripts/ref/stores/getters.js | 5 | ||||
-rw-r--r-- | app/assets/javascripts/ref/stores/index.js | 16 | ||||
-rw-r--r-- | app/assets/javascripts/ref/stores/mutation_types.js | 16 | ||||
-rw-r--r-- | app/assets/javascripts/ref/stores/mutations.js | 91 | ||||
-rw-r--r-- | app/assets/javascripts/ref/stores/state.js | 24 |
8 files changed, 233 insertions, 2 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 460611356c0..b89b09521ee 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -37,7 +37,9 @@ const Api = { userStatusPath: '/api/:version/users/:id/status', userProjectsPath: '/api/:version/users/:id/projects', userPostStatusPath: '/api/:version/user/status', - commitPath: '/api/:version/projects/:id/repository/commits', + commitPath: '/api/:version/projects/:id/repository/commits/:sha', + commitsPath: '/api/:version/projects/:id/repository/commits', + applySuggestionPath: '/api/:version/suggestions/:id/apply', applySuggestionBatchPath: '/api/:version/suggestions/batch_apply', commitPipelinesPath: '/:project_id/commit/:sha/pipelines', @@ -319,9 +321,17 @@ const Api = { .catch(() => flash(__('Something went wrong while fetching projects'))); }, + commit(id, sha, params = {}) { + const url = Api.buildUrl(this.commitPath) + .replace(':id', encodeURIComponent(id)) + .replace(':sha', encodeURIComponent(sha)); + + return axios.get(url, { params }); + }, + commitMultiple(id, data) { // see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions - const url = Api.buildUrl(Api.commitPath).replace(':id', encodeURIComponent(id)); + const url = Api.buildUrl(Api.commitsPath).replace(':id', encodeURIComponent(id)); return axios.post(url, JSON.stringify(data), { headers: { 'Content-Type': 'application/json; charset=utf-8', diff --git a/app/assets/javascripts/ref/constants.js b/app/assets/javascripts/ref/constants.js new file mode 100644 index 00000000000..524ff2380c0 --- /dev/null +++ b/app/assets/javascripts/ref/constants.js @@ -0,0 +1,4 @@ +// This eslint-disable can be removed once a second +// value is added to this file. +/* eslint-disable import/prefer-default-export */ +export const X_TOTAL_HEADER = 'x-total'; diff --git a/app/assets/javascripts/ref/stores/actions.js b/app/assets/javascripts/ref/stores/actions.js new file mode 100644 index 00000000000..8fcc99cef38 --- /dev/null +++ b/app/assets/javascripts/ref/stores/actions.js @@ -0,0 +1,65 @@ +import Api from '~/api'; +import * as types from './mutation_types'; + +export const setProjectId = ({ commit }, projectId) => commit(types.SET_PROJECT_ID, projectId); + +export const setSelectedRef = ({ commit }, selectedRef) => + commit(types.SET_SELECTED_REF, selectedRef); + +export const search = ({ dispatch, commit }, query) => { + commit(types.SET_QUERY, query); + + dispatch('searchBranches'); + dispatch('searchTags'); + dispatch('searchCommits'); +}; + +export const searchBranches = ({ commit, state }) => { + commit(types.REQUEST_START); + + Api.branches(state.projectId, state.query) + .then(response => { + commit(types.RECEIVE_BRANCHES_SUCCESS, response); + }) + .catch(error => { + commit(types.RECEIVE_BRANCHES_ERROR, error); + }) + .finally(() => { + commit(types.REQUEST_FINISH); + }); +}; + +export const searchTags = ({ commit, state }) => { + commit(types.REQUEST_START); + + Api.tags(state.projectId, state.query) + .then(response => { + commit(types.RECEIVE_TAGS_SUCCESS, response); + }) + .catch(error => { + commit(types.RECEIVE_TAGS_ERROR, error); + }) + .finally(() => { + commit(types.REQUEST_FINISH); + }); +}; + +export const searchCommits = ({ commit, state, getters }) => { + // Only query the Commit API if the search query looks like a commit SHA + if (getters.isQueryPossiblyASha) { + commit(types.REQUEST_START); + + Api.commit(state.projectId, state.query) + .then(response => { + commit(types.RECEIVE_COMMITS_SUCCESS, response); + }) + .catch(error => { + commit(types.RECEIVE_COMMITS_ERROR, error); + }) + .finally(() => { + commit(types.REQUEST_FINISH); + }); + } else { + commit(types.RESET_COMMIT_MATCHES); + } +}; diff --git a/app/assets/javascripts/ref/stores/getters.js b/app/assets/javascripts/ref/stores/getters.js new file mode 100644 index 00000000000..02d4ae8ff91 --- /dev/null +++ b/app/assets/javascripts/ref/stores/getters.js @@ -0,0 +1,5 @@ +/** Returns `true` if the query string looks like it could be a commit SHA */ +export const isQueryPossiblyASha = ({ query }) => /^[0-9a-f]{4,40}$/i.test(query); + +/** Returns `true` if there is at least one in-progress request */ +export const isLoading = ({ requestCount }) => requestCount > 0; diff --git a/app/assets/javascripts/ref/stores/index.js b/app/assets/javascripts/ref/stores/index.js new file mode 100644 index 00000000000..2bebffc19ab --- /dev/null +++ b/app/assets/javascripts/ref/stores/index.js @@ -0,0 +1,16 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import * as actions from './actions'; +import * as getters from './getters'; +import mutations from './mutations'; +import createState from './state'; + +Vue.use(Vuex); + +export default () => + new Vuex.Store({ + actions, + getters, + mutations, + state: createState(), + }); diff --git a/app/assets/javascripts/ref/stores/mutation_types.js b/app/assets/javascripts/ref/stores/mutation_types.js new file mode 100644 index 00000000000..9f6195f5f3f --- /dev/null +++ b/app/assets/javascripts/ref/stores/mutation_types.js @@ -0,0 +1,16 @@ +export const SET_PROJECT_ID = 'SET_PROJECT_ID'; +export const SET_SELECTED_REF = 'SET_SELECTED_REF'; +export const SET_QUERY = 'SET_QUERY'; + +export const REQUEST_START = 'REQUEST_START'; +export const REQUEST_FINISH = 'REQUEST_FINISH'; + +export const RECEIVE_BRANCHES_SUCCESS = 'RECEIVE_BRANCHES_SUCCESS'; +export const RECEIVE_BRANCHES_ERROR = 'RECEIVE_BRANCHES_ERROR'; + +export const RECEIVE_TAGS_SUCCESS = 'RECEIVE_TAGS_SUCCESS'; +export const RECEIVE_TAGS_ERROR = 'RECEIVE_TAGS_ERROR'; + +export const RECEIVE_COMMITS_SUCCESS = 'RECEIVE_COMMITS_SUCCESS'; +export const RECEIVE_COMMITS_ERROR = 'RECEIVE_COMMITS_ERROR'; +export const RESET_COMMIT_MATCHES = 'RESET_COMMIT_MATCHES'; diff --git a/app/assets/javascripts/ref/stores/mutations.js b/app/assets/javascripts/ref/stores/mutations.js new file mode 100644 index 00000000000..73f9d7ee487 --- /dev/null +++ b/app/assets/javascripts/ref/stores/mutations.js @@ -0,0 +1,91 @@ +import * as types from './mutation_types'; +import { X_TOTAL_HEADER } from '../constants'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import httpStatusCodes from '~/lib/utils/http_status'; + +export default { + [types.SET_PROJECT_ID](state, projectId) { + state.projectId = projectId; + }, + [types.SET_SELECTED_REF](state, selectedRef) { + state.selectedRef = selectedRef; + }, + [types.SET_QUERY](state, query) { + state.query = query; + }, + + [types.REQUEST_START](state) { + state.requestCount += 1; + }, + [types.REQUEST_FINISH](state) { + state.requestCount -= 1; + }, + + [types.RECEIVE_BRANCHES_SUCCESS](state, response) { + state.matches.branches = { + list: convertObjectPropsToCamelCase(response.data).map(b => ({ + name: b.name, + default: b.default, + })), + totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10), + error: null, + }; + }, + [types.RECEIVE_BRANCHES_ERROR](state, error) { + state.matches.branches = { + list: [], + totalCount: 0, + error, + }; + }, + + [types.RECEIVE_TAGS_SUCCESS](state, response) { + state.matches.tags = { + list: convertObjectPropsToCamelCase(response.data).map(b => ({ + name: b.name, + })), + totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10), + error: null, + }; + }, + [types.RECEIVE_TAGS_ERROR](state, error) { + state.matches.tags = { + list: [], + totalCount: 0, + error, + }; + }, + + [types.RECEIVE_COMMITS_SUCCESS](state, response) { + const commit = convertObjectPropsToCamelCase(response.data); + + state.matches.commits = { + list: [ + { + name: commit.shortId, + value: commit.id, + subtitle: commit.title, + }, + ], + totalCount: 1, + error: null, + }; + }, + [types.RECEIVE_COMMITS_ERROR](state, error) { + state.matches.commits = { + list: [], + totalCount: 0, + + // 404's are expected when the search query doesn't match any commits + // and shouldn't be treated as an actual error + error: error.response?.status !== httpStatusCodes.NOT_FOUND ? error : null, + }; + }, + [types.RESET_COMMIT_MATCHES](state) { + state.matches.commits = { + list: [], + totalCount: 0, + error: null, + }; + }, +}; diff --git a/app/assets/javascripts/ref/stores/state.js b/app/assets/javascripts/ref/stores/state.js new file mode 100644 index 00000000000..65b9d6449d7 --- /dev/null +++ b/app/assets/javascripts/ref/stores/state.js @@ -0,0 +1,24 @@ +export default () => ({ + projectId: null, + + query: '', + matches: { + branches: { + list: [], + totalCount: 0, + error: null, + }, + tags: { + list: [], + totalCount: 0, + error: null, + }, + commits: { + list: [], + totalCount: 0, + error: null, + }, + }, + selectedRef: null, + requestCount: 0, +}); |