Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/flash.js')
-rw-r--r--app/assets/javascripts/flash.js139
1 files changed, 137 insertions, 2 deletions
diff --git a/app/assets/javascripts/flash.js b/app/assets/javascripts/flash.js
index f0ef55f73eb..d9c2e55cffe 100644
--- a/app/assets/javascripts/flash.js
+++ b/app/assets/javascripts/flash.js
@@ -1,5 +1,8 @@
import * as Sentry from '@sentry/browser';
import { escape } from 'lodash';
+import Vue from 'vue';
+import { GlAlert } from '@gitlab/ui';
+import { __ } from '~/locale';
import { spriteIcon } from './lib/utils/common_utils';
const FLASH_TYPES = {
@@ -9,6 +12,12 @@ const FLASH_TYPES = {
WARNING: 'warning',
};
+const VARIANT_SUCCESS = 'success';
+const VARIANT_WARNING = 'warning';
+const VARIANT_DANGER = 'danger';
+const VARIANT_INFO = 'info';
+const VARIANT_TIP = 'tip';
+
const FLASH_CLOSED_EVENT = 'flashClosed';
const getCloseEl = (flashEl) => {
@@ -68,6 +77,126 @@ const addDismissFlashClickListener = (flashEl, fadeTransition) => {
getCloseEl(flashEl)?.addEventListener('click', () => hideFlash(flashEl, fadeTransition));
};
+/**
+ * Render an alert at the top of the page, or, optionally an
+ * arbitrary existing container.
+ *
+ * This alert is always dismissible.
+ *
+ * Usage:
+ *
+ * 1. Render a new alert
+ *
+ * import { createAlert, ALERT_VARIANTS } from '~/flash';
+ *
+ * createAlert({ message: 'My error message' });
+ * createAlert({ message: 'My warning message', variant: ALERT_VARIANTS.WARNING });
+ *
+ * 2. Dismiss this alert programmatically
+ *
+ * const alert = createAlert({ message: 'Message' });
+ *
+ * // ...
+ *
+ * alert.dismiss();
+ *
+ * 3. Respond to the alert being dismissed
+ *
+ * createAlert({ message: 'Message', onDismiss: () => { ... }});
+ *
+ * @param {Object} options Options to control the flash message
+ * @param {String} options.message Alert message text
+ * @param {String?} options.variant Which GlAlert variant to use, should be VARIANT_SUCCESS, VARIANT_WARNING, VARIANT_DANGER, VARIANT_INFO or VARIANT_TIP. Defaults to VARIANT_DANGER.
+ * @param {Object?} options.parent Reference to parent element under which alert needs to appear. Defaults to `document`.
+ * @param {Function?} options.onDismiss Handler to call when this alert is dismissed.
+ * @param {Object?} options.containerSelector Selector for the container of the alert
+ * @param {Object?} options.primaryButton Object describing primary button of alert
+ * @param {String?} link Href of primary button
+ * @param {String?} text Text of primary button
+ * @param {Function?} clickHandler Handler to call when primary button is clicked on. The click event is sent as an argument.
+ * @param {Object?} options.secondaryButton Object describing secondary button of alert
+ * @param {String?} link Href of secondary button
+ * @param {String?} text Text of secondary button
+ * @param {Function?} clickHandler Handler to call when secondary button is clicked on. The click event is sent as an argument.
+ * @param {Boolean?} options.captureError Whether to send error to Sentry
+ * @param {Object} options.error Error to be captured in Sentry
+ * @returns
+ */
+const createAlert = function createAlert({
+ message,
+ variant = VARIANT_DANGER,
+ parent = document,
+ containerSelector = '.flash-container',
+ primaryButton = null,
+ secondaryButton = null,
+ onDismiss = null,
+ captureError = false,
+ error = null,
+}) {
+ if (captureError && error) Sentry.captureException(error);
+
+ const alertContainer = parent.querySelector(containerSelector);
+ if (!alertContainer) return null;
+
+ const el = document.createElement('div');
+ alertContainer.appendChild(el);
+
+ return new Vue({
+ el,
+ components: {
+ GlAlert,
+ },
+ methods: {
+ /**
+ * Public method to dismiss this alert and removes
+ * this Vue instance.
+ */
+ dismiss() {
+ if (onDismiss) {
+ onDismiss();
+ }
+ this.$destroy();
+ this.$el.parentNode.removeChild(this.$el);
+ },
+ },
+ render(h) {
+ const on = {};
+
+ on.dismiss = () => {
+ this.dismiss();
+ };
+
+ if (primaryButton?.clickHandler) {
+ on.primaryAction = (e) => {
+ primaryButton.clickHandler(e);
+ };
+ }
+ if (secondaryButton?.clickHandler) {
+ on.secondaryAction = (e) => {
+ secondaryButton.clickHandler(e);
+ };
+ }
+
+ return h(
+ GlAlert,
+ {
+ props: {
+ dismissible: true,
+ dismissLabel: __('Dismiss'),
+ variant,
+ primaryButtonLink: primaryButton?.link,
+ primaryButtonText: primaryButton?.text,
+ secondaryButtonLink: secondaryButton?.link,
+ secondaryButtonText: secondaryButton?.text,
+ },
+ on,
+ },
+ message,
+ );
+ },
+ });
+};
+
/*
* Flash banner supports different types of Flash configurations
* along with ability to provide actionConfig which can be used to show
@@ -82,8 +211,8 @@ const addDismissFlashClickListener = (flashEl, fadeTransition) => {
* @param {String} title Title of action
* @param {Function} clickHandler Method to call when action is clicked on
* @param {Boolean} options.fadeTransition Boolean to determine whether to fade the alert out
- * @param {Boolean} options.captureError Boolean to determine whether to send error to sentry
- * @param {Object} options.error Error to be captured in sentry
+ * @param {Boolean} options.captureError Boolean to determine whether to send error to Sentry
+ * @param {Object} options.error Error to be captured in Sentry
*/
const createFlash = function createFlash({
message,
@@ -134,4 +263,10 @@ export {
addDismissFlashClickListener,
FLASH_TYPES,
FLASH_CLOSED_EVENT,
+ createAlert,
+ VARIANT_SUCCESS,
+ VARIANT_WARNING,
+ VARIANT_DANGER,
+ VARIANT_INFO,
+ VARIANT_TIP,
};