fix: Fix tags overflow handler in workflows header (#6784)

* fix: fix tags container overflowing

* fix: fix intersection observer error
This commit is contained in:
Alex Grozav
2023-07-31 15:17:05 +03:00
committed by GitHub
parent dc295ac5bf
commit 7cd45885bf
4 changed files with 56 additions and 19 deletions

View File

@@ -54,7 +54,9 @@ export default defineComponent({
this.observer = observer; this.observer = observer;
this.eventBus.on('observe', (observed: Element) => { this.eventBus.on('observe', (observed: Element) => {
observer.observe(observed); if (observed) {
observer.observe(observed);
}
}); });
this.eventBus.on('unobserve', (observed: Element) => { this.eventBus.on('unobserve', (observed: Element) => {

View File

@@ -26,19 +26,18 @@
</BreakpointsObserver> </BreakpointsObserver>
<span v-if="settingsStore.areTagsEnabled" class="tags" data-test-id="workflow-tags-container"> <span v-if="settingsStore.areTagsEnabled" class="tags" data-test-id="workflow-tags-container">
<div v-if="isTagsEditEnabled && !readOnly"> <TagsDropdown
<TagsDropdown v-if="isTagsEditEnabled && !readOnly"
v-model="appliedTagIds" v-model="appliedTagIds"
:createEnabled="true" :createEnabled="true"
:eventBus="tagsEditBus" :eventBus="tagsEditBus"
:placeholder="$locale.baseText('workflowDetails.chooseOrCreateATag')" :placeholder="$locale.baseText('workflowDetails.chooseOrCreateATag')"
ref="dropdown" ref="dropdown"
class="tags-edit" class="tags-edit"
data-test-id="workflow-tags-dropdown" data-test-id="workflow-tags-dropdown"
@blur="onTagsBlur" @blur="onTagsBlur"
@esc="onTagsEditEsc" @esc="onTagsEditEsc"
/> />
</div>
<div v-else-if="currentWorkflowTagIds.length === 0 && !readOnly"> <div v-else-if="currentWorkflowTagIds.length === 0 && !readOnly">
<span class="add-tag clickable" data-test-id="new-tag-link" @click="onTagsEditEnable"> <span class="add-tag clickable" data-test-id="new-tag-link" @click="onTagsEditEnable">
+ {{ $locale.baseText('workflowDetails.addTag') }} + {{ $locale.baseText('workflowDetails.addTag') }}
@@ -658,12 +657,16 @@ $--header-spacing: 20px;
} }
.tags { .tags {
display: flex;
align-items: center;
width: 100%;
flex: 1; flex: 1;
margin-right: $--header-spacing; margin-right: $--header-spacing;
} }
.tags-edit { .tags-edit {
min-width: 100px; min-width: 100px;
width: 100%;
max-width: 460px; max-width: 460px;
} }

View File

@@ -3,8 +3,10 @@
:threshold="1.0" :threshold="1.0"
@observed="onObserved" @observed="onObserved"
class="tags-container" class="tags-container"
:style="style"
:enabled="responsive" :enabled="responsive"
:event-bus="intersectionEventBus" :event-bus="intersectionEventBus"
ref="tagsContainer"
> >
<span class="tags"> <span class="tags">
<span <span
@@ -47,6 +49,7 @@ import IntersectionObserved from './IntersectionObserved.vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { useTagsStore } from '@/stores/tags.store'; import { useTagsStore } from '@/stores/tags.store';
import { createEventBus } from 'n8n-design-system/utils'; import { createEventBus } from 'n8n-design-system/utils';
import { debounce } from 'lodash-es';
// random upper limit if none is set to minimize performance impact of observers // random upper limit if none is set to minimize performance impact of observers
const DEFAULT_MAX_TAGS_LIMIT = 20; const DEFAULT_MAX_TAGS_LIMIT = 20;
@@ -63,12 +66,29 @@ export default defineComponent({
props: ['tagIds', 'limit', 'clickable', 'responsive', 'hoverable'], props: ['tagIds', 'limit', 'clickable', 'responsive', 'hoverable'],
data() { data() {
return { return {
maxWidth: 320,
intersectionEventBus: createEventBus(), intersectionEventBus: createEventBus(),
visibility: {} as { [id: string]: boolean }, visibility: {} as { [id: string]: boolean },
debouncedSetMaxWidth: () => {},
}; };
}, },
created() {
this.debouncedSetMaxWidth = debounce(this.setMaxWidth, 100);
},
mounted() {
this.setMaxWidth();
window.addEventListener('resize', this.debouncedSetMaxWidth);
},
beforeUnmount() {
window.removeEventListener('resize', this.debouncedSetMaxWidth);
},
computed: { computed: {
...mapStores(useTagsStore), ...mapStores(useTagsStore),
style() {
return {
'max-width': `${this.maxWidth}px`,
};
},
tags() { tags() {
const tags = this.tagIds const tags = this.tagIds
.map((tagId: string) => this.tagsStore.getTagById(tagId)) .map((tagId: string) => this.tagsStore.getTagById(tagId))
@@ -109,6 +129,17 @@ export default defineComponent({
}, },
}, },
methods: { methods: {
setMaxWidth() {
const container = this.$refs.tagsContainer.$el as HTMLElement;
const parent = container.parentNode as HTMLElement;
if (parent) {
this.maxWidth = 0;
void this.$nextTick(() => {
this.maxWidth = parent.clientWidth;
});
}
},
onObserved({ el, isIntersecting }: { el: HTMLElement; isIntersecting: boolean }) { onObserved({ el, isIntersecting }: { el: HTMLElement; isIntersecting: boolean }) {
if (el.dataset.id) { if (el.dataset.id) {
this.visibility = { ...this.visibility, [el.dataset.id]: isIntersecting }; this.visibility = { ...this.visibility, [el.dataset.id]: isIntersecting };
@@ -130,12 +161,15 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.tags-container { .tags-container {
display: inline-flex; display: block;
overflow: hidden; max-width: 300px;
} }
.tags { .tags {
display: flex; display: block;
white-space: nowrap;
overflow: hidden;
max-width: 100%;
> span { > span {
padding-right: 4px; // why not margin? for space between tags to be clickable padding-right: 4px; // why not margin? for space between tags to be clickable

View File

@@ -161,8 +161,6 @@ export const useLogStreamingStore = defineStore('logStreaming', {
delete this.items[id]; delete this.items[id];
}, },
clearDestinationItemTrees() { clearDestinationItemTrees() {
console.log('clearing destinations');
this.items = {} as DestinationSettingsStore; this.items = {} as DestinationSettingsStore;
}, },
setSelectionAndBuildItems(destination: MessageEventBusDestinationOptions) { setSelectionAndBuildItems(destination: MessageEventBusDestinationOptions) {