Commit 537b7bfa authored by Sean Arnold's avatar Sean Arnold

WIP updating image metric url, urltext

parent 0676662b
......@@ -347,6 +347,25 @@ export default {
return axios.post(metricImagesUrl, formData, options);
},
updateIssueMetricImage({ issueIid, id, imageId, url = null, urlText = null }) {
const metricImagesUrl = Api.buildUrl(this.issueMetricSingleImagePath)
.replace(':id', encodeURIComponent(id))
.replace(':issue_iid', encodeURIComponent(issueIid))
.replace(':image_id', encodeURIComponent(imageId));
// Construct multipart form data
const formData = new FormData();
if (url) {
formData.append('url', url);
}
if (urlText) {
formData.append('url_text', urlText);
}
return axios.put(metricImagesUrl, formData);
},
deleteMetricImage({ issueIid, id, imageId }) {
const individualMetricImageUrl = Api.buildUrl(this.issueMetricSingleImagePath)
.replace(':id', encodeURIComponent(id))
......
<script>
import { GlButton, GlCard, GlIcon, GlLink, GlModal, GlSprintf } from '@gitlab/ui';
import { GlButton, GlFormGroup, GlFormInput, GlCard, GlIcon, GlLink, GlModal, GlSprintf } from '@gitlab/ui';
import { mapActions } from 'vuex';
import { __, s__ } from '~/locale';
......@@ -9,9 +9,13 @@ export default {
modalDescription: s__('Incident|Are you sure you wish to delete this image?'),
modalCancel: __('Cancel'),
modalTitle: s__('Incident|Deleting %{filename}'),
editModalUpdate: __('Update'),
editModalTitle: s__('Incident|Editing %{filename}'),
},
components: {
GlButton,
GlFormGroup,
GlFormInput,
GlCard,
GlIcon,
GlLink,
......@@ -48,10 +52,13 @@ export default {
isCollapsed: false,
isDeleting: false,
modalVisible: false,
editModalVisible: false,
modalUrl: this.url,
modalUrlText: this.urlText,
};
},
computed: {
actionPrimaryProps() {
deleteActionPrimaryProps() {
return {
text: this.$options.i18n.modalDelete,
attributes: {
......@@ -62,6 +69,17 @@ export default {
},
};
},
updateActionPrimaryProps() {
return {
text: this.$options.i18n.editModalUpdate,
attributes: {
loading: this.isDeleting,
disabled: this.isDeleting,
category: 'primary',
variant: 'confirm',
},
};
},
arrowIconName() {
return this.isCollapsed ? 'chevron-right' : 'chevron-down';
},
......@@ -75,10 +93,15 @@ export default {
},
},
methods: {
...mapActions(['deleteImage']),
...mapActions(['deleteImage', 'updateImage']),
toggleCollapsed() {
this.isCollapsed = !this.isCollapsed;
},
resetEditFields() {
this.modalUrl = this.url;
this.modalUrlText = this.urlText;
this.editModalVisible = false;
},
async onDelete() {
try {
this.isDeleting = true;
......@@ -88,6 +111,21 @@ export default {
this.modalVisible = false;
}
},
async onUpdate() {
try {
this.isDeleting = true;
await this.updateImage({
imageId: this.id,
url: this.modalUrl,
urlText: this.modalUrlText
});
} finally {
this.isDeleting = false;
this.modalUrl = '';
this.modalUrlText = '';
this.editModalVisible = false;
}
},
},
};
</script>
......@@ -103,10 +141,10 @@ export default {
modal-id="delete-metric-modal"
size="sm"
:visible="modalVisible"
:action-primary="actionPrimaryProps"
:action-primary="deleteActionPrimaryProps"
:action-cancel="{ text: $options.i18n.modalCancel }"
@primary.prevent="onDelete"
@hidden="modalVisible = false"
@hidden="resetEditFields"
>
<template #modal-title>
<gl-sprintf :message="$options.i18n.modalTitle">
......@@ -117,6 +155,37 @@ export default {
</template>
<p>{{ $options.i18n.modalDescription }}</p>
</gl-modal>
<gl-modal
modal-id="edit-metric-modal"
size="sm"
:action-primary="updateActionPrimaryProps"
:action-cancel="{ text: $options.i18n.modalCancel }"
:visible="editModalVisible"
@hidden="resetEditFields"
@primary.prevent="onUpdate"
>
<template #modal-title>
<gl-sprintf :message="$options.i18n.editModalTitle">
<template #filename>
{{ filename }}
</template>
</gl-sprintf>
</template>
<gl-form-group :label="__('Text (optional)')" label-for="upload-text-input">
<gl-form-input id="upload-text-input" v-model="modalUrlText" />
</gl-form-group>
<gl-form-group
:label="__('Link (optional)')"
label-for="upload-url-input"
:description="s__('Incidents|Must start with http or https')"
>
<gl-form-input id="upload-url-input" v-model="modalUrl" />
</gl-form-group>
</gl-modal>
<template #header>
<div class="gl-w-full gl-display-flex gl-flex-direction-row gl-justify-content-space-between">
<div class="gl-display-flex gl-flex-direction-row gl-align-items-center gl-w-full">
......@@ -134,14 +203,23 @@ export default {
{{ urlText != null ? urlText : filename }}
</gl-link>
<span v-else>{{ urlText != null ? urlText : filename }}</span>
<gl-button
v-if="canUpdate"
class="gl-ml-auto"
icon="remove"
:aria-label="__('Delete')"
data-testid="delete-button"
@click="modalVisible = true"
/>
<div class='gl-ml-auto'>
<gl-button
v-if="canUpdate"
class="gl-mr-2"
icon="pencil"
:aria-label="__('Edit')"
data-testid="edit-button"
@click="editModalVisible = true"
/>
<gl-button
v-if="canUpdate"
icon="remove"
:aria-label="__('Delete')"
data-testid="delete-button"
@click="modalVisible = true"
/>
</div>
</div>
</div>
</template>
......
......@@ -11,6 +11,11 @@ export const uploadMetricImage = async (payload) => {
return convertObjectPropsToCamelCase(response.data);
};
export const updateMetricImage = async (payload) => {
const response = await Api.updateIssueMetricImage(payload);
return convertObjectPropsToCamelCase(response.data);
};
export const deleteMetricImage = async (payload) => {
const response = await Api.deleteMetricImage(payload);
return convertObjectPropsToCamelCase(response.data);
......
import createFlash from '~/flash';
import { s__ } from '~/locale';
import { deleteMetricImage, getMetricImages, uploadMetricImage } from '../service';
import { deleteMetricImage, getMetricImages, uploadMetricImage, updateMetricImage } from '../service';
import * as types from './mutation_types';
export const fetchMetricImages = async ({ state, commit }) => {
......@@ -37,6 +37,26 @@ export const uploadImage = async ({ state, commit }, { files, url, urlText }) =>
}
};
export const updateImage = async ({ state, commit }, { imageId, url, urlText }) => {
commit(types.REQUEST_METRIC_UPLOAD);
const { issueIid, projectId } = state;
try {
const response = await updateMetricImage({
issueIid,
id: projectId,
imageId,
url,
urlText,
});
commit(types.RECEIVE_METRIC_UPLOAD_SUCCESS, response);
} catch (error) {
commit(types.RECEIVE_METRIC_UPLOAD_ERROR);
createFlash({ message: s__('Incidents|There was an issue updating your image.') });
}
};
export const deleteImage = async ({ state, commit }, imageId) => {
const { issueIid, projectId } = state;
......
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