mirror of
https://github.com/kestra-io/kestra.git
synced 2025-12-26 05:00:31 -05:00
Compare commits
1 Commits
develop
...
refactor/v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27c35a9be9 |
6
ui/package-lock.json
generated
6
ui/package-lock.json
generated
@@ -19216,9 +19216,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/storybook": {
|
||||
"version": "9.1.16",
|
||||
"resolved": "https://registry.npmjs.org/storybook/-/storybook-9.1.16.tgz",
|
||||
"integrity": "sha512-339U14K6l46EFyRvaPS2ZlL7v7Pb+LlcXT8KAETrGPxq8v1sAjj2HAOB6zrlAK3M+0+ricssfAwsLCwt7Eg8TQ==",
|
||||
"version": "9.1.17",
|
||||
"resolved": "https://registry.npmjs.org/storybook/-/storybook-9.1.17.tgz",
|
||||
"integrity": "sha512-kfr6kxQAjA96ADlH6FMALJwJ+eM80UqXy106yVHNgdsAP/CdzkkicglRAhZAvUycXK9AeadF6KZ00CWLtVMN4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
});
|
||||
|
||||
const panelWidth = ref(640)
|
||||
const panelWrapper = ref<HTMLDivElement | null>(null)
|
||||
|
||||
const {startResizing, resizing} = useResizablePanel(activeTab)
|
||||
|
||||
|
||||
@@ -380,7 +380,6 @@
|
||||
import TopNavBar from "../layout/TopNavBar.vue";
|
||||
import BulkSelect from "../layout/BulkSelect.vue";
|
||||
import LogsWrapper from "../logs/LogsWrapper.vue";
|
||||
//@ts-expect-error No declaration file
|
||||
import SelectTable from "../layout/SelectTable.vue";
|
||||
import TriggerAvatar from "../flows/TriggerAvatar.vue";
|
||||
import KSFilter from "../filter/components/KSFilter.vue";
|
||||
|
||||
@@ -200,7 +200,6 @@
|
||||
|
||||
const activeStep = ref(0)
|
||||
const userForm: Ref<any> = ref(null)
|
||||
const surveyForm: Ref<any> = ref(null)
|
||||
|
||||
const userFormData = ref<UserFormData>({
|
||||
firstName: "",
|
||||
|
||||
@@ -113,10 +113,10 @@
|
||||
provide(FULL_SOURCE_INJECTION_KEY, computed(() => dashboardStore.sourceCode ?? ""));
|
||||
provide(POSITION_INJECTION_KEY, props.position ?? "after");
|
||||
provide(ON_TASK_EDITOR_CLICK_INJECTION_KEY, (elt) => {
|
||||
const type = elt?.type;
|
||||
const cls = elt?.type;
|
||||
dashboardStore.loadChart(elt);
|
||||
if(type){
|
||||
pluginsStore.updateDocumentation({type});
|
||||
if(cls){
|
||||
pluginsStore.updateDocumentation({cls});
|
||||
}else{
|
||||
pluginsStore.updateDocumentation();
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
import {useExecutionsStore} from "../../stores/executions";
|
||||
import {useExecutionRoot} from "./composables/useExecutionRoot";
|
||||
import useRouteContext from "../../composables/useRouteContext";
|
||||
//@ts-expect-error no declaration file
|
||||
import Tabs from "../../components/Tabs.vue";
|
||||
//@ts-expect-error no declaration file
|
||||
import ExecutionRootTopBar from "./ExecutionRootTopBar.vue";
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
import ChartAreaspline from "vue-material-design-icons/ChartAreaspline.vue"
|
||||
import Drawer from "../Drawer.vue"
|
||||
import MetricsTable from "./MetricsTable.vue"
|
||||
import {Execution} from "../../stores/executions";
|
||||
|
||||
const props = defineProps<{
|
||||
embed?: boolean;
|
||||
taskRun: Record<string, any>;
|
||||
execution: Record<string, any>;
|
||||
execution: Execution;
|
||||
}>();
|
||||
|
||||
const isOpen = ref(false)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<el-button
|
||||
type="primary"
|
||||
tag="a"
|
||||
:href="itemUrl(value.toString())"
|
||||
:href="value && itemUrl(value.toString())"
|
||||
target="_blank"
|
||||
size="small"
|
||||
:icon="Download"
|
||||
@@ -11,7 +11,7 @@
|
||||
>
|
||||
{{ $t('download') }}
|
||||
</el-button>
|
||||
<FilePreview v-if="isFile(value)" :value="value.toString()" :executionId="execution.id" />
|
||||
<FilePreview v-if="isFile(value)" :value="value.toString()" :executionId="execution?.id" />
|
||||
<el-button disabled size="small" type="primary" v-if="humanSize">
|
||||
({{ humanSize }})
|
||||
</el-button>
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
import {useRoute} from "vue-router";
|
||||
// @ts-expect-error types to be done
|
||||
import DateRange from "../../layout/DateRange.vue";
|
||||
// @ts-expect-error types to be done
|
||||
import TimeSelect from "./TimeSelect.vue";
|
||||
import moment from "moment";
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
import ClockOutline from "vue-material-design-icons/ClockOutline.vue";
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
value?: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -429,7 +429,7 @@
|
||||
elements: execution.value?.trigger,
|
||||
includeDebug: "trigger",
|
||||
},
|
||||
];
|
||||
] as const;
|
||||
|
||||
const options = useValues("executions").VALUES.RELATIVE_DATE;
|
||||
const timerange = ref<string>("PT168H"); // Default to last 7 days
|
||||
|
||||
@@ -300,7 +300,6 @@
|
||||
import TriggerAvatar from "./TriggerAvatar.vue";
|
||||
import DataTable from "../layout/DataTable.vue";
|
||||
import BulkSelect from "../layout/BulkSelect.vue";
|
||||
//@ts-expect-error no declaration file
|
||||
import SelectTable from "../layout/SelectTable.vue";
|
||||
import KSFilter from "../filter/components/KSFilter.vue";
|
||||
import MarkdownTooltip from "../layout/MarkdownTooltip.vue";
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
import {TaskIcon} from "@kestra-io/ui-libs";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import {useToast} from "../../utils/toast";
|
||||
import {Execution} from "../../stores/executions";
|
||||
|
||||
interface Flow {
|
||||
namespace: string;
|
||||
@@ -39,11 +40,6 @@
|
||||
triggers?: Trigger[];
|
||||
}
|
||||
|
||||
interface Execution {
|
||||
id: string;
|
||||
trigger?: Trigger;
|
||||
}
|
||||
|
||||
interface Trigger {
|
||||
id: string;
|
||||
type: string;
|
||||
|
||||
@@ -33,12 +33,13 @@
|
||||
import VarValue from "../executions/VarValue.vue";
|
||||
import Markdown from "../layout/Markdown.vue";
|
||||
import Cron from "../layout/Cron.vue";
|
||||
import {Execution} from "../../stores/executions";
|
||||
|
||||
const {t, te} = useI18n();
|
||||
|
||||
defineProps<{
|
||||
data: Record<string, any>;
|
||||
execution?: Record<string, any>;
|
||||
execution?: Execution;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{ (e: "on-copy", event: any): void }>();
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
import BookmarkLink from "./BookmarkLink.vue"
|
||||
|
||||
defineProps<{
|
||||
pages: {label?:string, path:string}[]
|
||||
pages: {label:string, path:string}[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
@@ -4,22 +4,16 @@
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts" setup>
|
||||
import {computed} from "vue";
|
||||
import Utils from "../../utils/utils";
|
||||
import cronstrue from "cronstrue";
|
||||
import "cronstrue/locales/fr";
|
||||
const props = defineProps<{
|
||||
cronExpression?: string
|
||||
}>()
|
||||
|
||||
export default {
|
||||
props: {
|
||||
cronExpression: {
|
||||
type: String,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
humanReadableCron() {
|
||||
return cronstrue.toString(this.cronExpression, {locale: Utils.getLang()});
|
||||
}
|
||||
}
|
||||
}
|
||||
const humanReadableCron = computed(() => {
|
||||
return props.cronExpression ? cronstrue.toString(props.cronExpression, {locale: Utils.getLang()}) : "";
|
||||
});
|
||||
</script>
|
||||
@@ -4,31 +4,30 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapStores} from "pinia";
|
||||
<script setup lang="ts">
|
||||
import {computed} from "vue";
|
||||
import {cssVariable} from "@kestra-io/ui-libs";
|
||||
import {useLayoutStore} from "../../stores/layout";
|
||||
import {useMiscStore} from "override/stores/misc";
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapStores(useLayoutStore, useMiscStore),
|
||||
name() {
|
||||
return this.layoutStore.envName || this.miscStore.configs?.environment?.name;
|
||||
},
|
||||
color() {
|
||||
if (this.layoutStore.envColor) {
|
||||
return this.layoutStore.envColor;
|
||||
}
|
||||
const layoutStore = useLayoutStore();
|
||||
const miscStore = useMiscStore();
|
||||
|
||||
if (this.miscStore.configs?.environment?.color) {
|
||||
return this.miscStore.configs.environment.color;
|
||||
}
|
||||
const name = computed(() => {
|
||||
return layoutStore.envName || miscStore.configs?.environment?.name;
|
||||
});
|
||||
|
||||
return cssVariable("--bs-info");
|
||||
}
|
||||
const color = computed(() => {
|
||||
if (layoutStore.envColor) {
|
||||
return layoutStore.envColor;
|
||||
}
|
||||
}
|
||||
|
||||
if (miscStore.configs?.environment?.color) {
|
||||
return miscStore.configs.environment.color;
|
||||
}
|
||||
|
||||
return cssVariable("--bs-info");
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
const table = ref<any>(null);
|
||||
const hasSelection = ref(false);
|
||||
const container = ref<HTMLElement>(null);
|
||||
const container = ref<HTMLElement>();
|
||||
|
||||
const toggleRowExpansion = (row: any, expand?: boolean) => {
|
||||
table.value?.toggleRowExpansion(row, expand);
|
||||
|
||||
@@ -68,21 +68,27 @@
|
||||
function disabledCurrentRoute(items: MenuItem[]) {
|
||||
return items
|
||||
.map(r => {
|
||||
const newR = r as MenuItem & {class:string};
|
||||
|
||||
const routeName = $route.name?.toString();
|
||||
|
||||
if (r.href?.path === $route.path) {
|
||||
r.disabled = true;
|
||||
}
|
||||
|
||||
// route hack is still needed for blueprints
|
||||
if (r.href !== "/" && ($route.path.startsWith(r.href) || r.routes?.includes($route.name))) {
|
||||
r.class = "vsm--link_active";
|
||||
if (r.href?.path && r.href.path !== "/" && ($route.path.startsWith(r.href.path)
|
||||
|| routeName && r.routes?.includes(routeName))) {
|
||||
newR.class = "vsm--link_active";
|
||||
}
|
||||
|
||||
if (r.child && r.child.some(c => $route.path.startsWith(c.href) || c.routes?.includes($route.name))) {
|
||||
r.class = "vsm--link_active";
|
||||
r.child = disabledCurrentRoute(r.child);
|
||||
if (r.child && r.child.some(c => c.href?.path && $route.path.startsWith(c.href.path)
|
||||
|| routeName && c.routes?.includes(routeName))) {
|
||||
newR.class = "vsm--link_active";
|
||||
newR.child = disabledCurrentRoute(r.child);
|
||||
}
|
||||
|
||||
return r;
|
||||
return newR;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
// when tab is opened, load the documentation
|
||||
onActivated(() => {
|
||||
if(selectedTaskType.value && parentPath !== "inputs"){
|
||||
pluginsStore.updateDocumentation({type: selectedTaskType.value, ...taskModel.value});
|
||||
pluginsStore.updateDocumentation({cls: selectedTaskType.value, ...taskModel.value});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, ref, useTemplateRef, watch} from "vue";
|
||||
import {computed, ref, watch} from "vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import {DeleteOutline} from "../../utils/icons";
|
||||
|
||||
@@ -85,8 +85,6 @@
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const valueComponent = useTemplateRef<any[]>("valueComponent");
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
modelValue?: Record<string, any>;
|
||||
schema?: any;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
:name="plugin.group"
|
||||
:title="plugin.title?.capitalize()"
|
||||
:key="plugin.group"
|
||||
:ref="(el) => pluginRefs[plugin.group] = el"
|
||||
:ref="(el: any) => pluginRefs[plugin.group] = el"
|
||||
>
|
||||
<ul class="toc-h3">
|
||||
<li v-for="(types, namespace) in group(plugin)" :key="namespace">
|
||||
@@ -70,7 +70,7 @@
|
||||
const route = useRoute();
|
||||
const pluginsStore = usePluginsStore();
|
||||
|
||||
const pluginRefs = reactive({});
|
||||
const pluginRefs = reactive<Record<string, any>>({});
|
||||
const activeNames = ref<string[]>([]);
|
||||
const searchInput = ref<string>("");
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
});
|
||||
|
||||
const addSecretModalVisible = ref(false);
|
||||
const hasData = ref(undefined);
|
||||
const hasData = ref<boolean | undefined>(undefined);
|
||||
|
||||
const {t} = useI18n({useScope: "global"});
|
||||
const routeInfo = computed(() => ({title: t("secret.names")}));
|
||||
|
||||
@@ -304,7 +304,6 @@
|
||||
|
||||
const form = ref<FormInstance>();
|
||||
const dataTable = useTemplateRef<DataTableRef>("dataTable");
|
||||
const selectTable = ref<InstanceType<typeof SelectTable>>();
|
||||
|
||||
const total = ref(0);
|
||||
const hasData = ref<boolean>();
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
return result;
|
||||
});
|
||||
|
||||
const namespaceLabel = (path) => {
|
||||
const namespaceLabel = (path: string) => {
|
||||
const segments = path.split(".");
|
||||
return segments.length > 1 ? segments[segments.length - 1] : path;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,8 @@ import ShieldKeyOutline from "vue-material-design-icons/ShieldKeyOutline.vue";
|
||||
import FlaskOutline from "vue-material-design-icons/FlaskOutline.vue";
|
||||
|
||||
export type MenuItem = {
|
||||
title: string,
|
||||
routes?: string[],
|
||||
href?: {
|
||||
path?: string,
|
||||
name: string,
|
||||
@@ -47,7 +49,8 @@ export function useLeftMenu() {
|
||||
.filter(
|
||||
(r) => typeof r.name === "string" && r.name.startsWith(route),
|
||||
)
|
||||
.map((r) => r.name);
|
||||
.map((r) => r.name)
|
||||
.filter((name) => typeof name === "string");
|
||||
}
|
||||
|
||||
const flatMenuItems = (items: MenuItem[]): MenuItem[] => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {ComputedRef} from "vue";
|
||||
import type {JSONSchema} from "@kestra-io/ui-libs";
|
||||
import {YamlElement} from "@kestra-io/ui-libs";
|
||||
import * as YAML_UTILS from "@kestra-io/ui-libs/flow-yaml-utils";
|
||||
import {QUOTE, YamlAutoCompletion} from "../../services/autoCompletionProvider";
|
||||
@@ -109,7 +108,7 @@ export class FlowAutoCompletion extends YamlAutoCompletion {
|
||||
const fetchTriggerVarsByType = await Promise.all(
|
||||
distinct(flowAsJs?.triggers?.map(trigger => trigger.type))
|
||||
.map(async triggerType => {
|
||||
const triggerDoc: {schema: JSONSchema} | undefined = await this.pluginsStore.load({
|
||||
const triggerDoc = await this.pluginsStore.load({
|
||||
cls: triggerType,
|
||||
commit: false
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ const LOCAL_STORAGE_KEY = "starred.bookmarks"
|
||||
const initialPages = localStorage.getItem(LOCAL_STORAGE_KEY) ?? "[]"
|
||||
interface Page {
|
||||
path: string;
|
||||
label?: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
@@ -25,7 +25,7 @@ export const useBookmarksStore = defineStore("bookmarks", {
|
||||
this.updateAll(pages)
|
||||
}
|
||||
},
|
||||
remove(page: Page) {
|
||||
remove(page: Pick<Page, "path">) {
|
||||
const pages = this.pages
|
||||
const index = pages.findIndex(p => p.path === page.path)
|
||||
if (index > -1) {
|
||||
|
||||
@@ -93,7 +93,7 @@ export async function render(markdown: string, options: RenderOptions = {}) {
|
||||
}
|
||||
|
||||
function applyEnhancedRenderers(md: any) {
|
||||
const defaultHeadingOpen = md.renderer.rules.heading_open?.bind(md.renderer.rules) ?? ((tokens: any, idx: number, options: any, env: any, self: any) => self.renderToken(tokens, idx, options));
|
||||
const defaultHeadingOpen = md.renderer.rules.heading_open?.bind(md.renderer.rules) ?? ((tokens: any, idx: number, options: any, _env: any, self: any) => self.renderToken(tokens, idx, options));
|
||||
md.renderer.rules.heading_open = (tokens: any, idx: number, options: any, env: any, self: any) => {
|
||||
const token = tokens[idx];
|
||||
const level = typeof token.tag === "string" && /^h\d$/i.test(token.tag) ? Number(token.tag.substring(1)) : null;
|
||||
@@ -104,7 +104,7 @@ function applyEnhancedRenderers(md: any) {
|
||||
return defaultHeadingOpen(tokens, idx, options, env, self);
|
||||
};
|
||||
|
||||
const defaultTableOpen = md.renderer.rules.table_open?.bind(md.renderer.rules) ?? ((tokens: any, idx: number, options: any, env: any, self: any) => self.renderToken(tokens, idx, options));
|
||||
const defaultTableOpen = md.renderer.rules.table_open?.bind(md.renderer.rules) ?? ((tokens: any, idx: number, options: any, _env: any, self: any) => self.renderToken(tokens, idx, options));
|
||||
md.renderer.rules.table_open = (tokens: any, idx: number, options: any, env: any, self: any) => {
|
||||
const token = tokens[idx];
|
||||
token.attrSet("class", "doc-table");
|
||||
@@ -112,7 +112,7 @@ function applyEnhancedRenderers(md: any) {
|
||||
return defaultTableOpen(tokens, idx, options, env, self);
|
||||
};
|
||||
|
||||
const defaultFence = md.renderer.rules.fence?.bind(md.renderer.rules) ?? ((tokens: any, idx: number, options: any, env: any, self: any) => self.renderToken(tokens, idx, options));
|
||||
const defaultFence = md.renderer.rules.fence?.bind(md.renderer.rules) ?? ((tokens: any, idx: number, options: any, _env: any, self: any) => self.renderToken(tokens, idx, options));
|
||||
|
||||
md.renderer.rules.fence = (tokens: any, idx: number, options: any, env: any, self: any) => {
|
||||
const token = tokens[idx];
|
||||
|
||||
@@ -60,7 +60,7 @@ const mockFilterKeys = {
|
||||
description: "Filter by key-value pairs",
|
||||
comparators: [Comparators.IN],
|
||||
valueType: "details",
|
||||
} as FilterKeyConfig,
|
||||
} as unknown as FilterKeyConfig,
|
||||
radio: {
|
||||
key: "child",
|
||||
label: "Child",
|
||||
|
||||
@@ -71,6 +71,7 @@ const revisionSourceMock = fn((revision: number) => {
|
||||
`{"revision": ${revision}, "content": "Content for revision ${revision}"}`
|
||||
);
|
||||
});
|
||||
|
||||
export const Default: Story = {
|
||||
render: render.bind({}),
|
||||
args: {
|
||||
@@ -119,7 +120,7 @@ export const Default: Story = {
|
||||
confirmButton.click();
|
||||
});
|
||||
await waitFor(() => expect(revisions[revisions.length - 1].revision).toEqual(5));
|
||||
await expect(revisions[revisions.length - 1].source).toContain('"revision": 1');
|
||||
await expect(revisions[revisions.length - 1].source ?? "").toContain("\"revision\": 1");
|
||||
await expect(revisionSourceMock).not.toHaveBeenCalledWith(5);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user