Browse Source

feat: support vue file unit testing, add some components unit testing (#4119)

pull/4130/head
Vben 2 years ago
committed by GitHub
parent
commit
3f9ce63868
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 8
      .github/workflows/deploy.yml
  2. 3
      package.json
  3. 2
      packages/@core/ui-kit/shadcn-ui/src/components/alert-dialog/alert-dialog.vue
  4. 6
      packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue
  5. 2
      packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-background.vue
  6. 10
      packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb.vue
  7. 2
      packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/index.ts
  8. 0
      packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/types.ts
  9. 6
      packages/@core/ui-kit/shadcn-ui/src/components/button/button.vue
  10. 4
      packages/@core/ui-kit/shadcn-ui/src/components/button/icon-button.vue
  11. 4
      packages/@core/ui-kit/shadcn-ui/src/components/checkbox/checkbox.vue
  12. 6
      packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue
  13. 2
      packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/dropdown-menu.vue
  14. 2
      packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/dropdown-radio-menu.vue
  15. 6
      packages/@core/ui-kit/shadcn-ui/src/components/hover-card/hover-card.vue
  16. 5
      packages/@core/ui-kit/shadcn-ui/src/components/input-password/input-password.vue
  17. 2
      packages/@core/ui-kit/shadcn-ui/src/components/input/index.ts
  18. 2
      packages/@core/ui-kit/shadcn-ui/src/components/input/input.vue
  19. 0
      packages/@core/ui-kit/shadcn-ui/src/components/input/types.ts
  20. 2
      packages/@core/ui-kit/shadcn-ui/src/components/pin-input/index.ts
  21. 10
      packages/@core/ui-kit/shadcn-ui/src/components/pin-input/input.vue
  22. 0
      packages/@core/ui-kit/shadcn-ui/src/components/pin-input/types.ts
  23. 6
      packages/@core/ui-kit/shadcn-ui/src/components/popover/popover.vue
  24. 6
      packages/@core/ui-kit/shadcn-ui/src/components/scrollbar/scrollbar.vue
  25. 4
      packages/@core/ui-kit/shadcn-ui/src/components/segmented/index.ts
  26. 9
      packages/@core/ui-kit/shadcn-ui/src/components/segmented/segmented.vue
  27. 0
      packages/@core/ui-kit/shadcn-ui/src/components/segmented/types.ts
  28. 13
      packages/@core/ui-kit/shadcn-ui/src/components/sheet/sheet.vue
  29. 2
      packages/@core/ui-kit/shadcn-ui/src/components/tooltip/tooltip.vue
  30. 3
      packages/@core/ui-kit/shadcn-ui/src/components/ui/alert-dialog/AlertDialogAction.vue
  31. 3
      packages/@core/ui-kit/shadcn-ui/src/components/ui/alert-dialog/AlertDialogCancel.vue
  32. 3
      packages/@core/ui-kit/shadcn-ui/src/components/ui/toggle-group/ToggleGroup.vue
  33. 3
      packages/@core/ui-kit/shadcn-ui/src/components/ui/toggle-group/ToggleGroupItem.vue
  34. 39
      packages/effects/common-ui/src/components/ellipsis-text/__tests__/ellipsis-text.test.ts
  35. 1
      packages/effects/common-ui/src/components/ellipsis-text/ellipsis-text.vue
  36. 74
      packages/effects/common-ui/src/components/page/__tests__/page.test.ts
  37. 13
      packages/effects/common-ui/src/components/page/page-footer.vue
  38. 18
      packages/effects/common-ui/src/components/page/page-header.vue
  39. 11
      packages/effects/common-ui/src/components/page/page.ts
  40. 39
      packages/effects/common-ui/src/components/page/page.vue
  41. 2
      packages/effects/common-ui/src/ui/authentication/code-login.vue
  42. 2
      packages/effects/common-ui/src/ui/authentication/index.ts
  43. 2
      packages/effects/common-ui/src/ui/authentication/login-expired-modal.vue
  44. 2
      packages/effects/common-ui/src/ui/authentication/login.vue
  45. 2
      packages/effects/common-ui/src/ui/authentication/register.vue
  46. 0
      packages/effects/common-ui/src/ui/authentication/types.ts
  47. 10
      packages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vue
  48. 9
      packages/effects/layouts/src/widgets/lock-screen/typings.ts
  49. 8
      playground/src/views/demos/access/admin-visible.vue
  50. 8
      playground/src/views/demos/access/super-visible.vue
  51. 8
      playground/src/views/demos/access/user-visible.vue
  52. 10
      pnpm-lock.yaml
  53. 3
      vitest.config.ts

8
.github/workflows/deploy.yml

@ -7,7 +7,7 @@ on:
jobs:
deploy-push-playground-ftp:
name: Deploy Push Ftp
name: Deploy Push Playground Ftp
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-latest
steps:
@ -46,7 +46,7 @@ jobs:
local-dir: ./docs/.vitepress/dist/
deploy-push-antd-ftp:
name: Deploy Push Ftp
name: Deploy Push Antd Ftp
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-latest
steps:
@ -77,7 +77,7 @@ jobs:
local-dir: ./apps/web-antd/dist/
deploy-push-ele-ftp:
name: Deploy Push Ftp
name: Deploy Push Element Ftp
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-latest
steps:
@ -108,7 +108,7 @@ jobs:
local-dir: ./apps/web-ele/dist/
deploy-push-naive-ftp:
name: Deploy Push Ftp
name: Deploy Push Naive Ftp
if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-latest
steps:

3
package.json

@ -70,6 +70,8 @@
"@vben/turbo-run": "workspace:*",
"@vben/vite-config": "workspace:*",
"@vben/vsh": "workspace:*",
"@vitejs/plugin-vue": "^5.1.2",
"@vitejs/plugin-vue-jsx": "^4.0.0",
"@vue/test-utils": "^2.4.6",
"autoprefixer": "^10.4.20",
"cross-env": "^7.0.3",
@ -85,6 +87,7 @@
"unbuild": "^2.0.0",
"vite": "^5.4.0",
"vitest": "^2.0.5",
"vue": "^3.4.37",
"vue-tsc": "^2.0.29"
},
"engines": {

2
packages/@core/ui-kit/shadcn-ui/src/components/alert-dialog/alert-dialog.vue

@ -8,7 +8,7 @@ import {
AlertDialogHeader,
AlertDialog as AlertDialogRoot,
AlertDialogTitle,
} from '@vben-core/shadcn-ui/components/ui/alert-dialog';
} from '../ui/alert-dialog';
interface Props {
cancelText?: string;

6
packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue

@ -7,11 +7,7 @@ import type {
import { computed } from 'vue';
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@vben-core/shadcn-ui/components/ui/avatar';
import { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar';
interface Props extends AvatarRootProps, AvatarFallbackProps, AvatarImageProps {
alt?: string;

2
packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-background.vue

@ -1,5 +1,5 @@
<script lang="ts" setup>
import type { IBreadcrumb } from './interface';
import type { IBreadcrumb } from './types';
import { VbenIcon } from '../icon';

10
packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb.vue

@ -1,7 +1,9 @@
<script lang="ts" setup>
import type { IBreadcrumb } from './interface';
import type { IBreadcrumb } from './types';
import { ChevronDown } from '@vben-core/icons';
import { VbenIcon } from '../icon';
import {
Breadcrumb,
BreadcrumbItem,
@ -9,15 +11,13 @@ import {
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@vben-core/shadcn-ui/components/ui/breadcrumb';
} from '../ui/breadcrumb';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
import { VbenIcon } from '../icon';
} from '../ui/dropdown-menu';
interface Props {
breadcrumbs: IBreadcrumb[];

2
packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/index.ts

@ -1,4 +1,4 @@
export { default as VbenBreadcrumb } from './breadcrumb.vue';
export { default as VbenBackgroundBreadcrumb } from './breadcrumb-background.vue';
export type * from './interface';
export type * from './types';

0
packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/interface.ts → packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/types.ts

6
packages/@core/ui-kit/shadcn-ui/src/components/button/button.vue

@ -2,14 +2,12 @@
import { computed } from 'vue';
import { LoaderCircle } from '@vben-core/icons';
import {
type ButtonVariants,
buttonVariants,
} from '@vben-core/shadcn-ui/components/ui/button';
import { cn } from '@vben-core/shared';
import { Primitive, type PrimitiveProps } from 'radix-vue';
import { type ButtonVariants, buttonVariants } from '../ui/button';
interface Props extends PrimitiveProps {
class?: any;
disabled?: boolean;

4
packages/@core/ui-kit/shadcn-ui/src/components/button/icon-button.vue

@ -1,13 +1,13 @@
<script setup lang="ts">
import type { ButtonVariants } from '@vben-core/shadcn-ui/components/ui/button';
import type { ButtonVariants } from '../ui/button';
import { computed, useSlots } from 'vue';
import { VbenTooltip } from '@vben-core/shadcn-ui/components/tooltip';
import { cn } from '@vben-core/shared';
import { type PrimitiveProps } from 'radix-vue';
import { VbenTooltip } from '../tooltip';
import VbenButton from './button.vue';
interface Props extends PrimitiveProps {

4
packages/@core/ui-kit/shadcn-ui/src/components/checkbox/checkbox.vue

@ -1,10 +1,10 @@
<script setup lang="ts">
import type { CheckboxRootEmits, CheckboxRootProps } from 'radix-vue';
import { Checkbox } from '@vben-core/shadcn-ui/components/ui/checkbox';
import { useForwardPropsEmits } from 'radix-vue';
import { Checkbox } from '../ui/checkbox';
const props = defineProps<
{
name: string;

6
packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue

@ -9,6 +9,8 @@ import type { IContextMenuItem } from './interface';
import { computed } from 'vue';
import { useForwardPropsEmits } from 'radix-vue';
import {
ContextMenu,
ContextMenuContent,
@ -16,9 +18,7 @@ import {
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuTrigger,
} from '@vben-core/shadcn-ui/components/ui/context-menu';
import { useForwardPropsEmits } from 'radix-vue';
} from '../ui/context-menu';
const props = defineProps<
{

2
packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/dropdown-menu.vue

@ -11,7 +11,7 @@ import {
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
} from '../ui/dropdown-menu';
interface Props extends DropdownMenuProps {}

2
packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/dropdown-radio-menu.vue

@ -7,7 +7,7 @@ import {
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
} from '../ui/dropdown-menu';
interface Props extends DropdownMenuProps {}

6
packages/@core/ui-kit/shadcn-ui/src/components/hover-card/hover-card.vue

@ -7,13 +7,13 @@ import type {
import { computed } from 'vue';
import { useForwardPropsEmits } from 'radix-vue';
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from '@vben-core/shadcn-ui/components/ui/hover-card';
import { useForwardPropsEmits } from 'radix-vue';
} from '../ui/hover-card';
interface Props extends HoverCardRootProps {
class?: any;

5
packages/@core/ui-kit/shadcn-ui/src/components/input-password/input-password.vue

@ -2,13 +2,10 @@
import { ref, useSlots } from 'vue';
import { Eye, EyeOff } from '@vben-core/icons';
import {
type InputProps,
VbenInput,
} from '@vben-core/shadcn-ui/components/input';
import { useForwardProps } from 'radix-vue';
import { type InputProps, VbenInput } from '../input';
import PasswordStrength from './password-strength.vue';
interface Props extends InputProps {}

2
packages/@core/ui-kit/shadcn-ui/src/components/input/index.ts

@ -1,2 +1,2 @@
export { default as VbenInput } from './input.vue';
export type * from './interface';
export type * from './types';

2
packages/@core/ui-kit/shadcn-ui/src/components/input/input.vue

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { InputProps } from './interface';
import type { InputProps } from './types';
import { computed } from 'vue';

0
packages/@core/ui-kit/shadcn-ui/src/components/input/interface.ts → packages/@core/ui-kit/shadcn-ui/src/components/input/types.ts

2
packages/@core/ui-kit/shadcn-ui/src/components/pin-input/index.ts

@ -1,3 +1,3 @@
export { default as VbenPinInput } from './input.vue';
export type * from './interface';
export type * from './types';

10
packages/@core/ui-kit/shadcn-ui/src/components/pin-input/input.vue

@ -1,14 +1,10 @@
<script setup lang="ts">
import type { PinInputProps } from './interface';
import type { PinInputProps } from './types';
import { computed, ref, watch } from 'vue';
import { VbenButton } from '@vben-core/shadcn-ui/components/button';
import {
PinInput,
PinInputGroup,
PinInputInput,
} from '@vben-core/shadcn-ui/components/ui/pin-input';
import { VbenButton } from '../button';
import { PinInput, PinInputGroup, PinInputInput } from '../ui/pin-input';
defineOptions({
inheritAttrs: false,

0
packages/@core/ui-kit/shadcn-ui/src/components/pin-input/interface.ts → packages/@core/ui-kit/shadcn-ui/src/components/pin-input/types.ts

6
packages/@core/ui-kit/shadcn-ui/src/components/popover/popover.vue

@ -7,13 +7,13 @@ import type {
import { computed } from 'vue';
import { useForwardPropsEmits } from 'radix-vue';
import {
PopoverContent,
Popover as PopoverRoot,
PopoverTrigger,
} from '@vben-core/shadcn-ui/components/ui/popover';
import { useForwardPropsEmits } from 'radix-vue';
} from '../ui/popover';
interface Props extends PopoverRootProps {
class?: any;

6
packages/@core/ui-kit/shadcn-ui/src/components/scrollbar/scrollbar.vue

@ -1,12 +1,10 @@
<script setup lang="ts">
import { ref } from 'vue';
import {
ScrollArea,
ScrollBar,
} from '@vben-core/shadcn-ui/components/ui/scroll-area';
import { cn } from '@vben-core/shared';
import { ScrollArea, ScrollBar } from '../ui/scroll-area';
interface Props {
class?: any;
horizontal?: boolean;

4
packages/@core/ui-kit/shadcn-ui/src/components/segmented/index.ts

@ -1,3 +1,3 @@
export type * from './interface';
export { default as VbenSegmented } from './segmented.vue';
export type * from './types';

9
packages/@core/ui-kit/shadcn-ui/src/components/segmented/segmented.vue

@ -1,16 +1,11 @@
<script setup lang="ts">
import type { SegmentedItem } from './interface';
import type { SegmentedItem } from './types';
import { computed } from 'vue';
import {
Tabs,
TabsContent,
TabsList,
} from '@vben-core/shadcn-ui/components/ui/tabs';
import { TabsTrigger } from 'radix-vue';
import { Tabs, TabsContent, TabsList } from '../ui/tabs';
import TabsIndicator from './tabs-indicator.vue';
interface Props {

0
packages/@core/ui-kit/shadcn-ui/src/components/segmented/interface.ts → packages/@core/ui-kit/shadcn-ui/src/components/segmented/types.ts

13
packages/@core/ui-kit/shadcn-ui/src/components/sheet/sheet.vue

@ -1,11 +1,10 @@
<script setup lang="ts">
import { computed, useSlots } from 'vue';
import {
VbenButton,
VbenIconButton,
} from '@vben-core/shadcn-ui/components/button';
import { VbenScrollbar } from '@vben-core/shadcn-ui/components/scrollbar';
import { X } from 'lucide-vue-next';
import { VbenButton, VbenIconButton } from '../button';
import { VbenScrollbar } from '../scrollbar';
import {
Sheet,
SheetClose,
@ -15,9 +14,7 @@ import {
SheetHeader,
SheetTitle,
SheetTrigger,
} from '@vben-core/shadcn-ui/components/ui/sheet';
import { X } from 'lucide-vue-next';
} from '../ui/sheet';
interface Props {
cancelText?: string;

2
packages/@core/ui-kit/shadcn-ui/src/components/tooltip/tooltip.vue

@ -8,7 +8,7 @@ import {
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@vben-core/shadcn-ui/components/ui/tooltip';
} from '../ui/tooltip';
interface Props {
contentClass?: any;

3
packages/@core/ui-kit/shadcn-ui/src/components/ui/alert-dialog/AlertDialogAction.vue

@ -1,11 +1,12 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { buttonVariants } from '@vben-core/shadcn-ui/components/ui/button';
import { cn } from '@vben-core/shared';
import { AlertDialogAction, type AlertDialogActionProps } from 'radix-vue';
import { buttonVariants } from '../button';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & AlertDialogActionProps
>();

3
packages/@core/ui-kit/shadcn-ui/src/components/ui/alert-dialog/AlertDialogCancel.vue

@ -1,11 +1,12 @@
<script setup lang="ts">
import { computed, type HTMLAttributes } from 'vue';
import { buttonVariants } from '@vben-core/shadcn-ui/components/ui/button';
import { cn } from '@vben-core/shared';
import { AlertDialogCancel, type AlertDialogCancelProps } from 'radix-vue';
import { buttonVariants } from '../button';
const props = defineProps<
{ class?: HTMLAttributes['class'] } & AlertDialogCancelProps
>();

3
packages/@core/ui-kit/shadcn-ui/src/components/ui/toggle-group/ToggleGroup.vue

@ -1,7 +1,8 @@
<script setup lang="ts">
import type { toggleVariants } from '@vben-core/shadcn-ui/components/ui/toggle';
import type { VariantProps } from 'class-variance-authority';
import type { toggleVariants } from '../toggle';
import { computed, type HTMLAttributes, provide } from 'vue';
import { cn } from '@vben-core/shared';

3
packages/@core/ui-kit/shadcn-ui/src/components/ui/toggle-group/ToggleGroupItem.vue

@ -3,7 +3,6 @@ import type { VariantProps } from 'class-variance-authority';
import { computed, type HTMLAttributes, inject } from 'vue';
import { toggleVariants } from '@vben-core/shadcn-ui/components/ui/toggle';
import { cn } from '@vben-core/shared';
import {
@ -12,6 +11,8 @@ import {
useForwardProps,
} from 'radix-vue';
import { toggleVariants } from '../toggle';
type ToggleGroupVariants = VariantProps<typeof toggleVariants>;
const props = defineProps<

39
packages/effects/common-ui/src/components/ellipsis-text/__tests__/ellipsis-text.test.ts

@ -0,0 +1,39 @@
import { mount } from '@vue/test-utils';
import { describe, expect, it } from 'vitest';
import { EllipsisText } from '..';
describe('ellipsis-text.vue', () => {
it('renders the correct content and truncates text', async () => {
const wrapper = mount(EllipsisText, {
props: {
line: 1,
title: 'Test Title',
},
slots: {
default: 'This is a very long text that should be truncated.',
},
});
expect(wrapper.text()).toContain('This is a very long text');
// 检查 ellipsis 是否应用了正确的 class
const ellipsis = wrapper.find('.truncate');
expect(ellipsis.exists()).toBe(true);
});
it('expands text on click if expand is true', async () => {
const wrapper = mount(EllipsisText, {
props: {
expand: true,
line: 1,
},
slots: {
default: 'This is a very long text that should be truncated.',
},
});
const ellipsis = wrapper.find('.truncate');
await ellipsis.trigger('click');
expect(wrapper.emitted('expandChange')).toBeTruthy();
});
});

1
packages/effects/common-ui/src/components/ellipsis-text/ellipsis-text.vue

@ -51,6 +51,7 @@ interface Props {
*/
tooltipOverlayStyle?: CSSProperties;
}
const props = withDefaults(defineProps<Props>(), {
expand: false,
line: 1,

74
packages/effects/common-ui/src/components/page/__tests__/page.test.ts

@ -0,0 +1,74 @@
import { mount } from '@vue/test-utils';
import { describe, expect, it } from 'vitest';
import { Page } from '..';
describe('page.vue', () => {
it('renders title when passed', () => {
const wrapper = mount(Page, {
props: {
title: 'Test Title',
},
});
expect(wrapper.text()).toContain('Test Title');
});
it('renders description when passed', () => {
const wrapper = mount(Page, {
props: {
description: 'Test Description',
},
});
expect(wrapper.text()).toContain('Test Description');
});
it('renders default slot content', () => {
const wrapper = mount(Page, {
slots: {
default: '<p>Default Slot Content</p>',
},
});
expect(wrapper.html()).toContain('<p>Default Slot Content</p>');
});
it('renders footer slot when showFooter is true', () => {
const wrapper = mount(Page, {
props: {
showFooter: true,
},
slots: {
footer: '<p>Footer Slot Content</p>',
},
});
expect(wrapper.html()).toContain('<p>Footer Slot Content</p>');
});
it('applies the custom contentClass', () => {
const wrapper = mount(Page, {
props: {
contentClass: 'custom-class',
},
});
const contentDiv = wrapper.find('.m-4');
expect(contentDiv.classes()).toContain('custom-class');
});
it('does not render description slot if description prop is provided', () => {
const wrapper = mount(Page, {
props: {
description: 'Test Description',
},
slots: {
description: '<p>Description Slot Content</p>',
},
});
expect(wrapper.text()).toContain('Test Description');
expect(wrapper.html()).not.toContain('Description Slot Content');
});
});

13
packages/effects/common-ui/src/components/page/page-footer.vue

@ -1,13 +0,0 @@
<script setup lang="ts">
defineOptions({
name: 'PageFooter',
});
</script>
<template>
<div
class="bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4"
>
<slot></slot>
</div>
</template>

18
packages/effects/common-ui/src/components/page/page-header.vue

@ -1,18 +0,0 @@
<script setup lang="ts">
import type { PageHeaderProps } from './page.ts';
defineOptions({
name: 'PageHeader',
});
const props = defineProps<PageHeaderProps>();
</script>
<template>
<div class="bg-card px-6 py-4">
<div class="mb-2 flex justify-between text-xl font-bold leading-10">
{{ props.title }}
</div>
<slot></slot>
</div>
</template>

11
packages/effects/common-ui/src/components/page/page.ts

@ -1,11 +0,0 @@
interface PageHeaderProps {
title?: string;
description?: string;
}
interface Props extends PageHeaderProps {
contentClass?: string;
showFooter?: boolean;
}
export type { PageHeaderProps, Props };

39
packages/effects/common-ui/src/components/page/page.vue

@ -1,14 +1,17 @@
<script setup lang="ts">
import type { Props } from './page';
import PageFooter from './page-footer.vue';
import PageHeader from './page-header.vue';
interface Props {
title?: string;
description?: string;
contentClass?: string;
showFooter?: boolean;
}
defineOptions({
name: 'Page',
});
const props = withDefaults(defineProps<Props>(), {
contentClass: '',
description: '',
showFooter: false,
title: '',
@ -17,22 +20,26 @@ const props = withDefaults(defineProps<Props>(), {
<template>
<div class="relative h-full">
<PageHeader
<div
v-if="description || $slots.description || title"
:title="props.title"
class="bg-card px-6 py-4"
>
<template #default>
<template v-if="description">{{ description }}</template>
<slot v-else name="description"></slot>
</template>
</PageHeader>
<div class="mb-2 flex justify-between text-xl font-bold leading-10">
{{ title }}
</div>
<template v-if="description">{{ description }}</template>
<slot v-else name="description"></slot>
</div>
<div :class="contentClass" class="m-4">
<slot></slot>
</div>
<PageFooter v-if="props.showFooter">
<template #default>
<slot name="footer"></slot>
</template>
</PageFooter>
<div
v-if="props.showFooter"
class="bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4"
>
<slot name="footer"></slot>
</div>
</div>
</template>

2
packages/effects/common-ui/src/ui/authentication/code-login.vue

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { LoginCodeEmits } from './typings';
import type { LoginCodeEmits } from './types';
import { computed, onBeforeUnmount, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';

2
packages/effects/common-ui/src/ui/authentication/index.ts

@ -8,4 +8,4 @@ export type {
AuthenticationProps,
LoginAndRegisterParams,
LoginCodeParams,
} from './typings';
} from './types';

2
packages/effects/common-ui/src/ui/authentication/login-expired-modal.vue

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { AuthenticationProps, LoginAndRegisterParams } from './typings';
import type { AuthenticationProps, LoginAndRegisterParams } from './types';
import { useForwardPropsEmits } from '@vben/hooks';
import {

2
packages/effects/common-ui/src/ui/authentication/login.vue

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { AuthenticationProps, LoginEmits } from './typings';
import type { AuthenticationProps, LoginEmits } from './types';
import { computed, reactive } from 'vue';
import { useRouter } from 'vue-router';

2
packages/effects/common-ui/src/ui/authentication/register.vue

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { RegisterEmits } from './typings';
import type { RegisterEmits } from './types';
import { computed, reactive } from 'vue';
import { useRouter } from 'vue-router';

0
packages/effects/common-ui/src/ui/authentication/typings.ts → packages/effects/common-ui/src/ui/authentication/types.ts

10
packages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vue

@ -1,6 +1,4 @@
<script setup lang="ts">
import type { RegisterEmits } from './typings';
import { computed, reactive } from 'vue';
import {
@ -19,6 +17,14 @@ interface Props {
text?: string;
}
interface LockAndRegisterParams {
lockScreenPassword: string;
}
interface RegisterEmits {
submit: [LockAndRegisterParams];
}
defineOptions({
name: 'LockScreenModal',
});

9
packages/effects/layouts/src/widgets/lock-screen/typings.ts

@ -1,9 +0,0 @@
interface LockAndRegisterParams {
lockScreenPassword: string;
}
interface RegisterEmits {
submit: [LockAndRegisterParams];
}
export type { LockAndRegisterParams, RegisterEmits };

8
playground/src/views/demos/access/admin-visible.vue

@ -1,7 +1,11 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { Fallback } from '@vben/common-ui';
</script>
<template>
<Page description="当前页面仅 Admin 账号可见" title="页面访问测试" />
<Fallback
description="当前页面仅 Admin 账号可见"
status="coming-soon"
title="页面访问测试"
/>
</template>

8
playground/src/views/demos/access/super-visible.vue

@ -1,7 +1,11 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { Fallback } from '@vben/common-ui';
</script>
<template>
<Page description="当前页面仅 Super 账号可见" title="页面访问测试" />
<Fallback
description="当前页面仅 Super 账号可见"
status="coming-soon"
title="页面访问测试"
/>
</template>

8
playground/src/views/demos/access/user-visible.vue

@ -1,7 +1,11 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { Fallback } from '@vben/common-ui';
</script>
<template>
<Page description="当前页面仅 User 账号可见" title="页面访问测试" />
<Fallback
description="当前页面仅 User 账号可见"
status="coming-soon"
title="页面访问测试"
/>
</template>

10
pnpm-lock.yaml

@ -55,6 +55,12 @@ importers:
'@vben/vsh':
specifier: workspace:*
version: link:scripts/vsh
'@vitejs/plugin-vue':
specifier: ^5.1.2
version: 5.1.2(vite@5.4.0(@types/node@22.2.0)(sass@1.77.8)(terser@5.31.3))(vue@3.4.37(typescript@5.5.4))
'@vitejs/plugin-vue-jsx':
specifier: ^4.0.0
version: 4.0.0(vite@5.4.0(@types/node@22.2.0)(sass@1.77.8)(terser@5.31.3))(vue@3.4.37(typescript@5.5.4))
'@vue/test-utils':
specifier: ^2.4.6
version: 2.4.6
@ -100,6 +106,9 @@ importers:
vitest:
specifier: ^2.0.5
version: 2.0.5(@types/node@22.2.0)(jsdom@24.1.1)(sass@1.77.8)(terser@5.31.3)
vue:
specifier: ^3.4.37
version: 3.4.37(typescript@5.5.4)
vue-tsc:
specifier: ^2.0.29
version: 2.0.29(typescript@5.5.4)
@ -3344,6 +3353,7 @@ packages:
'@ls-lint/ls-lint@2.2.3':
resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==}
cpu: [x64, arm64, s390x]
os: [darwin, linux, win32]
hasBin: true

3
vitest.config.ts

@ -1,6 +1,9 @@
import Vue from '@vitejs/plugin-vue';
import VueJsx from '@vitejs/plugin-vue-jsx';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [Vue(), VueJsx()],
test: {
environment: 'jsdom',
},

Loading…
Cancel
Save