n8n-editor-ui
Version:
Workflow Editor UI for n8n
550 lines (549 loc) • 24.5 kB
JavaScript
import { C as computed, Cn as toDisplayString, D as createElementBlock, E as createCommentVNode, Gt as unref, It as ref, M as createVNode, P as defineComponent, T as createBlock, W as mergeProps, _t as watch, at as renderSlot, bt as withCtx, et as openBlock, j as createTextVNode, mt as useTemplateRef, vn as normalizeClass, w as createBaseVNode } from "./vue.runtime.esm-bundler-tP5dCd7J.js";
import { D as useElementSize, P as useResizeObserver, _t as useI18n } from "./_MapCache-ficiegRb.js";
import { Sn as N8nButton_default, ht as N8nTooltip_default, it as N8nActionToggle_default, xn as N8nText_default, xt as N8nIconButton_default, y as N8nTabs_default, yn as N8nHeading_default } from "./src-DgvumQTi.js";
import { t as __plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BwBpWJRZ.js";
import { v as useRoute, y as useRouter } from "./truncate-B1HVeveJ.js";
import { Dr as useUsersStore, O as useTelemetry, Qn as ProjectTypes, Xn as useProjectsStore, Zn as useSourceControlStore, gs as useSettingsStore, oa as useUIStore, ts as VARIABLE_MODAL_KEY, v as useToast } from "./builder.store-sBTWwxRU.js";
import { Gr as PROJECT_DATA_TABLES, Oo as getResourcePermissions, Ro as VIEWS, bc as EnterpriseEditionFeature } from "./constants-BbpucWL4.js";
import { t as useFoldersStore } from "./folders.store-BjAwtSH4.js";
import { n as isIconOrEmoji, t as ProjectIcon_default } from "./ProjectIcon-A2WPT9dM.js";
import { n as useProjectPages, t as useReadyToRunStore } from "./readyToRun.store-CsvyRJzn.js";
function processDynamicTab(tab, projectId) {
if (!tab.dynamicRoute) return tab;
const tabRoute = { name: tab.dynamicRoute.name };
if (tab.dynamicRoute.includeProjectId && projectId) tabRoute.params = { projectId };
const { dynamicRoute,...tabWithoutDynamic } = tab;
return {
...tabWithoutDynamic,
to: tabRoute
};
}
function processDynamicTabs(tabs, projectId) {
return tabs.map((tab) => processDynamicTab(tab, projectId));
}
var ProjectTabs_default = /* @__PURE__ */ defineComponent({
__name: "ProjectTabs",
props: {
showSettings: {
type: Boolean,
default: false
},
showExecutions: {
type: Boolean,
default: true
},
pageType: { default: "project" },
additionalTabs: { default: () => [] }
},
setup(__props) {
const props = __props;
const locale = useI18n();
const route = useRoute();
const projectStore = useProjectsStore();
const telemetry = useTelemetry();
const selectedTab = ref("");
const selectedTabLabel = computed(() => selectedTab.value ? String(selectedTab.value) : "");
const projectId = computed(() => {
return Array.isArray(route?.params?.projectId) ? route.params.projectId[0] : route?.params?.projectId;
});
const isTeamProject = computed(() => projectStore.currentProject?.type === ProjectTypes.Team);
const getRouteConfigs = () => {
if (projectId.value) return {
workflows: {
name: VIEWS.PROJECTS_WORKFLOWS,
params: { projectId: projectId.value }
},
credentials: {
name: VIEWS.PROJECTS_CREDENTIALS,
params: { projectId: projectId.value }
},
executions: {
name: VIEWS.PROJECTS_EXECUTIONS,
params: { projectId: projectId.value }
},
variables: {
name: VIEWS.PROJECTS_VARIABLES,
params: { projectId: projectId.value }
}
};
if (props.pageType === "shared") return {
workflows: { name: VIEWS.SHARED_WORKFLOWS },
credentials: { name: VIEWS.SHARED_CREDENTIALS },
executions: { name: VIEWS.NOT_FOUND },
variables: { name: VIEWS.NOT_FOUND }
};
return {
workflows: { name: VIEWS.WORKFLOWS },
credentials: { name: VIEWS.CREDENTIALS },
executions: { name: VIEWS.EXECUTIONS },
variables: { name: VIEWS.HOME_VARIABLES }
};
};
const createTab = (label, routeKey, routes) => {
return {
label: locale.baseText(label),
value: routes[routeKey].name,
to: routes[routeKey]
};
};
const options = computed(() => {
const routes = getRouteConfigs();
const tabs = [createTab("mainSidebar.workflows", "workflows", routes), createTab("mainSidebar.credentials", "credentials", routes)];
if (props.showExecutions) tabs.push(createTab("mainSidebar.executions", "executions", routes));
if (props.pageType === "overview" || isTeamProject.value) tabs.push(createTab("mainSidebar.variables", "variables", routes));
if (props.additionalTabs?.length) {
const processedAdditionalTabs = processDynamicTabs(props.additionalTabs, projectId.value);
tabs.push(...processedAdditionalTabs);
}
if (props.showSettings) tabs.push({
label: locale.baseText("projects.settings"),
value: VIEWS.PROJECT_SETTINGS,
to: {
name: VIEWS.PROJECT_SETTINGS,
params: { projectId: projectId.value }
}
});
return tabs;
});
watch(() => route?.name, () => {
selectedTab.value = route.name === VIEWS.PROJECTS_FOLDERS ? VIEWS.PROJECTS_WORKFLOWS : route.name;
}, { immediate: true });
function onSelectTab(value) {
if (selectedTab.value === "variables") telemetry.track("User clicked project variables tab", { project_id: projectId.value });
selectedTab.value = value;
}
return (_ctx, _cache) => {
return openBlock(), createBlock(unref(N8nTabs_default), {
"model-value": selectedTabLabel.value,
options: options.value,
"data-test-id": "project-tabs",
"onUpdate:modelValue": onSelectTab
}, null, 8, ["model-value", "options"]);
};
}
});
var ProjectCreateResource_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
__name: "ProjectCreateResource",
props: {
actions: {},
disabled: { type: Boolean },
type: {}
},
emits: ["action"],
setup(__props, { expose: __expose, emit: __emit }) {
const emit = __emit;
const actionToggleRef = useTemplateRef("actionToggleRef");
__expose({ openActionToggle: (isOpen) => actionToggleRef.value?.openActionToggle(isOpen) });
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", { class: normalizeClass([_ctx.$style.buttonGroup]) }, [renderSlot(_ctx.$slots, "default"), createVNode(unref(N8nActionToggle_default), {
ref_key: "actionToggleRef",
ref: actionToggleRef,
"data-test-id": "add-resource",
actions: _ctx.actions,
placement: "bottom-end",
teleported: false,
onAction: _cache[0] || (_cache[0] = ($event) => emit("action", $event))
}, {
default: withCtx(() => [createVNode(unref(N8nIconButton_default), {
disabled: _ctx.disabled,
class: normalizeClass([_ctx.$style.buttonGroupDropdown]),
icon: "chevron-down",
type: _ctx.type ?? "primary"
}, null, 8, [
"disabled",
"class",
"type"
])]),
_: 1
}, 8, ["actions"])], 2);
};
}
});
var ProjectCreateResource_vue_vue_type_style_index_0_lang_module_default = {
buttonGroup: "_buttonGroup_1ofs3_123",
buttonGroupDropdown: "_buttonGroupDropdown_1ofs3_137"
};
var ProjectCreateResource_default = /* @__PURE__ */ __plugin_vue_export_helper_default(ProjectCreateResource_vue_vue_type_script_setup_true_lang_default, [["__cssModules", { "$style": ProjectCreateResource_vue_vue_type_style_index_0_lang_module_default }]]);
const truncateTextToFitWidth = (text, availableWidth, fontSizeInPixels) => {
if (!text || availableWidth <= 0) return "";
const averageCharWidth = .55 * fontSizeInPixels;
const maxLengthToDisplay = Math.floor(availableWidth / averageCharWidth);
if (text.length <= maxLengthToDisplay) return "";
const truncated = text.slice(0, maxLengthToDisplay);
const lastSpaceIndex = truncated.lastIndexOf(" ");
return truncated.slice(0, lastSpaceIndex === -1 ? maxLengthToDisplay : lastSpaceIndex) + "...";
};
var ReadyToRunButton_default = /* @__PURE__ */ defineComponent({
__name: "ReadyToRunButton",
props: { hasActiveCallouts: { type: Boolean } },
setup(__props) {
const props = __props;
const route = useRoute();
const i18n = useI18n();
const toast = useToast();
const projectPages = useProjectPages();
const projectsStore = useProjectsStore();
const sourceControlStore = useSourceControlStore();
const foldersStore = useFoldersStore();
const readyToRunStore = useReadyToRunStore();
const projectPermissions = computed(() => {
return getResourcePermissions(projectsStore.currentProject?.scopes ?? projectsStore.personalProject?.scopes);
});
const showButton = computed(() => {
return readyToRunStore.getButtonVisibility(foldersStore.totalWorkflowCount > 0, projectPermissions.value.workflow.create, sourceControlStore.preferences.branchReadOnly) && !props.hasActiveCallouts;
});
const handleClick = async () => {
const projectId = projectPages.isOverviewSubPage ? projectsStore.personalProject?.id : route.params.projectId;
try {
await readyToRunStore.claimCreditsAndOpenWorkflow("button", route.params.folderId, projectId);
} catch (error) {
toast.showError(error, i18n.baseText("generic.error"));
}
};
return (_ctx, _cache) => {
return showButton.value ? (openBlock(), createBlock(unref(N8nButton_default), {
key: 0,
"data-test-id": "ready-to-run-button",
type: "secondary",
icon: "sparkles",
loading: unref(readyToRunStore).claimingCredits,
disabled: unref(sourceControlStore).preferences.branchReadOnly || unref(readyToRunStore).claimingCredits,
onClick: handleClick
}, {
default: withCtx(() => [createTextVNode(toDisplayString(unref(i18n).baseText("workflows.empty.readyToRun")), 1)]),
_: 1
}, 8, ["loading", "disabled"])) : createCommentVNode("", true);
};
}
});
var _hoisted_1 = { style: {
"display": "flex",
"gap": "var(--spacing--xs)",
"align-items": "center"
} };
var ProjectHeader_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
__name: "ProjectHeader",
props: {
hasActiveCallouts: { type: Boolean },
mainButton: {}
},
emits: ["createFolder"],
setup(__props, { emit: __emit }) {
const route = useRoute();
const router = useRouter();
const i18n = useI18n();
const projectsStore = useProjectsStore();
const sourceControlStore = useSourceControlStore();
const settingsStore = useSettingsStore();
const uiStore = useUIStore();
const telemetry = useTelemetry();
const usersStore = useUsersStore();
const projectPages = useProjectPages();
const props = __props;
const emit = __emit;
const headerIcon = computed(() => {
if (projectsStore.currentProject?.type === ProjectTypes.Personal) return {
type: "icon",
value: "user"
};
else if (projectsStore.currentProject?.name) return isIconOrEmoji(projectsStore.currentProject.icon) ? projectsStore.currentProject.icon : {
type: "icon",
value: "layers"
};
else return {
type: "icon",
value: "house"
};
});
const homeProject = computed(() => projectsStore.currentProject ?? projectsStore.personalProject);
const isPersonalProject = computed(() => {
return homeProject.value?.type === ProjectTypes.Personal;
});
const projectName = computed(() => {
if (!projectsStore.currentProject) {
if (projectPages.isSharedSubPage) return i18n.baseText("projects.header.shared.title");
else if (projectPages.isOverviewSubPage) return i18n.baseText("projects.menu.overview");
else if (isPersonalProject.value) return i18n.baseText("projects.menu.personal");
return null;
} else if (projectsStore.currentProject.type === ProjectTypes.Personal) return i18n.baseText("projects.menu.personal");
else return projectsStore.currentProject.name;
});
const projectPermissions = computed(() => getResourcePermissions(projectsStore.currentProject?.scopes).project);
const projectVariablePermissions = computed(() => getResourcePermissions(projectsStore.currentProject?.scopes).projectVariable);
const globalVariablesPermissions = computed(() => getResourcePermissions(usersStore.currentUser?.globalScopes).variable);
const showSettings = computed(() => !!route?.params?.projectId && !!projectPermissions.value.update && projectsStore.currentProject?.type === ProjectTypes.Team);
const showFolders = computed(() => {
return settingsStore.isFoldersFeatureEnabled && [VIEWS.PROJECTS_WORKFLOWS, VIEWS.PROJECTS_FOLDERS].includes(route.name);
});
const customProjectTabs = computed(() => {
let tabType;
if (projectPages.isSharedSubPage) tabType = "shared";
else if (projectPages.isOverviewSubPage) tabType = "overview";
else tabType = "project";
return Object.keys(uiStore.moduleTabs[tabType]).filter(settingsStore.isModuleActive).flatMap((module) => uiStore.moduleTabs[tabType][module]);
});
const ACTION_TYPES = {
WORKFLOW: "workflow",
CREDENTIAL: "credential",
FOLDER: "folder",
DATA_TABLE: "dataTable",
VARIABLE: "variable"
};
const createWorkflowButton = computed(() => ({
value: ACTION_TYPES.WORKFLOW,
label: i18n.baseText("projects.header.create.workflow"),
icon: sourceControlStore.preferences.branchReadOnly ? "lock" : void 0,
size: "mini",
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes).workflow.create
}));
const createCredentialButton = computed(() => ({
value: ACTION_TYPES.CREDENTIAL,
label: i18n.baseText("projects.header.create.credential"),
icon: sourceControlStore.preferences.branchReadOnly ? "lock" : void 0,
size: "mini",
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes).credential.create
}));
const createDataTableButton = computed(() => ({
value: ACTION_TYPES.DATA_TABLE,
label: i18n.baseText("dataTable.add.button.label"),
icon: sourceControlStore.preferences.branchReadOnly ? "lock" : void 0,
size: "mini",
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes)?.dataTable?.create
}));
const createVariableButton = computed(() => ({
value: ACTION_TYPES.VARIABLE,
label: i18n.baseText("variables.add.button.label"),
icon: sourceControlStore.preferences.branchReadOnly ? "lock" : void 0,
size: "mini",
disabled: sourceControlStore.preferences.branchReadOnly || !projectVariablePermissions.value.create && !globalVariablesPermissions.value.create
}));
const selectedMainButtonType = computed(() => props.mainButton ?? ACTION_TYPES.WORKFLOW);
const mainButtonConfig = computed(() => {
switch (selectedMainButtonType.value) {
case ACTION_TYPES.CREDENTIAL: return createCredentialButton.value;
case ACTION_TYPES.DATA_TABLE: return createDataTableButton.value;
case ACTION_TYPES.VARIABLE: return createVariableButton.value;
case ACTION_TYPES.WORKFLOW:
default: return createWorkflowButton.value;
}
});
const menu = computed(() => {
const items = [];
if (selectedMainButtonType.value !== ACTION_TYPES.WORKFLOW) items.push({
value: ACTION_TYPES.WORKFLOW,
label: i18n.baseText("projects.header.create.workflow"),
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes).workflow.create
});
if (selectedMainButtonType.value !== ACTION_TYPES.CREDENTIAL) items.push({
value: ACTION_TYPES.CREDENTIAL,
label: i18n.baseText("projects.header.create.credential"),
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes).credential.create
});
if (selectedMainButtonType.value !== ACTION_TYPES.VARIABLE && settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Variables]) items.push({
value: ACTION_TYPES.VARIABLE,
label: i18n.baseText("variables.add.button.label"),
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes).projectVariable.create
});
if (showFolders.value) items.push({
value: ACTION_TYPES.FOLDER,
label: i18n.baseText("projects.header.create.folder"),
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes).folder.create
});
if (settingsStore.isDataTableFeatureEnabled && selectedMainButtonType.value !== ACTION_TYPES.DATA_TABLE) items.push({
value: ACTION_TYPES.DATA_TABLE,
label: i18n.baseText("dataTable.add.button.label"),
disabled: sourceControlStore.preferences.branchReadOnly || !getResourcePermissions(homeProject.value?.scopes)?.dataTable?.create
});
return items;
});
const showProjectIcon = computed(() => {
return !projectPages.isOverviewSubPage && !projectPages.isSharedSubPage && !isPersonalProject.value;
});
function isCredentialsListView(routeName) {
return [
VIEWS.PROJECTS_CREDENTIALS,
VIEWS.CREDENTIALS,
VIEWS.SHARED_CREDENTIALS
].includes(routeName);
}
function isWorkflowListView(routeName) {
return [
VIEWS.PROJECTS_WORKFLOWS,
VIEWS.WORKFLOWS,
VIEWS.SHARED_WORKFLOWS,
VIEWS.PROJECTS_FOLDERS
].includes(routeName);
}
function getUIContext(routeName) {
if (isCredentialsListView(routeName)) return "credentials_list";
else if (isWorkflowListView(routeName)) return "workflow_list";
else return;
}
const actions$1 = {
[ACTION_TYPES.WORKFLOW]: (projectId) => {
router.push({
name: VIEWS.NEW_WORKFLOW,
query: {
projectId,
parentFolderId: route.params.folderId,
uiContext: getUIContext(route.name?.toString() ?? "")
}
});
},
[ACTION_TYPES.CREDENTIAL]: (projectId) => {
router.push({
name: VIEWS.PROJECTS_CREDENTIALS,
params: {
projectId,
credentialId: "create"
},
query: { uiContext: getUIContext(route.name?.toString() ?? "") }
});
},
[ACTION_TYPES.FOLDER]: () => {
emit("createFolder");
},
[ACTION_TYPES.DATA_TABLE]: (projectId) => {
router.push({
name: PROJECT_DATA_TABLES,
params: {
projectId,
new: "new"
}
});
},
[ACTION_TYPES.VARIABLE]: () => {
uiStore.openModalWithData({
name: VARIABLE_MODAL_KEY,
data: { mode: "new" }
});
telemetry.track("User clicked header add variable button");
}
};
const pageType = computed(() => {
if (projectPages.isSharedSubPage) return "shared";
else if (projectPages.isOverviewSubPage) return "overview";
else return "project";
});
const sectionDescription = computed(() => {
if (projectPages.isSharedSubPage) return i18n.baseText("projects.header.shared.subtitle");
else if (projectPages.isOverviewSubPage) return i18n.baseText(settingsStore.isDataTableFeatureEnabled ? "projects.header.overview.subtitleWithDataTables" : "projects.header.overview.subtitle");
else if (isPersonalProject.value) return i18n.baseText(settingsStore.isDataTableFeatureEnabled ? "projects.header.personal.subtitleWithDataTables" : "projects.header.personal.subtitle");
return null;
});
const projectDescription = computed(() => {
if (projectPages.isProjectsSubPage) return projectsStore.currentProject?.description;
return null;
});
const projectHeaderRef = ref(null);
const { width: projectHeaderWidth } = useElementSize(projectHeaderRef);
const headerActionsRef = ref(null);
const { width: headerActionsWidth } = useElementSize(headerActionsRef);
const projectSubtitleFontSizeInPxs = ref(null);
useResizeObserver(projectHeaderRef, () => {
if (!projectHeaderRef.value) return;
const projectSubtitleEl = projectHeaderRef.value.querySelector("span[data-test-id=\"project-subtitle\"]");
if (projectSubtitleEl) {
const computedStyle = window.getComputedStyle(projectSubtitleEl);
projectSubtitleFontSizeInPxs.value = parseFloat(computedStyle.fontSize);
}
});
const projectDescriptionTruncated = computed(() => {
if (!projectDescription.value) return "";
const availableTextWidth = projectHeaderWidth.value - headerActionsWidth.value;
const fontSizeInPixels = projectSubtitleFontSizeInPxs.value ?? 14;
return truncateTextToFitWidth(projectDescription.value, availableTextWidth, fontSizeInPixels);
});
const onSelect = (action) => {
const executableAction = actions$1[action];
if (!homeProject.value) return;
executableAction(homeProject.value.id);
};
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", null, [
createBaseVNode("div", {
ref_key: "projectHeaderRef",
ref: projectHeaderRef,
class: normalizeClass(_ctx.$style.projectHeader)
}, [createBaseVNode("div", { class: normalizeClass(_ctx.$style.projectDetails) }, [showProjectIcon.value ? (openBlock(), createBlock(ProjectIcon_default, {
key: 0,
icon: headerIcon.value,
"border-less": true,
size: "medium"
}, null, 8, ["icon"])) : createCommentVNode("", true), createBaseVNode("div", { class: normalizeClass(_ctx.$style.headerActions) }, [projectName.value ? (openBlock(), createBlock(unref(N8nHeading_default), {
key: 0,
bold: "",
tag: "h2",
size: "xlarge",
"data-test-id": "project-name"
}, {
default: withCtx(() => [createTextVNode(toDisplayString(projectName.value), 1)]),
_: 1
})) : createCommentVNode("", true), sectionDescription.value ? (openBlock(), createBlock(unref(N8nText_default), {
key: 1,
color: "text-light",
"data-test-id": "project-subtitle"
}, {
default: withCtx(() => [createTextVNode(toDisplayString(sectionDescription.value), 1)]),
_: 1
})) : projectDescription.value ? (openBlock(), createElementBlock("div", {
key: 2,
class: normalizeClass(_ctx.$style.projectDescriptionWrapper)
}, [createVNode(unref(N8nText_default), {
color: "text-light",
"data-test-id": "project-subtitle"
}, {
default: withCtx(() => [createTextVNode(toDisplayString(projectDescriptionTruncated.value || projectDescription.value), 1)]),
_: 1
}), projectDescriptionTruncated.value ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(_ctx.$style.tooltip)
}, [createVNode(unref(N8nText_default), { color: "text-light" }, {
default: withCtx(() => [createTextVNode(toDisplayString(projectDescription.value), 1)]),
_: 1
})], 2)) : createCommentVNode("", true)], 2)) : createCommentVNode("", true)], 2)], 2), unref(route).name !== unref(VIEWS).PROJECT_SETTINGS ? (openBlock(), createElementBlock("div", {
key: 0,
ref_key: "headerActionsRef",
ref: headerActionsRef,
class: normalizeClass([_ctx.$style.headerActions])
}, [createVNode(unref(N8nTooltip_default), {
disabled: !unref(sourceControlStore).preferences.branchReadOnly,
content: unref(i18n).baseText("readOnlyEnv.cantAdd.any")
}, {
default: withCtx(() => [createBaseVNode("div", _hoisted_1, [createVNode(ReadyToRunButton_default, { "has-active-callouts": props.hasActiveCallouts }, null, 8, ["has-active-callouts"]), createVNode(ProjectCreateResource_default, {
"data-test-id": "add-resource-buttons",
actions: menu.value,
disabled: unref(sourceControlStore).preferences.branchReadOnly,
onAction: onSelect
}, {
default: withCtx(() => [createVNode(unref(N8nButton_default), mergeProps({ "data-test-id": `add-resource-${selectedMainButtonType.value}` }, mainButtonConfig.value, { onClick: _cache[0] || (_cache[0] = ($event) => onSelect(selectedMainButtonType.value)) }), null, 16, ["data-test-id"])]),
_: 1
}, 8, ["actions", "disabled"])])]),
_: 1
}, 8, ["disabled", "content"])], 2)) : createCommentVNode("", true)], 2),
renderSlot(_ctx.$slots, "default"),
createBaseVNode("div", { class: normalizeClass(_ctx.$style.actions) }, [createVNode(ProjectTabs_default, {
"page-type": pageType.value,
"show-executions": !unref(projectPages).isSharedSubPage,
"show-settings": showSettings.value,
"additional-tabs": customProjectTabs.value
}, null, 8, [
"page-type",
"show-executions",
"show-settings",
"additional-tabs"
])], 2)
]);
};
}
});
var ProjectHeader_vue_vue_type_style_index_0_lang_module_default = {
projectHeader: "_projectHeader_sx5k1_123",
projectDetails: "_projectDetails_sx5k1_130",
actions: "_actions_sx5k1_135",
projectDescriptionWrapper: "_projectDescriptionWrapper_sx5k1_139",
tooltip: "_tooltip_sx5k1_143",
headerActions: "_headerActions_sx5k1_166"
};
var ProjectHeader_default = /* @__PURE__ */ __plugin_vue_export_helper_default(ProjectHeader_vue_vue_type_script_setup_true_lang_default, [["__cssModules", { "$style": ProjectHeader_vue_vue_type_style_index_0_lang_module_default }]]);
export { ProjectHeader_default as t };