Skip to content

Commit

Permalink
Merge pull request #22 from qianmoQ/feature-dev
Browse files Browse the repository at this point in the history
[Chat] Add Resizable chat
  • Loading branch information
devlivecommunity authored Apr 19, 2024
2 parents 38e881e + cc698a2 commit 565b2a9
Show file tree
Hide file tree
Showing 22 changed files with 701 additions and 49 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "shadcn-ui-vue-admin",
"description": "Admin Dashboard UI crafted with Shadcn ui and Vite and Vue. Built with responsiveness and accessibility in mind.",
"private": true,
"version": "2024.0.3",
"version": "2024.0.4",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build && cp CNAME dist/",
Expand All @@ -12,6 +12,7 @@
"@radix-icons/vue": "^1.0.0",
"@vee-validate/zod": "^4.12.6",
"@vueuse/core": "^10.9.0",
"@vueuse/motion": "^2.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"lodash": "^4.17.21",
Expand Down
26 changes: 26 additions & 0 deletions src/components/ui/resizable/ResizableHandle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'radix-vue'
import { DragHandleDots2Icon } from '@radix-icons/vue'
import { cn } from '@/lib/utils'
const props = defineProps<SplitterResizeHandleProps & { class?: HTMLAttributes['class'], withHandle?: boolean }>()
const emits = defineEmits<SplitterResizeHandleEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>

<template>
<SplitterResizeHandle v-bind="forwarded" :class="cn('relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-orientation=vertical]]:h-px [&[data-orientation=vertical]]:w-full [&[data-orientation=vertical]]:after:left-0 [&[data-orientation=vertical]]:after:h-1 [&[data-orientation=vertical]]:after:w-full [&[data-orientation=vertical]]:after:-translate-y-1/2 [&[data-orientation=vertical]]:after:translate-x-0 [&[data-orientation=vertical]>div]:rotate-90', props.class)">
<template v-if="props.withHandle">
<div class="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
<DragHandleDots2Icon class="h-2.5 w-2.5" />
</div>
</template>
</SplitterResizeHandle>
</template>
21 changes: 21 additions & 0 deletions src/components/ui/resizable/ResizablePanelGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import { SplitterGroup, type SplitterGroupEmits, type SplitterGroupProps, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps<SplitterGroupProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<SplitterGroupEmits>()
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>

<template>
<SplitterGroup v-bind="forwarded" :class="cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', props.class)">
<slot />
</SplitterGroup>
</template>
3 changes: 3 additions & 0 deletions src/components/ui/resizable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as ResizablePanelGroup } from './ResizablePanelGroup.vue'
export { default as ResizableHandle } from './ResizableHandle.vue'
export { SplitterPanel as ResizablePanel } from 'radix-vue'
17 changes: 10 additions & 7 deletions src/data/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const createNavigation = (): void => {

const datacap = createNavigationItem('common.common.datacap',
undefined,
'https://datacap.edurt.io',
'https://datacap.devlive.org',
undefined,
NavigationPosition.TOP,
undefined
Expand All @@ -46,16 +46,13 @@ const createNavigation = (): void => {
formArray, undefined, 'common.common.form')
NavigationService.addNavigation(froms)

const cardHome = createNavigationItem('card.common.default', undefined, '/card/index', undefined, NavigationPosition.LEFT_TOP)
const cardWithGit = createNavigationItem('card.common.cardWithGit', undefined, '/card/git', undefined, NavigationPosition.LEFT_TOP)
const cardWithTeam = createNavigationItem('card.common.cardWithTeam', undefined, '/card/team', undefined, NavigationPosition.LEFT_TOP)
const cardHome = createNavigationItem('card.common.default', undefined, '/cards/index', undefined, NavigationPosition.LEFT_TOP)
const cardWithGit = createNavigationItem('card.common.cardWithGit', undefined, '/cards/git', undefined, NavigationPosition.LEFT_TOP)
const cardWithTeam = createNavigationItem('card.common.cardWithTeam', undefined, '/cards/team', undefined, NavigationPosition.LEFT_TOP)
const cardArray = [cardHome, cardWithGit, cardWithTeam]
const cards = createNavigationItem('card.common.default', cardArray.length.toString(), '/card/index', CreditCard, NavigationPosition.LEFT_TOP, cardArray)
NavigationService.addNavigation(cards)

const chat = createNavigationItem('common.common.chat', undefined, '/chat', MessageCircle, NavigationPosition.LEFT_TOP)
NavigationService.addNavigation(chat)

const page404 = createNavigationItem('common.common.page404', undefined, '/common/404', Ban, NavigationPosition.LEFT_TOP)
const page403 = createNavigationItem('common.common.page403', undefined, '/common/403', CircleOff, NavigationPosition.LEFT_TOP)
const pageArray = [page404, page403]
Expand All @@ -69,6 +66,12 @@ const createNavigation = (): void => {
const components = createNavigationItem('common.common.component', componentArray.length.toString(), '/components', Command, NavigationPosition.LEFT_TOP, componentArray)
NavigationService.addNavigation(components)

const chat = createNavigationItem('common.common.chat', undefined, '/chats/basic', MessageCircle, NavigationPosition.LEFT_TOP)
const resizable = createNavigationItem('common.common.resizable', undefined, '/chats/resizable', MessageCircle, NavigationPosition.LEFT_TOP)
const chatArray = [chat, resizable]
const chats = createNavigationItem('common.common.chat', chatArray.length.toString(), '/chats', MessageCircle, NavigationPosition.LEFT_TOP, chatArray)
NavigationService.addNavigation(chats)

const external = createNavigationItem('common.common.externalLink', undefined, 'https://datacap.devlive.org', Link, NavigationPosition.LEFT_TOP)
external.external = true
NavigationService.addNavigation(external)
Expand Down
1 change: 1 addition & 0 deletions src/i18n/langs/en/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export default {
type: 'Type',
icon: 'Icon',
card: 'Card',
resizable: 'Resizable',
},
tip: {
signInInfo: 'Enter your information to sign in to your account.',
Expand Down
1 change: 1 addition & 0 deletions src/i18n/langs/zhCn/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export default {
type: '类型',
icon: '图标',
card: '卡片',
resizable: '可调整大小',
},
tip: {
signInInfo: '输入您的信息以登录您的帐户。',
Expand Down
3 changes: 3 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import './assets/index.css'
// Import mock data
import '@/data/index'

import { MotionPlugin } from '@vueuse/motion'

const app = createApp(App)
app.use(router)
app.use(i18n)
app.use(MotionPlugin)
app.provide('$t', i18n.global.t)
// Setting moment
app.config.globalProperties.$dt = moment
Expand Down
73 changes: 47 additions & 26 deletions src/router/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,14 @@ const createDefaultRouter = (router: Router): void => {
name: 'dashboard',
path: 'dashboard',
component: () => import('@/views/pages/dashboard/DashboardHome.vue')
},
{
name: 'card',
path: 'card',
children: [
{
name: 'index',
path: 'index',
component: () => import('@/views/pages/card/CardHome.vue')
},
{
name: 'git',
path: 'git',
component: () => import('@/views/pages/card/CardWithGit.vue')
},
{
name: 'team',
path: 'team',
component: () => import('@/views/pages/card/CardWithTeam.vue')
}
]
},
{
name: 'chat',
path: 'chat',
component: () => import('@/views/pages/chat/ChatHome.vue')
}
]
})
createHttpRouter(router)
createUserRouter(router)
createFormRouter(router)
createCardRouter(router)
createChatRouter(router)
createComponentRouter(router)
}

Expand Down Expand Up @@ -138,6 +114,51 @@ const createFormRouter = (router: Router): void => {
})
}

const createCardRouter = (router: Router): void => {
router.addRoute({
path: '/cards',
name: 'cardExample',
component: LayoutContainer,
children: [
{
name: 'index',
path: 'index',
component: () => import('@/views/pages/card/CardHome.vue')
},
{
name: 'git',
path: 'git',
component: () => import('@/views/pages/card/CardWithGit.vue')
},
{
name: 'team',
path: 'team',
component: () => import('@/views/pages/card/CardWithTeam.vue')
}
]
})
}

const createChatRouter = (router: Router): void => {
router.addRoute({
path: '/chats',
name: 'chat',
component: LayoutContainer,
children: [
{
name: 'chatBasic',
path: 'basic',
component: () => import('@/views/pages/chat/basic/ChatHome.vue')
},
{
name: 'chatResizable',
path: 'resizable',
component: () => import('@/views/pages/chat/resizable/ResizableChatHome.vue')
}
]
})
}

const createComponentRouter = (router: Router): void => {
router.addRoute({
path: '/components',
Expand Down
38 changes: 38 additions & 0 deletions src/ui/avatar/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<Avatar>
<AvatarImage :src="src as string" :alt="alt as string" :width="width" :height="height" :class="imageClass"/>
<AvatarFallback>{{ alt }}</AvatarFallback>
</Avatar>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
export default defineComponent({
name: 'IAvatar',
components: {
Avatar, AvatarImage, AvatarFallback
},
props: {
src: {
type: String
},
alt: {
type: String
},
width: {
type: Number,
default: 32
},
height: {
type: Number,
default: 32
},
imageClass: {
type: String,
default: ''
}
}
})
</script>
38 changes: 38 additions & 0 deletions src/ui/tooltip/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<TooltipProvider :delay-duration="duration">
<Tooltip>
<TooltipTrigger as-child>
<slot/>
</TooltipTrigger>
<TooltipContent :side="side as any">
<p v-if="content">{{ content }}</p>
<slot v-else name="content"/>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
export default defineComponent({
name: 'ITooltip',
components: {
Tooltip, TooltipContent, TooltipProvider, TooltipTrigger
},
props: {
content: {
type: String
},
duration: {
type: Number,
default: 0
},
side: {
type: String,
default: 'top'
}
}
})
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="flex flex-1 flex-col">
<div class="flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-8">
<Card>
<CardHeader class="flex flex-row items-center justify-between">
<template #title>
<div class="flex items-center space-x-4">
<Avatar>
<AvatarImage alt="SUA" src="https://www.shadcn-vue.com/avatars/01.png"/>
Expand All @@ -13,6 +13,8 @@
<p class="text-sm text-muted-foreground">[email protected]</p>
</div>
</div>
</template>
<template #extra>
<TooltipProvider>
<Tooltip :delay-duration="200">
<TooltipTrigger as-child>
Expand All @@ -23,25 +25,24 @@
<TooltipContent :side-offset="10">{{ $t('common.common.newMessage') }}</TooltipContent>
</Tooltip>
</TooltipProvider>
</CardHeader>
<Separator/>
<CardContent class="mt-3">
</template>
<div class="mt-3 mb-3">
<div class="space-y-4">
<div v-for="(message, index) in messages" :key="index"
:class="cn( 'flex w-max max-w-[75%] flex-col gap-2 rounded-lg px-3 py-2 text-sm', message.role === 'user' ? 'ml-auto bg-primary text-primary-foreground' : 'bg-muted')">
{{ `${message.content} ${index + 1}` }}
{{ `${ message.content } ${ index + 1 }` }}
</div>
</div>
</CardContent>
<CardFooter>
</div>
<template #footer>
<form class="flex w-full items-center space-x-2" @submit.prevent="handlerSubmit">
<Input v-model="inputValue as string" :placeholder="$t('common.tip.inputMessage')" class="flex-1"/>
<Button class="p-2.5 flex items-center justify-center" :disabled="!inputValue">
<Send class="w-4 h-4"/>
<span class="sr-only">{{ $t('common.common.send') }}</span>
</Button>
</form>
</CardFooter>
</template>
</Card>
</div>
<ChatUser :visible="visible" @close="visible = $event"/>
Expand All @@ -50,24 +51,24 @@

<script lang="ts">
import { defineComponent } from 'vue'
import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
import Card from '@/ui/card/card.vue'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { cn } from '@/lib/utils'
import { cn } from '@/lib/utils.ts'
import { PlusIcon, Send } from 'lucide-vue-next'
import { createMessages } from '@/views/pages/chat/ChatUtils'
import { createMessages } from '@/views/pages/chat/basic/ChatUtils.ts'
import { useI18n } from 'vue-i18n'
import { Separator } from '@/components/ui/separator'
import ChatUser from '@/views/pages/chat/components/ChatUser.vue'
import ChatUser from '@/views/pages/chat/basic/components/ChatUser.vue'
export default defineComponent({
name: 'ChatHome',
components: {
ChatUser,
Separator,
Card, CardContent, CardFooter, CardHeader,
Card,
Avatar, AvatarFallback, AvatarImage,
Tooltip, TooltipContent, TooltipProvider, TooltipTrigger,
Button,
Expand Down
File renamed without changes.
Loading

0 comments on commit 565b2a9

Please sign in to comment.