Skip to content
Snippets Groups Projects

Allow urlText to be saved on metric images

Merged Sean Arnold requested to merge 346171-frontend-for-metric-image-url-text into master
All threads resolved!
<script>
import { GlButton, GlCard, GlIcon, GlLink, GlModal, GlSprintf } from '@gitlab/ui';
import {
GlButton,
GlFormGroup,
GlFormInput,
GlCard,
GlIcon,
GlLink,
GlModal,
GlSprintf,
GlTooltipDirective,
} from '@gitlab/ui';
import { mapActions } from 'vuex';
import { __, s__ } from '~/locale';
@@ -9,15 +19,24 @@ 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}'),
editIconTitle: s__('Incident|Edit image text or link'),
deleteIconTitle: s__('Incident|Delete image'),
},
components: {
GlButton,
GlFormGroup,
GlFormInput,
GlCard,
GlIcon,
GlLink,
GlModal,
GlSprintf,
},
directives: {
GlTooltip: GlTooltipDirective,
},
inject: ['canUpdate'],
props: {
id: {
@@ -37,16 +56,25 @@ export default {
required: false,
default: null,
},
urlText: {
type: String,
required: false,
default: null,
},
},
data() {
return {
isCollapsed: false,
isDeleting: false,
isUpdating: false,
modalVisible: false,
editModalVisible: false,
modalUrl: this.url,
modalUrlText: this.urlText,
};
},
computed: {
actionPrimaryProps() {
deleteActionPrimaryProps() {
return {
text: this.$options.i18n.modalDelete,
attributes: {
@@ -57,6 +85,17 @@ export default {
},
};
},
updateActionPrimaryProps() {
return {
text: this.$options.i18n.editModalUpdate,
attributes: {
loading: this.isUpdating,
disabled: this.isUpdating,
category: 'primary',
variant: 'confirm',
},
};
},
arrowIconName() {
return this.isCollapsed ? 'chevron-right' : 'chevron-down';
},
@@ -70,10 +109,16 @@ 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;
this.modalVisible = false;
},
async onDelete() {
try {
this.isDeleting = true;
@@ -83,6 +128,21 @@ export default {
this.modalVisible = false;
}
},
async onUpdate() {
try {
this.isUpdating = true;
await this.updateImage({
imageId: this.id,
url: this.modalUrl,
urlText: this.modalUrlText,
});
} finally {
this.isUpdating = false;
this.modalUrl = '';
this.modalUrlText = '';
this.editModalVisible = false;
}
},
},
};
</script>
@@ -98,10 +158,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">
@@ -112,6 +172,46 @@ 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"
data-testid="metric-image-edit-modal"
@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"
data-testid="metric-image-text-field"
/>
</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"
data-testid="metric-image-url-field"
/>
</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">
@@ -125,18 +225,33 @@ export default {
>
<gl-icon class="gl-mr-2" :name="arrowIconName" />
</gl-button>
<gl-link v-if="url" :href="url">
{{ filename }}
<gl-link v-if="url" :href="url" target="_blank" data-testid="metric-image-label-span">
{{ urlText == null || urlText == '' ? filename : urlText }}
<gl-icon name="external-link" class="gl-vertical-align-middle" />
</gl-link>
<span v-else>{{ filename }}</span>
<gl-button
v-if="canUpdate"
class="gl-ml-auto"
icon="remove"
:aria-label="__('Delete')"
data-testid="delete-button"
@click="modalVisible = true"
/>
<span v-else data-testid="metric-image-label-span">{{
urlText == null || urlText == '' ? filename : urlText
}}</span>
<div class="gl-ml-auto btn-group">
<gl-button
v-if="canUpdate"
v-gl-tooltip.bottom
icon="pencil"
:aria-label="__('Edit')"
:title="$options.i18n.editIconTitle"
data-testid="edit-button"
@click="editModalVisible = true"
/>
<gl-button
v-if="canUpdate"
v-gl-tooltip.bottom
icon="remove"
:aria-label="__('Delete')"
:title="$options.i18n.deleteIconTitle"
data-testid="delete-button"
@click="modalVisible = true"
/>
</div>
</div>
</div>
</template>
Loading