mirror of https://github.com/Fabio286/antares.git
refactor(UI): various improvements on sidebar
This commit is contained in:
parent
ece6c6401d
commit
321b387083
|
@ -4,7 +4,6 @@
|
||||||
item-key="'uid'"
|
item-key="'uid'"
|
||||||
ghost-class="ghost"
|
ghost-class="ghost"
|
||||||
:group="{ name: 'connections', pull: 'clone' }"
|
:group="{ name: 'connections', pull: 'clone' }"
|
||||||
class="pb-1"
|
|
||||||
:swap-threshold="0.3"
|
:swap-threshold="0.3"
|
||||||
@start="emit('start', $event)"
|
@start="emit('start', $event)"
|
||||||
@end="emit('end', $event)"
|
@end="emit('end', $event)"
|
||||||
|
@ -14,6 +13,7 @@
|
||||||
<li
|
<li
|
||||||
v-if="element.isFolder || !folderedConnections.includes(element.uid)"
|
v-if="element.isFolder || !folderedConnections.includes(element.uid)"
|
||||||
:draggable="true"
|
:draggable="true"
|
||||||
|
:class="{'folder': element.isFolder}"
|
||||||
@dragstart="draggedElement = element.uid"
|
@dragstart="draggedElement = element.uid"
|
||||||
@dragend="dragEnd"
|
@dragend="dragEnd"
|
||||||
@contextmenu.prevent="emit('context', $event, element)"
|
@contextmenu.prevent="emit('context', $event, element)"
|
||||||
|
@ -37,22 +37,28 @@
|
||||||
/>
|
/>
|
||||||
<i v-if="coveredElement === element.uid && draggedElement !== coveredElement" class="settingbar-element-icon mdi mdi-folder-plus mdi-36px" />
|
<i v-if="coveredElement === element.uid && draggedElement !== coveredElement" class="settingbar-element-icon mdi mdi-folder-plus mdi-36px" />
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<i
|
<div class="settingbar-element-icon-wrapper">
|
||||||
class="settingbar-element-icon dbi"
|
<i
|
||||||
:class="[`dbi-${element.client}`, getStatusBadge(element.uid)]"
|
class="settingbar-element-icon dbi"
|
||||||
/>
|
:class="[`dbi-${element.client}`, getStatusBadge(element.uid)]"
|
||||||
<small class="settingbar-element-name">{{ getConnectionName(element.uid) }}</small>
|
/>
|
||||||
|
<small class="settingbar-element-name">{{ getConnectionName(element.uid) }}</small>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<SettingBarConnectionsFolder
|
<SettingBarConnectionsFolder
|
||||||
v-else-if="element.isFolder"
|
v-else-if="element.isFolder"
|
||||||
|
:key="element.uid"
|
||||||
:folder="element"
|
:folder="element"
|
||||||
:covered-element="coveredElement"
|
:covered-element="coveredElement"
|
||||||
:dragged-element="draggedElement"
|
:dragged-element="draggedElement"
|
||||||
|
:folder-drag="folderDrag"
|
||||||
@select-workspace="selectWorkspace"
|
@select-workspace="selectWorkspace"
|
||||||
@covered="coveredElement = element.uid"
|
@covered="coveredElement = element.uid"
|
||||||
@uncovered="coveredElement = false"
|
@uncovered="coveredElement = false"
|
||||||
@folder-sort="emit('update:modelValue', localList)"
|
@folder-sort="emit('update:modelValue', localList)"
|
||||||
|
@folder-drag="folderDrag = $event"
|
||||||
|
@context="emit('context', $event.event, $event.content)"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
@ -88,6 +94,7 @@ const localList = ref(props.modelValue);
|
||||||
const dummyNested = ref([]);
|
const dummyNested = ref([]);
|
||||||
const draggedElement: Ref<string | false> = ref(false);
|
const draggedElement: Ref<string | false> = ref(false);
|
||||||
const coveredElement: Ref<string | false> = ref(false);
|
const coveredElement: Ref<string | false> = ref(false);
|
||||||
|
const folderDrag = ref(false);
|
||||||
|
|
||||||
const foldersUid = computed(() => folders.value.reduce<string[]>((acc, curr) => {
|
const foldersUid = computed(() => folders.value.reduce<string[]>((acc, curr) => {
|
||||||
acc.push(curr.uid);
|
acc.push(curr.uid);
|
||||||
|
@ -140,6 +147,7 @@ watch(() => dummyNested.value.length, () => {
|
||||||
|
|
||||||
watch(() => props.modelValue, (value) => {
|
watch(() => props.modelValue, (value) => {
|
||||||
localList.value = value;
|
localList.value = value;
|
||||||
|
folderDrag.value = false;// Prenent some edge cases
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -168,7 +176,32 @@ watch(() => props.modelValue, (value) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ghost {
|
.ghost:not(.folder) {
|
||||||
background-color: rgba($primary-color, 20%);
|
height: $settingbar-width;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 4px;
|
||||||
|
position: relative;
|
||||||
|
transition: opacity .2s;
|
||||||
|
|
||||||
|
.settingbar-element {
|
||||||
|
border-radius: 15px!important;
|
||||||
|
background: rgba($color: #fff, $alpha: 0.1);
|
||||||
|
|
||||||
|
.settingbar-element-name {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
left: 3px!important;
|
||||||
|
text-align: center!important;
|
||||||
|
font-size: 65%;
|
||||||
|
font-style: normal;
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="settingbar-element btn btn-link p-1"
|
class="settingbar-element folder btn btn-link p-1"
|
||||||
|
:class="[{ 'selected-inside': hasSelectedInside && !isOpen }]"
|
||||||
:style="isOpen ? `height: auto; opacity: 1;` : null"
|
:style="isOpen ? `height: auto; opacity: 1;` : null"
|
||||||
:title="folder.name"
|
:title="folder.name"
|
||||||
>
|
>
|
||||||
|
@ -8,22 +9,29 @@
|
||||||
class="folder-container"
|
class="folder-container"
|
||||||
:item-key="((item: string) => localList.indexOf(item))"
|
:item-key="((item: string) => localList.indexOf(item))"
|
||||||
:class="[{'opened': isOpen}]"
|
:class="[{'opened': isOpen}]"
|
||||||
:style="[`background: ${folder.color};`, isOpen ? `max-height: ${60*(folder.connections.length+1)}px` : 'max-height: 60px']"
|
:style="[
|
||||||
|
`background: ${folder.color};`,
|
||||||
|
isOpen ? `max-height: ${60*(folder.connections.length+1)}px` : 'max-height: 60px',
|
||||||
|
!isOpen ? `overflow: hidden;` : ''
|
||||||
|
]"
|
||||||
:list="localList"
|
:list="localList"
|
||||||
ghost-class="ghost"
|
ghost-class="ghost"
|
||||||
:group="{ name: 'connections' }"
|
:group="{ name: 'connections', put: folderDrag ? undefined : 'clone' }"
|
||||||
|
@start="dragStart"
|
||||||
|
@end="dragStop"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div
|
<div
|
||||||
v-if="!isOpen"
|
v-if="!isOpen"
|
||||||
class="folder-overlay"
|
class="folder-overlay"
|
||||||
@click="isOpen = true"
|
@click="openFolder"
|
||||||
|
@contextmenu.stop="emit('context', {event: $event, content: folder})"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="isOpen"
|
v-if="isOpen"
|
||||||
class="folder-icon"
|
class="folder-icon"
|
||||||
:style="`color: ${folder.color};`"
|
:style="`color: ${folder.color};`"
|
||||||
@click="isOpen = false"
|
@click="closeFolder"
|
||||||
>
|
>
|
||||||
<i class="folder-icon-open mdi mdi-folder-open mdi-36px" />
|
<i class="folder-icon-open mdi mdi-folder-open mdi-36px" />
|
||||||
<i class="folder-icon-close mdi mdi-folder mdi-36px" />
|
<i class="folder-icon-close mdi mdi-folder mdi-36px" />
|
||||||
|
@ -33,13 +41,13 @@
|
||||||
<div
|
<div
|
||||||
:key="element"
|
:key="element"
|
||||||
class="folder-element"
|
class="folder-element"
|
||||||
|
|
||||||
:class="{ 'selected': element === selectedWorkspace }"
|
:class="{ 'selected': element === selectedWorkspace }"
|
||||||
@click="emit('select-workspace', element)"
|
@click="emit('select-workspace', element)"
|
||||||
|
@contextmenu.stop="emit('context', {event: $event, content: getConnectionByUid(element)})"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="folder-element-icon dbi"
|
class="folder-element-icon dbi"
|
||||||
:class="[`dbi-${getConnectionByUid(element).client}`, getStatusBadge(getConnectionByUid(element).uid)]"
|
:class="[`dbi-${getConnectionByUid(element)?.client}`, getStatusBadge(getConnectionByUid(element).uid)]"
|
||||||
/>
|
/>
|
||||||
<small v-if="isOpen" class="folder-element-name">{{ getConnectionName(element) }}</small>
|
<small v-if="isOpen" class="folder-element-name">{{ getConnectionName(element) }}</small>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,6 +58,7 @@
|
||||||
class="drag-area"
|
class="drag-area"
|
||||||
:class="[{'folder-preview': coveredElement === folder.uid && draggedElement !== coveredElement}]"
|
:class="[{'folder-preview': coveredElement === folder.uid && draggedElement !== coveredElement}]"
|
||||||
:list="dummyNested"
|
:list="dummyNested"
|
||||||
|
:swap-threshold="1"
|
||||||
@dragenter="emit('covered')"
|
@dragenter="emit('covered')"
|
||||||
@dragleave="emit('uncovered')"
|
@dragleave="emit('uncovered')"
|
||||||
@change="addIntoFolder"
|
@change="addIntoFolder"
|
||||||
|
@ -73,11 +82,17 @@ const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
||||||
const { getWorkspace } = workspacesStore;
|
const { getWorkspace } = workspacesStore;
|
||||||
const { getConnectionByUid, getConnectionName, addToFolder } = connectionsStore;
|
const { getConnectionByUid, getConnectionName, addToFolder } = connectionsStore;
|
||||||
|
|
||||||
|
const foldersOpened = JSON.parse(localStorage.getItem('opened-folders')) || [];
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
folder: {
|
folder: {
|
||||||
type: Object as PropType<SidebarElement>,
|
type: Object as PropType<SidebarElement>,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
folderDrag: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
draggedElement: {
|
draggedElement: {
|
||||||
type: [String, Boolean] as PropType<string | false>,
|
type: [String, Boolean] as PropType<string | false>,
|
||||||
required: true
|
required: true
|
||||||
|
@ -88,12 +103,14 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['covered', 'uncovered', 'select-workspace', 'folder-sort']);
|
const emit = defineEmits(['context', 'covered', 'uncovered', 'select-workspace', 'folder-sort', 'folder-drag']);
|
||||||
|
|
||||||
const isOpen = ref(false);
|
const isOpen = ref(foldersOpened.includes(props.folder.uid));
|
||||||
const localList = ref(props.folder.connections);
|
const localList = ref(props.folder.connections);
|
||||||
const dummyNested = ref([]);
|
const dummyNested = ref([]);
|
||||||
|
|
||||||
|
const hasSelectedInside = computed(() => localList.value.includes(selectedWorkspace.value));
|
||||||
|
|
||||||
const foldersUid = computed(() => folders.value.reduce<string[]>((acc, curr) => {
|
const foldersUid = computed(() => folders.value.reduce<string[]>((acc, curr) => {
|
||||||
acc.push(curr.uid);
|
acc.push(curr.uid);
|
||||||
return acc;
|
return acc;
|
||||||
|
@ -127,17 +144,57 @@ const getStatusBadge = (uid: string) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openFolder = () => {
|
||||||
|
isOpen.value = true;
|
||||||
|
const opened: string[] = JSON.parse(localStorage.getItem('opened-folders')) || [];
|
||||||
|
opened.push(props.folder.uid);
|
||||||
|
localStorage.setItem('opened-folders', JSON.stringify(opened));
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeFolder = () => {
|
||||||
|
isOpen.value = false;
|
||||||
|
let opened: string[] = JSON.parse(localStorage.getItem('opened-folders')) || [];
|
||||||
|
opened = opened.filter(uid => uid !== props.folder.uid);
|
||||||
|
localStorage.setItem('opened-folders', JSON.stringify(opened));
|
||||||
|
};
|
||||||
|
|
||||||
|
const dragStart = () => {
|
||||||
|
emit('folder-drag', true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dragStop = () => {
|
||||||
|
emit('folder-drag', false);
|
||||||
|
};
|
||||||
|
|
||||||
watch(() => dummyNested.value.length, () => {
|
watch(() => dummyNested.value.length, () => {
|
||||||
dummyNested.value = [];
|
dummyNested.value = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(localList, () => {
|
|
||||||
emit('folder-sort');
|
|
||||||
}, { deep: true });
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.folder-container{
|
.folder {
|
||||||
|
position: relative;
|
||||||
|
&.selected-inside {
|
||||||
|
opacity: 1!important;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
height: 2.5rem;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
height: 0;
|
||||||
|
width: 3px;
|
||||||
|
transition: height 0.2s;
|
||||||
|
background-color: rgba($color: #fff, $alpha: 0.8);
|
||||||
|
border-radius: $border-radius;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto auto;
|
grid-template-columns: auto auto;
|
||||||
grid-template-rows: 50%;
|
grid-template-rows: 50%;
|
||||||
|
@ -146,19 +203,79 @@ watch(localList, () => {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
overflow: hidden;
|
|
||||||
transition: background .3s;
|
transition: background .3s;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
height: 0;
|
||||||
|
width: 3px;
|
||||||
|
transition: height 0.2s;
|
||||||
|
background-color: rgba($color: #fff, $alpha: 0.8);
|
||||||
|
border-radius: $border-radius;
|
||||||
|
position: absolute;
|
||||||
|
left: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-element-icon {
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
&.badge::after {
|
||||||
|
top: 10px;
|
||||||
|
right: 0px;
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-update::after {
|
||||||
|
bottom: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.opened {
|
&.opened {
|
||||||
gap: 4px 6px;
|
gap: 4px 6px;
|
||||||
grid-template-columns: auto;
|
grid-template-columns: auto;
|
||||||
grid-template-rows: auto;
|
grid-template-rows: auto;
|
||||||
background: rgba($color: #fff, $alpha: 0.1)!important;
|
background: rgba($color: #fff, $alpha: 0.1)!important;
|
||||||
transition: max-height .3s;
|
transition: max-height .1s;
|
||||||
|
|
||||||
.folder-element {
|
.folder-element {
|
||||||
opacity: .6;
|
opacity: .6;
|
||||||
height: 2.5rem;
|
height: 2.5rem;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
height: 2.5rem;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
height: 0;
|
||||||
|
width: 3px;
|
||||||
|
transition: height 0.2s;
|
||||||
|
background-color: rgba($color: #fff, $alpha: 0.8);
|
||||||
|
border-radius: $border-radius;
|
||||||
|
position: absolute;
|
||||||
|
left: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-element-icon {
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
&.badge::after {
|
||||||
|
top: 14px;
|
||||||
|
right: -4px;
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-update::after {
|
||||||
|
bottom: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-icon {
|
.folder-icon {
|
||||||
|
@ -209,10 +326,20 @@ watch(localList, () => {
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: opacity .2s;
|
transition: opacity .2s;
|
||||||
|
|
||||||
|
&.ghost {
|
||||||
|
margin:0 ;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover, &.selected {
|
&:hover, &.selected {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folder-element-icon {
|
||||||
|
transition: margin .2s;
|
||||||
|
}
|
||||||
|
|
||||||
.folder-element-name {
|
.folder-element-name {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
max-width: 90%;
|
max-width: 90%;
|
||||||
|
@ -224,6 +351,7 @@ watch(localList, () => {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
transition: bottom .2s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,4 +365,52 @@ watch(localList, () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ghost {
|
||||||
|
border-radius: 15px!important;
|
||||||
|
background: rgba($color: #fff, $alpha: 0.1);
|
||||||
|
|
||||||
|
&.folder-element {
|
||||||
|
height: $settingbar-width;
|
||||||
|
border-radius: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 4px;
|
||||||
|
position: relative;
|
||||||
|
transition: opacity .2s;
|
||||||
|
|
||||||
|
&:hover, &.selected {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-element-icon {
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
&.badge::after {
|
||||||
|
top: 5px;
|
||||||
|
right: -4px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-update::after {
|
||||||
|
bottom: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-element-name {
|
||||||
|
position: absolute;
|
||||||
|
max-width: 90%;
|
||||||
|
bottom: 5px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 65%;
|
||||||
|
font-style: normal;
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
:title="t('message.allConnections')"
|
:title="t('message.allConnections')"
|
||||||
@click="emit('show-connections-modal')"
|
@click="emit('show-connections-modal')"
|
||||||
>
|
>
|
||||||
<i class="settingbar-element-icon mdi mdi-24px mdi-dots-horizontal text-light" />
|
<div class="settingbar-element-icon-wrapper">
|
||||||
|
<i class="settingbar-element-icon mdi mdi-24px mdi-dots-horizontal text-light" />
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="settingbar-element btn btn-link"
|
class="settingbar-element btn btn-link"
|
||||||
|
@ -31,7 +33,9 @@
|
||||||
:title="t('message.addConnection')"
|
:title="t('message.addConnection')"
|
||||||
@click="selectWorkspace('NEW')"
|
@click="selectWorkspace('NEW')"
|
||||||
>
|
>
|
||||||
<i class="settingbar-element-icon mdi mdi-24px mdi-plus text-light" />
|
<div class="settingbar-element-icon-wrapper">
|
||||||
|
<i class="settingbar-element-icon mdi mdi-24px mdi-plus text-light" />
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -164,6 +168,10 @@ watch(selectedWorkspace, (newVal, oldVal) => {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.settingbar-element {
|
.settingbar-element {
|
||||||
height: $settingbar-width;
|
height: $settingbar-width;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -172,7 +180,7 @@ watch(selectedWorkspace, (newVal, oldVal) => {
|
||||||
transition: opacity 0.2s;
|
transition: opacity 0.2s;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: center;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -185,7 +193,7 @@ watch(selectedWorkspace, (newVal, oldVal) => {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
height: $settingbar-width;
|
height: calc(#{$settingbar-width} - 0.4rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,53 +202,56 @@ watch(selectedWorkspace, (newVal, oldVal) => {
|
||||||
height: 0;
|
height: 0;
|
||||||
width: 3px;
|
width: 3px;
|
||||||
transition: height 0.2s;
|
transition: height 0.2s;
|
||||||
background-color: $primary-color;
|
background-color: rgba($color: #fff, $alpha: 0.8);
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingbar-element-icon {
|
.settingbar-element-icon-wrapper{
|
||||||
margin: 0 auto;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
&.badge::after {
|
.settingbar-element-icon {
|
||||||
top: 5px;
|
&.badge::after {
|
||||||
right: -4px;
|
top: 10px;
|
||||||
position: absolute;
|
right: -6px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-update::after {
|
||||||
|
bottom: initial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.badge-update::after {
|
.settingbar-element-name {
|
||||||
bottom: initial;
|
font-size: 65%;
|
||||||
|
max-width: 90%;
|
||||||
|
font-style: normal;
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: calc($settingbar-width - 15px);
|
||||||
|
line-height: 1.1;
|
||||||
|
color: rgba($body-font-color-dark, 0.8);
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.settingbar-element-name {
|
.settingbar-element-pin {// <- Dead
|
||||||
font-size: 65%;
|
margin: 0 auto;
|
||||||
bottom: 5px;
|
|
||||||
left: 7px;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
width: calc($settingbar-width - 15px);
|
|
||||||
text-align: left;
|
|
||||||
line-height: 1.1;
|
|
||||||
color: rgba($body-font-color-dark, 0.8);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settingbar-element-pin {
|
&::before {
|
||||||
margin: 0 auto;
|
font: normal normal normal 14px/1 "Material Design Icons";
|
||||||
|
content: "\F0403";
|
||||||
&::before {
|
color: $body-font-color-dark;
|
||||||
font: normal normal normal 14px/1 "Material Design Icons";
|
transform: rotate(45deg);
|
||||||
content: "\F0403";
|
opacity: 0.25;
|
||||||
color: $body-font-color-dark;
|
top: -8px;
|
||||||
transform: rotate(45deg);
|
left: -10px;
|
||||||
opacity: 0.25;
|
position: absolute;
|
||||||
top: -8px;
|
}
|
||||||
left: -10px;
|
|
||||||
position: absolute;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,21 +132,32 @@ export const useConnectionsStore = defineStore('connections', {
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!invalidElements.length) return;
|
if (invalidElements.length) {
|
||||||
|
invalidElements.forEach(el => {
|
||||||
|
let connIndex = connections.findIndex(conn => conn.uid === el.uid);
|
||||||
|
const conn = connections[connIndex];
|
||||||
|
|
||||||
invalidElements.forEach(el => {
|
if (connIndex === -1) return;
|
||||||
const connIndex = connections.findIndex(conn => conn.uid === el.uid);
|
|
||||||
const conn = connections[connIndex];
|
|
||||||
|
|
||||||
if (connIndex === -1) return;
|
connections.splice(el.index, 1, { // Move to new position
|
||||||
|
isFolder: false,
|
||||||
|
client: conn.client,
|
||||||
|
uid: conn.uid
|
||||||
|
});
|
||||||
|
|
||||||
connections.splice(connIndex, 1);// Delete olt object
|
connIndex = connections.findIndex(conn => conn.uid === el.uid);
|
||||||
connections.splice(el.index, 1, { // Move to new position
|
connections.splice(connIndex, 1);// Delete old object
|
||||||
isFolder: false,
|
|
||||||
client: conn.client,
|
|
||||||
uid: conn.uid
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// Clear empty folders
|
||||||
|
const emptyFolders = connections.reduce<string[]>((acc, curr) => {
|
||||||
|
if (curr.connections && curr.connections.length === 0)
|
||||||
|
acc.push(curr.uid);
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
connections = connections.filter(el => !emptyFolders.includes(el.uid));
|
||||||
|
|
||||||
this.connectionsOrder = connections;
|
this.connectionsOrder = connections;
|
||||||
persistentStore.set('connectionsOrder', this.connectionsOrder);
|
persistentStore.set('connectionsOrder', this.connectionsOrder);
|
||||||
|
|
|
@ -1,2 +1,80 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/ban-types */
|
||||||
declare module '@/App.vue';
|
declare module '@/App.vue';
|
||||||
declare module 'v-mask';
|
declare module 'v-mask';
|
||||||
|
declare module 'vuedraggable' {// <- to export as default
|
||||||
|
const draggableComponent: import('vue').DefineComponent<{
|
||||||
|
list: {
|
||||||
|
type: ArrayConstructor;
|
||||||
|
required: boolean;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
modelValue: {
|
||||||
|
type: ArrayConstructor;
|
||||||
|
required: boolean;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
itemKey: {
|
||||||
|
type: (FunctionConstructor | StringConstructor)[];
|
||||||
|
required: boolean;
|
||||||
|
};
|
||||||
|
clone: {
|
||||||
|
type: FunctionConstructor;
|
||||||
|
default: (original: any) => any;
|
||||||
|
};
|
||||||
|
tag: {
|
||||||
|
type: StringConstructor;
|
||||||
|
default: string;
|
||||||
|
};
|
||||||
|
move: {
|
||||||
|
type: FunctionConstructor;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
componentData: {
|
||||||
|
type: ObjectConstructor;
|
||||||
|
required: boolean;
|
||||||
|
default: any;
|
||||||
|
};
|
||||||
|
}, unknown, {
|
||||||
|
error: boolean;
|
||||||
|
}, {
|
||||||
|
realList(): any;
|
||||||
|
getKey(): any;
|
||||||
|
}, {
|
||||||
|
getUnderlyingVm(domElement: any): any;
|
||||||
|
getUnderlyingPotencialDraggableComponent(htmElement: any): any;
|
||||||
|
emitChanges(evt: any): void;
|
||||||
|
alterList(onList: any): void;
|
||||||
|
spliceList(): void;
|
||||||
|
updatePosition(oldIndex: any, newIndex: any): void;
|
||||||
|
getRelatedContextFromMoveEvent({ to, related }: {
|
||||||
|
to: any;
|
||||||
|
related: any;
|
||||||
|
}): any;
|
||||||
|
getVmIndexFromDomIndex(domIndex: any): any;
|
||||||
|
onDragStart(evt: any): void;
|
||||||
|
onDragAdd(evt: any): void;
|
||||||
|
onDragRemove(evt: any): void;
|
||||||
|
onDragUpdate(evt: any): void;
|
||||||
|
computeFutureIndex(relatedContext: any, evt: any): any;
|
||||||
|
onDragMove(evt: any, originalEvent: any): any;
|
||||||
|
onDragEnd(): void;
|
||||||
|
}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, any[], any, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<{
|
||||||
|
move: Function;
|
||||||
|
tag: string;
|
||||||
|
clone: Function;
|
||||||
|
list: unknown[];
|
||||||
|
modelValue: unknown[];
|
||||||
|
componentData: Record<string, any>;
|
||||||
|
} & {
|
||||||
|
itemKey?: string | Function;
|
||||||
|
}>, {
|
||||||
|
move: Function;
|
||||||
|
tag: string;
|
||||||
|
clone: Function;
|
||||||
|
list: unknown[];
|
||||||
|
modelValue: unknown[];
|
||||||
|
componentData: Record<string, any>;
|
||||||
|
}>;
|
||||||
|
export = draggableComponent;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue