fix: always load the right version of plugin docs (#13571)

This commit is contained in:
Barthélémy Ledoux
2025-12-11 14:06:10 +01:00
committed by GitHub
parent b7cb933e1e
commit 8a55ab3af6
6 changed files with 44 additions and 67 deletions

View File

@@ -86,6 +86,7 @@
import {computed, onActivated, onMounted, ref, provide, onBeforeUnmount, watch, InjectionKey, inject} from "vue";
import {useRoute, useRouter} from "vue-router";
import {apiUrl} from "override/utils/route";
import type * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import {EDITOR_CURSOR_INJECTION_KEY, EDITOR_WRAPPER_INJECTION_KEY} from "../no-code/injectionKeys";
import {usePluginsStore} from "../../stores/plugins";
@@ -165,7 +166,6 @@
pluginsStore.lazyLoadSchemaType({type: "flow"});
}
loadFile();
loadPluginsHash();
window.addEventListener("keydown", handleGlobalSave);
window.addEventListener("keydown", toggleAiShortcut);
if(route.query.ai === "open") {
@@ -215,15 +215,15 @@
const isCreating = computed(() => flowStore.isCreating);
const timeout = ref<any>(null);
const hash = ref<any>(null);
const editorContent = computed(() => {
return draftSource.value ?? source.value;
});
const pluginsStore = usePluginsStore();
const namespacesStore = useNamespacesStore();
const miscStore = useMiscStore();
const hash = computed<number>(() => miscStore.configs?.pluginsHash ?? 0);
const editorScrollKey = computed(() => {
if (props.flow) {
@@ -238,11 +238,6 @@
return undefined;
});
function loadPluginsHash() {
miscStore.loadConfigs().then(config => {
hash.value = config.pluginsHash;
});
}
const updateContent = inject(FILES_UPDATE_CONTENT_INJECTION_KEY);
@@ -279,34 +274,10 @@
clearTimeout(timeout.value);
});
function updatePluginDocumentation(event: any) {
const source = event.model.getValue();
const cursorOffset = event.model.getOffsetAt(event.position);
const isPlugin = (type: string) => pluginsStore.allTypes.includes(type);
const isInRange = (range: [number, number, number]) =>
cursorOffset >= range[0] && cursorOffset <= range[2];
const getRangeSize = (range: [number, number, number]) => range[2] - range[0];
const getElementFromRange = (typeElement: any) => {
const wrapper = YAML_UTILS.localizeElementAtIndex(source, typeElement.range[0]);
return wrapper?.value?.type && isPlugin(wrapper.value.type)
? wrapper.value
: {type: typeElement.type};
};
const selectedElement = YAML_UTILS.extractFieldFromMaps(source, "type", () => true, isPlugin)
.filter(el => el.range && isInRange(el.range))
.reduce((closest, current) =>
!closest || getRangeSize(current.range) < getRangeSize(closest.range)
? current
: closest
, null as any);
let result = selectedElement ? getElementFromRange(selectedElement) : undefined;
result = {...result, hash: hash.value, forceRefresh: true};
pluginsStore.updateDocumentation(result as Parameters<typeof pluginsStore.updateDocumentation>[0]);
function updatePluginDocumentation(event: {position: monaco.Position, model: monaco.editor.ITextModel}) {
const cls = YAML_UTILS.getTypeAtPosition(source.value, event.position, pluginsStore.allTypes);
const version = YAML_UTILS.getVersionAtPosition(source.value, event.position);
pluginsStore.updateDocumentation({cls, version, hash: hash.value});
};
const saveFlowYaml = async () => {

View File

@@ -86,8 +86,8 @@
flowStore.flowYaml = source
const result = await flowStore.onEdit({
source,
currentIsFlow,
editorViewType: "YAML",
topologyVisible: true,
})
if (currentIsFlow && source) {

View File

@@ -51,6 +51,7 @@
import {getValueAtJsonPath, resolve$ref} from "../../../utils/utils";
import PlaygroundRunTaskButton from "../../inputs/PlaygroundRunTaskButton.vue";
import isEqual from "lodash/isEqual";
import {useMiscStore} from "../../../override/stores/misc";
const {t} = useI18n();
@@ -370,10 +371,12 @@
onTaskInput(value);
}
const miscStore = useMiscStore();
const hash = computed(() => miscStore.configs?.pluginsHash ?? 0);
const onTaskEditorClick = inject(ON_TASK_EDITOR_CLICK_INJECTION_KEY, (elt?: PartialNoCodeElement) => {
const type = elt?.type;
if(isPlugin.value && type){
pluginsStore.updateDocumentation({type});
if(isPlugin.value && elt?.type){
pluginsStore.updateDocumentation({cls: elt.type, version: elt.version, hash: hash.value});
}else{
pluginsStore.updateDocumentation();
}

View File

@@ -110,7 +110,6 @@
const version = ref<string | undefined>(undefined);
const pluginType = ref<string | undefined>(undefined);
const filteredPlugins = ref<any[] | undefined>(undefined);
const hash = ref<string | undefined>(undefined);
const routeInfo = computed(() => ({
title: pluginType.value ?? t("plugins.names"),
@@ -125,6 +124,8 @@
],
}));
const hash = computed(() => miscStore.configs?.pluginsHash ?? 0);
const pluginName = computed(() => {
const split = pluginType.value?.split(".");
return split ? split[split.length - 1] : undefined;
@@ -152,13 +153,13 @@
version.value = route.params.version as string;
}
const clsParam = (route.params as Record<string, any>).cls as string | undefined;
const clsParam = route.params.version as string | undefined;
if (!clsParam) {
return;
}
const loadParams = {
...(route.params as Record<string, any>),
version: version.value,
hash: hash.value,
cls: clsParam,
};
@@ -166,8 +167,8 @@
isLoading.value = true;
try {
await Promise.all([
pluginsStore.load(loadParams as any),
pluginsStore.loadVersions(loadParams as any).then((data: any) => {
pluginsStore.load(loadParams),
pluginsStore.loadVersions(loadParams).then((data) => {
if (data.versions?.length > 0) {
if (!version.value) version.value = data.versions[0];
}
@@ -219,9 +220,8 @@
{immediate: true}
);
onMounted(async () => {
const config = await miscStore.loadConfigs();
hash.value = config?.pluginsHash;
onMounted(() => {
miscStore.loadConfigs();
loadToc();
loadPlugin();
});

View File

@@ -81,6 +81,7 @@
import {usePluginsStore} from "../../stores/plugins";
import {useScrollMemory} from "../../composables/useScrollMemory";
import {capitalize, formatPluginTitle} from "../../utils/global";
import {useMiscStore} from "../../override/stores/misc";
interface Props {
plugins: any[];
@@ -257,10 +258,14 @@
const hasIcon = (cls: string) => !!icons.value?.[cls];
const navigateToEditorPlugin = async (editorPlugin: any) => {
const hash = computed(() => miscStore.configs?.pluginsHash ?? 0);
const miscStore = useMiscStore();
const navigateToEditorPlugin = async (editorPlugin: {cls: string, version?: string}) => {
if (!editorPlugin?.cls) return;
const pluginCls = editorPlugin.cls;
const pluginVersion = editorPlugin.version;
const matchingPlugin = props.plugins.find(plugin => getPluginElements(plugin).includes(pluginCls));
if (!matchingPlugin) {
@@ -283,7 +288,7 @@
pushNavigationItem(getSimpleType(pluginCls), "element", {cls: pluginCls});
currentView.value = "documentation";
const pluginData = await pluginsStore.load({cls: pluginCls});
const pluginData = await pluginsStore.load({cls: pluginCls, version: pluginVersion, hash: hash.value});
currentDocumentationPlugin.value = pluginData ? {cls: pluginCls, ...pluginData} : editorPlugin;
};

View File

@@ -208,7 +208,8 @@ export const usePluginsStore = defineStore("plugins", () => {
}
const id = options.version ? `${options.cls}/${options.version}` : options.cls;
const cachedPluginDoc = pluginsDocumentation.value[options.hash ? options.hash + id : id];
const cacheKey = options.hash ? options.hash + id : id;
const cachedPluginDoc = pluginsDocumentation.value[cacheKey];
if (!options.all && cachedPluginDoc) {
nextTick(() => {
plugin.value = cachedPluginDoc;
@@ -233,10 +234,7 @@ export const usePluginsStore = defineStore("plugins", () => {
}
if (!options.all) {
pluginsDocumentation.value = {
...pluginsDocumentation.value,
[options.hash ? options.hash+id : id]: response.data
};
pluginsDocumentation.value[cacheKey] = response.data;
}
return response.data;
@@ -283,30 +281,30 @@ export const usePluginsStore = defineStore("plugins", () => {
});
}
let currentlyLoading: {type?: string; version?: string} | undefined = undefined;
let currentlyLoading: {cls?: string; version?: string} | undefined = undefined;
async function updateDocumentation(pluginElement?: ({type: string, version?: string, forceRefresh?: boolean} & Record<string, any>) | undefined) {
if (!pluginElement?.type || !allTypes.value.includes(pluginElement.type)) {
async function updateDocumentation(pluginElement?: (LoadOptions & {forceRefresh?: boolean}) | undefined) {
if (!pluginElement?.cls || !allTypes.value.includes(pluginElement.cls)) {
editorPlugin.value = undefined;
currentlyLoading = undefined;
return;
}
const {type, version, forceRefresh = false} = pluginElement;
const {cls, version, hash, forceRefresh = false} = pluginElement;
if (currentlyLoading?.type === type &&
if (currentlyLoading?.cls === cls &&
currentlyLoading?.version === version &&
!forceRefresh) {
return
}
if (!forceRefresh &&
editorPlugin.value?.cls === type &&
editorPlugin.value?.cls === cls &&
editorPlugin.value?.version === version) {
return;
}
let payload: LoadOptions = {cls: type, hash: pluginElement.hash};
let payload: LoadOptions = {cls, version, hash}
if (version !== undefined) {
if (semver.valid(version) !== null ||
@@ -321,21 +319,21 @@ export const usePluginsStore = defineStore("plugins", () => {
}
currentlyLoading = {
type,
cls,
version,
};
const pluginData = await load(payload);
editorPlugin.value = {
cls: type,
cls,
version,
...pluginData,
};
trackPluginDocumentationView(type);
trackPluginDocumentationView(cls);
forceIncludeProperties.value = Object.keys(pluginElement).filter(k => k !== "type" && k !== "version" && k !== "forceRefresh");
forceIncludeProperties.value = Object.keys(pluginElement).filter(k => k !== "cls" && k !== "version" && k !== "forceRefresh");
}
const {icons, iconsLoaded, fetchIcons} = usePluginsIcons()