summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/admin/broadcast_messages/components/base.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/admin/broadcast_messages/components/base.vue')
-rw-r--r--app/assets/javascripts/admin/broadcast_messages/components/base.vue112
1 files changed, 112 insertions, 0 deletions
diff --git a/app/assets/javascripts/admin/broadcast_messages/components/base.vue b/app/assets/javascripts/admin/broadcast_messages/components/base.vue
new file mode 100644
index 00000000000..b7bafe46327
--- /dev/null
+++ b/app/assets/javascripts/admin/broadcast_messages/components/base.vue
@@ -0,0 +1,112 @@
+<script>
+import { GlPagination } from '@gitlab/ui';
+import { redirectTo } from '~/lib/utils/url_utility';
+import { buildUrlWithCurrentLocation } from '~/lib/utils/common_utils';
+import { createAlert, VARIANT_DANGER } from '~/flash';
+import { s__ } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+import MessagesTable from './messages_table.vue';
+
+const PER_PAGE = 20;
+
+export default {
+ name: 'BroadcastMessagesBase',
+ components: {
+ GlPagination,
+ MessagesTable,
+ },
+
+ props: {
+ page: {
+ type: Number,
+ required: true,
+ },
+ messagesCount: {
+ type: Number,
+ required: true,
+ },
+ messages: {
+ type: Array,
+ required: true,
+ },
+ },
+
+ i18n: {
+ deleteError: s__(
+ 'BroadcastMessages|There was an issue deleting this message, please try again later.',
+ ),
+ },
+
+ data() {
+ return {
+ currentPage: this.page,
+ totalMessages: this.messagesCount,
+ visibleMessages: this.messages.map((message) => ({
+ ...message,
+ disable_delete: false,
+ })),
+ };
+ },
+
+ computed: {
+ hasVisibleMessages() {
+ return this.visibleMessages.length > 0;
+ },
+ },
+
+ watch: {
+ totalMessages(newVal, oldVal) {
+ // Pagination controls disappear when there is only
+ // one page worth of messages. Since we're relying on static data,
+ // this could hide messages on the next page, or leave the user
+ // stranded on page 2 when deleting the last message.
+ // Force a page reload to avoid this edge case.
+ if (newVal === PER_PAGE && oldVal === PER_PAGE + 1) {
+ redirectTo(this.buildPageUrl(1));
+ }
+ },
+ },
+
+ methods: {
+ buildPageUrl(newPage) {
+ return buildUrlWithCurrentLocation(`?page=${newPage}`);
+ },
+
+ async deleteMessage(messageId) {
+ const index = this.visibleMessages.findIndex((m) => m.id === messageId);
+ if (!index === -1) return;
+
+ const message = this.visibleMessages[index];
+ this.$set(this.visibleMessages, index, { ...message, disable_delete: true });
+
+ try {
+ await axios.delete(message.delete_path);
+ } catch (e) {
+ this.$set(this.visibleMessages, index, { ...message, disable_delete: false });
+ createAlert({ message: this.$options.i18n.deleteError, variant: VARIANT_DANGER });
+ return;
+ }
+
+ // Remove the message from the table
+ this.visibleMessages = this.visibleMessages.filter((m) => m.id !== messageId);
+ this.totalMessages -= 1;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <messages-table
+ v-if="hasVisibleMessages"
+ :messages="visibleMessages"
+ @delete-message="deleteMessage"
+ />
+ <gl-pagination
+ v-model="currentPage"
+ :total-items="totalMessages"
+ :link-gen="buildPageUrl"
+ align="center"
+ />
+ </div>
+</template>