Commit 293a0460 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Add api request for creating value streams

Submit a post request to create a new
value stream.

Clear the form after success

Replace breakpoint check with utility css
parent a7c7b257
<script> <script>
import { GlEmptyState, GlLoadingIcon } from '@gitlab/ui'; import { GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import { sprintf, __ } from '~/locale';
import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants'; import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
import { PROJECTS_PER_PAGE, STAGE_ACTIONS } from '../constants'; import { PROJECTS_PER_PAGE, STAGE_ACTIONS } from '../constants';
import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue'; import GroupsDropdownFilter from '../../shared/components/groups_dropdown_filter.vue';
...@@ -121,9 +119,6 @@ export default { ...@@ -121,9 +119,6 @@ export default {
isLoadingTypeOfWork() { isLoadingTypeOfWork() {
return this.isLoadingTasksByTypeChartTopLabels || this.isLoadingTasksByTypeChart; return this.isLoadingTasksByTypeChartTopLabels || this.isLoadingTasksByTypeChart;
}, },
isXSBreakpoint() {
return bp.getBreakpointSize() === 'xs';
},
hasDateRangeSet() { hasDateRangeSet() {
return this.startDate && this.endDate; return this.startDate && this.endDate;
}, },
...@@ -200,10 +195,6 @@ export default { ...@@ -200,10 +195,6 @@ export default {
onStageReorder(data) { onStageReorder(data) {
this.reorderStage(data); this.reorderStage(data);
}, },
onCreateValueStream({ name }) {
// stub - this will eventually trigger a vuex action
this.$toast.show(sprintf(__("'%{name}' Value Stream created"), { name }));
},
}, },
multiProjectSelect: true, multiProjectSelect: true,
dateOptions: [7, 30, 90], dateOptions: [7, 30, 90],
...@@ -228,12 +219,7 @@ export default { ...@@ -228,12 +219,7 @@ export default {
<h3>{{ __('Value Stream Analytics') }}</h3> <h3>{{ __('Value Stream Analytics') }}</h3>
<value-stream-select <value-stream-select
v-if="shouldDisplayCreateMultipleValueStreams" v-if="shouldDisplayCreateMultipleValueStreams"
class="gl-align-self-center" class="gl-align-self-start gl-sm-align-self-start gl-mt-0 gl-sm-mt-5"
:class="{
'gl-w-full': isXSBreakpoint,
'gl-mt-5': !isXSBreakpoint,
}"
@create="onCreateValueStream"
/> />
</div> </div>
<div class="mw-100"> <div class="mw-100">
......
<script> <script>
import { GlButton, GlForm, GlFormInput, GlModal, GlModalDirective } from '@gitlab/ui'; import { GlButton, GlForm, GlFormInput, GlModal, GlModalDirective } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
import { sprintf, __ } from '~/locale';
export default { export default {
components: { components: {
...@@ -11,16 +13,35 @@ export default { ...@@ -11,16 +13,35 @@ export default {
directives: { directives: {
GlModalDirective, GlModalDirective,
}, },
props: {
isLoading: {
type: Boolean,
required: false,
default: false,
},
},
data() { data() {
return { return {
name: '', name: '',
}; };
}, },
computed: { computed: {
...mapState({ isCreatingValueStream: 'isLoading' }),
isValid() { isValid() {
return Boolean(this.name.length); return Boolean(this.name.length);
}, },
}, },
methods: {
...mapActions(['createValueStream']),
onSubmit() {
const { name } = this;
return this.createValueStream({ name }).then(() => {
this.$refs.modal.hide();
this.$toast.show(sprintf(__("'%{name}' Value Stream created"), { name }));
this.name = '';
});
},
},
}; };
</script> </script>
<template> <template>
...@@ -29,6 +50,7 @@ export default { ...@@ -29,6 +50,7 @@ export default {
__('Create new value stream') __('Create new value stream')
}}</gl-button> }}</gl-button>
<gl-modal <gl-modal
ref="modal"
modal-id="create-value-stream-modal" modal-id="create-value-stream-modal"
:title="__('Value Stream Name')" :title="__('Value Stream Name')"
:action-primary="{ :action-primary="{
...@@ -38,10 +60,11 @@ export default { ...@@ -38,10 +60,11 @@ export default {
{ {
disabled: !isValid, disabled: !isValid,
}, },
{ loading: isLoading },
], ],
}" }"
:action-cancel="{ text: __('Cancel') }" :action-cancel="{ text: __('Cancel') }"
@primary="$emit('create', { name })" @primary.prevent="onSubmit"
> >
<gl-form-input id="name" v-model="name" :placeholder="__('Example: My value stream')" /> <gl-form-input id="name" v-model="name" :placeholder="__('Example: My value stream')" />
</gl-modal> </gl-modal>
......
...@@ -295,3 +295,26 @@ export const reorderStage = ({ dispatch, state }, initialData) => { ...@@ -295,3 +295,26 @@ export const reorderStage = ({ dispatch, state }, initialData) => {
dispatch('receiveReorderStageError', { status, responseData }), dispatch('receiveReorderStageError', { status, responseData }),
); );
}; };
export const receiveCreateValueStreamSuccess = ({ commit }) => {
// TODO: fetch / update list of value streams
commit(types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS);
};
export const createValueStream = ({ commit, rootState }, data) => {
const {
selectedGroup: { fullPath },
} = rootState;
commit(types.REQUEST_CREATE_VALUE_STREAM);
return Api.cycleAnalyticsCreateValueStream(fullPath, data)
.then(response => {
const { status, data: responseData } = response;
commit(types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS, { status, data: responseData });
})
.catch(({ response } = {}) => {
const { data: { message, errors } = null } = response;
commit(types.RECEIVE_CREATE_VALUE_STREAM_ERROR, { data, message, errors });
});
};
...@@ -35,3 +35,7 @@ export const INITIALIZE_CYCLE_ANALYTICS_SUCCESS = 'INITIALIZE_CYCLE_ANALYTICS_SU ...@@ -35,3 +35,7 @@ export const INITIALIZE_CYCLE_ANALYTICS_SUCCESS = 'INITIALIZE_CYCLE_ANALYTICS_SU
export const REQUEST_REORDER_STAGE = 'REQUEST_REORDER_STAGE'; export const REQUEST_REORDER_STAGE = 'REQUEST_REORDER_STAGE';
export const RECEIVE_REORDER_STAGE_SUCCESS = 'RECEIVE_REORDER_STAGE_SUCCESS'; export const RECEIVE_REORDER_STAGE_SUCCESS = 'RECEIVE_REORDER_STAGE_SUCCESS';
export const RECEIVE_REORDER_STAGE_ERROR = 'RECEIVE_REORDER_STAGE_ERROR'; export const RECEIVE_REORDER_STAGE_ERROR = 'RECEIVE_REORDER_STAGE_ERROR';
export const REQUEST_CREATE_VALUE_STREAM = 'REQUEST_CREATE_VALUE_STREAM';
export const RECEIVE_CREATE_VALUE_STREAM_SUCCESS = 'RECEIVE_CREATE_VALUE_STREAM_SUCCESS';
export const RECEIVE_CREATE_VALUE_STREAM_ERROR = 'RECEIVE_CREATE_VALUE_STREAM_ERROR';
...@@ -122,4 +122,13 @@ export default { ...@@ -122,4 +122,13 @@ export default {
state.selectedMilestone = selectedMilestone; state.selectedMilestone = selectedMilestone;
state.selectedLabels = selectedLabels; state.selectedLabels = selectedLabels;
}, },
[types.REQUEST_CREATE_VALUE_STREAM](state) {
state.isCreatingValueStream = true;
},
[types.RECEIVE_CREATE_VALUE_STREAM_ERROR](state) {
state.isCreatingValueStream = false;
},
[types.RECEIVE_CREATE_VALUE_STREAM_SUCCESS](state) {
state.isCreatingValueStream = false;
},
}; };
...@@ -23,6 +23,8 @@ export default () => ({ ...@@ -23,6 +23,8 @@ export default () => ({
currentStageEvents: [], currentStageEvents: [],
isCreatingValueStream: false,
stages: [], stages: [],
summary: [], summary: [],
medians: {}, medians: {},
......
...@@ -18,6 +18,7 @@ export default { ...@@ -18,6 +18,7 @@ export default {
cycleAnalyticsSummaryDataPath: '/groups/:id/-/analytics/value_stream_analytics/summary', cycleAnalyticsSummaryDataPath: '/groups/:id/-/analytics/value_stream_analytics/summary',
cycleAnalyticsTimeSummaryDataPath: '/groups/:id/-/analytics/value_stream_analytics/time_summary', cycleAnalyticsTimeSummaryDataPath: '/groups/:id/-/analytics/value_stream_analytics/time_summary',
cycleAnalyticsGroupStagesAndEventsPath: '/groups/:id/-/analytics/value_stream_analytics/stages', cycleAnalyticsGroupStagesAndEventsPath: '/groups/:id/-/analytics/value_stream_analytics/stages',
cycleAnalyticsValueStreamsPath: '/groups/:id/-/analytics/value_stream_analytics/value_streams',
cycleAnalyticsStageEventsPath: cycleAnalyticsStageEventsPath:
'/groups/:id/-/analytics/value_stream_analytics/stages/:stage_id/records', '/groups/:id/-/analytics/value_stream_analytics/stages/:stage_id/records',
cycleAnalyticsStageMedianPath: cycleAnalyticsStageMedianPath:
...@@ -191,6 +192,11 @@ export default { ...@@ -191,6 +192,11 @@ export default {
return axios.post(url, data); return axios.post(url, data);
}, },
cycleAnalyticsCreateValueStream(groupId, data) {
const url = Api.buildUrl(this.cycleAnalyticsValueStreamsPath).replace(':id', groupId);
return axios.post(url, data);
},
cycleAnalyticsStageUrl(stageId, groupId) { cycleAnalyticsStageUrl(stageId, groupId) {
return Api.buildUrl(this.cycleAnalyticsStagePath) return Api.buildUrl(this.cycleAnalyticsStagePath)
.replace(':id', groupId) .replace(':id', groupId)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment