mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-19 19:11:13 +00:00
feat(editor): Update icons to Lucide icons (#16231)
Co-authored-by: Mutasem Aldmour <mutasem@n8n.io>
This commit is contained in:
@@ -70,6 +70,7 @@ import type { BulkCommand, Undoable } from '@/models/history';
|
||||
|
||||
import type { ProjectSharingData } from '@/types/projects.types';
|
||||
import type { PathItem } from '@n8n/design-system/components/N8nBreadcrumbs/Breadcrumbs.vue';
|
||||
import { type IconName } from '@n8n/design-system/src/components/N8nIcon/icons';
|
||||
|
||||
export * from '@n8n/design-system/types';
|
||||
|
||||
@@ -668,7 +669,7 @@ export type SimplifiedNodeType = Pick<
|
||||
export interface SubcategoryItemProps {
|
||||
description?: string;
|
||||
iconType?: string;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
iconProps?: {
|
||||
color?: string;
|
||||
};
|
||||
@@ -1072,7 +1073,7 @@ export interface ITab<Value extends string | number = string | number> {
|
||||
value: Value;
|
||||
label?: string;
|
||||
href?: string;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
align?: 'right';
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ const onBlur = (): void => {
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
data-test-id="assignment-remove"
|
||||
:class="[$style.iconButton, $style.extraTopPadding]"
|
||||
@click="onRemove"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useI18n } from '@n8n/i18n';
|
||||
import type { BaseTextKey } from '@n8n/i18n';
|
||||
import { ASSIGNMENT_TYPES } from './constants';
|
||||
import { computed } from 'vue';
|
||||
import { type IconName } from '@n8n/design-system/components/N8nIcon/icons';
|
||||
|
||||
interface Props {
|
||||
modelValue: string;
|
||||
@@ -19,7 +20,9 @@ const i18n = useI18n();
|
||||
|
||||
const types = ASSIGNMENT_TYPES;
|
||||
|
||||
const icon = computed(() => types.find((type) => type.type === props.modelValue)?.icon ?? 'cube');
|
||||
const icon = computed(
|
||||
(): IconName => types.find((type) => type.type === props.modelValue)?.icon ?? 'box',
|
||||
);
|
||||
|
||||
const onTypeChange = (type: string): void => {
|
||||
emit('update:model-value', type);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
export const ASSIGNMENT_TYPES = [
|
||||
{ type: 'string', icon: 'font' },
|
||||
{ type: 'number', icon: 'hashtag' },
|
||||
{ type: 'boolean', icon: 'check-square' },
|
||||
import { type IconName } from '@n8n/design-system/components/N8nIcon/icons';
|
||||
|
||||
export const ASSIGNMENT_TYPES: Array<{ type: string; icon: IconName }> = [
|
||||
{ type: 'string', icon: 'case-upper' },
|
||||
{ type: 'number', icon: 'hash' },
|
||||
{ type: 'boolean', icon: 'square-check' },
|
||||
{ type: 'array', icon: 'list' },
|
||||
{ type: 'object', icon: 'cube' },
|
||||
{ type: 'object', icon: 'box' },
|
||||
];
|
||||
|
||||
@@ -37,8 +37,8 @@ const onClick = () => {
|
||||
|
||||
<template>
|
||||
<el-tag :type="theme" :disable-transitions="true" :class="$style.container">
|
||||
<font-awesome-icon
|
||||
:icon="theme === 'success' ? 'check-circle' : 'exclamation-triangle'"
|
||||
<n8n-icon
|
||||
:icon="theme === 'success' ? 'circle-check' : 'triangle-alert'"
|
||||
:class="theme === 'success' ? $style.icon : $style.dangerIcon"
|
||||
/>
|
||||
<div :class="$style.banner">
|
||||
|
||||
@@ -28,7 +28,7 @@ const onClick = () => {
|
||||
data-test-id="close-become-template-creator-cta"
|
||||
@click="store.dismissCta()"
|
||||
>
|
||||
<n8n-icon icon="times" size="xsmall" :title="i18n.baseText('generic.close')" />
|
||||
<n8n-icon icon="x" size="xsmall" :title="i18n.baseText('generic.close')" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ onMounted(() => {
|
||||
v-text="`${prompt.length} / ${ASK_AI_MAX_PROMPT_LENGTH}`"
|
||||
/>
|
||||
<a href="https://docs.n8n.io/code-examples/ai-code" target="_blank" :class="$style.help">
|
||||
<n8n-icon icon="question-circle" color="text-light" size="large" />{{
|
||||
<n8n-icon icon="circle-help" color="text-light" size="large" />{{
|
||||
i18n.baseText('codeNodeEditor.askAi.help')
|
||||
}}
|
||||
</a>
|
||||
|
||||
@@ -133,7 +133,7 @@ watch(
|
||||
{{ i18n.baseText('settings.communityNodes.failedToLoad.tooltip') }}
|
||||
</div>
|
||||
</template>
|
||||
<n8n-icon icon="exclamation-triangle" color="danger" size="large" />
|
||||
<n8n-icon icon="triangle-alert" color="danger" size="large" />
|
||||
</n8n-tooltip>
|
||||
<n8n-tooltip
|
||||
v-else-if="hasUnverifiedPackagesUpdate || hasVerifiedPackageUpdate"
|
||||
@@ -152,7 +152,7 @@ watch(
|
||||
{{ i18n.baseText('settings.communityNodes.upToDate.tooltip') }}
|
||||
</div>
|
||||
</template>
|
||||
<n8n-icon icon="check-circle" color="text-light" size="large" />
|
||||
<n8n-icon icon="circle-check" color="text-light" size="large" />
|
||||
</n8n-tooltip>
|
||||
<div :class="$style.cardActions">
|
||||
<n8n-action-toggle :actions="packageActions" @action="onAction"></n8n-action-toggle>
|
||||
|
||||
@@ -110,7 +110,7 @@ const onLearnMoreLinkClick = () => {
|
||||
</div>
|
||||
<n8n-button
|
||||
:label="i18n.baseText('settings.communityNodes.browseButton.label')"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
:class="$style.browseButton"
|
||||
@click="openNPMPage"
|
||||
/>
|
||||
|
||||
@@ -225,7 +225,7 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n8n-callout v-if="isManaged" theme="warning" icon="exclamation-triangle">
|
||||
<n8n-callout v-if="isManaged" theme="warning" icon="triangle-alert">
|
||||
{{ i18n.baseText('freeAi.credits.credentials.edit') }}
|
||||
</n8n-callout>
|
||||
<div v-else>
|
||||
|
||||
@@ -1106,7 +1106,7 @@ const { width } = useElementSize(credNameRef);
|
||||
<n8n-icon-button
|
||||
v-if="currentCredential && credentialPermissions.delete"
|
||||
:title="i18n.baseText('credentialEdit.credentialEdit.delete')"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
type="tertiary"
|
||||
:disabled="isSaving"
|
||||
:loading="isDeleting"
|
||||
|
||||
@@ -23,7 +23,7 @@ export const TEST_CREDENTIALS: ICredentialMap = {
|
||||
id: '2',
|
||||
type: 'team',
|
||||
name: 'Test Project',
|
||||
icon: { type: 'icon', value: 'exchange-alt' },
|
||||
icon: { type: 'icon', value: 'arrow-left-right' },
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
@@ -51,7 +51,7 @@ export const TEST_CREDENTIALS: ICredentialMap = {
|
||||
id: '2',
|
||||
type: 'team',
|
||||
name: 'Test Project',
|
||||
icon: { type: 'icon', value: 'exchange-alt' },
|
||||
icon: { type: 'icon', value: 'arrow-left-right' },
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
@@ -107,7 +107,7 @@ export const TEST_CREDENTIALS: ICredentialMap = {
|
||||
id: '2',
|
||||
type: 'team',
|
||||
name: 'Test Project',
|
||||
icon: { type: 'icon', value: 'exchange-alt' },
|
||||
icon: { type: 'icon', value: 'arrow-left-right' },
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
|
||||
@@ -89,7 +89,7 @@ function openCredentialType() {
|
||||
@update:model-value="onSelect"
|
||||
>
|
||||
<template #prefix>
|
||||
<font-awesome-icon icon="search" />
|
||||
<n8n-icon icon="search" />
|
||||
</template>
|
||||
<N8nOption
|
||||
v-for="credential in credentialsStore.allCredentialTypes"
|
||||
|
||||
@@ -462,7 +462,7 @@ async function onAskAssistantClick() {
|
||||
>
|
||||
<div class="copy-button">
|
||||
<N8nIconButton
|
||||
icon="copy"
|
||||
icon="files"
|
||||
type="secondary"
|
||||
size="mini"
|
||||
:text="true"
|
||||
@@ -484,7 +484,7 @@ async function onAskAssistantClick() {
|
||||
class="node-error-view__details"
|
||||
>
|
||||
<summary class="node-error-view__details-summary">
|
||||
<font-awesome-icon class="node-error-view__details-icon" icon="angle-right" />
|
||||
<n8n-icon class="node-error-view__details-icon" icon="chevron-right" />
|
||||
{{
|
||||
i18n.baseText('nodeErrorView.details.from', {
|
||||
interpolate: { node: `${nodeDefaultName}` },
|
||||
@@ -539,7 +539,7 @@ async function onAskAssistantClick() {
|
||||
|
||||
<details class="node-error-view__details">
|
||||
<summary class="node-error-view__details-summary">
|
||||
<font-awesome-icon class="node-error-view__details-icon" icon="angle-right" />
|
||||
<n8n-icon class="node-error-view__details-icon" icon="chevron-right" />
|
||||
{{ i18n.baseText('nodeErrorView.details.info') }}
|
||||
</summary>
|
||||
<div class="node-error-view__details-content">
|
||||
|
||||
@@ -1,34 +1,37 @@
|
||||
import type { TestRunRecord } from '@/api/evaluation.ee';
|
||||
import { type IconName } from '@n8n/design-system/components/N8nIcon/icons';
|
||||
import type { IconColor } from '@n8n/design-system/types/icon';
|
||||
|
||||
export const statusDictionary: Record<TestRunRecord['status'], { icon: string; color: IconColor }> =
|
||||
{
|
||||
new: {
|
||||
icon: 'status-new',
|
||||
color: 'foreground-xdark',
|
||||
},
|
||||
running: {
|
||||
icon: 'spinner',
|
||||
color: 'secondary',
|
||||
},
|
||||
completed: {
|
||||
icon: 'status-completed',
|
||||
color: 'success',
|
||||
},
|
||||
error: {
|
||||
icon: 'exclamation-triangle',
|
||||
color: 'danger',
|
||||
},
|
||||
cancelled: {
|
||||
icon: 'status-canceled',
|
||||
color: 'foreground-xdark',
|
||||
},
|
||||
warning: {
|
||||
icon: 'status-warning',
|
||||
color: 'warning',
|
||||
},
|
||||
success: {
|
||||
icon: 'status-completed',
|
||||
color: 'success',
|
||||
},
|
||||
};
|
||||
export const statusDictionary: Record<
|
||||
TestRunRecord['status'],
|
||||
{ icon: IconName; color: IconColor }
|
||||
> = {
|
||||
new: {
|
||||
icon: 'status-new',
|
||||
color: 'foreground-xdark',
|
||||
},
|
||||
running: {
|
||||
icon: 'spinner',
|
||||
color: 'secondary',
|
||||
},
|
||||
completed: {
|
||||
icon: 'status-completed',
|
||||
color: 'success',
|
||||
},
|
||||
error: {
|
||||
icon: 'triangle-alert',
|
||||
color: 'danger',
|
||||
},
|
||||
cancelled: {
|
||||
icon: 'status-canceled',
|
||||
color: 'foreground-xdark',
|
||||
},
|
||||
warning: {
|
||||
icon: 'status-warning',
|
||||
color: 'warning',
|
||||
},
|
||||
success: {
|
||||
icon: 'status-completed',
|
||||
color: 'success',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -205,7 +205,7 @@ defineExpose({ focus, select });
|
||||
square
|
||||
outline
|
||||
type="tertiary"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="mini"
|
||||
:class="$style['expression-editor-modal-opener']"
|
||||
data-test-id="expander"
|
||||
|
||||
@@ -133,11 +133,8 @@ async function onActionDropdownClick(id: string) {
|
||||
</span>
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div v-if="provider.name === 'infisical'">
|
||||
<font-awesome-icon
|
||||
:class="$style['warningTriangle']"
|
||||
icon="exclamation-triangle"
|
||||
></font-awesome-icon>
|
||||
<div :class="$style.deprecationWarning" v-if="provider.name === 'infisical'">
|
||||
<n8n-icon :class="$style['warningTriangle']" icon="triangle-alert" />
|
||||
<N8nBadge class="mr-xs" theme="tertiary" bold data-test-id="card-badge">
|
||||
{{ i18n.baseText('settings.externalSecrets.card.deprecated') }}
|
||||
</N8nBadge>
|
||||
@@ -193,6 +190,10 @@ async function onActionDropdownClick(id: string) {
|
||||
margin-left: var(--spacing-s);
|
||||
}
|
||||
|
||||
.deprecationWarning {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.warningTriangle {
|
||||
color: var(--color-warning);
|
||||
margin-right: var(--spacing-2xs);
|
||||
|
||||
@@ -68,7 +68,7 @@ async function onUpdateConnected(value: boolean) {
|
||||
<n8n-icon
|
||||
v-if="provider.state === 'error'"
|
||||
color="danger"
|
||||
icon="exclamation-triangle"
|
||||
icon="triangle-alert"
|
||||
class="mr-2xs"
|
||||
/>
|
||||
<n8n-text :color="connectedTextColor" bold class="mr-2xs">
|
||||
|
||||
@@ -21,10 +21,7 @@ function onFeedback(feedback: 'positive' | 'negative') {
|
||||
{{ i18n.baseText('feedback.title') }}
|
||||
</N8nText>
|
||||
<N8nText v-else :color="modelValue === 'positive' ? 'success' : 'danger'">
|
||||
<FontAwesomeIcon
|
||||
:icon="modelValue === 'positive' ? 'thumbs-up' : 'thumbs-down'"
|
||||
class="mr-2xs"
|
||||
/>
|
||||
<N8nIcon :icon="modelValue === 'positive' ? 'thumbs-up' : 'thumbs-down'" class="mr-2xs" />
|
||||
{{ i18n.baseText(`feedback.${modelValue}`) }}
|
||||
</N8nText>
|
||||
<N8nTooltip v-if="!modelValue" :content="i18n.baseText('feedback.positive')">
|
||||
@@ -33,7 +30,7 @@ function onFeedback(feedback: 'positive' | 'negative') {
|
||||
data-test-id="feedback-button-positive"
|
||||
@click="onFeedback('positive')"
|
||||
>
|
||||
<FontAwesomeIcon icon="thumbs-up" />
|
||||
<N8nIcon icon="thumbs-up" />
|
||||
</span>
|
||||
</N8nTooltip>
|
||||
<N8nTooltip v-if="!modelValue" :content="i18n.baseText('feedback.negative')">
|
||||
@@ -42,7 +39,7 @@ function onFeedback(feedback: 'positive' | 'negative') {
|
||||
data-test-id="feedback-button-negative"
|
||||
@click="onFeedback('negative')"
|
||||
>
|
||||
<FontAwesomeIcon icon="thumbs-down" />
|
||||
<N8nIcon icon="thumbs-down" />
|
||||
</span>
|
||||
</N8nTooltip>
|
||||
</div>
|
||||
|
||||
@@ -168,7 +168,7 @@ const onBlur = (): void => {
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
data-test-id="filter-remove-condition"
|
||||
:title="i18n.baseText('filter.removeCondition')"
|
||||
:class="[$style.iconButton, $style.extraTopPadding]"
|
||||
@@ -231,7 +231,7 @@ const onBlur = (): void => {
|
||||
<template #content>
|
||||
{{ i18n.baseText('filter.condition.resolvedTrue') }}
|
||||
</template>
|
||||
<n8n-icon :class="$style.statusIcon" icon="check-circle" size="medium" color="text-light" />
|
||||
<n8n-icon :class="$style.statusIcon" icon="circle-check" size="medium" color="text-light" />
|
||||
</n8n-tooltip>
|
||||
|
||||
<n8n-tooltip
|
||||
@@ -241,7 +241,7 @@ const onBlur = (): void => {
|
||||
<template #content>
|
||||
{{ i18n.baseText('filter.condition.resolvedFalse') }}
|
||||
</template>
|
||||
<n8n-icon :class="$style.statusIcon" icon="times-circle" size="medium" color="text-light" />
|
||||
<n8n-icon :class="$style.statusIcon" icon="circle-x" size="medium" color="text-light" />
|
||||
</n8n-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -285,13 +285,13 @@ export const OPERATOR_GROUPS: FilterOperatorGroup[] = [
|
||||
{
|
||||
id: 'string',
|
||||
name: 'type.string',
|
||||
icon: 'font',
|
||||
icon: 'case-upper',
|
||||
children: OPERATORS.filter((operator) => operator.type === 'string'),
|
||||
},
|
||||
{
|
||||
id: 'number',
|
||||
name: 'type.number',
|
||||
icon: 'hashtag',
|
||||
icon: 'hash',
|
||||
children: OPERATORS.filter((operator) => operator.type === 'number'),
|
||||
},
|
||||
{
|
||||
@@ -303,7 +303,7 @@ export const OPERATOR_GROUPS: FilterOperatorGroup[] = [
|
||||
{
|
||||
id: 'boolean',
|
||||
name: 'type.boolean',
|
||||
icon: 'check-square',
|
||||
icon: 'square-check',
|
||||
children: OPERATORS.filter((operator) => operator.type === 'boolean'),
|
||||
},
|
||||
{
|
||||
@@ -315,7 +315,7 @@ export const OPERATOR_GROUPS: FilterOperatorGroup[] = [
|
||||
{
|
||||
id: 'object',
|
||||
name: 'type.object',
|
||||
icon: 'cube',
|
||||
icon: 'box',
|
||||
children: OPERATORS.filter((operator) => operator.type === 'object'),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { IconName } from '@n8n/design-system/components/N8nIcon/icons';
|
||||
import type { BaseTextKey } from '@n8n/i18n';
|
||||
import type { FilterConditionValue, FilterOperatorValue } from 'n8n-workflow';
|
||||
|
||||
@@ -8,7 +9,7 @@ export interface FilterOperator extends FilterOperatorValue {
|
||||
export interface FilterOperatorGroup {
|
||||
id: string;
|
||||
name: BaseTextKey;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
children: FilterOperator[];
|
||||
}
|
||||
|
||||
|
||||
@@ -287,7 +287,7 @@ const trackWorkflowInputFieldAdded = () => {
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
data-test-id="fixed-collection-delete"
|
||||
:title="locale.baseText('fixedCollectionParameter.deleteItem')"
|
||||
@click="deleteOption(property.name, index)"
|
||||
@@ -315,7 +315,7 @@ const trackWorkflowInputFieldAdded = () => {
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
data-test-id="fixed-collection-delete"
|
||||
:title="locale.baseText('fixedCollectionParameter.deleteItem')"
|
||||
@click="deleteOption(property.name)"
|
||||
|
||||
@@ -130,6 +130,7 @@ const onBreadcrumbItemClick = async (item: PathItem) => {
|
||||
:class="$style['folder-icon']"
|
||||
icon="folder"
|
||||
size="xlarge"
|
||||
:strokeWidth="1"
|
||||
/>
|
||||
</template>
|
||||
<template #header>
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import {
|
||||
type Project,
|
||||
type ProjectIcon as ProjectIconType,
|
||||
ProjectTypes,
|
||||
} from '@/types/projects.types';
|
||||
import { type Project, ProjectTypes } from '@/types/projects.types';
|
||||
import { isIconOrEmoji, type IconOrEmoji } from '@n8n/design-system/components/N8nIconPicker/types';
|
||||
|
||||
type Props = {
|
||||
currentProject: Project;
|
||||
@@ -23,13 +20,15 @@ const emit = defineEmits<{
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const projectIcon = computed((): ProjectIconType => {
|
||||
const projectIcon = computed((): IconOrEmoji => {
|
||||
if (props.currentProject?.type === ProjectTypes.Personal) {
|
||||
return { type: 'icon', value: 'user' };
|
||||
} else if (props.currentProject?.name) {
|
||||
return props.currentProject.icon ?? { type: 'icon', value: 'layer-group' };
|
||||
return isIconOrEmoji(props.currentProject.icon)
|
||||
? props.currentProject.icon
|
||||
: { type: 'icon', value: 'layers' };
|
||||
} else {
|
||||
return { type: 'icon', value: 'home' };
|
||||
return { type: 'icon', value: 'house' };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ const onClaimCreditsClicked = async () => {
|
||||
<n8n-callout
|
||||
v-if="userCanClaimOpenAiCredits && !showSuccessCallout"
|
||||
theme="secondary"
|
||||
icon="exclamation-circle"
|
||||
icon="circle-alert"
|
||||
>
|
||||
{{
|
||||
i18n.baseText('freeAi.credits.callout.claim.title', {
|
||||
@@ -110,7 +110,7 @@ const onClaimCreditsClicked = async () => {
|
||||
/>
|
||||
</template>
|
||||
</n8n-callout>
|
||||
<n8n-callout v-else-if="showSuccessCallout" theme="success" icon="check-circle">
|
||||
<n8n-callout v-else-if="showSuccessCallout" theme="success" icon="circle-check">
|
||||
<n8n-text size="small">
|
||||
{{
|
||||
i18n.baseText('freeAi.credits.callout.success.title.part1', {
|
||||
|
||||
@@ -298,7 +298,7 @@ const onUpdate = (change: FormFieldValueUpdate) => {
|
||||
<el-col :span="5" :offset="19">
|
||||
<n8n-button
|
||||
data-test-id="execute-workflow-button"
|
||||
icon="flask"
|
||||
icon="flask-conical"
|
||||
:label="i18n.baseText('fromAiParametersModal.execute')"
|
||||
@click="onExecute"
|
||||
/>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
<template>
|
||||
<div :class="$style['gift-icon']">
|
||||
<font-awesome-icon icon="gift" />
|
||||
<div :class="$style['notification']">
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" module>
|
||||
.gift-icon {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
svg {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.notification {
|
||||
height: 0.47em;
|
||||
width: 0.47em;
|
||||
border-radius: 50%;
|
||||
color: $gift-notification-active-color;
|
||||
position: absolute;
|
||||
background-color: $gift-notification-outer-color;
|
||||
right: -0.3em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
top: -0.148em;
|
||||
|
||||
div {
|
||||
height: 0.36em;
|
||||
width: 0.36em;
|
||||
background-color: $gift-notification-inner-color;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -13,7 +13,7 @@ const navigateTo = () => {
|
||||
|
||||
<template>
|
||||
<div :class="$style.wrapper" @click="navigateTo">
|
||||
<font-awesome-icon :class="$style.icon" icon="arrow-left" />
|
||||
<n8n-icon :class="$style.icon" icon="arrow-left" />
|
||||
<div :class="$style.text" v-text="i18n.baseText('template.buttons.goBackButton')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { nextTick, ref } from 'vue';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { onClickOutside } from '@vueuse/core';
|
||||
import type { InputType } from '@n8n/design-system';
|
||||
|
||||
interface Props {
|
||||
modelValue: string;
|
||||
subtitle?: string;
|
||||
type: InputType;
|
||||
readonly?: boolean;
|
||||
placeholder?: string;
|
||||
maxlength?: number;
|
||||
required?: boolean;
|
||||
autosize?: boolean | { minRows: number; maxRows: number };
|
||||
inputType?: InputType;
|
||||
maxHeight?: string;
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
placeholder: '',
|
||||
maxlength: 64,
|
||||
required: true,
|
||||
autosize: false,
|
||||
inputType: 'text',
|
||||
maxHeight: '22px',
|
||||
subtitle: '',
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string];
|
||||
}>();
|
||||
|
||||
const isNameEdit = ref(false);
|
||||
const nameInput = ref<HTMLInputElement | null>(null);
|
||||
const { showToast } = useToast();
|
||||
|
||||
const onNameEdit = (value: string) => {
|
||||
emit('update:modelValue', value);
|
||||
};
|
||||
|
||||
const enableNameEdit = () => {
|
||||
isNameEdit.value = true;
|
||||
void nextTick(() => nameInput.value?.focus());
|
||||
};
|
||||
|
||||
const disableNameEdit = () => {
|
||||
if (!props.modelValue && props.required) {
|
||||
emit('update:modelValue', `Untitled ${props.type}`);
|
||||
showToast({
|
||||
title: 'Error',
|
||||
message: `${props.type} name cannot be empty`,
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
isNameEdit.value = false;
|
||||
};
|
||||
|
||||
onClickOutside(nameInput, disableNameEdit);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="$style.container">
|
||||
<span v-if="readonly" :class="$style.headline">
|
||||
{{ modelValue }}
|
||||
</span>
|
||||
<div
|
||||
v-else
|
||||
:class="{
|
||||
[$style.headline]: true,
|
||||
[$style['headline-editable']]: true,
|
||||
[$style.editing]: isNameEdit,
|
||||
}"
|
||||
@keydown.stop
|
||||
@click="enableNameEdit"
|
||||
>
|
||||
<div v-if="!isNameEdit">
|
||||
<span>
|
||||
<n8n-text v-if="!modelValue" size="small" color="text-base">{{ placeholder }}</n8n-text>
|
||||
<slot v-else>{{ modelValue }}</slot>
|
||||
</span>
|
||||
<i><font-awesome-icon icon="pen" /></i>
|
||||
</div>
|
||||
<div v-else :class="{ [$style.nameInput]: props.inputType !== 'textarea' }">
|
||||
<n8n-input
|
||||
ref="nameInput"
|
||||
:model-value="modelValue"
|
||||
size="large"
|
||||
:type="inputType"
|
||||
:maxlength
|
||||
:placeholder
|
||||
:autosize
|
||||
@update:model-value="onNameEdit"
|
||||
@change="disableNameEdit"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!isNameEdit && subtitle" :class="$style.subtitle">
|
||||
{{ subtitle }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style module lang="scss">
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-size: var(--font-size-m);
|
||||
line-height: 1.4;
|
||||
margin-bottom: var(--spacing-5xs);
|
||||
display: inline-block;
|
||||
padding: 0 var(--spacing-4xs);
|
||||
border-radius: var(--border-radius-base);
|
||||
position: relative;
|
||||
min-height: 22px;
|
||||
max-height: v-bind(maxHeight);
|
||||
font-weight: var(--font-weight-regular);
|
||||
|
||||
&.editing {
|
||||
width: 100%;
|
||||
}
|
||||
i {
|
||||
display: var(--headline-icon-display, none);
|
||||
font-size: 0.75em;
|
||||
margin-left: 8px;
|
||||
color: var(--color-text-base);
|
||||
}
|
||||
|
||||
:global(textarea) {
|
||||
resize: none;
|
||||
}
|
||||
}
|
||||
|
||||
.headline-editable {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-base);
|
||||
--headline-icon-display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
.nameInput {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
margin-top: 1px;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
width: 400px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: var(--font-size-2xs);
|
||||
color: var(--color-text-light);
|
||||
margin-left: 4px;
|
||||
font-weight: var(--font-weight-regular);
|
||||
}
|
||||
</style>
|
||||
@@ -480,7 +480,7 @@ function activatePane() {
|
||||
<template #content>
|
||||
{{ i18n.baseText('ndv.input.noOutputData.hint.tooltip') }}
|
||||
</template>
|
||||
<N8nIcon icon="question-circle" />
|
||||
<N8nIcon icon="circle-help" />
|
||||
</N8nTooltip>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
||||
@@ -286,7 +286,7 @@ function hideGithubButton() {
|
||||
</GithubButton>
|
||||
<N8nIcon
|
||||
:class="$style['close-github-button']"
|
||||
icon="times-circle"
|
||||
icon="circle-x"
|
||||
size="medium"
|
||||
@click="hideGithubButton"
|
||||
/>
|
||||
|
||||
@@ -86,7 +86,7 @@ const mainMenuItems = computed<IMenuItem[]>(() => [
|
||||
{
|
||||
// Link to in-app templates, available if custom templates are enabled
|
||||
id: 'templates',
|
||||
icon: 'box-open',
|
||||
icon: 'package-open',
|
||||
label: i18n.baseText('mainSidebar.templates'),
|
||||
position: 'bottom',
|
||||
available: settingsStore.isTemplatesEnabled && templatesStore.hasCustomTemplatesHost,
|
||||
@@ -95,7 +95,7 @@ const mainMenuItems = computed<IMenuItem[]>(() => [
|
||||
{
|
||||
// Link to website templates, available if custom templates are not enabled
|
||||
id: 'templates',
|
||||
icon: 'box-open',
|
||||
icon: 'package-open',
|
||||
label: i18n.baseText('mainSidebar.templates'),
|
||||
position: 'bottom',
|
||||
available: settingsStore.isTemplatesEnabled && !templatesStore.hasCustomTemplatesHost,
|
||||
@@ -114,7 +114,7 @@ const mainMenuItems = computed<IMenuItem[]>(() => [
|
||||
},
|
||||
{
|
||||
id: 'insights',
|
||||
icon: 'chart-bar',
|
||||
icon: 'chart-column-decreasing',
|
||||
label: 'Insights',
|
||||
customIconSize: 'medium',
|
||||
position: 'bottom',
|
||||
@@ -125,7 +125,7 @@ const mainMenuItems = computed<IMenuItem[]>(() => [
|
||||
},
|
||||
{
|
||||
id: 'help',
|
||||
icon: 'question',
|
||||
icon: 'circle-help',
|
||||
label: i18n.baseText('mainSidebar.help'),
|
||||
position: 'bottom',
|
||||
children: [
|
||||
@@ -206,7 +206,7 @@ const mainMenuItems = computed<IMenuItem[]>(() => [
|
||||
),
|
||||
{
|
||||
id: 'full-changelog',
|
||||
icon: 'external-link-alt',
|
||||
icon: 'external-link',
|
||||
label: i18n.baseText('mainSidebar.whatsNew.fullChangelog'),
|
||||
link: {
|
||||
href: RELEASE_NOTES_URL,
|
||||
|
||||
@@ -128,7 +128,7 @@ async function pullWorkfolder() {
|
||||
data-test-id="main-sidebar-source-control-connected"
|
||||
>
|
||||
<span :class="$style.branchName">
|
||||
<n8n-icon icon="code-branch" />
|
||||
<n8n-icon icon="git-branch" />
|
||||
{{ currentBranch }}
|
||||
</span>
|
||||
<div :class="{ 'pt-xs': !isCollapsed }">
|
||||
|
||||
@@ -241,7 +241,7 @@ onMounted(async () => {
|
||||
<div>
|
||||
<n8n-button
|
||||
type="primary"
|
||||
icon="download"
|
||||
icon="hard-drive-download"
|
||||
float="right"
|
||||
:label="i18n.baseText('mfa.setup.step2.button.download')"
|
||||
data-test-id="mfa-recovery-codes-button"
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { IUpdateInformation } from '@/Interface';
|
||||
import CollectionParameter from '@/components/CollectionParameter.vue';
|
||||
import ParameterInputFull from '@/components/ParameterInputFull.vue';
|
||||
import { N8nButton, N8nInputLabel, N8nText } from '@n8n/design-system';
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
@@ -127,22 +126,22 @@ const valueChanged = (parameterData: IUpdateInformation) => {
|
||||
:class="parameter.type"
|
||||
>
|
||||
<div v-if="!isReadOnly" class="delete-item clickable">
|
||||
<FontAwesomeIcon
|
||||
icon="trash"
|
||||
<N8nIcon
|
||||
icon="trash-2"
|
||||
:title="i18n.baseText('multipleParameter.deleteItem')"
|
||||
@click="deleteItem(index)"
|
||||
/>
|
||||
<div v-if="sortable">
|
||||
<FontAwesomeIcon
|
||||
<N8nIcon
|
||||
v-if="index !== 0"
|
||||
icon="angle-up"
|
||||
icon="chevron-up"
|
||||
class="clickable"
|
||||
:title="i18n.baseText('multipleParameter.moveUp')"
|
||||
@click="moveOptionUp(index)"
|
||||
/>
|
||||
<FontAwesomeIcon
|
||||
<N8nIcon
|
||||
v-if="index !== mutableValues.length - 1"
|
||||
icon="angle-down"
|
||||
icon="chevron-down"
|
||||
class="clickable"
|
||||
:title="i18n.baseText('multipleParameter.moveDown')"
|
||||
@click="moveOptionDown(index)"
|
||||
|
||||
@@ -87,32 +87,17 @@ describe('NDVSubConnections', () => {
|
||||
props: {
|
||||
rootNode: node,
|
||||
},
|
||||
global: {
|
||||
stubs: {
|
||||
N8nButton: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
vi.advanceTimersByTime(1000); // Event debounce time
|
||||
|
||||
await waitFor(() => {});
|
||||
expect(getByTestId('subnode-connection-group-ai_tool-0')).toBeVisible();
|
||||
expect(html()).toEqual(
|
||||
`<div class="container">
|
||||
<div class="connections" style="--possible-connections: 1;">
|
||||
<div data-test-id="subnode-connection-group-ai_tool-0">
|
||||
<div class="connectionType"><span class="connectionLabel">Tools</span>
|
||||
<div>
|
||||
<div class="connectedNodesWrapper" style="--nodes-length: 0;">
|
||||
<div class="plusButton"><button class="button button tertiary medium withIcon square el-tooltip__trigger el-tooltip__trigger" aria-live="polite" data-test-id="add-subnode-ai_tool-0"><span class="icon"><span class="n8n-text compact size-medium regular n8n-icon n8n-icon"><!----></span></span>
|
||||
<!--v-if-->
|
||||
</button>
|
||||
<!--teleport start-->
|
||||
<!--teleport end-->
|
||||
</div>
|
||||
<!--v-if-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`,
|
||||
);
|
||||
expect(html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not render container if no possible connections', async () => {
|
||||
|
||||
@@ -109,7 +109,7 @@ function nodeTypeSelected(value: NodeTypeSelectedPayload[]) {
|
||||
<n8n-icon-button
|
||||
size="large"
|
||||
type="tertiary"
|
||||
:icon="['far', 'note-sticky']"
|
||||
icon="sticky-note"
|
||||
data-test-id="add-sticky-button"
|
||||
@click="addStickyNote"
|
||||
/>
|
||||
@@ -131,14 +131,14 @@ function nodeTypeSelected(value: NodeTypeSelectedPayload[]) {
|
||||
v-if="experimentalNdvStore.isEnabled"
|
||||
type="tertiary"
|
||||
size="large"
|
||||
icon="expand"
|
||||
icon="maximize-2"
|
||||
@click="experimentalNdvStore.expandAllNodes"
|
||||
/>
|
||||
<n8n-icon-button
|
||||
v-if="experimentalNdvStore.isEnabled"
|
||||
type="tertiary"
|
||||
size="large"
|
||||
icon="compress"
|
||||
icon="minimize-2"
|
||||
@click="experimentalNdvStore.collapseAllNodes"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -27,8 +27,8 @@ describe('CategoryItem', () => {
|
||||
props: { name: 'Category Test', isTrigger: true },
|
||||
});
|
||||
|
||||
expect(container.querySelector('[data-icon="bolt"]')).toBeInTheDocument();
|
||||
expect(container.querySelector('[data-icon="zap"]')).toBeInTheDocument();
|
||||
await rerender({ isTrigger: false });
|
||||
expect(container.querySelector('[data-icon="bolt"]')).not.toBeInTheDocument();
|
||||
expect(container.querySelector('[data-icon="zap"]')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,11 +28,11 @@ const categoryName = computed(() => {
|
||||
<div :class="{ [$style.category]: true, [$style.active]: active }">
|
||||
<span :class="$style.name">
|
||||
<span v-text="categoryName" />
|
||||
<font-awesome-icon v-if="isTrigger" icon="bolt" size="xs" :class="$style.triggerIcon" />
|
||||
<n8n-icon v-if="isTrigger" icon="zap" size="xsmall" :class="$style.triggerIcon" />
|
||||
<slot />
|
||||
</span>
|
||||
<font-awesome-icon v-if="expanded" icon="chevron-down" :class="$style.arrow" />
|
||||
<font-awesome-icon v-else :class="$style.arrow" icon="chevron-up" />
|
||||
<n8n-icon v-if="expanded" icon="chevron-down" color="text-light" size="large" />
|
||||
<n8n-icon v-else icon="chevron-up" color="text-light" size="large" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -72,10 +72,4 @@ const categoryName = computed(() => {
|
||||
flex-grow: 1;
|
||||
color: var(--color-text-dark);
|
||||
}
|
||||
|
||||
.arrow {
|
||||
font-size: var(--font-size-2xs);
|
||||
width: 12px;
|
||||
color: $node-creator-arrow-color;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -18,7 +18,13 @@ defineProps<Props>();
|
||||
:show-action-arrow="true"
|
||||
>
|
||||
<template #icon>
|
||||
<n8n-node-icon type="icon" :name="link.icon" :circle="false" :show-tooltip="false" />
|
||||
<n8n-node-icon
|
||||
type="icon"
|
||||
:name="link.icon"
|
||||
:circle="false"
|
||||
:show-tooltip="false"
|
||||
:use-updated-icons="true"
|
||||
/>
|
||||
</template>
|
||||
</n8n-node-creator-node>
|
||||
</template>
|
||||
|
||||
@@ -212,7 +212,7 @@ function onCommunityNodeTooltipClick(event: MouseEvent) {
|
||||
@click="onCommunityNodeTooltipClick"
|
||||
/>
|
||||
</template>
|
||||
<n8n-icon size="small" :class="$style.icon" icon="cube" />
|
||||
<n8n-icon size="small" :class="$style.icon" icon="box" />
|
||||
</N8nTooltip>
|
||||
</template>
|
||||
<template #dragContent>
|
||||
|
||||
@@ -18,7 +18,13 @@ defineProps<Props>();
|
||||
:show-action-arrow="true"
|
||||
>
|
||||
<template #icon>
|
||||
<n8n-node-icon type="icon" :name="openTemplate.icon" :circle="false" :show-tooltip="false" />
|
||||
<n8n-node-icon
|
||||
type="icon"
|
||||
:name="openTemplate.icon"
|
||||
:circle="false"
|
||||
:show-tooltip="false"
|
||||
:use-updated-icons="true"
|
||||
/>
|
||||
</template>
|
||||
</n8n-node-creator-node>
|
||||
</template>
|
||||
|
||||
@@ -30,6 +30,7 @@ const subcategoryName = computed(() => camelCase(props.item.subcategory || props
|
||||
:name="item.icon"
|
||||
:circle="false"
|
||||
:show-tooltip="false"
|
||||
:use-updated-icons="true"
|
||||
v-bind="item.iconProps"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -18,7 +18,13 @@ defineProps<Props>();
|
||||
:show-action-arrow="true"
|
||||
>
|
||||
<template #icon>
|
||||
<n8n-node-icon type="icon" :name="view.icon" :circle="false" :show-tooltip="false" />
|
||||
<n8n-node-icon
|
||||
type="icon"
|
||||
:name="view.icon"
|
||||
:circle="false"
|
||||
:show-tooltip="false"
|
||||
:use-updated-icons="true"
|
||||
/>
|
||||
</template>
|
||||
</n8n-node-creator-node>
|
||||
</template>
|
||||
|
||||
@@ -165,7 +165,7 @@ onBeforeUnmount(() => {
|
||||
v-if="active"
|
||||
:class="$style.close"
|
||||
type="secondary"
|
||||
icon="times"
|
||||
icon="x"
|
||||
aria-label="Close Node Creator"
|
||||
@click="emit('closeNodeCreator')"
|
||||
/>
|
||||
|
||||
@@ -249,7 +249,7 @@ describe('NodesListPanel', () => {
|
||||
expect(screen.queryAllByTestId('item-iterator-item')).toHaveLength(0);
|
||||
expect(screen.queryByText("We didn't make that... yet")).toBeInTheDocument();
|
||||
|
||||
await fireEvent.click(container.querySelector('.clear')!);
|
||||
await fireEvent.click(container.querySelector('svg[data-icon=circle-x]')!);
|
||||
await nextTick();
|
||||
expect(screen.queryAllByTestId('item-iterator-item')).toHaveLength(9);
|
||||
});
|
||||
|
||||
@@ -130,11 +130,7 @@ const onInstall = async () => {
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="communityNodeDetails.installed" :class="$style.installed">
|
||||
<FontAwesomeIcon
|
||||
v-if="!communityNodeDetails.official"
|
||||
:class="$style.installedIcon"
|
||||
icon="cube"
|
||||
/>
|
||||
<N8nIcon v-if="!communityNodeDetails.official" :class="$style.installedIcon" icon="box" />
|
||||
<N8nText color="text-light" size="small" bold>
|
||||
{{ i18n.baseText('communityNodeDetails.installed') }}
|
||||
</N8nText>
|
||||
|
||||
@@ -25,7 +25,7 @@ const openCommunityNodeDocsPage = () => {
|
||||
<N8nText size="small" bold style="margin-right: 5px">
|
||||
{{ i18n.baseText('communityNodesDocsLink.title') }}
|
||||
</N8nText>
|
||||
<FontAwesomeIcon icon="external-link-alt" />
|
||||
<N8nIcon icon="external-link" />
|
||||
</N8nLink>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ onMounted(async () => {
|
||||
<N8nTooltip v-else placement="top">
|
||||
<template #content>{{ i18n.baseText('communityNodeInfo.unverified') }}</template>
|
||||
<div>
|
||||
<FontAwesomeIcon :class="$style.tooltipIcon" icon="cube" />
|
||||
<N8nIcon :class="$style.tooltipIcon" icon="box" />
|
||||
<N8nText color="text-light" size="xsmall" bold>
|
||||
{{ i18n.baseText('communityNodeInfo.unverified.label') }}
|
||||
</N8nText>
|
||||
@@ -134,21 +134,21 @@ onMounted(async () => {
|
||||
</N8nTooltip>
|
||||
|
||||
<div v-if="downloads">
|
||||
<FontAwesomeIcon :class="$style.tooltipIcon" icon="download" />
|
||||
<N8nIcon :class="$style.tooltipIcon" icon="hard-drive-download" />
|
||||
<N8nText color="text-light" size="xsmall" bold data-test-id="number-of-downloads">
|
||||
{{ i18n.baseText('communityNodeInfo.downloads', { interpolate: { downloads } }) }}
|
||||
</N8nText>
|
||||
</div>
|
||||
|
||||
<div v-if="publisherName">
|
||||
<FontAwesomeIcon :class="$style.tooltipIcon" icon="user" />
|
||||
<N8nIcon :class="$style.tooltipIcon" icon="user" />
|
||||
<N8nText color="text-light" size="xsmall" bold data-test-id="publisher-name">
|
||||
{{ i18n.baseText('communityNodeInfo.publishedBy', { interpolate: { publisherName } }) }}
|
||||
</N8nText>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!isOwner && !communityNodeDetails?.installed" :class="$style.contactOwnerHint">
|
||||
<N8nIcon color="text-light" icon="info-circle" size="large" />
|
||||
<N8nIcon color="text-light" icon="info" size="large" />
|
||||
<N8nText color="text-base" size="medium">
|
||||
<div style="padding-bottom: 8px">
|
||||
{{ i18n.baseText('communityNodeInfo.contact.admin') }}
|
||||
|
||||
@@ -15,7 +15,7 @@ defineProps<Props>();
|
||||
|
||||
<template>
|
||||
<div v-if="isOwner" :class="$style.container">
|
||||
<N8nIcon color="text-light" icon="info-circle" size="large" />
|
||||
<N8nIcon color="text-light" icon="info" size="large" />
|
||||
<N8nText color="text-base" size="medium"> {{ hint }} </N8nText>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -53,9 +53,9 @@ const i18n = useI18n();
|
||||
<span>{{ i18n.baseText('nodeCreator.noResults.requestTheNode') }}</span
|
||||
>
|
||||
<span>
|
||||
<font-awesome-icon
|
||||
<n8n-icon
|
||||
:class="$style.external"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
:title="i18n.baseText('nodeCreator.noResults.requestTheNode')"
|
||||
/>
|
||||
</span>
|
||||
|
||||
@@ -184,7 +184,7 @@ function onBackButton() {
|
||||
:class="$style.backButton"
|
||||
@click="onBackButton"
|
||||
>
|
||||
<font-awesome-icon :class="$style.backButtonIcon" icon="arrow-left" size="2x" />
|
||||
<n8n-icon :class="$style.backButtonIcon" icon="arrow-left" :size="22" />
|
||||
</button>
|
||||
<NodeIcon
|
||||
v-if="activeViewStack.nodeIcon"
|
||||
@@ -193,6 +193,7 @@ function onBackButton() {
|
||||
:circle="false"
|
||||
:show-tooltip="false"
|
||||
:size="20"
|
||||
:use-updated-icons="true"
|
||||
/>
|
||||
<p v-if="activeViewStack.title" :class="$style.title" v-text="activeViewStack.title" />
|
||||
|
||||
@@ -275,12 +276,11 @@ function onBackButton() {
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0 var(--spacing-xs) 0 0;
|
||||
padding: var(--spacing-2xs) var(--spacing-xs) 0 0;
|
||||
}
|
||||
|
||||
.backButtonIcon {
|
||||
color: $node-creator-arrow-color;
|
||||
height: 16px;
|
||||
padding: 0;
|
||||
}
|
||||
.nodeIcon {
|
||||
|
||||
@@ -53,7 +53,7 @@ defineExpose({
|
||||
<template>
|
||||
<div :class="$style.searchContainer" data-test-id="search-bar">
|
||||
<div :class="{ [$style.prefix]: true, [$style.active]: modelValue.length > 0 }">
|
||||
<font-awesome-icon icon="search" size="sm" />
|
||||
<n8n-icon icon="search" size="small" />
|
||||
</div>
|
||||
<div :class="$style.text">
|
||||
<input
|
||||
@@ -67,10 +67,8 @@ defineExpose({
|
||||
@input="onInput"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="modelValue.length > 0" :class="$style.suffix" @click="clear">
|
||||
<button :class="[$style.clear, $style.clickable]">
|
||||
<font-awesome-icon icon="times-circle" />
|
||||
</button>
|
||||
<div v-if="modelValue.length > 0" :class="[$style.suffix, $style.clickable]" @click="clear">
|
||||
<n8n-icon size="small" icon="circle-x" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -143,4 +141,8 @@ defineExpose({
|
||||
fill: $node-creator-search-clear-background-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -113,7 +113,7 @@ registerKeyHook(`CategoryLeft_${props.category}`, {
|
||||
>
|
||||
<span v-if="mouseOverTooltip" :class="$style.mouseOverTooltip">
|
||||
<n8n-tooltip placement="top" :popper-class="$style.tooltipPopper">
|
||||
<n8n-icon icon="question-circle" size="small" />
|
||||
<n8n-icon icon="circle-help" size="small" />
|
||||
<template #content>
|
||||
<div v-n8n-html="mouseOverTooltip" />
|
||||
</template>
|
||||
|
||||
@@ -55,7 +55,7 @@ const mockSubcategoryItemProps = (
|
||||
): SubcategoryItemProps => ({
|
||||
description: 'Sample description',
|
||||
iconType: 'sampleIconType',
|
||||
icon: 'sampleIcon',
|
||||
icon: 'smile',
|
||||
title: 'Sample title',
|
||||
subcategory: 'sampleSubcategory',
|
||||
defaults: { color: '#ffffff' },
|
||||
|
||||
@@ -255,7 +255,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
|
||||
properties: {
|
||||
title: AI_CATEGORY_DOCUMENT_LOADERS,
|
||||
info: getSubcategoryInfo(AI_CATEGORY_DOCUMENT_LOADERS),
|
||||
icon: 'file-import',
|
||||
icon: 'file-input',
|
||||
...getAISubcategoryProperties(NodeConnectionTypes.AiDocument),
|
||||
},
|
||||
},
|
||||
@@ -343,7 +343,7 @@ export function AINodesView(_nodes: SimplifiedNodeType[]): NodeView {
|
||||
properties: {
|
||||
title: AI_CATEGORY_VECTOR_STORES,
|
||||
info: getSubcategoryInfo(AI_CATEGORY_VECTOR_STORES),
|
||||
icon: 'project-diagram',
|
||||
icon: 'waypoints',
|
||||
...getAISubcategoryProperties(NodeConnectionTypes.AiVectorStore),
|
||||
},
|
||||
},
|
||||
@@ -571,7 +571,7 @@ export function RegularView(nodes: SimplifiedNodeType[]) {
|
||||
category: CORE_NODES_CATEGORY,
|
||||
properties: {
|
||||
title: FLOWS_CONTROL_SUBCATEGORY,
|
||||
icon: 'code-branch',
|
||||
icon: 'git-branch',
|
||||
sections: [
|
||||
{
|
||||
key: 'popular',
|
||||
|
||||
@@ -582,7 +582,7 @@ async function onClickCreateCredential(type: ICredentialType | INodeCredentialDe
|
||||
:items="getIssues(type.name)"
|
||||
/>
|
||||
</template>
|
||||
<N8nIcon icon="exclamation-triangle" />
|
||||
<N8nIcon icon="triangle-alert" />
|
||||
</N8nTooltip>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -870,7 +870,7 @@ onBeforeUnmount(() => {
|
||||
target="_blank"
|
||||
@click="onFeatureRequestClick"
|
||||
>
|
||||
<font-awesome-icon icon="lightbulb" />
|
||||
<n8n-icon icon="lightbulb" />
|
||||
{{ i18n.baseText('ndv.featureRequest') }}
|
||||
</a>
|
||||
</template>
|
||||
|
||||
@@ -31,6 +31,7 @@ import { generateCodeForAiTransform } from '@/components/ButtonParameter/utils';
|
||||
import { needsAgentInput } from '@/utils/nodes/nodeTransforms';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import type { ButtonType } from '@n8n/design-system';
|
||||
import { type IconName } from '@n8n/design-system/components/N8nIcon/icons';
|
||||
|
||||
const NODE_TEST_STEP_POPUP_COUNT_KEY = 'N8N_NODE_TEST_STEP_POPUP_COUNT';
|
||||
const MAX_POPUP_COUNT = 10;
|
||||
@@ -221,9 +222,9 @@ const isLoading = computed(
|
||||
(isNodeRunning.value && !isListeningForEvents.value && !isListeningForWorkflowEvents.value),
|
||||
);
|
||||
|
||||
const buttonIcon = computed(() => {
|
||||
const buttonIcon = computed((): IconName | undefined => {
|
||||
if (shouldGenerateCode.value) return 'terminal';
|
||||
if (!isListeningForEvents.value && !props.hideIcon) return 'flask';
|
||||
if (!isListeningForEvents.value && !props.hideIcon) return 'flask-conical';
|
||||
return undefined;
|
||||
});
|
||||
|
||||
|
||||
@@ -801,7 +801,7 @@ function handleWheelEvent(event: WheelEvent) {
|
||||
</div>
|
||||
<div v-if="node && !nodeValid" class="node-is-not-valid">
|
||||
<p :class="$style.warningIcon">
|
||||
<font-awesome-icon icon="exclamation-triangle" />
|
||||
<n8n-icon icon="triangle-alert" />
|
||||
</p>
|
||||
<div class="missingNodeTitleContainer mt-s mb-xs">
|
||||
<n8n-text size="large" color="text-dark" bold>
|
||||
|
||||
@@ -95,7 +95,7 @@ const options = computed<ITab[]>(() => {
|
||||
|
||||
if (isCommunityNode.value) {
|
||||
options.push({
|
||||
icon: 'cube',
|
||||
icon: 'box',
|
||||
value: 'communityNode',
|
||||
align: 'right',
|
||||
tooltip: i18n.baseText('generic.communityNode.tooltip', {
|
||||
|
||||
@@ -188,7 +188,7 @@ watch(
|
||||
:title="isMinimized ? baseText.clickToDisplay : baseText.clickToHide"
|
||||
@click="isMinimized = !isMinimized"
|
||||
>
|
||||
<font-awesome-icon icon="angle-right" class="minimize-button minimize-icon" />
|
||||
<n8n-icon icon="chevron-right" class="minimize-button minimize-icon" />
|
||||
{{ baseText.toggleTitle }}
|
||||
</div>
|
||||
<el-collapse-transition>
|
||||
|
||||
@@ -40,13 +40,13 @@ const onDragStart = () => {
|
||||
v-if="canMoveLeft"
|
||||
:class="{ [$style.leftArrow]: true, [$style.visible]: isDragging }"
|
||||
>
|
||||
<font-awesome-icon icon="arrow-left" />
|
||||
<n8n-icon icon="arrow-left" />
|
||||
</span>
|
||||
<span
|
||||
v-if="canMoveRight"
|
||||
:class="{ [$style.rightArrow]: true, [$style.visible]: isDragging }"
|
||||
>
|
||||
<font-awesome-icon icon="arrow-right" />
|
||||
<n8n-icon icon="arrow-right" />
|
||||
</span>
|
||||
<div :class="$style.grid">
|
||||
<div>
|
||||
|
||||
@@ -1399,7 +1399,7 @@ onUpdated(async () => {
|
||||
<N8nIcon
|
||||
v-if="!editorIsReadOnly"
|
||||
data-test-id="code-editor-fullscreen-button"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@@ -1420,7 +1420,7 @@ onUpdated(async () => {
|
||||
<template #suffix>
|
||||
<N8nIcon
|
||||
data-test-id="code-editor-fullscreen-button"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@@ -1439,7 +1439,7 @@ onUpdated(async () => {
|
||||
<template #suffix>
|
||||
<N8nIcon
|
||||
data-test-id="code-editor-fullscreen-button"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@@ -1459,7 +1459,7 @@ onUpdated(async () => {
|
||||
<template #suffix>
|
||||
<N8nIcon
|
||||
data-test-id="code-editor-fullscreen-button"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@@ -1480,7 +1480,7 @@ onUpdated(async () => {
|
||||
<N8nIcon
|
||||
v-if="!editorIsReadOnly"
|
||||
data-test-id="code-editor-fullscreen-button"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@@ -1499,7 +1499,7 @@ onUpdated(async () => {
|
||||
<template #suffix>
|
||||
<N8nIcon
|
||||
data-test-id="code-editor-fullscreen-button"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@@ -1545,7 +1545,7 @@ onUpdated(async () => {
|
||||
<template #suffix>
|
||||
<N8nIcon
|
||||
v-if="!isReadOnly && !isSecretParameter"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
size="xsmall"
|
||||
class="edit-window-button textarea-modal-opener"
|
||||
:class="{
|
||||
|
||||
@@ -647,7 +647,7 @@ const onCalloutDismiss = async (parameter: INodeProperties) => {
|
||||
|
||||
<template #trailingContent>
|
||||
<N8nIcon
|
||||
icon="times"
|
||||
icon="x"
|
||||
title="Dismiss"
|
||||
size="medium"
|
||||
type="secondary"
|
||||
@@ -694,7 +694,7 @@ const onCalloutDismiss = async (parameter: INodeProperties) => {
|
||||
issue
|
||||
}}</span>
|
||||
</template>
|
||||
<N8nIcon icon="exclamation-triangle" size="small" color="danger" />
|
||||
<N8nIcon icon="triangle-alert" size="small" color="danger" />
|
||||
</N8nTooltip>
|
||||
</template>
|
||||
</N8nInputLabel>
|
||||
@@ -721,13 +721,13 @@ const onCalloutDismiss = async (parameter: INodeProperties) => {
|
||||
</template>
|
||||
<template #fallback>
|
||||
<N8nText size="small" class="async-notice">
|
||||
<N8nIcon icon="sync-alt" size="xsmall" :spin="true" />
|
||||
<N8nIcon icon="refresh-cw" size="xsmall" :spin="true" />
|
||||
{{ i18n.baseText('parameterInputList.loadingFields') }}
|
||||
</N8nText>
|
||||
</template>
|
||||
</Suspense>
|
||||
<N8nText v-else size="small" color="danger" class="async-notice">
|
||||
<N8nIcon icon="exclamation-triangle" size="xsmall" />
|
||||
<N8nIcon icon="triangle-alert" size="xsmall" />
|
||||
{{ i18n.baseText('parameterInputList.loadingError') }}
|
||||
</N8nText>
|
||||
<N8nIconButton
|
||||
@@ -735,7 +735,7 @@ const onCalloutDismiss = async (parameter: INodeProperties) => {
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
class="icon-button"
|
||||
:title="i18n.baseText('parameterInputList.delete')"
|
||||
@click="deleteOption(parameter.name)"
|
||||
@@ -778,7 +778,7 @@ const onCalloutDismiss = async (parameter: INodeProperties) => {
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
class="icon-button"
|
||||
:title="i18n.baseText('parameterInputList.delete')"
|
||||
@click="deleteOption(parameter.name)"
|
||||
|
||||
@@ -27,7 +27,7 @@ const emit = defineEmits<{
|
||||
type="tertiary"
|
||||
:class="['n8n-input', $style.overrideCloseButton]"
|
||||
:outline="false"
|
||||
icon="xmark"
|
||||
icon="x"
|
||||
size="mini"
|
||||
@click="emit('close')"
|
||||
/>
|
||||
|
||||
@@ -16,7 +16,7 @@ const i18n = useI18n();
|
||||
<template #content>
|
||||
<TitledList :title="`${i18n.baseText('parameterInput.issues')}:`" :items="issues" />
|
||||
</template>
|
||||
<N8nIcon icon="exclamation-triangle" />
|
||||
<N8nIcon icon="triangle-alert" />
|
||||
</N8nTooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('ParameterOptions', () => {
|
||||
iconOrientation: 'horizontal',
|
||||
},
|
||||
});
|
||||
expect(container.querySelector('[data-icon="ellipsis-h"]')).toBeInTheDocument();
|
||||
expect(container.querySelector('[data-icon="ellipsis"]')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render custom actions', async () => {
|
||||
|
||||
@@ -177,7 +177,7 @@ const getArgument = (argumentName: string) => {
|
||||
<div :class="$style.container" data-test-id="parameter-options-container">
|
||||
<div v-if="loading" :class="$style.loader" data-test-id="parameter-options-loader">
|
||||
<n8n-text v-if="loading" size="small">
|
||||
<n8n-icon icon="sync-alt" size="xsmall" :spin="true" />
|
||||
<n8n-icon icon="refresh-cw" size="xsmall" :spin="true" />
|
||||
{{ loadingMessage }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { ResourceType, splitName } from '@/utils/projects.utils';
|
||||
import type { Project, ProjectIcon as BadgeIcon } from '@/types/projects.types';
|
||||
import type { Project } from '@/types/projects.types';
|
||||
import { ProjectTypes } from '@/types/projects.types';
|
||||
import type { CredentialsResource, FolderResource, WorkflowResource } from '@/Interface';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { type IconOrEmoji, isIconOrEmoji } from '@n8n/design-system/components/N8nIconPicker/types';
|
||||
|
||||
type Props = {
|
||||
resource: WorkflowResource | CredentialsResource | FolderResource;
|
||||
@@ -76,7 +77,7 @@ const badgeText = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const badgeIcon = computed<BadgeIcon>(() => {
|
||||
const badgeIcon = computed<IconOrEmoji>(() => {
|
||||
switch (projectState.value) {
|
||||
case ProjectState.Owned:
|
||||
case ProjectState.SharedOwned:
|
||||
@@ -85,9 +86,11 @@ const badgeIcon = computed<BadgeIcon>(() => {
|
||||
return { type: 'icon', value: 'user' };
|
||||
case ProjectState.Team:
|
||||
case ProjectState.SharedTeam:
|
||||
return props.resource.homeProject?.icon ?? { type: 'icon', value: 'layer-group' };
|
||||
return isIconOrEmoji(props.resource.homeProject?.icon)
|
||||
? props.resource.homeProject?.icon
|
||||
: { type: 'icon', value: 'layers' };
|
||||
default:
|
||||
return { type: 'icon', value: 'layer-group' };
|
||||
return { type: 'icon', value: 'layers' };
|
||||
}
|
||||
});
|
||||
const badgeTooltip = computed(() => {
|
||||
|
||||
@@ -35,7 +35,7 @@ defineExpose({
|
||||
<N8nIconButton
|
||||
:disabled="disabled"
|
||||
:class="[$style.buttonGroupDropdown]"
|
||||
icon="angle-down"
|
||||
icon="chevron-down"
|
||||
:type="type ?? 'primary'"
|
||||
/>
|
||||
</N8nActionToggle>
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('ProjectHeader', () => {
|
||||
vi.spyOn(projectPages, 'isOverviewSubPage', 'get').mockReturnValue(true);
|
||||
const { container } = renderComponent();
|
||||
|
||||
expect(container.querySelector('.fa-home')).not.toBeInTheDocument();
|
||||
expect(container.querySelector('svg[data-icon=home]')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the correct icon', async () => {
|
||||
@@ -86,12 +86,12 @@ describe('ProjectHeader', () => {
|
||||
// We no longer render icon for personal project
|
||||
projectsStore.currentProject = { type: ProjectTypes.Personal } as Project;
|
||||
await rerender({});
|
||||
expect(container.querySelector('.fa-user')).not.toBeInTheDocument();
|
||||
expect(container.querySelector('svg[data-icon=user]')).not.toBeInTheDocument();
|
||||
|
||||
const projectName = 'My Project';
|
||||
projectsStore.currentProject = { name: projectName } as Project;
|
||||
await rerender({});
|
||||
expect(container.querySelector('.fa-layer-group')).toBeVisible();
|
||||
expect(container.querySelector('svg[data-icon=layers]')).toBeVisible();
|
||||
});
|
||||
|
||||
it('Overview: should render the correct title and subtitle', async () => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useElementSize, useResizeObserver } from '@vueuse/core';
|
||||
import type { UserAction } from '@n8n/design-system';
|
||||
import { N8nButton, N8nTooltip } from '@n8n/design-system';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { type ProjectIcon as ProjectIconType, ProjectTypes } from '@/types/projects.types';
|
||||
import { ProjectTypes } from '@/types/projects.types';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
|
||||
import ProjectIcon from '@/components/Projects/ProjectIcon.vue';
|
||||
@@ -16,7 +16,9 @@ import ProjectCreateResource from '@/components/Projects/ProjectCreateResource.v
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useProjectPages } from '@/composables/useProjectPages';
|
||||
import { truncateTextToFitWidth } from '@/utils/formatters/textFormatter';
|
||||
import { type IconName } from '@n8n/design-system/components/N8nIcon/icons';
|
||||
import type { IUser } from 'n8n-workflow';
|
||||
import { type IconOrEmoji, isIconOrEmoji } from '@n8n/design-system/components/N8nIconPicker/types';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
@@ -30,13 +32,15 @@ const emit = defineEmits<{
|
||||
createFolder: [];
|
||||
}>();
|
||||
|
||||
const headerIcon = computed((): ProjectIconType => {
|
||||
const headerIcon = computed((): IconOrEmoji => {
|
||||
if (projectsStore.currentProject?.type === ProjectTypes.Personal) {
|
||||
return { type: 'icon', value: 'user' };
|
||||
} else if (projectsStore.currentProject?.name) {
|
||||
return projectsStore.currentProject.icon ?? { type: 'icon', value: 'layer-group' };
|
||||
return isIconOrEmoji(projectsStore.currentProject.icon)
|
||||
? projectsStore.currentProject.icon
|
||||
: { type: 'icon', value: 'layers' };
|
||||
} else {
|
||||
return { type: 'icon', value: 'home' };
|
||||
return { type: 'icon', value: 'house' };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -89,7 +93,7 @@ type ActionTypes = (typeof ACTION_TYPES)[keyof typeof ACTION_TYPES];
|
||||
const createWorkflowButton = computed(() => ({
|
||||
value: ACTION_TYPES.WORKFLOW,
|
||||
label: i18n.baseText('projects.header.create.workflow'),
|
||||
icon: sourceControlStore.preferences.branchReadOnly ? 'lock' : undefined,
|
||||
icon: sourceControlStore.preferences.branchReadOnly ? ('lock' as IconName) : undefined,
|
||||
size: 'mini' as const,
|
||||
disabled:
|
||||
sourceControlStore.preferences.branchReadOnly ||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import type { ProjectIcon } from '@/types/projects.types';
|
||||
import { type IconOrEmoji } from '@n8n/design-system/components/N8nIconPicker/types';
|
||||
|
||||
type Props = {
|
||||
icon: ProjectIcon;
|
||||
icon: IconOrEmoji;
|
||||
size?: 'mini' | 'small' | 'medium' | 'large';
|
||||
round?: boolean;
|
||||
borderLess?: boolean;
|
||||
|
||||
@@ -28,7 +28,7 @@ const isFoldersFeatureEnabled = computed(() => settingsStore.isFoldersFeatureEna
|
||||
const home = computed<IMenuItem>(() => ({
|
||||
id: 'home',
|
||||
label: locale.baseText('projects.menu.overview'),
|
||||
icon: 'home',
|
||||
icon: 'house',
|
||||
route: {
|
||||
to: { name: VIEWS.HOMEPAGE },
|
||||
},
|
||||
|
||||
@@ -4,12 +4,12 @@ import { computed, ref, watch } from 'vue';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import {
|
||||
ProjectTypes,
|
||||
type ProjectIcon as ProjectIconItem,
|
||||
type ProjectListItem,
|
||||
type ProjectSharingData,
|
||||
} from '@/types/projects.types';
|
||||
import ProjectSharingInfo from '@/components/Projects/ProjectSharingInfo.vue';
|
||||
import { sortByProperty } from '@n8n/utils/sort/sortByProperty';
|
||||
import { isIconOrEmoji, type IconOrEmoji } from '@n8n/design-system/components/N8nIconPicker/types';
|
||||
|
||||
const locale = useI18n();
|
||||
|
||||
@@ -51,14 +51,14 @@ const filteredProjects = computed(() =>
|
||||
),
|
||||
);
|
||||
|
||||
const projectIcon = computed<ProjectIconItem>(() => {
|
||||
const defaultIcon: ProjectIconItem = { type: 'icon', value: 'layer-group' };
|
||||
const projectIcon = computed<IconOrEmoji>(() => {
|
||||
const defaultIcon: IconOrEmoji = { type: 'icon', value: 'layers' };
|
||||
const project = props.projects.find((p) => p.id === selectedProject.value);
|
||||
|
||||
if (project?.type === ProjectTypes.Personal) {
|
||||
return { type: 'icon', value: 'user' };
|
||||
} else if (project?.type === ProjectTypes.Team) {
|
||||
return project.icon ?? defaultIcon;
|
||||
return isIconOrEmoji(project.icon) ? project.icon : defaultIcon;
|
||||
}
|
||||
|
||||
return defaultIcon;
|
||||
@@ -171,7 +171,7 @@ watch(
|
||||
type="tertiary"
|
||||
native-type="button"
|
||||
square
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
:disabled="props.readonly"
|
||||
data-test-id="project-sharing-remove"
|
||||
@click="onRoleAction(project, 'remove')"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { computed } from 'vue';
|
||||
import type { ProjectListItem, ProjectSharingData } from '@/types/projects.types';
|
||||
import { splitName } from '@/utils/projects.utils';
|
||||
import { isIconOrEmoji } from '@n8n/design-system/components/N8nIconPicker/types';
|
||||
|
||||
type Props = {
|
||||
project: ProjectListItem | ProjectSharingData;
|
||||
@@ -21,7 +22,7 @@ const processedName = computed(() => {
|
||||
});
|
||||
|
||||
const projectIcon = computed(() => {
|
||||
if (props.project.icon) {
|
||||
if (props.project.icon && isIconOrEmoji(props.project.icon)) {
|
||||
return props.project.icon;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -29,7 +29,9 @@ describe('PushConnectionTracker', () => {
|
||||
});
|
||||
setActivePinia(pinia);
|
||||
|
||||
return createComponentRenderer(PushConnectionTracker)();
|
||||
return createComponentRenderer(PushConnectionTracker, {
|
||||
global: { stubs: { N8nIcon: true } },
|
||||
})();
|
||||
};
|
||||
|
||||
it('should not render error when connected and connection requested', () => {
|
||||
|
||||
@@ -23,7 +23,7 @@ const showConnectionLostError = computed(() => {
|
||||
<div v-n8n-html="i18n.baseText('pushConnectionTracker.cannotConnectToServer')"></div>
|
||||
</template>
|
||||
<span>
|
||||
<font-awesome-icon icon="exclamation-triangle" />
|
||||
<n8n-icon icon="triangle-alert" />
|
||||
{{ i18n.baseText('pushConnectionTracker.connectionLost') }}
|
||||
</span>
|
||||
</n8n-tooltip>
|
||||
|
||||
@@ -1069,7 +1069,7 @@ function removeOverride() {
|
||||
/>
|
||||
<div v-else-if="urlValue" :class="$style.openResourceLink">
|
||||
<n8n-link theme="text" @click.stop="openResource(urlValue)">
|
||||
<font-awesome-icon icon="external-link-alt" :title="getLinkAlt(valueToDisplay)" />
|
||||
<n8n-icon icon="external-link" :title="getLinkAlt(valueToDisplay)" />
|
||||
</n8n-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -244,7 +244,7 @@ defineExpose({ isWithinDropdown });
|
||||
@update:model-value="onFilterInput"
|
||||
>
|
||||
<template #prefix>
|
||||
<font-awesome-icon :class="$style.searchIcon" icon="search" />
|
||||
<n8n-icon :class="$style.searchIcon" icon="search" />
|
||||
</template>
|
||||
</N8nInput>
|
||||
</div>
|
||||
@@ -278,7 +278,7 @@ defineExpose({ isWithinDropdown });
|
||||
>
|
||||
<div :class="$style.resourceNameContainer">
|
||||
<span :class="$style.addResourceText">{{ allowNewResources.label }}</span>
|
||||
<font-awesome-icon :class="$style.addResourceIcon" :icon="['fa', 'plus']" />
|
||||
<n8n-icon :class="$style.addResourceIcon" icon="plus" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -304,9 +304,9 @@ defineExpose({ isWithinDropdown });
|
||||
</span>
|
||||
</div>
|
||||
<div :class="$style.urlLink">
|
||||
<font-awesome-icon
|
||||
<n8n-icon
|
||||
v-if="showHoverUrl && result.url && hoverIndex === i + 1"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
:title="result.linkAlt || i18n.baseText('resourceLocator.mode.list.openUrl')"
|
||||
@click="openUrl($event, result.url)"
|
||||
/>
|
||||
|
||||
@@ -319,10 +319,10 @@ defineExpose({
|
||||
})
|
||||
}}</span>
|
||||
</template>
|
||||
<N8nIcon icon="exclamation-triangle" size="small" color="warning" />
|
||||
<N8nIcon icon="triangle-alert" size="small" color="warning" />
|
||||
</N8nTooltip>
|
||||
<N8nIconButton
|
||||
icon="refresh"
|
||||
icon="refresh-cw"
|
||||
type="tertiary"
|
||||
size="small"
|
||||
:text="true"
|
||||
@@ -368,7 +368,7 @@ defineExpose({
|
||||
})
|
||||
}}</span>
|
||||
</template>
|
||||
<font-awesome-icon icon="question-circle" />
|
||||
<N8nIcon icon="circle-help" />
|
||||
</N8nTooltip>
|
||||
</div>
|
||||
<div
|
||||
@@ -385,7 +385,7 @@ defineExpose({
|
||||
type="tertiary"
|
||||
text
|
||||
size="mini"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
:data-test-id="`remove-field-button-${getParsedFieldName(field.name)}`"
|
||||
:title="
|
||||
locale.baseText('resourceMapper.removeField', {
|
||||
|
||||
@@ -138,7 +138,7 @@ defineExpose({
|
||||
</div>
|
||||
<div class="mt-5xs">
|
||||
<N8nText v-if="loading" size="small">
|
||||
<N8nIcon icon="sync-alt" size="xsmall" :spin="true" />
|
||||
<N8nIcon icon="refresh-cw" size="xsmall" :spin="true" />
|
||||
{{
|
||||
locale.baseText('resourceMapper.fetchingFields.message', {
|
||||
interpolate: {
|
||||
@@ -148,7 +148,7 @@ defineExpose({
|
||||
}}
|
||||
</N8nText>
|
||||
<N8nText v-else-if="errorMessage !== ''" size="small" color="danger">
|
||||
<N8nIcon icon="exclamation-triangle" size="xsmall" />
|
||||
<N8nIcon icon="triangle-alert" size="xsmall" />
|
||||
{{ errorMessage }}
|
||||
<N8nLink size="small" theme="danger" :underline="true" @click="onRetryClick">
|
||||
{{ locale.baseText('generic.retry') }}
|
||||
|
||||
@@ -598,7 +598,7 @@ defineExpose({
|
||||
@refresh-field-list="initFetching(true)"
|
||||
/>
|
||||
<N8nText v-if="!showMappingModeSelect && state.loading" size="small">
|
||||
<N8nIcon icon="sync-alt" size="xsmall" :spin="true" />
|
||||
<N8nIcon icon="refresh-cw" size="xsmall" :spin="true" />
|
||||
{{
|
||||
locale.baseText('resourceMapper.fetchingFields.message', {
|
||||
interpolate: {
|
||||
@@ -639,7 +639,7 @@ defineExpose({
|
||||
<template #trailingContent>
|
||||
<N8nButton
|
||||
size="mini"
|
||||
icon="refresh"
|
||||
icon="refresh-cw"
|
||||
type="secondary"
|
||||
:loading="state.refreshInProgress"
|
||||
@click="initFetching(true)"
|
||||
|
||||
@@ -1355,7 +1355,7 @@ defineExpose({ enterEditMode });
|
||||
!isProductionExecutionPreview
|
||||
"
|
||||
theme="secondary"
|
||||
icon="thumbtack"
|
||||
icon="pin"
|
||||
:class="$style.pinnedDataCallout"
|
||||
data-test-id="ndv-pinned-data-callout"
|
||||
>
|
||||
@@ -1444,7 +1444,7 @@ defineExpose({ enterEditMode });
|
||||
:title="i18n.baseText('runData.editOutput')"
|
||||
:circle="false"
|
||||
:disabled="node?.disabled"
|
||||
icon="pencil-alt"
|
||||
icon="pencil"
|
||||
type="tertiary"
|
||||
data-test-id="ndv-edit-pinned-data"
|
||||
@click="enterEditMode({ origin: 'editIconButton' })"
|
||||
|
||||
@@ -7,7 +7,6 @@ import type { NodeConnectionType, NodeError } from 'n8n-workflow';
|
||||
import RunDataAi from '@/components/RunDataParsedAiContent.vue';
|
||||
import { parseAiContent } from '@/utils/aiUtils';
|
||||
import { N8nRadioButtons } from '@n8n/design-system';
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
|
||||
const props = defineProps<{
|
||||
runData: IAiDataContent;
|
||||
@@ -52,7 +51,7 @@ function onRenderTypeChange(value: 'rendered' | 'json') {
|
||||
<div :class="$style.block">
|
||||
<header :class="$style.blockHeader" @click="onBlockHeaderClick">
|
||||
<button :class="$style.blockToggle">
|
||||
<FontAwesomeIcon :icon="isExpanded ? 'angle-down' : 'angle-right'" size="lg" />
|
||||
<N8nIcon :icon="isExpanded ? 'chevron-down' : 'chevron-right'" size="large" />
|
||||
</button>
|
||||
<p :class="$style.blockTitle">{{ capitalize(runData.inOut) }}</p>
|
||||
<N8nRadioButtons
|
||||
|
||||
@@ -117,7 +117,7 @@ watch(() => props.runIndex, selectFirst, { immediate: true });
|
||||
:class="$style.treeToggle"
|
||||
@click="toggleTreeItem(currentNode)"
|
||||
>
|
||||
<font-awesome-icon :icon="currentNode.expanded ? 'angle-down' : 'angle-right'" />
|
||||
<n8n-icon :icon="currentNode.expanded ? 'chevron-down' : 'chevron-right'" />
|
||||
</button>
|
||||
<n8n-tooltip :disabled="!slim" placement="right">
|
||||
<template #content>
|
||||
|
||||
@@ -65,7 +65,7 @@ watch(
|
||||
<N8nIcon v-else-if="option.value === 'json'" icon="json" size="small" />
|
||||
<N8nIcon v-else-if="option.value === 'binary'" icon="binary" size="small" />
|
||||
<N8nIcon v-else-if="option.value === 'schema'" icon="schema" size="small" />
|
||||
<N8nIcon v-else-if="option.value === 'html'" icon="html" size="small" />
|
||||
<N8nIcon v-else-if="option.value === 'html'" icon="file-code" size="small" />
|
||||
<N8nIcon v-else-if="option.value === 'ai'" icon="text" size="small" />
|
||||
<span v-else>{{ option.label }}</span>
|
||||
</template>
|
||||
|
||||
@@ -180,7 +180,7 @@ function handleCopyClick(commandData: { command: string }) {
|
||||
<n8n-icon-button
|
||||
v-if="noSelection"
|
||||
:title="i18n.baseText('runData.copyToClipboard')"
|
||||
icon="copy"
|
||||
icon="files"
|
||||
type="tertiary"
|
||||
:circle="false"
|
||||
@click="handleCopyClick({ command: 'value' })"
|
||||
@@ -189,7 +189,7 @@ function handleCopyClick(commandData: { command: string }) {
|
||||
<span class="el-dropdown-link">
|
||||
<n8n-icon-button
|
||||
:title="i18n.baseText('runData.copyToClipboard')"
|
||||
icon="copy"
|
||||
icon="files"
|
||||
type="tertiary"
|
||||
:circle="false"
|
||||
/>
|
||||
|
||||
@@ -128,7 +128,7 @@ function onCopyToClipboard(object: IDataObject | IDataObject[]) {
|
||||
:class="$style.copyToClipboard"
|
||||
type="secondary"
|
||||
:title="i18n.baseText('nodeErrorView.copyToClipboard')"
|
||||
icon="copy"
|
||||
icon="files"
|
||||
@click="onCopyToClipboard(raw)"
|
||||
/>
|
||||
<VueMarkdown :source="jsonToMarkdown(raw as JsonMarkdown)" :class="$style.markdown" />
|
||||
|
||||
@@ -56,7 +56,7 @@ const visible = computed(() =>
|
||||
:class="$style.pinDataButton"
|
||||
type="tertiary"
|
||||
:active="props.pinnedData.hasData.value"
|
||||
icon="thumbtack"
|
||||
icon="pin"
|
||||
:disabled="props.disabled"
|
||||
data-test-id="ndv-pin-data"
|
||||
@click="emit('togglePinData')"
|
||||
|
||||
@@ -479,7 +479,7 @@ watch(focusedMappableInput, (curr) => {
|
||||
v-show="showExecutionLink(index1)"
|
||||
element="a"
|
||||
type="secondary"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
data-test-id="debug-sub-execution"
|
||||
size="mini"
|
||||
target="_blank"
|
||||
@@ -541,7 +541,7 @@ watch(focusedMappableInput, (curr) => {
|
||||
:search="search"
|
||||
/>
|
||||
<div :class="$style.dragButton">
|
||||
<font-awesome-icon icon="grip-vertical" />
|
||||
<n8n-icon icon="grip-vertical" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -563,10 +563,7 @@ watch(focusedMappableInput, (curr) => {
|
||||
</div>
|
||||
</template>
|
||||
<span>
|
||||
<font-awesome-icon
|
||||
:class="$style['warningTooltip']"
|
||||
icon="exclamation-triangle"
|
||||
></font-awesome-icon>
|
||||
<n8n-icon :class="$style['warningTooltip']" icon="triangle-alert" />
|
||||
{{ i18n.baseText('dataMapping.tableView.tableColumnsExceeded') }}
|
||||
</span>
|
||||
</N8nTooltip>
|
||||
@@ -618,7 +615,7 @@ watch(focusedMappableInput, (curr) => {
|
||||
v-show="showExecutionLink(index1)"
|
||||
element="a"
|
||||
type="secondary"
|
||||
icon="external-link-alt"
|
||||
icon="external-link"
|
||||
data-test-id="debug-sub-execution"
|
||||
size="mini"
|
||||
target="_blank"
|
||||
|
||||
@@ -52,7 +52,12 @@ const runMetadata = computed(() => {
|
||||
></span>
|
||||
</N8nInfoTip>
|
||||
<div v-else-if="runMetadata" :class="$style.tooltipRow">
|
||||
<N8nInfoTip type="note" :theme="theme" :data-test-id="`node-run-status-${theme}`" />
|
||||
<N8nInfoTip
|
||||
type="note"
|
||||
:theme="theme"
|
||||
:data-test-id="`node-run-status-${theme}`"
|
||||
size="large"
|
||||
/>
|
||||
<N8nInfoTip
|
||||
type="tooltip"
|
||||
theme="info"
|
||||
|
||||
@@ -397,7 +397,7 @@ const { width } = useElementSize(defNameRef);
|
||||
<div :class="$style.destinationActions">
|
||||
<n8n-button
|
||||
v-if="nodeParameters && hasOnceBeenSaved && unchanged"
|
||||
:icon="testMessageSent ? (testMessageResult ? 'check' : 'exclamation-triangle') : ''"
|
||||
:icon="testMessageSent ? (testMessageResult ? 'check' : 'triangle-alert') : undefined"
|
||||
:title="
|
||||
testMessageSent && testMessageResult
|
||||
? 'Event sent and returned OK'
|
||||
@@ -413,7 +413,7 @@ const { width } = useElementSize(defNameRef);
|
||||
<n8n-icon-button
|
||||
v-if="nodeParameters && hasOnceBeenSaved"
|
||||
:title="i18n.baseText('settings.log-streaming.delete')"
|
||||
icon="trash"
|
||||
icon="trash-2"
|
||||
type="tertiary"
|
||||
:disabled="isSaving"
|
||||
:loading="isDeleting"
|
||||
|
||||
@@ -85,7 +85,7 @@ export default defineComponent({
|
||||
:popper-class="$style.tooltipPopper"
|
||||
class="ml-xs"
|
||||
>
|
||||
<n8n-icon icon="question-circle" size="small" class="ml-4xs" />
|
||||
<n8n-icon icon="circle-help" size="small" class="ml-4xs" />
|
||||
<template #content>
|
||||
{{ groupLabelInfo(group.name) }}
|
||||
</template>
|
||||
@@ -100,7 +100,7 @@ export default defineComponent({
|
||||
>
|
||||
{{ i18n.baseText('settings.log-streaming.tab.events.anonymize') }}
|
||||
<n8n-tooltip placement="top" :popper-class="$style.tooltipPopper">
|
||||
<n8n-icon icon="question-circle" size="small" class="ml-4xs" />
|
||||
<n8n-icon icon="circle-help" size="small" class="ml-4xs" />
|
||||
<template #content>
|
||||
{{ i18n.baseText('settings.log-streaming.tab.events.anonymize.info') }}
|
||||
</template>
|
||||
|
||||
@@ -28,7 +28,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
const menuItems: IMenuItem[] = [
|
||||
{
|
||||
id: 'settings-usage-and-plan',
|
||||
icon: 'chart-bar',
|
||||
icon: 'chart-column-decreasing',
|
||||
label: i18n.baseText('settings.usageAndPlan.title'),
|
||||
position: 'top',
|
||||
available: canUserAccessRouteByName(VIEWS.USAGE),
|
||||
@@ -36,7 +36,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
},
|
||||
{
|
||||
id: 'settings-personal',
|
||||
icon: 'user-circle',
|
||||
icon: 'circle-user-round',
|
||||
label: i18n.baseText('settings.personal'),
|
||||
position: 'top',
|
||||
available: canUserAccessRouteByName(VIEWS.PERSONAL_SETTINGS),
|
||||
@@ -44,7 +44,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
},
|
||||
{
|
||||
id: 'settings-users',
|
||||
icon: 'user-friends',
|
||||
icon: 'user-round',
|
||||
label: i18n.baseText('settings.users'),
|
||||
position: 'top',
|
||||
available: canUserAccessRouteByName(VIEWS.USERS_SETTINGS),
|
||||
@@ -69,7 +69,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
|
||||
{
|
||||
id: 'settings-source-control',
|
||||
icon: 'code-branch',
|
||||
icon: 'git-branch',
|
||||
label: i18n.baseText('settings.sourceControl.title'),
|
||||
position: 'top',
|
||||
available: canUserAccessRouteByName(VIEWS.SOURCE_CONTROL),
|
||||
@@ -85,7 +85,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
},
|
||||
{
|
||||
id: 'settings-ldap',
|
||||
icon: 'network-wired',
|
||||
icon: 'network',
|
||||
label: i18n.baseText('settings.ldap'),
|
||||
position: 'top',
|
||||
available: canUserAccessRouteByName(VIEWS.LDAP_SETTINGS),
|
||||
@@ -93,7 +93,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
},
|
||||
{
|
||||
id: 'settings-workersview',
|
||||
icon: 'project-diagram',
|
||||
icon: 'waypoints',
|
||||
label: i18n.baseText('mainSidebar.workersView'),
|
||||
position: 'top',
|
||||
available:
|
||||
@@ -105,7 +105,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
|
||||
menuItems.push({
|
||||
id: 'settings-log-streaming',
|
||||
icon: 'sign-in-alt',
|
||||
icon: 'log-in',
|
||||
label: i18n.baseText('settings.log-streaming'),
|
||||
position: 'top',
|
||||
available: canUserAccessRouteByName(VIEWS.LOG_STREAMING_SETTINGS),
|
||||
@@ -114,7 +114,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
|
||||
menuItems.push({
|
||||
id: 'settings-community-nodes',
|
||||
icon: 'cube',
|
||||
icon: 'box',
|
||||
label: i18n.baseText('settings.communityNodes'),
|
||||
position: 'top',
|
||||
available: canUserAccessRouteByName(VIEWS.COMMUNITY_NODES),
|
||||
@@ -131,7 +131,7 @@ const sidebarMenuItems = computed<IMenuItem[]>(() => {
|
||||
<template #header>
|
||||
<div :class="$style.returnButton" data-test-id="settings-back" @click="emit('return')">
|
||||
<i class="mr-xs">
|
||||
<font-awesome-icon icon="arrow-left" />
|
||||
<n8n-icon icon="arrow-left" />
|
||||
</i>
|
||||
<n8n-heading size="large" :bold="true">{{ i18n.baseText('settings') }}</n8n-heading>
|
||||
</div>
|
||||
|
||||
@@ -63,7 +63,7 @@ onBeforeUnmount(() => {
|
||||
:label="i18n.baseText('nodeView.setupTemplate')"
|
||||
data-test-id="setup-credentials-button"
|
||||
size="large"
|
||||
icon="box-open"
|
||||
icon="package-open"
|
||||
type="secondary"
|
||||
@click="handleClick()"
|
||||
/>
|
||||
|
||||
@@ -595,7 +595,7 @@ function castProject(project: ProjectListItem) {
|
||||
<N8nPopover trigger="click" width="304" style="align-self: normal">
|
||||
<template #reference>
|
||||
<N8nButton
|
||||
icon="filter"
|
||||
icon="funnel"
|
||||
type="tertiary"
|
||||
style="height: 100%"
|
||||
:active="Boolean(filterCount)"
|
||||
@@ -658,7 +658,7 @@ function castProject(project: ProjectListItem) {
|
||||
{{ i18n.baseText('settings.sourceControl.modals.push.projectAdmin.callout') }}
|
||||
<template #trailingContent>
|
||||
<N8nIcon
|
||||
icon="times"
|
||||
icon="x"
|
||||
title="Dismiss"
|
||||
size="medium"
|
||||
type="secondary"
|
||||
|
||||
@@ -233,7 +233,7 @@ onClickOutside(
|
||||
:value="CREATE_KEY"
|
||||
class="ops"
|
||||
>
|
||||
<font-awesome-icon icon="plus-circle" />
|
||||
<n8n-icon icon="circle-plus" />
|
||||
<span>
|
||||
{{ i18n.baseText('tagsDropdown.createTag', { interpolate: { filter } }) }}
|
||||
</span>
|
||||
@@ -257,7 +257,7 @@ onClickOutside(
|
||||
/>
|
||||
|
||||
<N8nOption v-if="manageEnabled" :key="MANAGE_KEY" :value="MANAGE_KEY" class="ops manage-tags">
|
||||
<font-awesome-icon icon="cog" />
|
||||
<n8n-icon icon="cog" />
|
||||
<span>{{ i18n.baseText('tagsDropdown.manageTags') }}</span>
|
||||
</N8nOption>
|
||||
</N8nSelect>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user