diff --git a/packages/design-system/src/components/N8nHeading/Heading.stories.js b/packages/design-system/src/components/N8nHeading/Heading.stories.js index 4a1ac65e84..055a48c370 100644 --- a/packages/design-system/src/components/N8nHeading/Heading.stories.js +++ b/packages/design-system/src/components/N8nHeading/Heading.stories.js @@ -13,7 +13,7 @@ export default { color: { control: { type: 'select', - options: ['primary', 'text-dark', 'text-base', 'text-light'], + options: ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'], }, }, }, diff --git a/packages/design-system/src/components/N8nHeading/Heading.vue b/packages/design-system/src/components/N8nHeading/Heading.vue index e4cd0bca07..3a66b3be03 100644 --- a/packages/design-system/src/components/N8nHeading/Heading.vue +++ b/packages/design-system/src/components/N8nHeading/Heading.vue @@ -23,7 +23,7 @@ export default { }, color: { type: String, - validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light'].includes(value), + validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'].includes(value), }, }, methods: { diff --git a/packages/design-system/src/components/N8nSquareButton/SquareButton.stories.js b/packages/design-system/src/components/N8nSquareButton/SquareButton.stories.js new file mode 100644 index 0000000000..0adf7824c8 --- /dev/null +++ b/packages/design-system/src/components/N8nSquareButton/SquareButton.stories.js @@ -0,0 +1,27 @@ +import N8nSquareButton from './SquareButton.vue'; +import { action } from '@storybook/addon-actions'; + +export default { + title: 'Atoms/SquareButton', + component: N8nSquareButton, + argTypes: { + label: { + control: 'text', + }, + }, +}; + +const methods = { + onClick: action('click'), +}; + +const Template = (args, { argTypes }) => ({ + props: Object.keys(argTypes), + components: { + N8nSquareButton, + }, + template: '', + methods, +}); + +export const SquareButton = Template.bind({}); diff --git a/packages/design-system/src/components/N8nSquareButton/SquareButton.vue b/packages/design-system/src/components/N8nSquareButton/SquareButton.vue new file mode 100644 index 0000000000..998a8636e4 --- /dev/null +++ b/packages/design-system/src/components/N8nSquareButton/SquareButton.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/packages/design-system/src/components/N8nSquareButton/index.js b/packages/design-system/src/components/N8nSquareButton/index.js new file mode 100644 index 0000000000..cf1617cefe --- /dev/null +++ b/packages/design-system/src/components/N8nSquareButton/index.js @@ -0,0 +1,3 @@ +import N8nSquareButton from './SquareButton.vue'; + +export default N8nSquareButton; diff --git a/packages/design-system/src/components/N8nText/Text.stories.js b/packages/design-system/src/components/N8nText/Text.stories.js index 6a048685b6..8f017e4614 100644 --- a/packages/design-system/src/components/N8nText/Text.stories.js +++ b/packages/design-system/src/components/N8nText/Text.stories.js @@ -13,7 +13,7 @@ export default { color: { control: { type: 'select', - options: ['primary', 'text-dark', 'text-base', 'text-light'], + options: ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'], }, }, }, diff --git a/packages/design-system/src/components/N8nText/Text.vue b/packages/design-system/src/components/N8nText/Text.vue index 67cf0a4277..c184c6a712 100644 --- a/packages/design-system/src/components/N8nText/Text.vue +++ b/packages/design-system/src/components/N8nText/Text.vue @@ -20,7 +20,7 @@ export default Vue.extend({ }, color: { type: String, - validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light'].includes(value), + validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'].includes(value), }, align: { type: String, diff --git a/packages/design-system/src/components/index.js b/packages/design-system/src/components/index.js index 6bdfd068f0..a82ddc6e3f 100644 --- a/packages/design-system/src/components/index.js +++ b/packages/design-system/src/components/index.js @@ -10,6 +10,7 @@ import N8nMenu from './N8nMenu'; import N8nMenuItem from './N8nMenuItem'; import N8nSelect from './N8nSelect'; import N8nSpinner from './N8nSpinner'; +import N8nSquareButton from './N8nSquareButton'; import N8nText from './N8nText'; import N8nTooltip from './N8nTooltip'; import N8nOption from './N8nOption'; @@ -27,6 +28,7 @@ export { N8nMenuItem, N8nSelect, N8nSpinner, + N8nSquareButton, N8nText, N8nTooltip, N8nOption, diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index a625f6c75b..4685b8d2aa 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -486,6 +486,21 @@ export interface IPersonalizationSurvey { shouldShow: boolean; } +export interface IN8nPrompts { + message: string; + title: string; + showContactPrompt: boolean; + showValueSurvey: boolean; +} + +export interface IN8nValueSurveyData { + [key: string]: string; +} + +export interface IN8nPromptResponse { + updated: boolean; +} + export interface IN8nUISettings { endpointWebhook: string; endpointWebhookTest: string; @@ -690,6 +705,7 @@ export interface IUiState { export interface ISettingsState { settings: IN8nUISettings; + promptsData: IN8nPrompts; } export interface IVersionsState { diff --git a/packages/editor-ui/src/api/helpers.ts b/packages/editor-ui/src/api/helpers.ts index 1ae753db1c..be34b1c3a3 100644 --- a/packages/editor-ui/src/api/helpers.ts +++ b/packages/editor-ui/src/api/helpers.ts @@ -93,3 +93,7 @@ export async function makeRestApiRequest(context: IRestApiContext, method: Metho export async function get(baseURL: string, endpoint: string, params?: IDataObject, headers?: IDataObject) { return await request({method: 'GET', baseURL, endpoint, headers, data: params}); } + +export async function post(baseURL: string, endpoint: string, params?: IDataObject, headers?: IDataObject) { + return await request({method: 'POST', baseURL, endpoint, headers, data: params}); +} diff --git a/packages/editor-ui/src/api/settings.ts b/packages/editor-ui/src/api/settings.ts index 44302f8168..6609524149 100644 --- a/packages/editor-ui/src/api/settings.ts +++ b/packages/editor-ui/src/api/settings.ts @@ -1,6 +1,7 @@ import { IDataObject } from 'n8n-workflow'; -import { IRestApiContext, IN8nUISettings, IPersonalizationSurveyAnswers } from '../Interface'; -import { makeRestApiRequest } from './helpers'; +import { IRestApiContext, IN8nPrompts, IN8nValueSurveyData, IN8nUISettings, IPersonalizationSurveyAnswers } from '../Interface'; +import { makeRestApiRequest, get, post } from './helpers'; +import { TEMPLATES_BASE_URL } from '@/constants'; export async function getSettings(context: IRestApiContext): Promise { return await makeRestApiRequest(context, 'GET', '/settings'); @@ -10,3 +11,15 @@ export async function submitPersonalizationSurvey(context: IRestApiContext, para await makeRestApiRequest(context, 'POST', '/user-survey', params as unknown as IDataObject); } +export async function getPromptsData(instanceId: string): Promise { + return await get(TEMPLATES_BASE_URL, '/prompts', {}, {'n8n-instance-id': instanceId}); +} + +export async function submitContactInfo(instanceId: string, email: string): Promise { + return await post(TEMPLATES_BASE_URL, '/prompt', { email }, {'n8n-instance-id': instanceId}); +} + +export async function submitValueSurvey(instanceId: string, params: IN8nValueSurveyData): Promise { + return await post(TEMPLATES_BASE_URL, '/value-survey', params, {'n8n-instance-id': instanceId}); +} + diff --git a/packages/editor-ui/src/components/ContactPromptModal.vue b/packages/editor-ui/src/components/ContactPromptModal.vue new file mode 100644 index 0000000000..903d931088 --- /dev/null +++ b/packages/editor-ui/src/components/ContactPromptModal.vue @@ -0,0 +1,128 @@ + + + + + + + diff --git a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue index 19589fa14d..888ec578d5 100644 --- a/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue +++ b/packages/editor-ui/src/components/MainHeader/WorkflowDetails.vue @@ -140,8 +140,9 @@ export default mixins(workflowHelpers).extend({ }, }, methods: { - onSaveButtonClick () { - this.saveCurrentWorkflow(undefined); + async onSaveButtonClick () { + const saved = await this.saveCurrentWorkflow(); + if (saved) this.$store.dispatch('settings/fetchPromptsData'); }, onTagsEditEnable() { this.$data.appliedTagIds = this.currentWorkflowTagIds; @@ -172,7 +173,7 @@ export default mixins(workflowHelpers).extend({ const saved = await this.saveCurrentWorkflow({ tags }); this.$telemetry.track('User edited workflow tags', { workflow_id: this.currentWorkflowId as string, new_tag_count: tags.length }); - + this.$data.tagsSaving = false; if (saved) { this.$data.isTagsEditEnabled = false; diff --git a/packages/editor-ui/src/components/MainSidebar.vue b/packages/editor-ui/src/components/MainSidebar.vue index 73844bbbbf..373a9f8fb0 100644 --- a/packages/editor-ui/src/components/MainSidebar.vue +++ b/packages/editor-ui/src/components/MainSidebar.vue @@ -425,7 +425,8 @@ export default mixins( saveAs(blob, workflowName + '.json'); } else if (key === 'workflow-save') { - this.saveCurrentWorkflow(undefined); + const saved = await this.saveCurrentWorkflow(); + if (saved) this.$store.dispatch('settings/fetchPromptsData'); } else if (key === 'workflow-duplicate') { this.$store.dispatch('ui/openModal', DUPLICATE_MODAL_KEY); } else if (key === 'help-about') { diff --git a/packages/editor-ui/src/components/ModalDrawer.vue b/packages/editor-ui/src/components/ModalDrawer.vue index 298081b1c4..ed9c3d82ce 100644 --- a/packages/editor-ui/src/components/ModalDrawer.vue +++ b/packages/editor-ui/src/components/ModalDrawer.vue @@ -3,7 +3,9 @@ :direction="direction" :visible="visible" :size="width" - :before-close="close" + :before-close="beforeClose" + :modal="modal" + :wrapperClosable="wrapperClosable" >