mirror of
				https://github.com/Fabio286/antares.git
				synced 2025-06-05 21:59:22 +02:00 
			
		
		
		
	refactor(UI): various improvements on sidebar
This commit is contained in:
		| @@ -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); | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								src/renderer/untyped.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								src/renderer/untyped.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -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; | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user