chore: type and ux improvement for SmartTree (#3126)
This commit is contained in:
@@ -193,7 +193,7 @@ import IconTrash2 from "~icons/lucide/trash-2"
|
|||||||
import IconEdit from "~icons/lucide/edit"
|
import IconEdit from "~icons/lucide/edit"
|
||||||
import IconFolder from "~icons/lucide/folder"
|
import IconFolder from "~icons/lucide/folder"
|
||||||
import IconFolderOpen from "~icons/lucide/folder-open"
|
import IconFolderOpen from "~icons/lucide/folder-open"
|
||||||
import { PropType, ref, computed, watch } from "vue"
|
import { ref, computed, watch } from "vue"
|
||||||
import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
|
import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
|
||||||
import { useI18n } from "@composables/i18n"
|
import { useI18n } from "@composables/i18n"
|
||||||
import { TippyComponent } from "vue-tippy"
|
import { TippyComponent } from "vue-tippy"
|
||||||
@@ -209,67 +209,36 @@ type FolderType = "collection" | "folder"
|
|||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = withDefaults(
|
||||||
id: {
|
defineProps<{
|
||||||
type: String,
|
id: string
|
||||||
default: "",
|
parentID?: string | null
|
||||||
required: true,
|
data: HoppCollection<HoppRESTRequest> | TeamCollection
|
||||||
},
|
/**
|
||||||
parentID: {
|
* Collection component can be used for both collections and folders.
|
||||||
type: String as PropType<string | null>,
|
* folderType is used to determine which one it is.
|
||||||
default: null,
|
*/
|
||||||
required: false,
|
collectionsType: CollectionType
|
||||||
},
|
folderType: FolderType
|
||||||
data: {
|
isOpen: boolean
|
||||||
type: Object as PropType<HoppCollection<HoppRESTRequest> | TeamCollection>,
|
isSelected?: boolean | null
|
||||||
default: () => ({}),
|
exportLoading?: boolean
|
||||||
required: true,
|
hasNoTeamAccess?: boolean
|
||||||
},
|
collectionMoveLoading?: string[]
|
||||||
collectionsType: {
|
isLastItem?: boolean
|
||||||
type: String as PropType<CollectionType>,
|
}>(),
|
||||||
default: "my-collections",
|
{
|
||||||
required: true,
|
id: "",
|
||||||
},
|
parentID: null,
|
||||||
/**
|
collectionsType: "my-collections",
|
||||||
* Collection component can be used for both collections and folders.
|
folderType: "collection",
|
||||||
* folderType is used to determine which one it is.
|
isOpen: false,
|
||||||
*/
|
isSelected: false,
|
||||||
folderType: {
|
exportLoading: false,
|
||||||
type: String as PropType<FolderType>,
|
hasNoTeamAccess: false,
|
||||||
default: "collection",
|
isLastItem: false,
|
||||||
required: true,
|
}
|
||||||
},
|
)
|
||||||
isOpen: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
isSelected: {
|
|
||||||
type: Boolean as PropType<boolean | null>,
|
|
||||||
default: false,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
exportLoading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
hasNoTeamAccess: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
collectionMoveLoading: {
|
|
||||||
type: Array as PropType<string[]>,
|
|
||||||
default: () => [],
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
isLastItem: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "toggle-children"): void
|
(event: "toggle-children"): void
|
||||||
@@ -448,8 +417,13 @@ const notSameDestination = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const isCollLoading = computed(() => {
|
const isCollLoading = computed(() => {
|
||||||
if (props.collectionMoveLoading.length > 0 && props.data.id) {
|
const { collectionMoveLoading } = props
|
||||||
return props.collectionMoveLoading.includes(props.data.id)
|
if (
|
||||||
|
collectionMoveLoading &&
|
||||||
|
collectionMoveLoading.length > 0 &&
|
||||||
|
props.data.id
|
||||||
|
) {
|
||||||
|
return collectionMoveLoading.includes(props.data.id)
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
class="flex flex-col flex-1"
|
class="flex flex-col flex-1"
|
||||||
>
|
>
|
||||||
<SmartTreeBranch
|
<SmartTreeBranch
|
||||||
|
:root-nodes-length="rootNodes.data.length"
|
||||||
:node-item="rootNode"
|
:node-item="rootNode"
|
||||||
:adapter="adapter as SmartTreeAdapter<T>"
|
:adapter="adapter as SmartTreeAdapter<T>"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -85,19 +85,25 @@ const props = defineProps<{
|
|||||||
* The node item that will be used to render the tree branch content
|
* The node item that will be used to render the tree branch content
|
||||||
*/
|
*/
|
||||||
nodeItem: TreeNode<T>
|
nodeItem: TreeNode<T>
|
||||||
|
/**
|
||||||
|
* Total number of rootNode
|
||||||
|
*/
|
||||||
|
rootNodesLength?: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const CHILD_SLOT_NAME = "default"
|
const CHILD_SLOT_NAME = "default"
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
|
|
||||||
|
const isOnlyRootChild = computed(() => props.rootNodesLength === 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks whether the children on this branch were ever rendered
|
* Marks whether the children on this branch were ever rendered
|
||||||
* See the usage inside '<template>' for more info
|
* See the usage inside '<template>' for more info
|
||||||
*/
|
*/
|
||||||
const childrenRendered = ref(false)
|
const childrenRendered = ref(isOnlyRootChild.value)
|
||||||
|
|
||||||
const showChildren = ref(false)
|
const showChildren = ref(isOnlyRootChild.value)
|
||||||
const isNodeOpen = ref(false)
|
const isNodeOpen = ref(isOnlyRootChild.value)
|
||||||
|
|
||||||
const highlightNode = ref(false)
|
const highlightNode = ref(false)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user