import { xss } from '@opentiny/utils'
import { deepClone } from '../picker-column'
export const filterInput =
({ state }) =>
(val) => {
state.filterValue = val
}
export const computeData =
({ props, vm }) =>
() =>
filterNodeUrl(props.data || [], vm)
const filterNodeUrl = (data, vm) => {
data.forEach((node) => {
node.url = xss.filterUrl(node.url)
vm.$set(node, 'isCurrent', false)
if (node.children) {
filterNodeUrl(node.children, vm)
}
})
return data
}
export const setIsCurrent =
({ props, vm, state }) =>
(data, node) => {
if (props.onlyCheckChildren && node.children) return
const nodeId = node.id
if (state.filterValue && state.filterData.length) {
getIsCurrent(vm, { children: state.filterData }, nodeId)
state.activedKeys = nodeId
} else {
getIsCurrent(vm, { children: data }, nodeId)
state.filterCheckedId = null
}
state.activedNodeId = nodeId
if (props.onlyCheckChildren) {
state.currentPaths = findPaths(data, nodeId)
}
}
const getIsCurrent = (vm, node, nodeId) => {
if (!node.children) return
for (let i = 0; i < node.children.length; i++) {
const isCurrentNode = node.children[i].id === nodeId
vm.$set(node.children[i], 'isCurrent', isCurrentNode)
getIsCurrent(vm, node.children[i], nodeId)
}
}
export const filterNodes =
({ state, api, nextTick }) =>
(label) => {
if (label !== '') {
state.filterData = filterTree(deepClone(state.data), label)
} else {
state.filterData = []
if (state.activedKeys) {
api.getActivedKeysPath(state.activedKeys)
nextTick(() => {
api.setIsCurrent(state.data, { id: state.activedKeys })
})
}
}
}
export const getExpandedKeysPath =
({ state }) =>
(keys) => {
const paths = []
const len = keys.length
for (let i = 0; i < len; i++) {
if (!paths.includes(keys[i])) {
paths.push(...findPaths(state.data, keys[i]))
}
}
state.expandedKeysPath = paths
}
export const getActivedKeysPath =
({ state }) =>
(key) => {
if (key !== null && key !== undefined) {
state.activedKeysPath = findPaths(state.data, key) || []
}
}
export const setNodeHidden =
({ props, vm, state }) =>
(nodeId) => {
if (state.filterValue && state.filterData.length) {
hiddenNode(vm, state.filterData, nodeId)
}
if (props.expandAll && !state.filterValue) {
hiddenNode(vm, state.data, nodeId)
}
}
export const setAllNodeVisible =
({ vm, state }) =>
() => {
setNodeVisible(vm, state.data)
}
const setNodeVisible = (vm, nodes) => {
if (!nodes) return
for (let i = 0; i < nodes.length; i++) {
vm.$set(nodes[i], 'visible', true)
if (nodes[i].children) {
setNodeVisible(vm, nodes[i].children)
}
}
}
const existChildren = (node) => node.children && node.children.length
const filterTree = (nodes, label) => {
const result = []
for (const node of nodes) {
if (existChildren(node)) {
node.children = filterTree(node.children, label)
}
if (node.label.includes(label) || existChildren(node)) {
node.visible = true
result.push(node)
}
}
return result
}
const hiddenNode = (vm, nodes, nodeId) => {
if (!nodes) return
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].id === nodeId) {
vm.$set(nodes[i], 'visible', false)
}
if (nodes[i].children) {
hiddenNode(vm, nodes[i].children, nodeId)
}
}
}
const findPaths = (nodes, nodeId) => {
for (let i in nodes) {
if (nodes[i].id === nodeId) {
return [nodes[i].id]
}
if (nodes[i].children) {
let res = findPaths(nodes[i].children, nodeId)
if (res) {
return res.concat(nodes[i].id)
}
}
}
}