Skip to content

Commit

Permalink
chore(ui): improve the labels behavior (#7397)
Browse files Browse the repository at this point in the history
  • Loading branch information
MilosPaunovic authored Feb 14, 2025
1 parent 41712b8 commit bf19a8f
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 67 deletions.
2 changes: 1 addition & 1 deletion ui/src/components/executions/Overview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<duration :histories="scope.row.value" />
</span>
<span v-else-if="scope.row.key === $t('labels')">
<labels :labels="scope.row.value" :filter-enabled="false" />
<labels :labels="scope.row.value" read-only />
</span>
<span v-else>
<span v-if="scope.row.key === $t('revision')">
Expand Down
10 changes: 10 additions & 0 deletions ui/src/components/filter/KestraFilter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,16 @@
};
const currentFilters = ref<CurrentItem[]>([]);
watch(
() => route.query,
(q: any) => {
// Handling change of label filters from direct click events
const routeFilters = decodeParams(route.path, q, props.include, OPTIONS);
currentFilters.value = routeFilters;
},
{immediate: true},
);
const prefixFilter = ref("");
const includedOptions = computed(() => {
Expand Down
129 changes: 63 additions & 66 deletions ui/src/components/layout/Labels.vue
Original file line number Diff line number Diff line change
@@ -1,81 +1,78 @@
<template>
<span data-component="FILENAME_PLACEHOLDER" v-if="labels">
<!-- 'el-check-tag' would be a better fit but it currently lacks customization (missing size, bold font) -->
<template
v-for="(value, key) in labelMap"
:key="key"
<span v-if="props.labels.length">
<el-check-tag
v-for="(label, index) in props.labels"
:key="index"
:disabled="readOnly"
:checked="isChecked(label)"
@change="updateLabel(label)"
class="me-1 el-tag label"
>
<router-link v-if="filterEnabled" :to="link(key, value)" class="me-1 labels el-tag el-tag--small" :class="{'el-tag--primary': checked(key, value)}">
{{ key }}: {{ value }}
</router-link>
<div v-else class="me-1 labels el-tag el-tag--small" :class="{'el-tag--primary': checked(key, value)}">{{ key }}: {{ value }}</div>
</template>
{{ label.key }}: {{ label.value }}
</el-check-tag>
</span>
</template>

<script>
export default {
props: {
labels: {
type: Object,
default: () => {}
},
filterEnabled: {
type: Boolean,
default: true
}
},
// this is needed as flows uses a Map and Execution a List of Labels.
// if we align both of them this can be removed
computed: {
labelMap() {
if (Array.isArray(this.labels)) {
return Object.fromEntries(this.labels.map(label => [label.key, label.value]));
} else {
return this.labels;
}
},
labelsFromQuery() {
const labels = new Map();
(this.$route.query.labels !== undefined ?
(typeof(this.$route.query.labels) === "string" ? [this.$route.query.labels] : this.$route.query.labels) :
[]
)
.forEach(label => {
const separatorIndex = label.indexOf(":");
<script setup lang="ts">
import {watch} from "vue";
if (separatorIndex === -1) {
return;
}
import {useRouter, useRoute} from "vue-router";
const router = useRouter();
const route = useRoute();
labels.set(label.slice(0, separatorIndex), label.slice(separatorIndex + 1));
})
interface Label {
key: string;
value: string;
}
return labels;
}
},
methods: {
checked(key, value) {
return this.labelsFromQuery.has(key) && this.labelsFromQuery.get(key) === value;
},
link(key, value) {
const labels = this.labelsFromQuery;
const props = withDefaults(
defineProps<{ labels: Label[]; readOnly?: boolean }>(),
{labels: () => [], readOnly: false},
);
if (labels.has(key)) {
labels.delete(key);
} else {
labels.set(key, value);
}
import {decodeSearchParams} from "../../components/filter/utils/helpers";
let query: any[] = [];
watch(
() => route.query,
(q: any) => (query = decodeSearchParams(q, undefined, [])),
{immediate: true},
);
const qs = {
...this.$route.query,
...{"labels": Array.from(labels.keys()).map((key) => key + ":" + labels.get(key))}
};
const isChecked = (label: Label) => {
return query.some((l) => {
if (typeof l?.value !== "string") return false;
delete qs.page;
const [key, value] = l.value.split(":");
return key === label.key && value === label.value;
});
};
const updateLabel = (label: Label) => {
const getKey = (key: string) => `filters[labels][$eq][${key}]`;
return {name: this.$route.name, params: this.$route.params, query: qs};
}
if (isChecked(label)) {
const replacementQuery = {...route.query};
delete replacementQuery[getKey(label.key)];
router.replace({query: replacementQuery});
} else {
router.replace({
query: {...route.query, [getKey(label.key)]: label.value},
});
}
};
</script>

<style scoped lang="scss">
.label {
font-weight: normal;
&:hover {
background-color: var(--ks-tag-background-hover);
}
}
.el-check-tag.el-check-tag--primary.is-checked {
background-color: var(--el-color-primary);
color: var(--ks-content-primary);
}
</style>

0 comments on commit bf19a8f

Please sign in to comment.