diff --git a/packages/applet/src/composables/custom-inspector-state.ts b/packages/applet/src/composables/custom-inspector-state.ts index 23a871d47..968337eac 100644 --- a/packages/applet/src/composables/custom-inspector-state.ts +++ b/packages/applet/src/composables/custom-inspector-state.ts @@ -8,6 +8,8 @@ type CustomInspectorState = Partial<{ label: string logo: string timelineLayerIds: string[] + treeFilterPlaceholder: string + stateFilterPlaceholder: string }> const VueDevToolsStateSymbol: InjectionKey> = Symbol.for('VueDevToolsCustomInspectorStateSymbol') diff --git a/packages/applet/src/modules/components/index.vue b/packages/applet/src/modules/components/index.vue index ed0cffc7a..0b788901b 100644 --- a/packages/applet/src/modules/components/index.vue +++ b/packages/applet/src/modules/components/index.vue @@ -17,7 +17,7 @@ import RootStateViewer from '~/components/state/RootStateViewer.vue' import ComponentTree from '~/components/tree/TreeViewer.vue' import { createSelectedContext } from '~/composables/select' import { createExpandedContext } from '~/composables/toggle-expanded' -import { searchDeepInObject } from '~/utils' +import { filterInspectorState } from '~/utils' import ComponentRenderCode from './components/RenderCode.vue' const emit = defineEmits(['openInEditor', 'onInspectComponentStart', 'onInspectComponentEnd']) @@ -104,27 +104,14 @@ const activeTreeNode = computed(() => { }) const activeTreeNodeFilePath = computed(() => activeTreeNode.value?.file ?? '') -const filteredState = computed(() => { - const result = {} - for (const groupKey in activeComponentState.value) { - const group = activeComponentState.value[groupKey] - const groupFields = group.filter((el) => { - try { - return searchDeepInObject({ - [el.key]: el.value, - }, filterStateName.value) - } - catch (e) { - return { - [el.key]: e, - } - } - }) - const normalized = flatten(Object.values(groupBy(sortByKey(groupFields), 'stateType'))) - if (groupFields.length) - result[groupKey] = normalized - } - return result +const displayState = computed(() => { + return filterInspectorState({ + state: activeComponentState.value, + filterKey: filterStateName.value, + processGroup(groupFields) { + return flatten(Object.values(groupBy(sortByKey(groupFields), 'stateType'))) + }, + }) }) const { expanded: expandedTreeNodes } = createExpandedContext() @@ -357,7 +344,7 @@ function toggleApp(id: string) { - + diff --git a/packages/applet/src/modules/custom-inspector/components/state/Index.vue b/packages/applet/src/modules/custom-inspector/components/state/Index.vue index 47fbde8b1..f1985bb35 100644 --- a/packages/applet/src/modules/custom-inspector/components/state/Index.vue +++ b/packages/applet/src/modules/custom-inspector/components/state/Index.vue @@ -2,7 +2,7 @@ import type { CustomInspectorNode, CustomInspectorOptions, CustomInspectorState } from '@vue/devtools-kit' import { DevToolsMessagingEvents, onRpcConnected, rpc } from '@vue/devtools-core' import { parse } from '@vue/devtools-kit' -import { vTooltip, VueIcIcon } from '@vue/devtools-ui' +import { vTooltip, VueIcIcon, VueInput } from '@vue/devtools-ui' import { until } from '@vueuse/core' import { Pane, Splitpanes } from 'splitpanes' import { computed, onUnmounted, ref, watch } from 'vue' @@ -13,6 +13,7 @@ import RootStateViewer from '~/components/state/RootStateViewer.vue' import ComponentTree from '~/components/tree/TreeViewer.vue' import { useCustomInspectorState } from '~/composables/custom-inspector-state' import { createExpandedContext } from '~/composables/toggle-expanded' +import { filterInspectorState } from '~/utils' const { expanded: expandedTreeNodes } = createExpandedContext() const { expanded: expandedStateNodes } = createExpandedContext('custom-inspector-state') @@ -32,6 +33,24 @@ const selected = ref('') const state = ref>({}) const emptyState = computed(() => !Object.keys(state.value).length) +const inspectorState = useCustomInspectorState() + +const filterTreeKey = ref('') +const filterStateKey = ref('') + +watch(filterTreeKey, (value, oldValue) => { + if (!value.trim().length && !oldValue.trim().length) + return + getInspectorTree(value) +}) + +const displayState = computed(() => { + return filterInspectorState({ + state: state.value, + filterKey: filterStateKey.value, + }) +}) + // tree function dfs(node: { id: string, children?: { id: string }[] }, path: string[] = [], linkedList: string[][] = []) { path.push(node.id) @@ -120,8 +139,8 @@ watch(selected, () => { getInspectorState(selected.value) }) -const getInspectorTree = () => { - rpc.value.getInspectorTree({ inspectorId: inspectorId.value, filter: '' }).then((_data) => { +function getInspectorTree(filter = '') { + rpc.value.getInspectorTree({ inspectorId: inspectorId.value, filter }).then((_data) => { const data = parse(_data!) tree.value = data if (!selected.value && data.length) { @@ -132,7 +151,7 @@ const getInspectorTree = () => { }) } -until(inspectorId).toBeTruthy().then(getInspectorTree) +until(inspectorId).toBeTruthy().then(() => getInspectorTree()) function onInspectorTreeUpdated(_data: string) { const data = parse(_data) as { @@ -179,32 +198,40 @@ onUnmounted(() => { - diff --git a/packages/applet/src/modules/custom-inspector/index.vue b/packages/applet/src/modules/custom-inspector/index.vue index fe956e0ed..4208e0856 100644 --- a/packages/applet/src/modules/custom-inspector/index.vue +++ b/packages/applet/src/modules/custom-inspector/index.vue @@ -68,6 +68,8 @@ function getInspectorInfo() { logo: payload?.logo, timelineLayerIds: payload?.timelineLayers.map(item => item.id), pluginId: props.pluginId, + treeFilterPlaceholder: payload.treeFilterPlaceholder, + stateFilterPlaceholder: payload.stateFilterPlaceholder, } inspectorState.value = state restoreRouter() diff --git a/packages/applet/src/modules/pinia/components/store/Index.vue b/packages/applet/src/modules/pinia/components/store/Index.vue index aa15071cd..bf66bac51 100644 --- a/packages/applet/src/modules/pinia/components/store/Index.vue +++ b/packages/applet/src/modules/pinia/components/store/Index.vue @@ -2,7 +2,7 @@ import type { CustomInspectorNode, CustomInspectorOptions, CustomInspectorState } from '@vue/devtools-kit' import { DevToolsMessagingEvents, rpc } from '@vue/devtools-core' import { parse } from '@vue/devtools-kit' -import { vTooltip } from '@vue/devtools-ui' +import { vTooltip, VueInput } from '@vue/devtools-ui' import { Pane, Splitpanes } from 'splitpanes' import { computed, onUnmounted, ref, watch } from 'vue' import DevToolsHeader from '~/components/basic/DevToolsHeader.vue' @@ -11,14 +11,18 @@ import Navbar from '~/components/basic/Navbar.vue' import RootStateViewer from '~/components/state/RootStateViewer.vue' import ComponentTree from '~/components/tree/TreeViewer.vue' +import { useCustomInspectorState } from '~/composables/custom-inspector-state' import { createExpandedContext } from '~/composables/toggle-expanded' +import { filterInspectorState } from '~/utils' +import { PiniaPluginInspectorId } from '../../constants' const { expanded: expandedTreeNodes } = createExpandedContext() const { expanded: expandedStateNodes } = createExpandedContext('pinia-store-state') -const inspectorId = 'pinia' +const inspectorId = PiniaPluginInspectorId const nodeActions = ref([]) const actions = ref([]) +const inspectorState = useCustomInspectorState() const selected = ref('') const tree = ref([]) @@ -26,6 +30,21 @@ const treeNodeLinkedList = computed(() => tree.value?.length ? dfs(tree.value?.[ const flattenedTreeNodes = computed(() => flattenTreeNodes(tree.value)) const flattenedTreeNodesIds = computed(() => flattenedTreeNodes.value.map(node => node.id)) const state = ref>({}) +const filterStoreKey = ref('') +const filterStateKey = ref('') + +watch(filterStoreKey, (value, oldValue) => { + if (!value.trim().length && !oldValue.trim().length) + return + getPiniaInspectorTree(value) +}) + +const displayState = computed(() => { + return filterInspectorState({ + state: state.value, + filterKey: filterStateKey.value, + }) +}) const emptyState = computed(() => !state.value.state?.length && !state.value.getters?.length) @@ -118,8 +137,8 @@ watch(selected, () => { getPiniaState(selected.value) }) -const getPiniaInspectorTree = () => { - rpc.value.getInspectorTree({ inspectorId, filter: '' }).then((_data) => { +function getPiniaInspectorTree(filter: string = '') { + rpc.value.getInspectorTree({ inspectorId, filter }).then((_data) => { const data = parse(_data!) tree.value = data if (!selected.value && data.length) { @@ -184,8 +203,9 @@ onUnmounted(() => {
-
-
+
+ +
@@ -198,14 +218,15 @@ onUnmounted(() => {
-
-
+
+ +
- + No Data diff --git a/packages/applet/src/modules/pinia/constants.ts b/packages/applet/src/modules/pinia/constants.ts new file mode 100644 index 000000000..085b6b6c7 --- /dev/null +++ b/packages/applet/src/modules/pinia/constants.ts @@ -0,0 +1,2 @@ +export const PiniaPluginDescriptorId = 'dev.esm.pinia' +export const PiniaPluginInspectorId = 'pinia' diff --git a/packages/applet/src/modules/pinia/index.vue b/packages/applet/src/modules/pinia/index.vue index faeb98662..0abbfc61e 100644 --- a/packages/applet/src/modules/pinia/index.vue +++ b/packages/applet/src/modules/pinia/index.vue @@ -1,11 +1,13 @@ diff --git a/packages/applet/src/utils/search.ts b/packages/applet/src/utils/search.ts index de71451e8..47d5f4fd2 100644 --- a/packages/applet/src/utils/search.ts +++ b/packages/applet/src/utils/search.ts @@ -1,4 +1,4 @@ -import { INFINITY, isPlainObject, NAN, NEGATIVE_INFINITY, UNDEFINED } from '@vue/devtools-kit' +import { CustomInspectorState, INFINITY, isPlainObject, NAN, NEGATIVE_INFINITY, UNDEFINED } from '@vue/devtools-kit' /** * Searches a key or value in the object, with a maximum deepness @@ -132,3 +132,26 @@ function internalSearchArray(array, searchTerm, seen, depth) { } return match } + +export function filterInspectorState(params: { + state: Record + filterKey?: string | null | undefined + // Each group is a flatten object + processGroup?: (item: T[]) => T[] +}) { + const { state, filterKey, processGroup } = params + if (!filterKey || !filterKey.trim().length) + return state + const result = {} + for (const groupKey in state) { + const group = state[groupKey] + const groupFields = group.filter(el => searchDeepInObject({ + // @ts-expect-error typing weak + [el.key]: el.value, + }, filterKey)) + if (groupFields.length) { + result[groupKey] = processGroup ? processGroup(groupFields) : groupFields + } + } + return result +} diff --git a/packages/devtools-kit/src/ctx/hook.ts b/packages/devtools-kit/src/ctx/hook.ts index 479e1bd15..007ff59ea 100644 --- a/packages/devtools-kit/src/ctx/hook.ts +++ b/packages/devtools-kit/src/ctx/hook.ts @@ -248,7 +248,7 @@ export function createDevToolsCtxHooks() { const _payload = { app: plugin.descriptor.app, inspectorId, - filter: inspector?.treeFilter || '', + filter: inspector?.treeFilterPlaceholder || '', rootNodes: [], } diff --git a/packages/devtools-kit/src/ctx/inspector.ts b/packages/devtools-kit/src/ctx/inspector.ts index e1a442425..1143517b4 100644 --- a/packages/devtools-kit/src/ctx/inspector.ts +++ b/packages/devtools-kit/src/ctx/inspector.ts @@ -11,7 +11,8 @@ import { devtoolsTimelineLayers } from './timeline' interface DevToolsKitInspector { options: CustomInspectorOptions descriptor: PluginDescriptor - treeFilter: string + treeFilterPlaceholder: string + stateFilterPlaceholder: string selectedNodeId: string appRecord: unknown } @@ -31,7 +32,8 @@ export function addInspector(inspector: CustomInspectorOptions, descriptor: Plug devtoolsInspector.push({ options: inspector, descriptor, - treeFilter: '', + treeFilterPlaceholder: inspector.treeFilterPlaceholder ?? 'Search tree...', + stateFilterPlaceholder: inspector.stateFilterPlaceholder ?? 'Search state...', selectedNodeId: '', appRecord: getAppRecord(descriptor.app), }) @@ -76,6 +78,8 @@ export function getInspectorInfo(id: string) { packageName: descriptor.packageName, homepage: descriptor.homepage, timelineLayers, + treeFilterPlaceholder: inspector.treeFilterPlaceholder, + stateFilterPlaceholder: inspector.stateFilterPlaceholder, } }