Files
lcbp3.np-dms.work/n8n-cache/n8n/public/assets/MainSidebar-D_xwIVsL.js
2025-09-21 20:29:15 +07:00

1577 lines
61 KiB
JavaScript
Executable File

import { d as defineComponent, r as ref, e as createBlock, g as openBlock, w as withCtx, i as createVNode, l as unref, b5 as ElSubMenu, n as normalizeClass, h as createElementBlock, F as Fragment, A as renderList, b6 as _sfc_main$6, b7 as ElMenuItem, f as createCommentVNode, k as createTextVNode, X as renderSlot, N as N8nIcon, p as N8nText, t as toDisplayString, K as mergeProps, b8 as withKeys, b9 as ElMenu, _ as _export_sfc, ba as get, af as useSourceControlStore, au as useProjectsStore, a2 as useRoute, b as useRouter, x as computed, aD as hasPermission, aB as getResourcePermissions, ap as normalizeStyle, j as createBaseVNode, a9 as Tooltip, q as N8nButton, c as useI18n, $ as defineStore, bb as useCloudPlanStore, at as useRootStore, bc as useStorage, bd as DateTime, a4 as STORES, al as useTelemetry, v as useSettingsStore, a as useToast, be as sortByProperty, V as VIEWS, bf as updatedIconSet, aA as usePageRedirectionHelper, u as useUsersStore, b1 as onBeforeMount, bg as N8nMenuItem, bh as useDebugInfo, bi as useVersionsStore, Q as useUIStore, C as N8nLink, bj as VERSIONS_MODAL_KEY, bk as useTemplatesStore, a1 as useWorkflowsStore, bl as usePersonalizedTemplatesV2Store, P as useDebounce, bm as useCalloutHelpers, bn as useKeybindings, bo as RELEASE_NOTES_URL, o as onMounted, bp as useExternalHooks, Y as nextTick, W as onBeforeUnmount, bq as onClickOutside, a8 as resolveComponent, ab as I18nT, aa as _sfc_main$7, br as createSlots, G as N8nAvatar, aM as N8nActionDropdown, bs as N8nMenu, bt as WHATS_NEW_MODAL_KEY, bu as ABOUT_MODAL_KEY, bv as EXPERIMENT_TEMPLATE_RECO_V2_KEY, bw as trackTemplatesClick, bx as TemplateClickSource } from "./index--OJ5nhDf.js";
import { L as Logo } from "./Logo-DHG_oEvt.js";
const ROOT_MENU_INDEX = "-1";
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
...{
name: "N8nNavigationDropdown"
},
__name: "NavigationDropdown",
props: {
menu: {},
disabled: { type: Boolean },
teleport: { type: Boolean }
},
emits: ["itemClick", "select"],
setup(__props, { expose: __expose, emit: __emit }) {
const menuRef = ref(null);
const emit = __emit;
const close = () => {
menuRef.value?.close(ROOT_MENU_INDEX);
};
const menuTrigger = ref("click");
const onOpen = (index) => {
if (index !== ROOT_MENU_INDEX) return;
menuTrigger.value = "hover";
};
const onClose = (index) => {
if (index !== ROOT_MENU_INDEX) return;
menuTrigger.value = "click";
};
__expose({
close
});
return (_ctx, _cache) => {
return openBlock(), createBlock(unref(ElMenu), {
ref_key: "menuRef",
ref: menuRef,
mode: "horizontal",
"unique-opened": "",
"menu-trigger": menuTrigger.value,
ellipsis: false,
class: normalizeClass(_ctx.$style.dropdown),
onSelect: _cache[1] || (_cache[1] = ($event) => emit("select", $event)),
onKeyup: withKeys(close, ["escape"]),
onOpen,
onClose
}, {
default: withCtx(() => [
createVNode(unref(ElSubMenu), {
index: ROOT_MENU_INDEX,
class: normalizeClass(_ctx.$style.trigger),
"popper-offset": -10,
"popper-class": _ctx.$style.submenu,
disabled: _ctx.disabled,
teleported: _ctx.teleport
}, {
title: withCtx(() => [
renderSlot(_ctx.$slots, "default")
]),
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.menu, (item) => {
return openBlock(), createElementBlock(Fragment, {
key: item.id
}, [
item.submenu ? (openBlock(), createBlock(unref(ElSubMenu), {
key: 0,
"popper-class": _ctx.$style.nestedSubmenu,
index: item.id,
"popper-offset": -10,
"data-test-id": "navigation-submenu"
}, {
title: withCtx(() => [
createTextVNode(toDisplayString(item.title), 1)
]),
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(item.submenu, (subitem) => {
return openBlock(), createBlock(unref(_sfc_main$6), {
key: subitem.id,
to: !subitem.disabled && subitem.route || void 0
}, {
default: withCtx(() => [
createVNode(unref(ElMenuItem), {
"data-test-id": "navigation-submenu-item",
index: subitem.id,
disabled: subitem.disabled,
onClick: _cache[0] || (_cache[0] = ($event) => emit("itemClick", $event))
}, {
default: withCtx(() => [
subitem.icon ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
typeof subitem.icon === "string" || subitem.icon.type === "icon" ? (openBlock(), createBlock(unref(N8nIcon), {
key: 0,
class: normalizeClass(_ctx.$style.submenu__icon),
icon: typeof subitem.icon === "object" ? subitem.icon.value : subitem.icon
}, null, 8, ["class", "icon"])) : subitem.icon.type === "emoji" ? (openBlock(), createBlock(unref(N8nText), {
key: 1,
class: normalizeClass(_ctx.$style.submenu__icon)
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(subitem.icon.value), 1)
]),
_: 2
}, 1032, ["class"])) : createCommentVNode("", true)
], 64)) : createCommentVNode("", true),
createTextVNode(" " + toDisplayString(subitem.title) + " ", 1),
renderSlot(_ctx.$slots, `item.append.${item.id}`, mergeProps({ ref_for: true }, { item }))
]),
_: 2
}, 1032, ["index", "disabled"])
]),
_: 2
}, 1032, ["to"]);
}), 128))
]),
_: 2
}, 1032, ["popper-class", "index"])) : (openBlock(), createBlock(unref(_sfc_main$6), {
key: 1,
to: !item.disabled && item.route || void 0
}, {
default: withCtx(() => [
createVNode(unref(ElMenuItem), {
index: item.id,
disabled: item.disabled,
"data-test-id": "navigation-menu-item"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(item.title) + " ", 1),
renderSlot(_ctx.$slots, `item.append.${item.id}`, mergeProps({ ref_for: true }, { item }))
]),
_: 2
}, 1032, ["index", "disabled"])
]),
_: 2
}, 1032, ["to"]))
], 64);
}), 128))
]),
_: 3
}, 8, ["class", "popper-class", "disabled", "teleported"])
]),
_: 3
}, 8, ["menu-trigger", "class"]);
};
}
});
const dropdown = "_dropdown_1dr86_123";
const nestedSubmenu = "_nestedSubmenu_1dr86_140";
const submenu = "_submenu_1dr86_145";
const submenu__icon = "_submenu__icon_1dr86_173";
const style0$5 = {
dropdown,
nestedSubmenu,
submenu,
submenu__icon
};
const cssModules$5 = {
"$style": style0$5
};
const N8nNavigationDropdown = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__cssModules", cssModules$5]]);
async function getBecomeCreatorCta(context) {
const response = await get(context.baseUrl, "/cta/become-creator");
return response;
}
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
__name: "MainSidebarSourceControl",
props: {
isCollapsed: { type: Boolean }
},
setup(__props) {
const sourceControlStore = useSourceControlStore();
const projectStore = useProjectsStore();
const i18n = useI18n();
const route = useRoute();
const router = useRouter();
const tooltipOpenDelay = ref(300);
const currentBranch = computed(() => {
return sourceControlStore.preferences.branchName;
});
const hasPushPermission = computed(() => {
return hasPermission(["rbac"], { rbac: { scope: "sourceControl:push" } }) || projectStore.myProjects.some(
(project) => project.type === "team" && getResourcePermissions(project?.scopes)?.sourceControl?.push
);
});
const hasPullPermission = computed(() => {
return hasPermission(["rbac"], { rbac: { scope: "sourceControl:pull" } });
});
const sourceControlAvailable = computed(
() => sourceControlStore.isEnterpriseSourceControlEnabled && (hasPullPermission.value || hasPushPermission.value)
);
async function pushWorkfolder() {
void router.push({
query: {
...route.query,
sourceControl: "push"
}
});
}
function pullWorkfolder() {
void router.push({
query: {
...route.query,
sourceControl: "pull"
}
});
}
return (_ctx, _cache) => {
const _component_n8n_icon = N8nIcon;
const _component_n8n_button = N8nButton;
const _component_n8n_tooltip = Tooltip;
return sourceControlAvailable.value ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass({
[_ctx.$style.sync]: true,
[_ctx.$style.collapsed]: _ctx.isCollapsed,
[_ctx.$style.isConnected]: unref(sourceControlStore).isEnterpriseSourceControlEnabled
}),
style: normalizeStyle({ borderLeftColor: unref(sourceControlStore).preferences.branchColor }),
"data-test-id": "main-sidebar-source-control"
}, [
unref(sourceControlStore).preferences.connected && unref(sourceControlStore).preferences.branchName ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(_ctx.$style.connected),
"data-test-id": "main-sidebar-source-control-connected"
}, [
createBaseVNode("span", {
class: normalizeClass(_ctx.$style.branchName)
}, [
createVNode(_component_n8n_icon, { icon: "git-branch" }),
createTextVNode(" " + toDisplayString(currentBranch.value), 1)
], 2),
createBaseVNode("div", {
class: normalizeClass({ "pt-xs": !_ctx.isCollapsed })
}, [
createVNode(_component_n8n_tooltip, {
disabled: !_ctx.isCollapsed && hasPullPermission.value,
"show-after": tooltipOpenDelay.value,
placement: _ctx.isCollapsed ? "right" : "top"
}, {
content: withCtx(() => [
createBaseVNode("div", null, toDisplayString(!hasPullPermission.value ? unref(i18n).baseText("settings.sourceControl.button.pull.forbidden") : unref(i18n).baseText("settings.sourceControl.button.pull")), 1)
]),
default: withCtx(() => [
createVNode(_component_n8n_button, {
class: normalizeClass({
"mr-2xs": !_ctx.isCollapsed,
"mb-2xs": _ctx.isCollapsed
}),
disabled: !hasPullPermission.value,
"data-test-id": "main-sidebar-source-control-pull",
icon: "arrow-down",
type: "tertiary",
size: "mini",
square: _ctx.isCollapsed,
label: _ctx.isCollapsed ? "" : unref(i18n).baseText("settings.sourceControl.button.pull"),
onClick: pullWorkfolder
}, null, 8, ["class", "disabled", "square", "label"])
]),
_: 1
}, 8, ["disabled", "show-after", "placement"]),
createVNode(_component_n8n_tooltip, {
disabled: !_ctx.isCollapsed && !unref(sourceControlStore).preferences.branchReadOnly && hasPushPermission.value,
"show-after": tooltipOpenDelay.value,
placement: _ctx.isCollapsed ? "right" : "top"
}, {
content: withCtx(() => [
createBaseVNode("div", null, toDisplayString(unref(sourceControlStore).preferences.branchReadOnly || !hasPushPermission.value ? unref(i18n).baseText("settings.sourceControl.button.push.forbidden") : unref(i18n).baseText("settings.sourceControl.button.push")), 1)
]),
default: withCtx(() => [
createVNode(_component_n8n_button, {
square: _ctx.isCollapsed,
label: _ctx.isCollapsed ? "" : unref(i18n).baseText("settings.sourceControl.button.push"),
disabled: unref(sourceControlStore).preferences.branchReadOnly || !hasPushPermission.value,
"data-test-id": "main-sidebar-source-control-push",
icon: "arrow-up",
type: "tertiary",
size: "mini",
onClick: pushWorkfolder
}, null, 8, ["square", "label", "disabled"])
]),
_: 1
}, 8, ["disabled", "show-after", "placement"])
], 2)
], 2)) : createCommentVNode("", true)
], 6)) : createCommentVNode("", true);
};
}
});
const sync = "_sync_fv3ov_123";
const isConnected = "_isConnected_fv3ov_130";
const collapsed$1 = "_collapsed_fv3ov_134";
const branchName = "_branchName_fv3ov_144";
const connected = "_connected_fv3ov_154";
const style0$4 = {
sync,
isConnected,
collapsed: collapsed$1,
branchName,
connected
};
const cssModules$4 = {
"$style": style0$4
};
const __unplugin_components_4 = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__cssModules", cssModules$4]]);
const LOCAL_STORAGE_KEY = "N8N_BECOME_TEMPLATE_CREATOR_CTA_DISMISSED_AT";
const RESHOW_DISMISSED_AFTER_DAYS = 30;
const POLL_INTERVAL_IN_MS = 15 * 60 * 1e3;
const useBecomeTemplateCreatorStore = defineStore(STORES.BECOME_TEMPLATE_CREATOR, () => {
const cloudPlanStore = useCloudPlanStore();
const rootStore = useRootStore();
const dismissedAt = useStorage(LOCAL_STORAGE_KEY);
const ctaMeetsCriteria = ref(false);
const monitorCtasTimer = ref(null);
const isDismissed = computed(() => {
return dismissedAt.value ? !hasEnoughTimePassedSinceDismissal(dismissedAt.value) : false;
});
const showBecomeCreatorCta = computed(() => {
return ctaMeetsCriteria.value && !cloudPlanStore.userIsTrialing && !isDismissed.value;
});
const dismissCta = () => {
dismissedAt.value = DateTime.now().toISO();
};
const fetchBecomeCreatorCta = async () => {
const becomeCreatorCta = await getBecomeCreatorCta(rootStore.restApiContext);
ctaMeetsCriteria.value = becomeCreatorCta;
};
const fetchUserCtasIfNeeded = async () => {
if (isDismissed.value || cloudPlanStore.userIsTrialing || ctaMeetsCriteria.value) {
return;
}
await fetchBecomeCreatorCta();
};
const startMonitoringCta = () => {
if (monitorCtasTimer.value) {
return;
}
setTimeout(fetchUserCtasIfNeeded, 1e3);
monitorCtasTimer.value = setInterval(fetchUserCtasIfNeeded, POLL_INTERVAL_IN_MS);
};
const stopMonitoringCta = () => {
if (!monitorCtasTimer.value) {
return;
}
clearInterval(monitorCtasTimer.value);
monitorCtasTimer.value = null;
};
return {
showBecomeCreatorCta,
dismissCta,
startMonitoringCta,
stopMonitoringCta
};
});
function hasEnoughTimePassedSinceDismissal(dismissedAt) {
const reshowAtTime = DateTime.fromISO(dismissedAt).plus({
days: RESHOW_DISMISSED_AFTER_DAYS
});
return reshowAtTime <= DateTime.now();
}
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
__name: "BecomeTemplateCreatorCta",
setup(__props) {
const i18n = useI18n();
const store = useBecomeTemplateCreatorStore();
const telemetry = useTelemetry();
const onClick = () => {
telemetry.track("User clicked become creator CTA");
};
return (_ctx, _cache) => {
const _component_n8n_icon = N8nIcon;
const _component_n8n_button = N8nButton;
return unref(store).showBecomeCreatorCta ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(_ctx.$style.container),
"data-test-id": "become-template-creator-cta"
}, [
createBaseVNode("div", {
class: normalizeClass(_ctx.$style.textAndCloseButton)
}, [
createBaseVNode("p", {
class: normalizeClass(_ctx.$style.text)
}, toDisplayString(unref(i18n).baseText("becomeCreator.text")), 3),
createBaseVNode("button", {
class: normalizeClass(_ctx.$style.closeButton),
"data-test-id": "close-become-template-creator-cta",
onClick: _cache[0] || (_cache[0] = ($event) => unref(store).dismissCta())
}, [
createVNode(_component_n8n_icon, {
icon: "x",
size: "xsmall",
title: unref(i18n).baseText("generic.close")
}, null, 8, ["title"])
], 2)
], 2),
createVNode(_component_n8n_button, {
class: normalizeClass(_ctx.$style.becomeCreatorButton),
label: unref(i18n).baseText("becomeCreator.buttonText"),
size: "xmini",
type: "secondary",
element: "a",
href: "https://creators.n8n.io/hub",
target: "_blank",
onClick
}, null, 8, ["class", "label"])
], 2)) : createCommentVNode("", true);
};
}
});
const container$1 = "_container_977ul_123";
const textAndCloseButton = "_textAndCloseButton_977ul_131";
const text = "_text_977ul_131";
const closeButton = "_closeButton_977ul_144";
const becomeCreatorButton = "_becomeCreatorButton_977ul_156";
const style0$3 = {
container: container$1,
textAndCloseButton,
text,
closeButton,
becomeCreatorButton
};
const cssModules$3 = {
"$style": style0$3
};
const __unplugin_components_3 = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__cssModules", cssModules$3]]);
const isIconName = (icon) => typeof icon === "string" && Object.keys(updatedIconSet).includes(icon);
const isProjectIcon = (icon) => isIconName(icon) || typeof icon === "object" && icon !== null && "value" in icon && typeof icon.value === "string" && "type" in icon && (icon.type === "emoji" || icon.type === "icon" && isIconName(icon.value));
const useGlobalEntityCreation = () => {
const CREATE_PROJECT_ID = "create-project";
const WORKFLOWS_MENU_ID = "workflow";
const CREDENTIALS_MENU_ID = "credential";
const DEFAULT_ICON = "layers";
const settingsStore = useSettingsStore();
const cloudPlanStore = useCloudPlanStore();
const projectsStore = useProjectsStore();
const sourceControlStore = useSourceControlStore();
const router = useRouter();
const i18n = useI18n();
const toast = useToast();
const isCreatingProject = ref(false);
const displayProjects = computed(
() => sortByProperty(
"name",
projectsStore.myProjects.filter((p) => p.type === "team")
)
);
const disabledWorkflow = (scopes = []) => sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(scopes).workflow.create;
const disabledCredential = (scopes = []) => sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(scopes).credential.create;
const menu = computed(() => {
if (!projectsStore.isTeamProjectFeatureEnabled) {
return [
{
id: "workflow",
title: "Workflow",
route: {
name: VIEWS.NEW_WORKFLOW,
query: {
projectId: projectsStore.personalProject?.id
}
}
},
{
id: "credential",
title: "Credential",
route: {
name: VIEWS.CREDENTIALS,
params: {
projectId: projectsStore.personalProject?.id,
credentialId: "create"
}
}
},
{
id: CREATE_PROJECT_ID,
title: "Project",
disabled: true
}
];
}
return [
{
id: WORKFLOWS_MENU_ID,
title: "Workflow",
disabled: sourceControlStore.preferences.branchReadOnly,
...!sourceControlStore.preferences.branchReadOnly && {
submenu: [
{
id: "workflow-title",
title: "Create in",
disabled: true
},
{
id: "workflow-personal",
title: i18n.baseText("projects.menu.personal"),
icon: "user",
disabled: disabledWorkflow(projectsStore.personalProject?.scopes),
route: {
name: VIEWS.NEW_WORKFLOW,
query: { projectId: projectsStore.personalProject?.id }
}
},
...displayProjects.value.map((project) => ({
id: `workflow-${project.id}`,
title: project.name,
icon: isProjectIcon(project.icon) ? project.icon : DEFAULT_ICON,
disabled: disabledWorkflow(project.scopes),
route: {
name: VIEWS.NEW_WORKFLOW,
query: { projectId: project.id }
}
}))
]
}
},
{
id: CREDENTIALS_MENU_ID,
title: "Credential",
disabled: sourceControlStore.preferences.branchReadOnly,
...!sourceControlStore.preferences.branchReadOnly && {
submenu: [
{
id: "credential-title",
title: "Create in",
disabled: true
},
{
id: "credential-personal",
title: i18n.baseText("projects.menu.personal"),
icon: "user",
disabled: disabledCredential(projectsStore.personalProject?.scopes),
route: {
name: VIEWS.PROJECTS_CREDENTIALS,
params: { projectId: projectsStore.personalProject?.id, credentialId: "create" }
}
},
...displayProjects.value.map((project) => ({
id: `credential-${project.id}`,
title: project.name,
icon: isProjectIcon(project.icon) ? project.icon : DEFAULT_ICON,
disabled: disabledCredential(project.scopes),
route: {
name: VIEWS.PROJECTS_CREDENTIALS,
params: { projectId: project.id, credentialId: "create" }
}
}))
]
}
},
{
id: CREATE_PROJECT_ID,
title: "Project",
disabled: !projectsStore.canCreateProjects || !projectsStore.hasPermissionToCreateProjects
}
];
});
const createProject = async (uiContext) => {
isCreatingProject.value = true;
try {
const newProject = await projectsStore.createProject({
name: i18n.baseText("projects.settings.newProjectName"),
icon: { type: "icon", value: DEFAULT_ICON },
uiContext
});
await router.push({ name: VIEWS.PROJECT_SETTINGS, params: { projectId: newProject.id } });
toast.showMessage({
title: i18n.baseText("projects.settings.save.successful.title", {
interpolate: { projectName: newProject.name }
}),
type: "success"
});
} catch (error) {
toast.showError(error, i18n.baseText("projects.error.title"));
} finally {
isCreatingProject.value = false;
}
};
const handleSelect = (id) => {
if (id !== CREATE_PROJECT_ID) return;
if (projectsStore.canCreateProjects && projectsStore.hasPermissionToCreateProjects) {
void createProject("universal_button");
return;
}
void usePageRedirectionHelper().goToUpgrade("rbac", "upgrade-rbac");
};
const projectsLimitReachedMessage = computed(() => {
if (settingsStore.isCloudDeployment) {
return i18n.baseText("projects.create.limitReached.cloud", {
interpolate: {
planName: cloudPlanStore.currentPlanData?.displayName ?? "",
limit: projectsStore.teamProjectsLimit
}
});
}
if (!projectsStore.isTeamProjectFeatureEnabled) {
return i18n.baseText("projects.create.limitReached.self");
}
if (!projectsStore.hasPermissionToCreateProjects) {
return i18n.baseText("projects.create.permissionDenied");
}
return i18n.baseText("projects.create.limitReached", {
interpolate: {
limit: projectsStore.teamProjectsLimit
}
});
});
const createProjectAppendSlotName = computed(() => `item.append.${CREATE_PROJECT_ID}`);
const createWorkflowsAppendSlotName = computed(() => `item.append.${WORKFLOWS_MENU_ID}`);
const createCredentialsAppendSlotName = computed(() => `item.append.${CREDENTIALS_MENU_ID}`);
const hasPermissionToCreateProjects = projectsStore.hasPermissionToCreateProjects;
const upgradeLabel = computed(() => {
if (settingsStore.isCloudDeployment) {
return i18n.baseText("generic.upgrade");
}
if (!projectsStore.isTeamProjectFeatureEnabled) {
return i18n.baseText("generic.enterprise");
}
return i18n.baseText("generic.upgrade");
});
return {
menu,
handleSelect,
createProjectAppendSlotName,
createWorkflowsAppendSlotName,
createCredentialsAppendSlotName,
projectsLimitReachedMessage,
hasPermissionToCreateProjects,
upgradeLabel,
createProject,
isCreatingProject,
displayProjects
};
};
const _hoisted_1$1 = {
key: 0,
class: "mt-m mb-m"
};
const _hoisted_2 = {
key: 4,
class: "mb-m"
};
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
__name: "ProjectNavigation",
props: {
collapsed: { type: Boolean },
planName: {}
},
setup(__props) {
const props = __props;
const locale = useI18n();
const globalEntityCreation = useGlobalEntityCreation();
const projectsStore = useProjectsStore();
const settingsStore = useSettingsStore();
const usersStore = useUsersStore();
const isCreatingProject = computed(() => globalEntityCreation.isCreatingProject.value);
const displayProjects = computed(() => globalEntityCreation.displayProjects.value);
const isFoldersFeatureEnabled = computed(() => settingsStore.isFoldersFeatureEnabled);
const hasMultipleVerifiedUsers = computed(
() => usersStore.allUsers.filter((user) => !user.isPendingUser).length > 1
);
const home = computed(() => ({
id: "home",
label: locale.baseText("projects.menu.overview"),
icon: "house",
route: {
to: { name: VIEWS.HOMEPAGE }
}
}));
const shared = computed(() => ({
id: "shared",
label: locale.baseText("projects.menu.shared"),
icon: "share",
route: {
to: { name: VIEWS.SHARED_WITH_ME }
}
}));
const getProjectMenuItem = (project) => ({
id: project.id,
label: project.name ?? "",
icon: project.icon,
route: {
to: {
name: VIEWS.PROJECTS_WORKFLOWS,
params: { projectId: project.id }
}
}
});
const personalProject = computed(() => ({
id: projectsStore.personalProject?.id ?? "",
label: locale.baseText("projects.menu.personal"),
icon: "user",
route: {
to: {
name: VIEWS.PROJECTS_WORKFLOWS,
params: { projectId: projectsStore.personalProject?.id }
}
}
}));
const showAddFirstProject = computed(
() => projectsStore.isTeamProjectFeatureEnabled && !displayProjects.value.length
);
const activeTabId = computed(() => {
return (Array.isArray(projectsStore.projectNavActiveId) ? projectsStore.projectNavActiveId[0] : projectsStore.projectNavActiveId) ?? void 0;
});
onBeforeMount(async () => {
await usersStore.fetchUsers();
});
return (_ctx, _cache) => {
const _component_N8nMenuItem = N8nMenuItem;
const _component_N8nButton = N8nButton;
const _component_N8nTooltip = Tooltip;
const _component_N8nText = N8nText;
return openBlock(), createElementBlock("div", {
class: normalizeClass(_ctx.$style.projects)
}, [
createVNode(unref(ElMenu), {
collapse: props.collapsed,
class: "home"
}, {
default: withCtx(() => [
createVNode(_component_N8nMenuItem, {
item: home.value,
compact: props.collapsed,
"active-tab": activeTabId.value,
mode: "tabs",
"data-test-id": "project-home-menu-item"
}, null, 8, ["item", "compact", "active-tab"]),
unref(projectsStore).isTeamProjectFeatureEnabled || isFoldersFeatureEnabled.value ? (openBlock(), createBlock(_component_N8nMenuItem, {
key: 0,
item: personalProject.value,
compact: props.collapsed,
"active-tab": activeTabId.value,
mode: "tabs",
"data-test-id": "project-personal-menu-item"
}, null, 8, ["item", "compact", "active-tab"])) : createCommentVNode("", true),
(unref(projectsStore).isTeamProjectFeatureEnabled || isFoldersFeatureEnabled.value) && hasMultipleVerifiedUsers.value ? (openBlock(), createBlock(_component_N8nMenuItem, {
key: 1,
item: shared.value,
compact: props.collapsed,
"active-tab": activeTabId.value,
mode: "tabs",
"data-test-id": "project-shared-menu-item"
}, null, 8, ["item", "compact", "active-tab"])) : createCommentVNode("", true)
]),
_: 1
}, 8, ["collapse"]),
unref(projectsStore).isTeamProjectFeatureEnabled ? (openBlock(), createElementBlock("hr", _hoisted_1$1)) : createCommentVNode("", true),
!props.collapsed && unref(projectsStore).isTeamProjectFeatureEnabled ? (openBlock(), createBlock(_component_N8nText, {
key: 1,
class: normalizeClass([_ctx.$style.projectsLabel]),
tag: "h3",
bold: ""
}, {
default: withCtx(() => [
createBaseVNode("span", null, toDisplayString(unref(locale).baseText("projects.menu.title")), 1),
unref(projectsStore).canCreateProjects ? (openBlock(), createBlock(_component_N8nTooltip, {
key: 0,
placement: "right",
disabled: unref(projectsStore).hasPermissionToCreateProjects,
content: unref(locale).baseText("projects.create.permissionDenied")
}, {
default: withCtx(() => [
createVNode(_component_N8nButton, {
icon: "plus",
text: "",
"data-test-id": "project-plus-button",
disabled: isCreatingProject.value || !unref(projectsStore).hasPermissionToCreateProjects,
class: normalizeClass(_ctx.$style.plusBtn),
onClick: _cache[0] || (_cache[0] = ($event) => unref(globalEntityCreation).createProject("add_icon"))
}, null, 8, ["disabled", "class"])
]),
_: 1
}, 8, ["disabled", "content"])) : createCommentVNode("", true)
]),
_: 1
}, 8, ["class"])) : createCommentVNode("", true),
unref(projectsStore).isTeamProjectFeatureEnabled || isFoldersFeatureEnabled.value ? (openBlock(), createBlock(unref(ElMenu), {
key: 2,
collapse: props.collapsed,
class: normalizeClass(_ctx.$style.projectItems)
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(displayProjects.value, (project) => {
return openBlock(), createBlock(_component_N8nMenuItem, {
key: project.id,
class: normalizeClass({
[_ctx.$style.collapsed]: props.collapsed
}),
item: getProjectMenuItem(project),
compact: props.collapsed,
"active-tab": activeTabId.value,
mode: "tabs",
"data-test-id": "project-menu-item"
}, null, 8, ["class", "item", "compact", "active-tab"]);
}), 128))
]),
_: 1
}, 8, ["collapse", "class"])) : createCommentVNode("", true),
showAddFirstProject.value ? (openBlock(), createBlock(_component_N8nTooltip, {
key: 3,
placement: "right",
disabled: unref(projectsStore).hasPermissionToCreateProjects,
content: unref(locale).baseText("projects.create.permissionDenied")
}, {
default: withCtx(() => [
createVNode(_component_N8nButton, {
class: normalizeClass([
_ctx.$style.addFirstProjectBtn,
{
[_ctx.$style.collapsed]: props.collapsed
}
]),
disabled: isCreatingProject.value || !unref(projectsStore).hasPermissionToCreateProjects,
type: "secondary",
icon: "plus",
"data-test-id": "add-first-project-button",
onClick: _cache[1] || (_cache[1] = ($event) => unref(globalEntityCreation).createProject("add_first_project_button"))
}, {
default: withCtx(() => [
createBaseVNode("span", null, toDisplayString(unref(locale).baseText("projects.menu.addFirstProject")), 1)
]),
_: 1
}, 8, ["class", "disabled"])
]),
_: 1
}, 8, ["disabled", "content"])) : createCommentVNode("", true),
unref(projectsStore).isTeamProjectFeatureEnabled ? (openBlock(), createElementBlock("hr", _hoisted_2)) : createCommentVNode("", true)
], 2);
};
}
});
const projects = "_projects_jcrfa_123";
const plusBtn = "_plusBtn_jcrfa_131";
const projectItems = "_projectItems_jcrfa_135";
const upgradeLink = "_upgradeLink_jcrfa_141";
const collapsed = "_collapsed_jcrfa_146";
const projectsLabel = "_projectsLabel_jcrfa_150";
const addFirstProjectBtn = "_addFirstProjectBtn_jcrfa_173";
const style0$2 = {
projects,
plusBtn,
projectItems,
upgradeLink,
collapsed,
projectsLabel,
addFirstProjectBtn
};
const cssModules$2 = {
"$style": style0$2
};
const __unplugin_components_2 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__cssModules", cssModules$2], ["__scopeId", "data-v-9256cda9"]]);
const BASE_FORUM_URL = "https://github.com/n8n-io/n8n/issues/new?labels=bug-report";
const REPORT_TEMPLATE = `
<!-- Please follow the template below. Skip the questions that are not relevant to you. -->
## Describe the problem/error/question
## What is the error message (if any)?
## Please share your workflow/screenshots/recording
\`\`\`
(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)
⚠️ WARNING ⚠️ If you have sensitive data in your workflow (like API keys), please remove it before sharing.
\`\`\`
## Share the output returned by the last node
<!-- If you need help with data transformations, please also share your expected output. -->
`;
function useBugReporting() {
const debugInfo = useDebugInfo();
const getReportingURL = () => {
const url = new URL(BASE_FORUM_URL);
const report = `${REPORT_TEMPLATE}
${debugInfo.generateDebugInfo({ skipSensitive: true, secondaryHeader: true })}}`;
url.searchParams.append("body", report);
return url.toString();
};
return {
getReportingURL
};
}
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
__name: "VersionUpdateCTA",
setup(__props) {
const i18n = useI18n();
const versionsStore = useVersionsStore();
const uiStore = useUIStore();
const pageRedirectionHelper = usePageRedirectionHelper();
const telemetry = useTelemetry();
const openUpdatesPanel = () => {
uiStore.openModal(VERSIONS_MODAL_KEY);
};
const onUpdateClick = async () => {
telemetry.track("User clicked on update button", {
source: "main-sidebar"
});
await pageRedirectionHelper.goToVersions();
};
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass(_ctx.$style.container)
}, [
createVNode(unref(N8nLink), {
size: "small",
theme: "text",
"data-test-id": "version-update-next-versions-link",
onClick: openUpdatesPanel
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(i18n).baseText("whatsNew.versionsBehind", {
interpolate: {
count: unref(versionsStore).nextVersions.length > 99 ? "99+" : unref(versionsStore).nextVersions.length
}
})), 1)
]),
_: 1
}),
createVNode(unref(N8nButton), {
class: normalizeClass(_ctx.$style.button),
label: unref(i18n).baseText("whatsNew.update"),
"data-test-id": "version-update-cta-button",
size: "mini",
onClick: onUpdateClick
}, null, 8, ["class", "label"])
], 2);
};
}
});
const container = "_container_1hqs4_123";
const button = "_button_1hqs4_136";
const style0$1 = {
container,
button
};
const cssModules$1 = {
"$style": style0$1
};
const VersionUpdateCTA = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__cssModules", cssModules$1]]);
const _hoisted_1 = {
class: "ml-3xs",
"data-test-id": "main-sidebar-user-menu"
};
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "MainSidebar",
setup(__props) {
const becomeTemplateCreatorStore = useBecomeTemplateCreatorStore();
const cloudPlanStore = useCloudPlanStore();
const rootStore = useRootStore();
const settingsStore = useSettingsStore();
const templatesStore = useTemplatesStore();
const uiStore = useUIStore();
const usersStore = useUsersStore();
const versionsStore = useVersionsStore();
const workflowsStore = useWorkflowsStore();
const sourceControlStore = useSourceControlStore();
const personalizedTemplatesV2Store = usePersonalizedTemplatesV2Store();
const { callDebounced } = useDebounce();
const externalHooks = useExternalHooks();
const i18n = useI18n();
useRoute();
const router = useRouter();
const telemetry = useTelemetry();
const pageRedirectionHelper = usePageRedirectionHelper();
const { getReportingURL } = useBugReporting();
const calloutHelpers = useCalloutHelpers();
useKeybindings({
ctrl_alt_o: () => handleSelect("about")
});
const user = ref(null);
const basePath = ref("");
const fullyExpanded = ref(false);
const userMenuItems = ref([
{
id: "settings",
label: i18n.baseText("settings")
},
{
id: "logout",
label: i18n.baseText("auth.signout")
}
]);
const showWhatsNewNotification = computed(
() => versionsStore.hasVersionUpdates || versionsStore.whatsNewArticles.some(
(article) => !versionsStore.isWhatsNewArticleRead(article.id)
)
);
const mainMenuItems = computed(() => [
{
id: "cloud-admin",
position: "bottom",
label: "Admin Panel",
icon: "cloud",
available: settingsStore.isCloudDeployment && hasPermission(["instanceOwner"])
},
{
// Link to in-app pre-built agent templates, available experiment is enabled
id: "templates",
icon: "package-open",
label: i18n.baseText("mainSidebar.templates"),
position: "bottom",
available: settingsStore.isTemplatesEnabled && calloutHelpers.isPreBuiltAgentsCalloutVisible.value && !personalizedTemplatesV2Store.isFeatureEnabled(),
route: { to: { name: VIEWS.PRE_BUILT_AGENT_TEMPLATES } }
},
{
// Link to templateRecoV2 modal, available when experiment is enabled
id: "templates",
icon: "package-open",
label: i18n.baseText("mainSidebar.templates"),
position: "bottom",
available: settingsStore.isTemplatesEnabled && !calloutHelpers.isPreBuiltAgentsCalloutVisible.value && personalizedTemplatesV2Store.isFeatureEnabled()
},
{
// Link to in-app templates, available if custom templates are enabled and experiment is disabled
id: "templates",
icon: "package-open",
label: i18n.baseText("mainSidebar.templates"),
position: "bottom",
available: settingsStore.isTemplatesEnabled && !calloutHelpers.isPreBuiltAgentsCalloutVisible.value && templatesStore.hasCustomTemplatesHost && !personalizedTemplatesV2Store.isFeatureEnabled(),
route: { to: { name: VIEWS.TEMPLATES } }
},
{
// Link to website templates, available if custom templates are not enabled
id: "templates",
icon: "package-open",
label: i18n.baseText("mainSidebar.templates"),
position: "bottom",
available: settingsStore.isTemplatesEnabled && !calloutHelpers.isPreBuiltAgentsCalloutVisible.value && !templatesStore.hasCustomTemplatesHost && !personalizedTemplatesV2Store.isFeatureEnabled(),
link: {
href: templatesStore.websiteTemplateRepositoryURL,
target: "_blank"
}
},
{
id: "variables",
icon: "variable",
label: i18n.baseText("mainSidebar.variables"),
position: "bottom",
route: { to: { name: VIEWS.VARIABLES } }
},
{
id: "insights",
icon: "chart-column-decreasing",
label: "Insights",
position: "bottom",
route: { to: { name: VIEWS.INSIGHTS } },
available: settingsStore.isModuleActive("insights") && hasPermission(["rbac"], { rbac: { scope: "insights:list" } })
},
{
id: "help",
icon: "circle-help",
label: i18n.baseText("mainSidebar.help"),
position: "bottom",
children: [
{
id: "quickstart",
icon: "video",
label: i18n.baseText("mainSidebar.helpMenuItems.quickstart"),
link: {
href: "https://www.youtube.com/watch?v=4cQWJViybAQ",
target: "_blank"
}
},
{
id: "docs",
icon: "book",
label: i18n.baseText("mainSidebar.helpMenuItems.documentation"),
link: {
href: "https://docs.n8n.io?utm_source=n8n_app&utm_medium=app_sidebar",
target: "_blank"
}
},
{
id: "forum",
icon: "users",
label: i18n.baseText("mainSidebar.helpMenuItems.forum"),
link: {
href: "https://community.n8n.io?utm_source=n8n_app&utm_medium=app_sidebar",
target: "_blank"
}
},
{
id: "examples",
icon: "graduation-cap",
label: i18n.baseText("mainSidebar.helpMenuItems.course"),
link: {
href: "https://docs.n8n.io/courses/",
target: "_blank"
}
},
{
id: "report-bug",
icon: "bug",
label: i18n.baseText("mainSidebar.helpMenuItems.reportBug"),
link: {
href: getReportingURL(),
target: "_blank"
}
},
{
id: "about",
icon: "info",
label: i18n.baseText("mainSidebar.aboutN8n"),
position: "bottom"
}
]
},
{
id: "whats-new",
icon: "bell",
notification: showWhatsNewNotification.value,
label: i18n.baseText("mainSidebar.whatsNew"),
position: "bottom",
available: versionsStore.hasVersionUpdates || versionsStore.whatsNewArticles.length > 0,
children: [
...versionsStore.whatsNewArticles.map(
(article) => ({
id: `whats-new-article-${article.id}`,
label: article.title,
size: "small",
customIconSize: "small",
icon: {
type: "emoji",
value: "•",
color: !versionsStore.isWhatsNewArticleRead(article.id) ? "primary" : "text-light"
}
})
),
{
id: "full-changelog",
icon: "external-link",
label: i18n.baseText("mainSidebar.whatsNew.fullChangelog"),
link: {
href: RELEASE_NOTES_URL,
target: "_blank"
},
size: "small",
customIconSize: "small"
},
{
id: "version-upgrade-cta",
component: VersionUpdateCTA,
available: versionsStore.hasVersionUpdates,
props: {}
}
]
}
]);
const createBtn = ref();
const isCollapsed = computed(() => uiStore.sidebarMenuCollapsed);
const showUserArea = computed(() => hasPermission(["authenticated"]));
const userIsTrialing = computed(() => cloudPlanStore.userIsTrialing);
onMounted(async () => {
window.addEventListener("resize", onResize);
basePath.value = rootStore.baseUrl;
if (user.value) {
void externalHooks.run("mainSidebar.mounted", {
userRef: user.value
});
}
becomeTemplateCreatorStore.startMonitoringCta();
await nextTick(onResizeEnd);
});
onBeforeUnmount(() => {
becomeTemplateCreatorStore.stopMonitoringCta();
window.removeEventListener("resize", onResize);
});
const trackHelpItemClick = (itemType) => {
telemetry.track("User clicked help resource", {
type: itemType,
workflow_id: workflowsStore.workflowId
});
};
const onUserActionToggle = (action) => {
switch (action) {
case "logout":
onLogout();
break;
case "settings":
void router.push({ name: VIEWS.SETTINGS });
break;
}
};
const onLogout = () => {
void router.push({ name: VIEWS.SIGNOUT });
};
const toggleCollapse = () => {
uiStore.toggleSidebarMenuCollapse();
if (!isCollapsed.value) {
setTimeout(() => {
fullyExpanded.value = !isCollapsed.value;
}, 300);
} else {
fullyExpanded.value = !isCollapsed.value;
}
};
const handleSelect = (key) => {
switch (key) {
case "templates":
if (personalizedTemplatesV2Store.isFeatureEnabled()) {
uiStore.openModalWithData({
name: EXPERIMENT_TEMPLATE_RECO_V2_KEY,
data: {}
});
trackTemplatesClick(TemplateClickSource.sidebarButton);
} else if (settingsStore.isTemplatesEnabled && !templatesStore.hasCustomTemplatesHost) {
trackTemplatesClick(TemplateClickSource.sidebarButton);
}
break;
case "about": {
trackHelpItemClick("about");
uiStore.openModal(ABOUT_MODAL_KEY);
break;
}
case "cloud-admin": {
void pageRedirectionHelper.goToDashboard();
break;
}
case "quickstart":
case "docs":
case "forum":
case "examples": {
trackHelpItemClick(key);
break;
}
case "insights":
telemetry.track("User clicked insights link from side menu");
default:
if (key.startsWith("whats-new-article-")) {
const articleId = Number(key.replace("whats-new-article-", ""));
telemetry.track("User clicked on what's new section", {
article_id: articleId
});
uiStore.openModalWithData({
name: WHATS_NEW_MODAL_KEY,
data: {
articleId
}
});
}
break;
}
};
function onResize() {
void callDebounced(onResizeEnd, { debounceTime: 250 });
}
async function onResizeEnd() {
if (window.innerWidth < 900) {
uiStore.sidebarMenuCollapsed = true;
} else {
uiStore.sidebarMenuCollapsed = uiStore.sidebarMenuCollapsedPreference;
}
void nextTick(() => {
fullyExpanded.value = !isCollapsed.value;
});
}
const {
menu,
handleSelect: handleMenuSelect,
createProjectAppendSlotName,
createWorkflowsAppendSlotName,
createCredentialsAppendSlotName,
projectsLimitReachedMessage,
upgradeLabel,
hasPermissionToCreateProjects
} = useGlobalEntityCreation();
onClickOutside(createBtn, () => {
createBtn.value?.close();
});
return (_ctx, _cache) => {
const _component_N8nIcon = N8nIcon;
const _component_N8nButton = N8nButton;
const _component_ProjectNavigation = __unplugin_components_2;
const _component_BecomeTemplateCreatorCta = __unplugin_components_3;
const _component_MainSidebarSourceControl = __unplugin_components_4;
const _component_N8nAvatar = N8nAvatar;
const _component_ElDropdownItem = resolveComponent("ElDropdownItem");
const _component_ElDropdownMenu = resolveComponent("ElDropdownMenu");
const _component_ElDropdown = resolveComponent("ElDropdown");
const _component_N8nText = N8nText;
const _component_N8nActionDropdown = N8nActionDropdown;
const _component_N8nMenu = N8nMenu;
return openBlock(), createElementBlock("div", {
id: "side-menu",
class: normalizeClass({
["side-menu"]: true,
[_ctx.$style.sideMenu]: true,
[_ctx.$style.sideMenuCollapsed]: isCollapsed.value
})
}, [
createBaseVNode("div", {
id: "collapse-change-button",
class: normalizeClass(["clickable", _ctx.$style.sideMenuCollapseButton]),
onClick: toggleCollapse
}, [
isCollapsed.value ? (openBlock(), createBlock(_component_N8nIcon, {
key: 0,
icon: "chevron-right",
size: "xsmall",
class: "ml-5xs"
})) : (openBlock(), createBlock(_component_N8nIcon, {
key: 1,
icon: "chevron-left",
size: "xsmall",
class: "mr-5xs"
}))
], 2),
createBaseVNode("div", {
class: normalizeClass(_ctx.$style.logo)
}, [
createVNode(Logo, {
location: "sidebar",
collapsed: isCollapsed.value,
"release-channel": unref(settingsStore).settings.releaseChannel
}, {
default: withCtx(() => [
unref(sourceControlStore).preferences.branchReadOnly && !isCollapsed.value ? (openBlock(), createBlock(unref(Tooltip), {
key: 0,
placement: "bottom"
}, {
content: withCtx(() => [
createVNode(unref(I18nT), {
keypath: "readOnlyEnv.tooltip",
scope: "global"
}, {
link: withCtx(() => [
createVNode(unref(N8nLink), {
to: "https://docs.n8n.io/source-control-environments/setup/#step-4-connect-n8n-and-configure-your-instance",
size: "small"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(i18n).baseText("readOnlyEnv.tooltip.link")), 1)
]),
_: 1
})
]),
_: 1
})
]),
default: withCtx(() => [
createVNode(_component_N8nIcon, {
"data-test-id": "read-only-env-icon",
icon: "lock",
size: "xsmall",
class: normalizeClass(_ctx.$style.readOnlyEnvironmentIcon)
}, null, 8, ["class"])
]),
_: 1
})) : createCommentVNode("", true)
]),
_: 1
}, 8, ["collapsed", "release-channel"]),
createVNode(unref(N8nNavigationDropdown), {
ref_key: "createBtn",
ref: createBtn,
"data-test-id": "universal-add",
menu: unref(menu),
onSelect: unref(handleMenuSelect)
}, {
[unref(createWorkflowsAppendSlotName)]: withCtx(() => [
unref(sourceControlStore).preferences.branchReadOnly ? (openBlock(), createBlock(unref(Tooltip), {
key: 0,
placement: "right",
content: unref(i18n).baseText("readOnlyEnv.cantAdd.workflow")
}, {
default: withCtx(() => [
createVNode(_component_N8nIcon, {
style: { "margin-left": "auto", "margin-right": "5px" },
icon: "lock",
size: "xsmall"
})
]),
_: 1
}, 8, ["content"])) : createCommentVNode("", true)
]),
[unref(createCredentialsAppendSlotName)]: withCtx(() => [
unref(sourceControlStore).preferences.branchReadOnly ? (openBlock(), createBlock(unref(Tooltip), {
key: 0,
placement: "right",
content: unref(i18n).baseText("readOnlyEnv.cantAdd.credential")
}, {
default: withCtx(() => [
createVNode(_component_N8nIcon, {
style: { "margin-left": "auto", "margin-right": "5px" },
icon: "lock",
size: "xsmall"
})
]),
_: 1
}, 8, ["content"])) : createCommentVNode("", true)
]),
[unref(createProjectAppendSlotName)]: withCtx(({ item }) => [
unref(sourceControlStore).preferences.branchReadOnly ? (openBlock(), createBlock(unref(Tooltip), {
key: 0,
placement: "right",
content: unref(i18n).baseText("readOnlyEnv.cantAdd.project")
}, {
default: withCtx(() => [
createVNode(_component_N8nIcon, {
style: { "margin-left": "auto", "margin-right": "5px" },
icon: "lock",
size: "xsmall"
})
]),
_: 1
}, 8, ["content"])) : item.disabled ? (openBlock(), createBlock(unref(Tooltip), {
key: 1,
placement: "right",
content: unref(projectsLimitReachedMessage)
}, {
default: withCtx(() => [
!unref(hasPermissionToCreateProjects) ? (openBlock(), createBlock(_component_N8nIcon, {
key: 0,
style: { "margin-left": "auto", "margin-right": "5px" },
icon: "lock",
size: "xsmall"
})) : (openBlock(), createBlock(_component_N8nButton, {
key: 1,
size: "mini",
style: { "margin-left": "auto" },
type: "tertiary",
onClick: ($event) => unref(handleMenuSelect)(item.id)
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(upgradeLabel)), 1)
]),
_: 2
}, 1032, ["onClick"]))
]),
_: 2
}, 1032, ["content"])) : createCommentVNode("", true)
]),
default: withCtx(() => [
createVNode(unref(_sfc_main$7), {
icon: "plus",
type: "secondary",
outline: ""
})
]),
_: 2
}, 1032, ["menu", "onSelect"])
], 2),
createVNode(_component_N8nMenu, {
items: mainMenuItems.value,
collapsed: isCollapsed.value,
onSelect: handleSelect
}, createSlots({
header: withCtx(() => [
createVNode(_component_ProjectNavigation, {
collapsed: isCollapsed.value,
"plan-name": unref(cloudPlanStore).currentPlanData?.displayName
}, null, 8, ["collapsed", "plan-name"])
]),
beforeLowerMenu: withCtx(() => [
fullyExpanded.value && !userIsTrialing.value ? (openBlock(), createBlock(_component_BecomeTemplateCreatorCta, { key: 0 })) : createCommentVNode("", true)
]),
menuSuffix: withCtx(() => [
createBaseVNode("div", null, [
createVNode(_component_MainSidebarSourceControl, { "is-collapsed": isCollapsed.value }, null, 8, ["is-collapsed"])
])
]),
_: 2
}, [
showUserArea.value ? {
name: "footer",
fn: withCtx(() => [
createBaseVNode("div", {
ref_key: "user",
ref: user,
class: normalizeClass(_ctx.$style.userArea)
}, [
createBaseVNode("div", _hoisted_1, [
createVNode(_component_ElDropdown, {
placement: "right-end",
trigger: "click",
onCommand: onUserActionToggle
}, createSlots({
default: withCtx(() => [
createBaseVNode("div", {
class: normalizeClass({ [_ctx.$style.avatar]: true, ["clickable"]: isCollapsed.value })
}, [
createVNode(_component_N8nAvatar, {
"first-name": unref(usersStore).currentUser?.firstName,
"last-name": unref(usersStore).currentUser?.lastName,
size: "small"
}, null, 8, ["first-name", "last-name"])
], 2)
]),
_: 2
}, [
isCollapsed.value ? {
name: "dropdown",
fn: withCtx(() => [
createVNode(_component_ElDropdownMenu, null, {
default: withCtx(() => [
createVNode(_component_ElDropdownItem, { command: "settings" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(i18n).baseText("settings")), 1)
]),
_: 1
}),
createVNode(_component_ElDropdownItem, { command: "logout" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(i18n).baseText("auth.signout")), 1)
]),
_: 1
})
]),
_: 1
})
]),
key: "0"
} : void 0
]), 1024)
]),
createBaseVNode("div", {
class: normalizeClass({ ["ml-2xs"]: true, [_ctx.$style.userName]: true, [_ctx.$style.expanded]: fullyExpanded.value })
}, [
createVNode(_component_N8nText, {
size: "small",
bold: true,
color: "text-dark"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(usersStore).currentUser?.fullName), 1)
]),
_: 1
})
], 2),
createBaseVNode("div", {
class: normalizeClass({ [_ctx.$style.userActions]: true, [_ctx.$style.expanded]: fullyExpanded.value })
}, [
createVNode(_component_N8nActionDropdown, {
items: userMenuItems.value,
placement: "top-start",
"data-test-id": "user-menu",
onSelect: onUserActionToggle
}, null, 8, ["items"])
], 2)
], 2)
]),
key: "0"
} : void 0
]), 1032, ["items", "collapsed"])
], 2);
};
}
});
const sideMenu = "_sideMenu_1w9ys_123";
const logo = "_logo_1w9ys_133";
const sideMenuCollapsed = "_sideMenuCollapsed_1w9ys_144";
const sideMenuCollapseButton = "_sideMenuCollapseButton_1w9ys_153";
const updates = "_updates_1w9ys_172";
const expanded = "_expanded_1w9ys_185";
const userArea = "_userArea_1w9ys_192";
const userName = "_userName_1w9ys_199";
const userActions = "_userActions_1w9ys_213";
const readOnlyEnvironmentIcon = "_readOnlyEnvironmentIcon_1w9ys_225";
const style0 = {
sideMenu,
logo,
sideMenuCollapsed,
sideMenuCollapseButton,
updates,
expanded,
userArea,
userName,
userActions,
readOnlyEnvironmentIcon
};
const cssModules = {
"$style": style0
};
const MainSidebar = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
export {
MainSidebar as default
};