Compare commits

...

16 Commits

Author SHA1 Message Date
Roman Acevedo
80cfaafd73 commit
make test crash on purpose
2025-06-09 13:24:53 +02:00
github-actions[bot]
4cddc704f4 chore(version): update to version '0.23.0-rc2-SNAPSHOT' 2025-06-09 10:48:43 +00:00
Miloš Paunović
f2f0e29f93 fix(namespaces): properly load flows when changing namespace (#9393)
Closes https://github.com/kestra-io/kestra/issues/9352.
2025-06-09 12:34:36 +02:00
Miloš Paunović
95011e022e fix(namespaces): reload namespace once the id parameter changes (#9372)
Closes https://github.com/kestra-io/kestra-ee/issues/3630.
2025-06-06 12:25:37 +02:00
brian.mulier
65503b708a fix(core): add DefaultFilterLanguage as default in KestraFilter
closes #9365
2025-06-05 17:42:34 +02:00
brian-mulier-p
876b8cb2e6 fix(core): avoid crashing in case of taskrun having too large value (#9359)
closes #9312
2025-06-05 14:11:37 +02:00
Nicolas K.
f3b7592dfa fix(flows): #9319 error when puase with timeout trigger an execution (#9334)
* fix(flows): #9319 error when puase with timeout trigger an execution even after it's terminated

* fix(flows): only skip paused flow when execution is terminated

---------

Co-authored-by: nKwiatkowski <nkwiatkowski@kestra.io>
2025-06-05 10:15:49 +02:00
brian.mulier
4dbeaf86bb fix(core): larger debounce for filter 2025-06-05 09:48:53 +02:00
brian.mulier
f98e78399d fix(core): handle whitespaces in label key and value 2025-06-05 09:48:43 +02:00
brian.mulier
71dac0f311 fix(core): smarter autocomplete order in editor 2025-06-05 09:48:00 +02:00
brian-mulier-p
3077d0ac7a fix(core): additional plugins are now properly shown in plugin docs (#9329)
closes kestra-io/plugin-langchain4j#61
2025-06-05 09:46:57 +02:00
YannC.
9504bbaffe fix(ci): put back bump helm chart and remove if condition 2025-06-05 08:48:56 +02:00
YannC.
159c9373ad fix(ci): checkout actions from main branch 2025-06-04 21:12:56 +02:00
YannC.
55b9088b55 fix(ci): modify actions order 2025-06-04 21:06:17 +02:00
YannC.
601d1a0abb fix(ci): Correctly pass all the secrets through all workflows 2025-06-04 15:10:33 +02:00
Florian Hussonnois
4a1cf98f26 chore(version): bump to version '0.23.0-rc1-SNAPSHOT' 2025-06-04 14:07:30 +02:00
16 changed files with 199 additions and 95 deletions

View File

@@ -43,6 +43,9 @@ jobs:
SONATYPE_GPG_KEYID: ${{ secrets.SONATYPE_GPG_KEYID }}
SONATYPE_GPG_PASSWORD: ${{ secrets.SONATYPE_GPG_PASSWORD }}
SONATYPE_GPG_FILE: ${{ secrets.SONATYPE_GPG_FILE }}
GH_PERSONAL_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
SLACK_RELEASES_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }}
end:
runs-on: ubuntu-latest

View File

@@ -6,23 +6,15 @@ on:
GH_PERSONAL_TOKEN:
description: "The Github personal token."
required: true
push:
tags:
- '*'
SLACK_RELEASES_WEBHOOK_URL:
description: "The Slack webhook URL."
required: true
jobs:
publish:
name: Github - Release
runs-on: ubuntu-latest
steps:
# Download Exec
- name: Artifacts - Download executable
uses: actions/download-artifact@v4
if: startsWith(github.ref, 'refs/tags/v')
with:
name: exe
path: build/executable
# Check out
- name: Checkout - Repository
uses: actions/checkout@v4
@@ -36,11 +28,20 @@ jobs:
with:
repository: kestra-io/actions
sparse-checkout-cone-mode: true
ref: fix/core-release
path: actions
sparse-checkout: |
.github/actions
# Download Exec
# Must be done after checkout actions
- name: Artifacts - Download executable
uses: actions/download-artifact@v4
if: startsWith(github.ref, 'refs/tags/v')
with:
name: exe
path: build/executable
# GitHub Release
- name: Create GitHub release
uses: ./actions/.github/actions/github-release
@@ -49,3 +50,16 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
SLACK_RELEASES_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }}
# Trigger gha workflow to bump helm chart version
- name: GitHub - Trigger the Helm chart version bump
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.GH_PERSONAL_TOKEN }}
repository: kestra-io/helm-charts
event-type: update-helm-chart-version
client-payload: |-
{
"new_version": "${{ github.ref_name }}",
"github_repository": "${{ github.repository }}",
"github_actor": "${{ github.actor }}"
}

View File

@@ -42,6 +42,12 @@ on:
SONATYPE_GPG_FILE:
description: "The Sonatype GPG file."
required: true
GH_PERSONAL_TOKEN:
description: "The Github personal token."
required: true
SLACK_RELEASES_WEBHOOK_URL:
description: "The Slack webhook URL."
required: true
jobs:
build-artifacts:
name: Build - Artifacts
@@ -77,4 +83,5 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v')
uses: ./.github/workflows/workflow-github-release.yml
secrets:
GH_PERSONAL_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
GH_PERSONAL_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }}
SLACK_RELEASES_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }}

View File

@@ -5,6 +5,7 @@ import com.amazon.ion.IonSystem;
import com.amazon.ion.system.*;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
@@ -36,6 +37,8 @@ import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import static com.fasterxml.jackson.core.StreamReadConstraints.DEFAULT_MAX_STRING_LEN;
public final class JacksonMapper {
public static final TypeReference<Map<String, Object>> MAP_TYPE_REFERENCE = new TypeReference<>() {};
public static final TypeReference<List<Object>> LIST_TYPE_REFERENCE = new TypeReference<>() {};
@@ -43,6 +46,12 @@ public final class JacksonMapper {
private JacksonMapper() {}
static {
StreamReadConstraints.overrideDefaultStreamReadConstraints(
StreamReadConstraints.builder().maxNameLength(DEFAULT_MAX_STRING_LEN).build()
);
}
private static final ObjectMapper MAPPER = JacksonMapper.configure(
new ObjectMapper()
);

View File

@@ -46,7 +46,7 @@ class ClassPluginDocumentationTest {
assertThat(doc.getDocLicense()).isEqualTo("EE");
// simple
assertThat(((Map<String, String>) doc.getInputs().get("format")).get("type")).isEqualTo("string");
assertThat(((Map<String, String>) doc.getInputs().get("format")).get("type")).isEqualTo("stdfsdsfdsfdsfdsfdsfdsfring");
assertThat(((Map<String, String>) doc.getInputs().get("format")).get("default")).isEqualTo("{}");
assertThat(((Map<String, String>) doc.getInputs().get("format")).get("pattern")).isEqualTo(".*");
assertThat(((Map<String, String>) doc.getInputs().get("format")).get("description")).contains("of this input");

View File

@@ -1,6 +1,6 @@
version=0.24.0-SNAPSHOT
version=0.23.0-rc2-SNAPSHOT
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.priority=low
org.gradle.priority=low

View File

@@ -1166,7 +1166,7 @@ public class JdbcExecutor implements ExecutorInterface, Service {
try {
// Handle paused tasks
if (executionDelay.getDelayType().equals(ExecutionDelay.DelayType.RESUME_FLOW)) {
if (executionDelay.getDelayType().equals(ExecutionDelay.DelayType.RESUME_FLOW) && !pair.getLeft().getState().isTerminated()) {
FlowInterface flow = flowMetaStore.findByExecution(pair.getLeft()).orElseThrow();
if (executionDelay.getTaskRunId() == null) {
// if taskRunId is null, this means we restart a flow that was delayed at startup (scheduled on)

View File

@@ -6,8 +6,8 @@
<MonacoEditor
ref="monacoEditor"
class="border flex-grow-1 position-relative"
:language="`${language?.domain === undefined ? '' : (language.domain + '-')}${legacyQuery ? 'legacy-' : ''}filter`"
:schema-type="language?.domain"
:language="`${language.domain === undefined ? '' : (language.domain + '-')}${legacyQuery ? 'legacy-' : ''}filter`"
:schema-type="language.domain"
:value="filter"
@change="filter = $event"
:theme="themeComputed"
@@ -84,6 +84,7 @@
import {Comparators, getComparator} from "../../composables/monaco/languages/filters/filterCompletion.ts";
import {watchDebounced} from "@vueuse/core";
import {FilterLanguage} from "../../composables/monaco/languages/filters/filterLanguage.ts";
import DefaultFilterLanguage from "../../composables/monaco/languages/filters/impl/defaultFilterLanguage.ts";
const router = useRouter();
const route = useRoute();
@@ -91,7 +92,7 @@
const props = withDefaults(defineProps<{
prefix?: string | undefined;
language?: FilterLanguage | undefined,
language?: FilterLanguage,
propertiesWidth?: number,
buttons?: (Omit<Buttons, "settings"> & {
settings: Omit<Buttons["settings"], "charts"> & { charts?: Buttons["settings"]["charts"] }
@@ -104,7 +105,7 @@
legacyQuery?: boolean,
}>(), {
prefix: undefined,
language: undefined,
language: () => DefaultFilterLanguage,
propertiesWidth: 144,
buttons: () => ({
refresh: {
@@ -220,7 +221,7 @@
values = [values];
}
return values.map(value => (queryRemapper?.[filterKey] ?? filterKey) + maybeSubKeyString + getComparator(comparator as Parameters<typeof getComparator>[0]) + value);
return values.map(value => (queryRemapper?.[filterKey] ?? filterKey) + maybeSubKeyString + getComparator(comparator as Parameters<typeof getComparator>[0]) + (value!.includes(" ") ? `"${value}"` : value));
})
.join(" ");
}
@@ -243,10 +244,10 @@
return {};
}
const KEY_MATCHER = "((?:(?!" + COMPARATORS_REGEX + ")\\S)+?)";
const KEY_MATCHER = "((?:(?!" + COMPARATORS_REGEX + ")(?:\\S|\"[^\"]*\"))+?)";
const COMPARATOR_MATCHER = "(" + COMPARATORS_REGEX + ")";
const MAYBE_PREVIOUS_VALUE = "(?:(?<=\\S),)?";
const VALUE_MATCHER = "((?:" + MAYBE_PREVIOUS_VALUE + "(?:(?:\"[^\\n,]*\")|(?:[^\\s,]*)))+)";
const VALUE_MATCHER = "((?:" + MAYBE_PREVIOUS_VALUE + "(?:(?:\"[^\"]*\")|(?:[^\\s,]*)))+)";
const filterMatcher = new RegExp("\\s*(?<!\\S)" +
"((?:" + KEY_MATCHER + COMPARATOR_MATCHER + VALUE_MATCHER + ")" +
"|\"([^\"]*)\"" +
@@ -259,7 +260,7 @@
// If we're not in a {key}{comparator}{value} format, we assume it's a text search
if (key === undefined) {
if (props.language?.textFilterSupported && (text === undefined || !props.language?.keyMatchers()?.some(keyMatcher => keyMatcher.test(text)))) {
if (props.language.textFilterSupported && (text === undefined || !props.language.keyMatchers()?.some(keyMatcher => keyMatcher.test(text)))) {
filters.push({
key: "text",
comparator: "EQUALS",
@@ -269,11 +270,11 @@
continue;
}
if (!props.language?.keyMatchers()?.some(keyMatcher => keyMatcher.test(key))) {
if (!props.language.keyMatchers()?.some(keyMatcher => keyMatcher.test(key))) {
continue; // Skip keys that don't match the language key matchers
}
if (!props.language?.comparatorsPerKey()[FilterLanguage.withNestedKeyPlaceholder(key)].some(c => Comparators[c] === comparator)) {
if (!props.language.comparatorsPerKey()[FilterLanguage.withNestedKeyPlaceholder(key)].some(c => Comparators[c] === comparator)) {
continue; // Skip comparators that are not valid for the key
}
@@ -310,7 +311,7 @@
if (key.includes(".")) {
const keyAndSubKeyMatch = queryKey.match(/([^.]+)\.([^.]+)/);
const rootKey = keyAndSubKeyMatch?.[1];
const subKey = keyAndSubKeyMatch?.[2];
const subKey = keyAndSubKeyMatch?.[2].replace(/^"([^"]*)"$/, "$1");
if (rootKey === undefined || subKey === undefined) {
return [];
}
@@ -452,7 +453,7 @@
...filterQueryString.value
}
});
}, {immediate: true, debounce: 500});
}, {immediate: true, debounce: 1000});
</script>
<style lang="scss" scoped>

View File

@@ -739,7 +739,7 @@
);
if (this.namespace) {
queryFilter["filters[namespace][EQUALS]"] = this.namespace;
queryFilter["filters[namespace][EQUALS]"] = this.$route.params.id || this.namespace;
}
return _merge(base, queryFilter);

View File

@@ -56,6 +56,7 @@
import {Moment} from "moment";
import PlaceholderContentWidget from "../../composables/monaco/PlaceholderContentWidget.ts";
import ICodeEditor = editor.ICodeEditor;
import debounce from "lodash/debounce";
import {hashCode} from "../../utils/global.ts";
const store = useStore();
@@ -168,7 +169,7 @@
base: kestraBaseTheme.base
}
: theme as Partial<editor.IStandaloneThemeData> & { base: editor.BuiltinTheme };
const themeId = hashCode(JSON.stringify(theme)).toString();
monaco.editor.defineTheme(themeId, {
inherit: true,
@@ -176,7 +177,7 @@
colors: {},
...base
});
return themeId;
}
@@ -244,7 +245,7 @@
watch(() => props.theme, (newTheme) => {
if (typeof newTheme === "object") {
const themeId = defineCustomTheme(newTheme);
if (editorResolved.value) {
monaco.editor.setTheme(themeId);
}
@@ -657,12 +658,12 @@
}
});
localEditor.onDidChangeCursorPosition(() => {
localEditor.onDidChangeCursorPosition(debounce(() => {
if (suggestController.model.state !== 0) {
suggestController.cancelSuggestWidget();
localEditor!.trigger("refreshSuggestionsOnCursorMove", "editor.action.triggerSuggest", {});
}
})
}, 300))
}
if (!props.input) {
@@ -797,4 +798,4 @@
}
}
}
</style>
</style>

View File

@@ -8,7 +8,7 @@
</template>
<script setup lang="ts">
import {ref, computed, Ref, onMounted} from "vue";
import {ref, computed, Ref, watch, onMounted} from "vue";
import {useTabs} from "override/components/namespaces/useTabs";
import {useHelpers} from "./utils/useHelpers";
@@ -25,11 +25,17 @@
const route = useRoute();
const context = ref({title: details.title});
const context = ref({title: details.value.title});
useRouteContext(context);
const namespace = computed(() => route.params?.id) as Ref<string>;
watch(namespace, (newID) => {
if (newID) {
store.dispatch("namespace/load", newID);
}
});
const store = useStore();
onMounted(() => {
if (namespace.value) {

View File

@@ -1,4 +1,4 @@
import {Component} from "vue";
import {Component, computed, Ref} from "vue";
import {useRoute} from "vue-router";
import {useI18n} from "vue-i18n";
@@ -45,30 +45,30 @@ export function useHelpers() {
const route = useRoute();
const {t} = useI18n({useScope: "global"});
const namespace = route.params?.id as string;
const namespace = computed(() => route.params?.id) as Ref<string>;
const parts = namespace?.split(".") ?? [];
const details: Details = {
title: parts.at(-1) || t("namespaces"),
const parts = computed(() => namespace.value?.split(".") ?? []);
const details: Ref<Details> = computed(() => ({
title: parts.value.at(-1) || t("namespaces"),
breadcrumb: [
{label: t("namespaces"), link: {name: "namespaces/list"}},
...parts.map((_: string, index: number) => ({
label: parts[index],
...parts.value.map((_: string, index: number) => ({
label: parts.value[index],
link: {
name: "namespaces/update",
params: {
id: parts.slice(0, index + 1).join("."),
id: parts.value.slice(0, index + 1).join("."),
tab: "overview",
},
},
disabled: index === parts.length - 1,
disabled: index === parts.value.length - 1,
})),
],
};
}));
const tabs: Tab[] = [
// If it's a system namespace, include the blueprints tab
...(namespace === "system"
...(namespace.value === "system"
? [
{
name: "blueprints",
@@ -88,26 +88,34 @@ export function useHelpers() {
name: "flows",
title: t("flows"),
component: Flows,
props: {namespace, topbar: false},
props: {namespace: namespace.value, topbar: false},
},
{
name: "executions",
title: t("executions"),
component: Executions,
props: {namespace, topbar: false, visibleCharts: true},
props: {
namespace: namespace.value,
topbar: false,
visibleCharts: true,
},
},
{
name: "dependencies",
title: t("dependencies"),
component: Dependencies,
props: {namespace, type: "dependencies"},
props: {namespace: namespace.value, type: "dependencies"},
},
{
maximized: true,
name: "files",
title: t("files"),
component: EditorView,
props: {namespace, isNamespace: true, isReadOnly: false},
props: {
namespace: namespace.value,
isNamespace: true,
isReadOnly: false,
},
},
];

View File

@@ -102,7 +102,7 @@ export default class FilterLanguageConfigurator extends AbstractLanguageConfigur
includeLF: true,
tokenizer: {
root: [
[/[\w."]+/, {
[/[\w.]*(?:"[^"]*")?[\w.]*/, {
cases: {
...keysTokenizerCases,
"@default": {token: "@rematch", next: "@rawText"}
@@ -344,4 +344,4 @@ export default class FilterLanguageConfigurator extends AbstractLanguageConfigur
}
})];
}
}
}

View File

@@ -57,19 +57,49 @@ export class YamlLanguageConfigurator extends AbstractLanguageConfigurator {
(defaultCompletion.suggestions as {
label: string,
filterText: string,
insertText: string
insertText: string,
sortText?: string
}[]).forEach(suggestion => {
if (suggestion.label.endsWith("...") && suggestion.insertText.includes(suggestion.label.substring(0, suggestion.label.length - 3))) {
suggestion.label = suggestion.insertText;
}
if (suggestion.label.includes(".")) {
const dotSplit = suggestion.label.split(/\.(?=\w)/);
const taskName = dotSplit.pop();
suggestion.filterText = [taskName, ...dotSplit, taskName].join(".");
}
});
const wordAtPosition = model.getWordAtPosition(position)?.word?.toLowerCase();
if (wordAtPosition !== undefined) {
const sortBumperText = "a1".repeat(10);
if (suggestion.label.includes(".")) {
const dotSplit = suggestion.label.toLowerCase().split(/\.(?=\w)/);
if (dotSplit[dotSplit.length - 1].startsWith(wordAtPosition)) {
suggestion.sortText = sortBumperText.repeat(5) + suggestion.label;
} else if (dotSplit[dotSplit.length - 1].includes(wordAtPosition)) {
suggestion.sortText = sortBumperText.repeat(4) + suggestion.label;
} else {
suggestion.sortText = dotSplit.splice(dotSplit.length - 1, 1).reduceRight((prefix, part) => {
let sortBumperPrefixForPart;
if (part.startsWith(wordAtPosition)) {
sortBumperPrefixForPart = sortBumperText.repeat(3)
} else if (part.includes(wordAtPosition)) {
sortBumperPrefixForPart = sortBumperText.repeat(2);
}
if (sortBumperPrefixForPart === undefined || prefix.length >= sortBumperPrefixForPart.length) {
return prefix;
}
return sortBumperPrefixForPart;
}, "") + suggestion.label;
}
suggestion.filterText = (suggestion.label.includes(wordAtPosition) ? wordAtPosition + " " : "") + suggestion.label.toLowerCase();
}
if (suggestion.sortText === undefined && suggestion.label.includes(wordAtPosition)) {
suggestion.sortText = sortBumperText + suggestion.label;
}
}
suggestion.sortText = suggestion.sortText?.toLowerCase();
});
return defaultCompletion;
};
@@ -258,4 +288,4 @@ export class YamlLanguageConfigurator extends AbstractLanguageConfigurator {
return autoCompletionProviders;
}
}
}

View File

@@ -19,19 +19,43 @@ export default {
actions: {
list({commit}) {
return this.$http.get(`${apiUrl(this)}/plugins`, {}).then(response => {
commit("setPlugins", response.data)
commit("setPluginSingleList", response.data.map(plugin => plugin.tasks.concat(plugin.triggers, plugin.conditions, plugin.controllers, plugin.storages, plugin.taskRunners, plugin.charts, plugin.dataFilters, plugin.aliases, plugin.logExporters)).flat())
commit("setPlugins", response.data);
commit("setPluginSingleList", response.data.map(plugin =>
plugin.tasks.concat(
plugin.triggers,
plugin.conditions,
plugin.controllers,
plugin.storages,
plugin.taskRunners,
plugin.charts,
plugin.dataFilters,
plugin.aliases,
plugin.logExporters,
plugin.additionalPlugins
)).flat());
return response.data;
})
});
},
listWithSubgroup({commit}, options) {
return this.$http.get(`${apiUrl(this)}/plugins/groups/subgroups`, {
params: options
}).then(response => {
commit("setPlugins", response.data)
commit("setPluginSingleList", response.data.map(plugin => plugin.tasks.concat(plugin.triggers, plugin.conditions, plugin.controllers, plugin.storages, plugin.taskRunners, plugin.charts, plugin.dataFilters, plugin.aliases, plugin.logExporters)).flat())
commit("setPlugins", response.data);
commit("setPluginSingleList", response.data.map(plugin =>
plugin.tasks.concat(
plugin.triggers,
plugin.conditions,
plugin.controllers,
plugin.storages,
plugin.taskRunners,
plugin.charts,
plugin.dataFilters,
plugin.aliases,
plugin.logExporters,
plugin.additionalPlugins
)).flat());
return response.data;
})
});
},
load({commit, state}, options) {
if (options.cls === undefined) {
@@ -63,7 +87,7 @@ export default {
}
return response.data;
})
});
},
loadVersions({commit}, options) {
const promise = this.$http.get(
@@ -74,7 +98,7 @@ export default {
commit("setVersions", response.data.versions);
}
return response.data;
})
});
},
icons({commit}) {
return Promise.all([
@@ -85,7 +109,7 @@ export default {
for (const [key, plugin] of Object.entries(responses[1].data)) {
if (icons[key] === undefined) {
icons[key] = plugin
icons[key] = plugin;
}
}
@@ -96,29 +120,29 @@ export default {
},
groupIcons(_) {
return Promise.all([
this.$http.get(`${apiUrl(this)}/plugins/icons/groups`, {}),
this.$http.get(`${apiUrl(this)}/plugins/icons/groups`, {})
]).then(responses => {
return responses[0].data
return responses[0].data;
});
},
loadInputsType({commit}) {
return this.$http.get(`${apiUrl(this)}/plugins/inputs`, {}).then(response => {
commit("setInputsType", response.data)
commit("setInputsType", response.data);
return response.data;
})
});
},
loadInputSchema({commit}, options) {
return this.$http.get(`${apiUrl(this)}/plugins/inputs/${options.type}`, {}).then(response => {
commit("setInputSchema", response.data)
commit("setInputSchema", response.data);
return response.data;
})
});
},
loadSchemaType(_, options = {type: "flow"}) {
return this.$http.get(`${apiUrlWithoutTenants()}/plugins/schemas/${options.type}`, {}).then(response => {
return response.data;
})
});
},
updateDocumentation({commit, dispatch, getters}, options) {
const taskType = options.task !== undefined ? options.task : YamlUtils.getTaskType(
@@ -129,9 +153,9 @@ export default {
const taskVersion = options.event
? YamlUtils.getVersionAtPosition(
options?.event?.model?.getValue(),
options?.event?.position,
)
options?.event?.model?.getValue(),
options?.event?.position
)
: undefined;
if (taskType) {
@@ -156,37 +180,37 @@ export default {
},
mutations: {
setPlugin(state, plugin) {
state.plugin = plugin
state.plugin = plugin;
},
setVersions(state, versions) {
state.versions = versions
state.versions = versions;
},
setPluginAllProps(state, pluginAllProps) {
state.pluginAllProps = pluginAllProps
state.pluginAllProps = pluginAllProps;
},
setPlugins(state, plugins) {
state.plugins = plugins
state.plugins = plugins;
},
setPluginSingleList(state, pluginSingleList) {
state.pluginSingleList = pluginSingleList
state.pluginSingleList = pluginSingleList;
},
setIcons(state, icons) {
state.icons = icons
state.icons = icons;
},
setPluginsDocumentation(state, pluginsDocumentation) {
state.pluginsDocumentation = pluginsDocumentation
state.pluginsDocumentation = pluginsDocumentation;
},
addPluginDocumentation(state, pluginDocumentation) {
state.pluginsDocumentation = {...state.pluginsDocumentation, ...pluginDocumentation}
state.pluginsDocumentation = {...state.pluginsDocumentation, ...pluginDocumentation};
},
setEditorPlugin(state, editorPlugin) {
state.editorPlugin = editorPlugin
state.editorPlugin = editorPlugin;
},
setInputsType(state, inputsType) {
state.inputsType = inputsType
state.inputsType = inputsType;
},
setInputSchema(state, schema) {
state.inputSchema = schema
state.inputSchema = schema;
}
},
getters: {
@@ -194,5 +218,5 @@ export default {
getPluginsDocumentation: state => state.pluginsDocumentation,
getIcons: state => state.icons
}
}
};

View File

@@ -125,7 +125,8 @@ public class PluginController {
plugin.getTaskRunners().stream(),
plugin.getLogExporters().stream(),
plugin.getApps().stream(),
plugin.getAppBlocks().stream()
plugin.getAppBlocks().stream(),
plugin.getAdditionalPlugins().stream()
)
.flatMap(i -> i)
.map(e -> new AbstractMap.SimpleEntry<>(