Skip to content
This repository was archived by the owner on Jan 6, 2024. It is now read-only.

feat: supports filtering documents #89

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"stub": "unbuild --stub",
"lint": "eslint .",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"lint:fix": "eslint --fix .",
"prepublishOnly": "npm run build",
"release": "bumpp && nr changelog && npm publish",
"dep:up": "taze -I major"
Expand Down
2 changes: 2 additions & 0 deletions src/client/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ declare module 'vue' {
AssetListItem: typeof import('./components/AssetListItem.vue')['default']
AssetPreview: typeof import('./components/AssetPreview.vue')['default']
ComponentTreeNode: typeof import('./components/ComponentTreeNode.vue')['default']
DocAdd: typeof import('./components/DocAdd.vue')['default']
DocDetails: typeof import('./components/DocDetails.vue')['default']
DockingPanel: typeof import('./components/DockingPanel.vue')['default']
DocSetting: typeof import('./components/DocSetting.vue')['default']
DrawerRight: typeof import('./components/DrawerRight.vue')['default']
FilepathItem: typeof import('./components/FilepathItem.vue')['default']
GraphSettings: typeof import('./components/GraphSettings.vue')['default']
Expand Down
2 changes: 1 addition & 1 deletion src/client/components/AssetPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defineProps<{
/>
<div v-else-if="asset.type === 'text' && !textContent" i-carbon-document text-3xl op20 />
<div v-else-if="asset.type === 'text' && textContent" w-full self-start p4>
<pre max-h-10rem of-hidden font-mono text-xs v-text="textContent" />
<pre max-h-10rem of-hidden text-xs font-mono v-text="textContent" />
</div>
<div v-else i-carbon-help text-3xl op20 />
</div>
Expand Down
83 changes: 83 additions & 0 deletions src/client/components/DocAdd.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<script setup lang="ts">
import { addDoc } from '../logic/documentations'
import type { DocumentInfo } from '../../types'

const props = defineProps<{
modelValue?: boolean
}>()

const emits = defineEmits<{
(event: 'update:modelValue', value: boolean): void
(event: 'cancel'): void
(event: 'add'): void
}>()

const value = useVModel(props, 'modelValue', emits, { passive: true })

function hide() {
value.value = false
}

const form = reactive([{
label: 'id',
necessary: true,
value: '',
},
{
label: 'name',
necessary: true,
value: '',
},
{
label: 'website',
necessary: true,
value: '',
},
{
label: 'github',
necessary: false,
value: '',
},
{
label: 'icon',
necessary: false,
value: '',
},
{
label: 'description',
necessary: false,
value: '',
}])

function handleAddDoc() {
const docInfo = Object.fromEntries(form.map(item => [item.label, item.value])) as any as DocumentInfo
addDoc(docInfo)
hide()
}
</script>

<template>
<VDialog v-model="value">
<div flex="~ col" min-w-100px w-30vw gap-15px p4>
<div v-for="item in form" :key="item.label" flex items-center>
<label
:class="{
'vue-doc-required': item.necessary,
}" w-95px
>{{ item.label }}</label>
<VTextInput v-model="item.value" op50 :placeholder="item.necessary ? 'necessary' : 'not necessary'" flex="1" />
</div>
<div w-full flex items-center justify-end gap-10px>
<VButton border-none bg="gray-300/30" @click.prevent="$emit('cancel'); hide()">
cancel
</VButton>
<VButton border-none bg-primary text-white hover:text-white @click.prevent="handleAddDoc">
add
</VButton>
</div>
</div>
</VDialog>
</template>

<style scoped>
</style>
24 changes: 18 additions & 6 deletions src/client/components/DocDetails.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script setup lang="ts">
import type { DocumentInfo } from '../../types'
import { removeDoc } from '../logic/documentations'

defineProps<{
const props = defineProps<{
data: DocumentInfo
}>()
const emit = defineEmits<{
Expand All @@ -11,6 +12,17 @@ const emit = defineEmits<{
function navigate(path: string) {
window.open(path, '_blank')
}

const showConfirm = ref(false)
const message = ref('')
function handleShowConfirm() {
message.value = `Are you sure you want to remove the document of ${props.data.name} ?`
showConfirm.value = true
}

function confirmHandler() {
removeDoc(props.data.name)
}
</script>

<template>
Expand All @@ -29,13 +41,10 @@ function navigate(path: string) {
</VTooltip>
</span>
</div>

<div v-if="data.description" class="line-clamp-2" mt--1 text-sm op50>
{{ data.description }}
</div>

<div flex-auto />

<div v-if="data.website" flex="~ gap-2" title="Documentation">
<span i-carbon-link text-lg op50 />
<span
Expand All @@ -54,13 +63,16 @@ function navigate(path: string) {
{{ data.github.replace(/^https?:\/\/github.com\//, "") }}
</span>
</div>

<slot name="items" />
</div>
<div flex="~ col">
<div flex="~ col" justify-between>
<div v-if="data.icon" h-20 w-20 flex flex-none rounded bg-gray:3 p4>
<img v-if="data.icon" :src="data.icon" :alt="data.name" ma h-full>
</div>
<div flex justify-end>
<VIconButton icon="material-symbols:delete" class="hover:color-red" @click.stop="handleShowConfirm" />
</div>
</div>
<VConfirm v-model="showConfirm" :message="message" @confirm="confirmHandler" />
</VCard>
</template>
29 changes: 29 additions & 0 deletions src/client/components/DocSetting.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script lang='ts' setup>
import { resetDoc } from '../logic/documentations'

const showDocAdd = ref(false)
const showConfirm = ref(false)
const message = ref('')

function handleShowConfirm() {
message.value = 'Are you sure you want to reset documents?'
showConfirm.value = true
}

function confirmResetHandler() {
resetDoc()
}
</script>

<template>
<div>
<VButton mr-10px n="primary" @click="showDocAdd = true">
Add Documents
</VButton>
<VButton n="primary" @click="handleShowConfirm">
Reset Documents
</VButton>
</div>
<DocAdd v-model="showDocAdd" />
<VConfirm v-model="showConfirm" :message="message" @confirm="confirmResetHandler" />
</template>
2 changes: 1 addition & 1 deletion src/client/components/DockingPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { isInPopup } from '../logic/state'
<PopupButton v-if="!isInPopup" />
<VDarkToggle v-slot="{ toggle, isDark }">
<VButton n="sm primary" @click="toggle">
<div carbon-sun dark:carbon-moon translate-y--1px />
<div carbon-sun translate-y--1px dark:carbon-moon />
{{ isDark.value ? "Dark" : "Light" }}
</VButton>
</VDarkToggle>
Expand Down
2 changes: 1 addition & 1 deletion src/client/components/RoutePathItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function navigate() {
<div px2 text-sm op50>
Fill params and navigate:
</div>
<div flex="~" items-center p2 font-mono text-sm>
<div flex="~" items-center p2 text-sm font-mono>
<template v-for="part, idx of parts" :key="idx">
<VTextInput
v-if="part[0] === ':'"
Expand Down
2 changes: 1 addition & 1 deletion src/client/components/RoutesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const sorted = computed(() => {
/>
</div>
</td>
<td w-30 ws-nowrap pr-1 text-left font-mono text-sm op50>
<td w-30 ws-nowrap pr-1 text-left text-sm font-mono op50>
{{ item.name ?? '-' }}
</td>
</tr>
Expand Down
1 change: 1 addition & 0 deletions src/client/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const FRAME_STATE_STORAGE_KEY = '__vue-devtools-frame-state__'
export const TABS_STORAGE_KEY = '__vue-devtools-tabs__'
export const TABS_GROUP_STORAGE_KEY = '__vue-devtools-tabs-group__'
export const DOC_GROUP_KEY = '__vue-devtools-doc-group__'
21 changes: 20 additions & 1 deletion src/client/logic/documentations.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import VueIcon from '../assets/icons/vue.svg'
import PiniaIcon from '../assets/icons/pinia.svg'
import VueUseIcon from '../assets/icons/vueuse.svg'
import type { DocumentInfo } from '../../types'
import { DOC_GROUP_KEY } from '../constants'

export const data = [
const normalData: DocumentInfo[] = [
{
id: 'vue',
name: 'Vue.js',
Expand Down Expand Up @@ -38,3 +40,20 @@ export const data = [
icon: VueUseIcon,
},
]

const localData = [...normalData]

export const data = useLocalStorage(DOC_GROUP_KEY, localData)

export function addDoc(docInfo: DocumentInfo) {
data.value.push(docInfo)
}

export function removeDoc(id: string) {
const idx = data.value.findIndex(i => i.name === id)
data.value.splice(idx, 1)
}

export function resetDoc() {
data.value = normalData
}
66 changes: 50 additions & 16 deletions src/client/pages/documentations.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<script setup lang="ts">
import { useFuse } from '@vueuse/integrations/useFuse'
import { rpc } from '../logic/rpc'
import type { DocumentInfo } from '../../types'
import { data } from '../logic/documentations'

const items = ref(data)
let localItems = data.value
let packagesName

const items = ref(localItems)
const iframeViewUrl = ref('')

rpc.getPackages().then((res) => {
const packagesName = Object.keys(res.packages)
items.value = items.value.filter(item => packagesName.includes(item.id))
packagesName = Object.keys(res.packages)
items.value = localItems.filter(item => packagesName.includes(item.id))
})

function navigate(data: DocumentInfo) {
Expand All @@ -17,24 +22,53 @@ function navigate(data: DocumentInfo) {
iframeViewUrl.value = data.website
}

const keywords = ref('')
const { results: filterDocuments } = useFuse(keywords, localItems.map(i => i.name), {
matchAllWhenSearchEmpty: true,
})

function handleFilterDoc() {
items.value = localItems.filter(item => (filterDocuments.value.map(i => i.item).includes(item.name) && packagesName.includes(item.id)))
}

// when remove the doc item from groups, need to update
watch(data, () => {
localItems = data.value
handleFilterDoc()
})

/**
* Why listen to filterDocuments instead of keywords,
* because the final filtering is based on filterDocuments,
* and its change is less than keywords
*/
watch(filterDocuments, () => {
handleFilterDoc()
})

function back() {
iframeViewUrl.value = ''
}
</script>

<template>
<div v-if="iframeViewUrl" relative h-screen>
<IframeView :src="iframeViewUrl" />
<teleport to="body">
<span
fixed left-2 top-2 z-1000 h-8 w-8 flex cursor-pointer select-none items-center justify-center rounded-5
bg-base hover="text-primary" @click.prevent.stop="back"
>
<i tabler:arrow-back-up />
</span>
</teleport>
</div>
<div v-else grid grid-cols-minmax-400px h-screen select-none gap3 overflow-scroll p4 class="no-scrollbar">
<DocDetails v-for="(item, index) in items" :key="index" :data="item" @navigate="navigate" />
<div class="overflow-y-scroll">
<div border="b base" flex="~ col gap1" px4 py3 navbar-glass>
<VTextInput v-model="keywords" font-mono icon="carbon:search" placeholder="Filter Documentations" op50 />
</div>
<div v-if="iframeViewUrl">
<IframeView :src="iframeViewUrl" />
<teleport to="body">
<span
fixed left-2 top-2 z-1000 h-8 w-8 flex cursor-pointer select-none items-center justify-center rounded-5
bg-base hover="text-primary" @click.prevent.stop="back"
>
<i tabler:arrow-back-up />
</span>
</teleport>
</div>
<div v-else grid grid-cols-minmax-400px h-screen select-none gap3 overflow-scroll p4 class="no-scrollbar">
<DocDetails v-for="(item, index) in items" :key="index" :data="item" @navigate="navigate" />
</div>
</div>
</template>
8 changes: 4 additions & 4 deletions src/client/pages/npm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ useInfiniteScroll(
</td>
<VDropdown max-w="10" placement="bottom-start" :distance="5">
<td
hover="text-primary" h-7 cursor-pointer ws-nowrap pr-1 text-left font-mono text-sm lh-7 underline
op70
hover="text-primary"
h-7 cursor-pointer ws-nowrap pr-1 text-left text-sm lh-7 font-mono underline op70
>
{{ item.activeVersion ?? item.version }}
</td>
Expand All @@ -243,12 +243,12 @@ useInfiniteScroll(
</ul>
</template>
</VDropdown>
<td w-30 ws-nowrap pr-1 text-left font-mono text-sm underline op70 hover="text-primary">
<td w-30 ws-nowrap pr-1 text-left text-sm font-mono underline op70 hover="text-primary">
<a :href="item?.owner?.link" target="_blank">
{{ item?.owner?.name ?? '-' }}
</a>
</td>
<td w-30 ws-nowrap pr-1 text-left font-mono text-sm op70>
<td w-30 ws-nowrap pr-1 text-left text-sm font-mono op70>
{{ item.humanDownloadsLast30Days }}
</td>
<td w-30 text-center>
Expand Down
Loading