feat: Add variables feature (#5602)

* feat: add variables db models and migrations

* feat: variables api endpoints

* feat: add $variables to expressions

* test: fix ActiveWorkflowRunner tests failing

* test: a different fix for the tests broken by $variables

* feat: variables licensing

* fix: could create one extra variable than licensed for

* feat: Add Variables UI page and $vars global property (#5750)

* feat: add support for row slot to datatable

* feat: add variables create, read, update, delete

* feat: add vars autocomplete

* chore: remove alert

* feat: add variables autocomplete for code and expressions

* feat: add tests for variable components

* feat: add variables search and sort

* test: update tests for variables view

* chore: fix test and linting issue

* refactor: review changes

* feat: add variable creation telemetry

* fix: Improve variables listing and disabled case, fix resource sorting (no-changelog) (#5903)

* fix: Improve variables disabled experience and fix sorting

* fix: update action box margin

* test: update tests for variables row and datatable

* fix: Add ee controller to base controller

* fix: variables.ee routes not being added

* feat: add variables validation

* fix: fix vue-fragment bug that breaks everything

* chore: Update lock

* feat: Add variables input validation and permissions (no-changelog) (#5910)

* feat: add input validation

* feat: handle variables view for non-instance-owner users

* test: update variables tests

* fix: fix data-testid pattern

* feat: improve overflow styles

* test: fix variables row snapshot

* feat: update sorting to take newly created variables into account

* fix: fix list layout overflow

* fix: fix adding variables on page other than 1. fix validation

* feat: add docs link

* fix: fix default displayName function for resource-list-layout

* feat: improve vars expressions ux, cm-tooltip

* test: fix datatable test

* feat: add MATCH_REGEX validation rule

* fix: overhaul how datatable pagination selector works

* feat: update  completer description

* fix: conditionally update usage syntax based on key validation

* test: update datatable snapshot

* fix: fix variables-row button margins

* fix: fix pagination overflow

* test: Fix broken test

* test: Update snapshot

* fix: Remove duplicate declaration

* feat: add custom variables icon

---------

Co-authored-by: Alex Grozav <alex@grozav.com>
Co-authored-by: Omar Ajoue <krynble@gmail.com>
This commit is contained in:
Val
2023-04-18 11:41:55 +01:00
committed by GitHub
parent 1555387ece
commit 1bb987140a
94 changed files with 2925 additions and 200 deletions

View File

@@ -0,0 +1,142 @@
import { Notification } from 'element-ui';
import type { ElNotificationComponent, ElNotificationOptions } from 'element-ui/types/notification';
import type { MessageType } from 'element-ui/types/message';
import { sanitizeHtml } from '@/utils';
import { useTelemetry } from '@/composables/useTelemetry';
import { useWorkflowsStore } from '@/stores';
import { useI18n } from './useI18n';
import { useExternalHooks } from './useExternalHooks';
const messageDefaults: Partial<Omit<ElNotificationOptions, 'message'>> = {
dangerouslyUseHTMLString: true,
position: 'bottom-right',
};
const stickyNotificationQueue: ElNotificationComponent[] = [];
export function useToast() {
const telemetry = useTelemetry();
const workflowsStore = useWorkflowsStore();
const externalHooks = useExternalHooks();
const i18n = useI18n();
function showMessage(
messageData: Omit<ElNotificationOptions, 'message'> & { message?: string },
track = true,
) {
messageData = { ...messageDefaults, ...messageData };
messageData.message = messageData.message
? sanitizeHtml(messageData.message)
: messageData.message;
const notification = Notification(messageData as ElNotificationOptions);
if (messageData.duration === 0) {
stickyNotificationQueue.push(notification);
}
if (messageData.type === 'error' && track) {
telemetry.track('Instance FE emitted error', {
error_title: messageData.title,
error_message: messageData.message,
workflow_id: workflowsStore.workflowId,
});
}
return notification;
}
function showToast(config: {
title: string;
message: string;
onClick?: () => void;
onClose?: () => void;
duration?: number;
customClass?: string;
closeOnClick?: boolean;
type?: MessageType;
}) {
// eslint-disable-next-line prefer-const
let notification: ElNotificationComponent;
if (config.closeOnClick) {
const cb = config.onClick;
config.onClick = () => {
if (notification) {
notification.close();
}
if (cb) {
cb();
}
};
}
notification = showMessage({
title: config.title,
message: config.message,
onClick: config.onClick,
onClose: config.onClose,
duration: config.duration,
customClass: config.customClass,
type: config.type,
});
return notification;
}
function collapsableDetails({ description, node }: Error) {
if (!description) return '';
const errorDescription =
description.length > 500 ? `${description.slice(0, 500)}...` : description;
return `
<br>
<br>
<details>
<summary
style="color: #ff6d5a; font-weight: bold; cursor: pointer;"
>
${i18n.baseText('showMessage.showDetails')}
</summary>
<p>${node.name}: ${errorDescription}</p>
</details>
`;
}
function showError(e: Error | unknown, title: string, message?: string) {
const error = e as Error;
const messageLine = message ? `${message}<br/>` : '';
showMessage(
{
title,
message: `
${messageLine}
<i>${error.message}</i>
${collapsableDetails(error)}`,
type: 'error',
duration: 0,
},
false,
);
externalHooks.run('showMessage.showError', {
title,
message,
errorMessage: error.message,
});
telemetry.track('Instance FE emitted error', {
error_title: title,
error_description: message,
error_message: error.message,
workflow_id: workflowsStore.workflowId,
});
}
return {
showMessage,
showToast,
showError,
};
}